项目地址: http://code.google.com/p/jrest4guice/
Demo演示: http://www.rest4g.org/full
http://www.javaeye.com/topic/201103 一个Java的Restful服务框架,支持JPA、JAAS、分布式资源对象 项目地址:http://code.google.com/p/jrest4guice/ 一个轻量级的基于Google Guice的Restful服务框架,支持JPA、JAAS、分布式资源对象,对OSGI的支持也在计划中. (Demo演示: http://cnoss.vicp.net/ ) 请大家直接从SVN中获取JRest4Guice工程即可 svn checkout http://jrest4guice.googlecode.com/svn/trunk/ jrest4guice-read-only (使用Maven)
当前版本: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、JRest4Guice-sample、libraries三个工程即可
http://jrest4guice.googlecode.com/files/JRest4Guice-0.8.1_Jpa4Guice-0.1-with-example.zip
http://jrest4guice.googlecode.com/files/JRest4Guice-0.8.1-with-example.zip
http://jrest4guice.googlecode.com/files/JRest4Guice.rar
http://jrest4guice.googlecode.com/svn/trunk/