- 基于Google guice
- 零配置,服务的自动扫描注册
- 非侵入式,用户不需要实现特定的接口来实现Restful服务
- 支持Post. Get. Put. Delete操作
- 灵活的注入(支持上下文环境request/response/session以及参数的自动注入)
- 根据客户端要求返回不同类型的数据(xml/json/html)
- 支持Velocity、Freemarker和Spry模板引擎(当返回类型是text/html时才有效,参见@ViewTemplate)
- 支持JPA,通过增强的BaseEntityManager实现实体的CRUD
- 支持事务,通过@Transactional注解声明事务的类型
- 支持JAAS,通过@RolesAllowed注解声明操作所需要的角色
- 支持分布式资源对象,实现业务逻辑的分布式部署
下一步计划:
- OSGI的支持
- 分布式事务的支持
代码示例:
- /**
- *
- * @author <a href="mailto:zhangyouqun@gmail.com">cnoss (QQ:86895156)</a>
- * 联系人的资源对象,并声明为Remote(可以通过@RemoteService的注入到任一资源对象,通常用在跨应用的资源调用上)
- */
- @Path( { "/contact", "/contacts/{contactId}" })
- @Remote
- public class ContactResource {
- @Inject
- private ContactService service;
- /**
- * 创建新的联系人
- * contact 联系人实体
- */
- @Post
- public String createContact(@ModelBean Contact contact) {
- return this.service.createContact(contact);
- }
- /**
- * 修改联系人信息
- * contact 联系人实体
- */
- @Put
- public void putContact(@ModelBean Contact contact) {
- this.service.updateContact(contact);
- }
- /**
- * 显示联系人列表,并限定服务所支持的返回数据类型只能为application/json和application/javabean
- * pageIndex 页码
- * pageSize 每页记录数
- */
- @Get
- @ProduceMime( {MimeType.MIME_OF_JSON,MimeType.MIME_OF_JAVABEAN})
- @Path("/contacts")
- public Page<Contact> listContacts(int pageIndex, int pageSize) {
- return this.service.listContacts(pageIndex, pageSize);
- }
- /**
- * 显示单个联系人的信息
- * 并指定了当客户端请求类型为text/html时的视图显示模板(现在系统内置对Velocity、Freemarker与Spry的支持)
- * contactId 联系对象ID
- */
- @Get
- @ViewTemplate(url="/template/contactDetail.vm",render=ViewRenderType.VELOCITY)
- // @ViewTemplate(url="/template/contactDetail.ftl",render=ViewRenderType.FREEMARKER)
- // @ViewTemplate(url="/template/contactDetail.html",render=ViewRenderType.SPRY)
- public Contact getContact(@Parameter("contactId") String contactId) {
- return this.service.findContactById(contactId);
- }
- /**
- * 删除指定ID的联系人
- * contactId 联系对象ID
- */
- @Delete
- public void deleteContact(@Parameter("contactId") String contactId) {
- this.service.deleteContact(contactId);
- }
- }
- /**
- * 业务对象
- * @author <a href="mailto:zhangyouqun@gmail.com">cnoss (QQ:86895156)</a>
- *
- */
- @SuppressWarnings({"unchecked", "unused"})
- public class ContactServiceBean implements ContactService {
- private BaseEntityManager<String, Contact> entityManager;
- @Inject
- private void init(EntityManager em) {
- this.entityManager = new BaseEntityManager<String, Contact>(
- Contact.class, em);
- }
- @Transactional
- @RolesAllowed({"user"})//权限声明
- 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();
- }
- @Transactional
- @RolesAllowed({"admin","audit"})//权限声明
- 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)
- public Page<Contact> listContacts(int pageIndex, int pageSize)
- throws RuntimeException {
- return this.entityManager.pageByNamedQuery("list",
- new Pagination(pageIndex, pageSize));
- }
- @Transactional
- @RolesAllowed({"admin","user"})//权限声明
- public void updateContact(Contact contact) {
- if (contact == null)
- throw new RuntimeException("联系人对象不能为空");
- this.entityManager.update(contact);
- }
- }
- /**
- * 远程资源引用的示例
- * @author <a href="mailto:zhangyouqun@gmail.com">cnoss (QQ:86895156)</a>
- *
- */
- @Path({"/testCallRemote"})
- public class TestRemoteResource {
- @Inject
- @RemoteService //注入远程资源对象的引用
- private ContactResource service;
- @Get
- @ProduceMime( {MimeType.MIME_OF_JSON,MimeType.MIME_OF_JAVABEAN})
- public Page<Contact> listContacts(int pageIndex, int pageSize) {
- return this.service.listContacts(pageIndex, pageSize);
- }
- }
/**
*
* @author <a href="mailto:zhangyouqun@gmail.com">cnoss (QQ:86895156)</a>
* 联系人的资源对象,并声明为Remote(可以通过@RemoteService的注入到任一资源对象,通常用在跨应用的资源调用上)
*/
@Path( { "/contact", "/contacts/{contactId}" })
@Remote
public class ContactResource {
@Inject
private ContactService service;
/**
* 创建新的联系人
* contact 联系人实体
*/
@Post
public String createContact(@ModelBean Contact contact) {
return this.service.createContact(contact);
}
/**
* 修改联系人信息
* contact 联系人实体
*/
@Put
public void putContact(@ModelBean Contact contact) {
this.service.updateContact(contact);
}
/**
* 显示联系人列表,并限定服务所支持的返回数据类型只能为application/json和application/javabean
* pageIndex 页码
* pageSize 每页记录数
*/
@Get
@ProduceMime( {MimeType.MIME_OF_JSON,MimeType.MIME_OF_JAVABEAN})
@Path("/contacts")
public Page<Contact> listContacts(int pageIndex, int pageSize) {
return this.service.listContacts(pageIndex, pageSize);
}
/**
* 显示单个联系人的信息
* 并指定了当客户端请求类型为text/html时的视图显示模板(现在系统内置对Velocity、Freemarker与Spry的支持)
* contactId 联系对象ID
*/
@Get
@ViewTemplate(url="/template/contactDetail.vm",render=ViewRenderType.VELOCITY)
// @ViewTemplate(url="/template/contactDetail.ftl",render=ViewRenderType.FREEMARKER)
// @ViewTemplate(url="/template/contactDetail.html",render=ViewRenderType.SPRY)
public Contact getContact(@Parameter("contactId") String contactId) {
return this.service.findContactById(contactId);
}
/**
* 删除指定ID的联系人
* contactId 联系对象ID
*/
@Delete
public void deleteContact(@Parameter("contactId") String contactId) {
this.service.deleteContact(contactId);
}
}
/**
* 业务对象
* @author <a href="mailto:zhangyouqun@gmail.com">cnoss (QQ:86895156)</a>
*
*/
@SuppressWarnings({"unchecked", "unused"})
public class ContactServiceBean implements ContactService {
private BaseEntityManager<String, Contact> entityManager;
@Inject
private void init(EntityManager em) {
this.entityManager = new BaseEntityManager<String, Contact>(
Contact.class, em);
}
@Transactional
@RolesAllowed({"user"})//权限声明
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();
}
@Transactional
@RolesAllowed({"admin","audit"})//权限声明
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)
public Page<Contact> listContacts(int pageIndex, int pageSize)
throws RuntimeException {
return this.entityManager.pageByNamedQuery("list",
new Pagination(pageIndex, pageSize));
}
@Transactional
@RolesAllowed({"admin","user"})//权限声明
public void updateContact(Contact contact) {
if (contact == null)
throw new RuntimeException("联系人对象不能为空");
this.entityManager.update(contact);
}
}
/**
* 远程资源引用的示例
* @author <a href="mailto:zhangyouqun@gmail.com">cnoss (QQ:86895156)</a>
*
*/
@Path({"/testCallRemote"})
public class TestRemoteResource {
@Inject
@RemoteService //注入远程资源对象的引用
private ContactResource service;
@Get
@ProduceMime( {MimeType.MIME_OF_JSON,MimeType.MIME_OF_JAVABEAN})
public Page<Contact> listContacts(int pageIndex, int pageSize) {
return this.service.listContacts(pageIndex, pageSize);
}
}
请大家直接从SVN中获取JRest4Guice、JRest4Guice-sample、libraries三个工程即可
真诚希望大家提出宝贵意见,联系方式:
- Email:zhangyouqun@gmail.com
- QQ: 86895156
- MSN: zhangyouqun@hotmail.com