`
cnoss
  • 浏览: 15532 次
  • 性别: Icon_minigender_1
  • 来自: 广州
文章分类
社区版块
存档分类
最新评论

一个Java的Restful服务框架,支持JPA、JAAS、分布式资源对象

阅读更多
项目地址: http://code.google.com/p/jrest4guice/
Demo演示: http://www.rest4g.org/full


当前版本:0.9.0 preview

特点:
  • 基于Google guice
  • 零配置,服务的自动扫描注册
  • 非侵入式,用户不需要实现特定的接口来实现Restful服务,只需要通过@RESTful来声明
  • 支持Post. Get. Put. Delete操作
  • 支持对Get操作的缓存机制,实现动态资源静态化(通过@Cache标注声明)
  • 灵活的注入(支持上下文环境request/response/session以及参数的自动注入)
  • 根据客户端要求返回不同类型的数据(xml/json/html)
  • 通过@PageFlow实现对MVC module2的支持,输出结果支持CTE、Velocity、Freemarker和Spry模板引擎(当返回类型是text/html时才有效)
  • 支持JPA,通过增强的BaseEntityManager实现实体的CRUD
  • 支持事务,通过@Transactional注解声明事务的类型
  • 支持JAAS,通过@RolesAllowed注解声明操作所需要的角色
  • 支持Hibernate validator
  • 支持拦截器 (interceptor)
  • 支持分布式资源对象,实现业务逻辑的分布式部署
  • 提供了与Struts2集成的插件

下一步计划:
  • OSGI的支持
  • 分布式事务的支持

代码示例:
//=======================================================
//资源类
//=======================================================

/**
 * @author <a href="mailto:zhangyouqun@gmail.com">cnoss (QQ:86895156)</a>
 * 联系人的资源对象
 * 声明remoteable为真(可以通过@RemoteReference的注入到任一资源对象,通常用在跨应用的资源调用上)
 */
@RESTful(name = "ContactResource", remoteable = true)
@Path( { "/contact", "/contacts/{contactId}" })
public class ContactResource {
	@Inject
	private ContactService service;//注入联系人管理的服务对象

	/**
	 * 创建新的联系人 
	 * PageFlow :当服务端返回类型是Text/Html类型时,重定向用户的请求到指定的页面,实现最基本功能的MVC。
	 * 		在这里,指明当操作成功时,重定向到/contacts,当操作失败时,将用户请求重定向到/contact。
	 * @param contact 联系人实体
	 */
	@Post
	@PageFlow(success = @PageInfo(value = "/contacts",type=ResultType.REDIRECT)
			,error=@PageInfo(value="/contact",type=ResultType.REDIRECT))
	public String createContact(@ModelBean Contact contact) {
		return this.service.createContact(contact);
	}

	/**
	 * 修改联系人信息 
	 * @param contact 联系人实体
	 */
	@Put
	@PageFlow(success = @PageInfo(value = "/contacts",type=ResultType.REDIRECT)
			,error=@PageInfo(value="/contact",type=ResultType.REDIRECT))
	public void putContact(@ModelBean Contact contact) {
		this.service.updateContact(contact);
	}

	/**
	 * 显示联系人列表 
	 * @param page 页码 
	 * @param size 每页记录数
	 */
	@Get
	@Path("/contacts")
	@PageFlow(success = @PageInfo(value = "/template/contacts.ctl"))
	public Page<Contact> listContacts(int page, int size) {
		return this.service.listContacts(page, size);
	}

	/**
	 * 显示单个联系人的信息 
	 * @param contactId 联系对象ID
	 */
	@Get
	@PageFlow(success = @PageInfo(value = "/template/contactDetail.ctl"))
	public Contact getContact(@Parameter("contactId") String contactId) {
		if(contactId == null)
			return new Contact();
		return this.service.findContactById(contactId);
	}

	/**
	 * 删除指定ID的联系人 
	 * @param contactId 联系对象ID
	 */
	@Delete
	@PageFlow(success = @PageInfo(value = "/contacts",type=ResultType.REDIRECT))
	public void deleteContact(@Parameter("contactId") String contactId) {
		this.service.deleteContact(contactId);
	}
}


//=======================================================
//业务类
//=======================================================

/**
 * 
 * @author <a href="mailto:zhangyouqun@gmail.com">cnoss (QQ:86895156)</a>
 *
 */
@Transactional//事务支持,缺省为TransactionalType.REQUIRED,可以在方法中覆写
@Interceptors({//自定义的拦截器(类级别的,作用于所有的方法,可以在方法中覆写)
	@Interceptor(TestInterceptor.class),
	@Interceptor(LogInterceptor.class)
})
public class ContactService{
	//注入实体管理器
	@Inject
	private BaseEntityManager<String, Contact> entityManager;

	public String createContact(Contact contact) {
		if (contact == null)
			throw new RuntimeException("联系人的内容不能为空");

		if (this.entityManager.loadByNamedQuery("byName", contact.getName()) != null) {
			throw new RuntimeException("联系人的姓名相同,请重新输入");
		}

		this.entityManager.create(contact);
		return contact.getId();
	}

	public void deleteContact(String contactId) {
		String[] ids = contactId.split(",");
		Contact contact;
		for (String id : ids) {
			contact = this.findContactById(id);
			if (contact == null)
				throw new RuntimeException("联系人不存在");
			this.entityManager.delete(contact);
		}
	}

	@Transactional(type=TransactionalType.READOLNY)
	public Contact findContactById(String contactId) {
		return this.entityManager.load(contactId);
	}

	@Transactional(type=TransactionalType.READOLNY)//覆盖类级别的事务类型为只读
	@Interceptor(ListContactsInterceptor.class)//覆盖类级别的拦截器
	public Page<Contact> listContacts(int pageIndex, int pageSize)
			throws RuntimeException {
		return this.entityManager.pageByNamedQuery("list",
				new Pagination(pageIndex, pageSize));
	}

	public void updateContact(Contact contact) {
		if (contact == null)
			throw new RuntimeException("联系人的内容不能为空");
		
		Contact tmpContact = this.entityManager.loadByNamedQuery("byName", contact.getName());
		if(tmpContact != null && !contact.getId().equals(tmpContact.getId()))
			throw new RuntimeException("联系人的姓名相同,请重新输入");

		this.entityManager.update(contact);
	}
}


//=======================================================
//远程调用的案例
//=======================================================

/**
 * 
 * @author <a href="mailto:zhangyouqun@gmail.com">cnoss (QQ:86895156)</a>
 *
 */
@Path( { "/testCallRemote"})
public class TestRemoteResource {
	@Inject
	@RemoteReference//注入远程资源对象
	private ContactResource service;

	@Get
	public Page<Contact> listContacts(int page, int size) {
		return this.service.listContacts(page, size);
	}
}



请大家直接从SVN中获取JRest4Guice工程即可(使用Maven)

真诚希望大家提出宝贵意见,联系方式:
  • Email:zhangyouqun@gmail.com
  • QQ: 86895156
  • MSN: zhangyouqun@hotmail.com
分享到:
评论
21 楼 cnoss 2008-06-15  
  • 我对JRest4Guice的定义是:A restful web service api base on google guice。旨在为java提供一个简单易用的Rest架构风格的API,所以可以看作是一个以资源为中心的数据仓库,为不同类型的客户端提供不同的数据格式(json、xml、text/html、javabean等)。
  • 提供对模板引擎的支持,是对返回类型为text/html时的一种装饰,可以灵活的渲染出不同样式的视图给客户端。至于页面流程的控制与转向交由其它成熟的MVC框架去处理(当然,不排除JRest4Guice今后也会提供类似的功能 )。我做的那个demo中就是将JRest4Guice结合了Adobe Spry,所有的页面控制全部交由前端JS来控制,JRest4Guice只是一个数据服务仓库。
  • JRest4Guice的文档正在整理当中,目前放出的0.9.0 preview版所涵盖的功能与特点就是文章开头处所介绍的。


非常感谢大家的支持,有你们的支持,我们会做得更好,fighting !!!
20 楼 store88 2008-06-15  
JRest4Guice还是不要提供完整的MVC支持吧
那guice之类的来做其它层吧....

ps 楼主再加一个完整的release note吧

楼主很热情的
一下子对于我这个门外汉的建议就增加了个对freemarker的支持
希望更多的人能看到楼主的热情
19 楼 minidarkey 2008-06-14  
这么快又增加了对模板引擎的支持
btw,请问JRest4Guice是否将会提供完整的MVC支持?
18 楼 bubble 2008-06-14  
学习ing
17 楼 BaSaRa 2008-06-13  
支持领导一手
16 楼 cnoss 2008-06-13  
fireflyc 写道
注解,又是注解。
改动注解就要重新编译。
已经没有了配置文件的有点,所以也就是说和硬编码没有什么区别。

动态语言代码就是配置文件~但是Java不行。


有关注解与配置文件的争论太多,我个人感觉没有谁对谁错,对此本文也不作讨论。
15 楼 fireflyc 2008-06-13  
注解,又是注解。
改动注解就要重新编译。
已经没有了配置文件的有点,所以也就是说和硬编码没有什么区别。

动态语言代码就是配置文件~但是Java不行。
14 楼 fengzi_kuang 2008-06-13  
比较感兴趣。先关注一下。
13 楼 backbase 2008-06-13  
非常强汗,受益匪浅,学习中!永远支持楼主。。。。。
12 楼 cnoss 2008-06-13  
最新变动 !!!

JRest4Guice已转成Maven方式的管理,请大家下载原代码时注意。

本次变动采纳了
agapple 写道
小建议一下, 能否像webwork一样,使用maven进行管理依赖

这样checkout就不需要下载额外的jar
的建议,谢谢agapple提出的宝贵意见。
11 楼 cnoss 2008-06-13  
yizhuo 写道
根据我使用Guice的经验,应该尽量使用Constructor injection,用field injection测试会非常困难。

你的annotation有些像JAX-RS,是否有支持JAX-RS的想法?

[list]
  • 1、先发一段引用来看一下三种不同方式注入的区别
  • 引用

    Guice best practices
    Field vs. method vs. constructor injection

    Field injection

    * + Most compact syntax (good for a trivial custom provider, e.g.)
    * - Can't take any special action upon injection
    * - Your class is not testable!

    Method injection

    * + Isn't field injection
    * + Only thing that works for some strange edge cases

    Constructor injection

    * + Fields can be final!
    * + Injection cannot possibly have been skipped, even if Guice is not in the picture
    * + Easy to see dependencies at a glance
    * + It's what the idea of construction is all about
    * - No optional injections
    * - Useless when Guice can't do instantiation itself, e.g. a servlet
    * - Subclasses need to "know about" the injections needed by their superclasses
    * - Less convenient for tests that only "care about" one of the parameters


    以上说明得很清楚,三种方式各有优缺点,我的理解是:对于非自定义提供者的使用构造器级注入,对于要带业务逻辑的使用方法级注入,而对于自定义提供者的采用属性级注入。我的案例中有以下的代码片段:

    [list=1]
  • 属性级的注入,因为使用了自定义提供者
  •     @Inject
        @RemoteReference //注入远程资源对象的引用
        private ContactResource service;   
    

  • 方法级的注入,因为要做额外的操作
  • 	private BaseEntityManager<String, Contact> entityManager;
    
    	@Inject
    	private void init(EntityManager em) {
    		this.entityManager = new BaseEntityManager<String, Contact>(
    				Contact.class, em);
    	}
    

  • 构造器级的注入,可以将我之前的代码改为
  • 	private ContactService service;
    	
    	@Inject
    	public ContactResource(ContactService service){
    		this.service = service;
    	}
    

    [/list]
  • 2、因为JSR311还没有最终发布,所以只是借鉴其中的一些规范。我个人也不太喜欢JSR311中子资源(sub resource)的实现方式。
  • [/list]
    10 楼 yizhuo 2008-06-13  
    根据我使用Guice的经验,应该尽量使用Constructor injection,用field injection测试会非常困难。

    你的annotation有些像JAX-RS,是否有支持JAX-RS的想法?
    9 楼 niefeng 2008-06-12  
    我的Email:nieyunf@gmail.com
    8 楼 niefeng 2008-06-12  
    上手起来真是方便,没想到还能通过这么简单代码实现如此强大的功能!楼主,能不能加入你的团队?谢谢!
    7 楼 aeoluskim 2008-06-12  
    顶下,好贴
    6 楼 niefeng 2008-06-12  
    好东西!正在学这个,当一个下去学习学习
    5 楼 jander 2008-06-08  
    支持!
    下载来,学习一下。
    4 楼 minidarkey 2008-06-07  
    支持事务,通过@Transactional注解声明事务的类型
    支持JAAS,通过@RolesAllowed注解声明操作所需要的角色
    支持分布式资源对象,实现业务逻辑的分布式部署

    这几点非常不错,很诱人 ,我先下载代码研究一下,期待对OSGI的支持
    3 楼 supper008 2008-06-07  
    不错!
    2 楼 cnoss 2008-06-07  
    • 1、将程序员从XML与JavaBean之间的来回切换中解放了出来。保持了思维的连贯性。
    • 2、弱化了DAO层,将其替换成BaseEntityManager,即使现在很多人用的动态DAO,虽然不用写实现,但是还是要写一堆看上去很怪的只有接口没有实现的DAO,加重了执行过程中的反射压力。
    • 3、BaseEntityManager增强并集成了我们常用的DAO功能,(查询、分页、动态参数构造等)减少了重复代码。
    • 4、注解式的权限声明为我们实现RBAC的权限系统提供了底层的支持。


    相关推荐

      Java服务器高级编程

      Java EE(现更名为Jakarta EE)是一个用于构建企业级应用的框架,包括了如EJB(Enterprise JavaBeans)、JPA(Java Persistence API)、JSF(JavaServer Faces)等技术,用于数据库交互、事务管理和服务层设计。...

      Java 服务器高级编程

      4. **Java Persistence API (JPA)**:JPA是Java标准的ORM(对象关系映射)框架,用于简化数据库操作。它允许开发者使用Java对象而不是SQL来操作数据,通过实体类和映射文件实现数据库表的映射。 5. **Java Message ...

      java2企业服务器高级编程

      Hibernate是JPA的一个流行实现,提供了更丰富的功能和更高的性能。 7. **Spring框架**:Spring以其依赖注入和面向切面编程(AOP)理念,成为Java企业级开发的首选框架。Spring还提供了完整的MVC(模型-视图-控制器...

      J2EE帮助文档 Java EE 5.0

      Java EE(以前称为J2EE)是Java平台上用于构建企业级分布式应用程序的框架。它提供了一个标准的、组件化的开发模型,支持多层架构,包括客户端、Web服务器、应用服务器和数据库。Java EE 5.0是这个平台的一个重要...

      Thinking in Enterprise Java

      1. **Java企业版(Java EE)**:Java企业版,也称为Java 2 Platform, Enterprise Edition,是Java平台的一个版本,专为开发和部署多层、分布式、面向服务的Web应用程序而设计。Java EE提供了许多企业级服务,如...

      java ee基础使用教程

      Java EE(Java Platform, Enterprise Edition)是Java平台上用于构建企业级Web应用的框架集合,它提供了丰富的服务和组件,使得开发者能够快速开发出分布式、多层架构的应用程序。本教程由知名讲师郑阿奇编著,旨在...

      Java EE 5 Tutorial (PDF文件)

      J2EE(Java 2 Platform, Enterprise Edition)是一个用于构建分布式、多层的企业级应用程序的框架,它提供了各种服务和API,便于开发人员快速构建可扩展且健壮的应用。 在Java EE 5中,有几个关键的知识点值得我们...

      Java_Web整合开发王者归来_16

      2. **Java EE(企业版)**:包括了诸如EJB(Enterprise JavaBeans)、JMS(Java Message Service)、JPA(Java Persistence API)等组件,它们提供了一套完整的框架来构建分布式、多层的企业级应用。 3. **Spring...

      java EE水果管理系统 Java学习资料

      通过这个“Java EE水果管理系统”的学习,你可以深入了解Java EE的各个组成部分,并学会如何将它们组合在一起构建一个完整的应用。实践中,你需要理解和配置应用服务器(如Tomcat、WildFly),编写Java代码,设置...

      java试题第一套

      J2EE(Java 2 Platform, Enterprise Edition)是Java平台的一个版本,专为构建分布式、多层的企业级应用程序而设计。在J2EE试题中,我们通常会看到以下几个核心知识点: 1. **Java基础知识**:这是所有J2EE学习的...

      java购物车系统

      Java提供了JTA(Java Transaction API)和JPA(Java Persistence API)来支持分布式事务处理。 4. **并发控制**:在高并发场景下,多个用户可能会同时操作同一购物车,因此需要处理并发问题。Java提供了...

      轻量级Java EE企业应用实战(第3版)04pdf

      Java EE(Java Platform, Enterprise Edition),是Java平台的一个版本,专为构建企业级应用而设计。它提供了大量的API和服务,包括但不限于:Servlet、JSP(JavaServer Pages)、EJB(Enterprise JavaBeans)、JMS...

      345_Java电子政务系统_网站调查_便民信息服务系统.rar

      4. 安全性:Java提供了一系列的安全机制,如JAAS(Java Authentication and Authorization Service)用于用户身份验证和权限管理,SSL/TLS协议支持加密通信,防止数据泄露。此外,还可以利用Java的过滤器(Filter)...

      J2EE框架(笔记)

      - **JPA(Java Persistence API)**:提供了ORM(对象关系映射)框架,如Hibernate,使Java对象可以透明地映射到数据库表。 5. **Web服务** - **JAX-WS(Java API for XML Web Services)**:用于创建和消费SOAP...

      2019年JAVAEE全套视频.zip

      最后,Java EE的安全性也是一个重要的主题,包括认证和授权机制,如JAAS(Java Authentication and Authorization Service),以及HTTPS、SSL/TLS等网络安全协议的应用。 2019年的黑马JAVA EE全套视频,很可能是...

      java教程\TSG-J2 J2EE高级课程和演示代码

      7. **JPA(Java Persistence API)**:JPA是Java标准的ORM(Object-Relational Mapping)框架,用于处理Java对象和关系数据库之间的映射。教程可能涵盖实体类的定义、持久化上下文的使用以及查询语言JQL。 8. **Web...

      Java EE 6 标准与规范(中文版)

      Java EE 6 提供了一个强大的事务管理框架,支持分布式事务。 **3.2 标准** - **JTA 1.1**:定义了事务服务接口。 - **JTS 1.1**:提供了一个事务服务的参考实现。 **3.3 事务的互用性** 支持与其他Java EE版本的...

      精通J2EE pdf

      8. **Java Transaction API (JTA)**:JTA为应用程序提供了一个统一的事务管理接口,支持分布式事务处理,确保数据的一致性。 9. **Java Authentication and Authorization Service (JAAS)**:JAAS提供了安全框架,...

      Java ee试卷两份

      Java EE,全称为Java Platform, Enterprise Edition,是Java平台针对企业级应用开发的版本,它提供了丰富的组件和服务,用于构建分布式、多层的企业系统。这两份试卷,"Java_EEB卷.doc"和"JAVA_EE期末复习参考题.doc...

      《J2EE应用框架设计与项目开发》

      J2EE(Java Platform, Enterprise Edition)是一个用于开发和部署多层分布式应用程序的平台,它提供了丰富的API和服务,以支持各种企业级功能,如事务管理、安全性、数据库连接池和消息队列等。 在J2EE应用框架设计...

    Global site tag (gtag.js) - Google Analytics