<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0">
  <channel>
    <title>cnoss</title>
    <description></description>
    <link>http://cnoss.javaeye.com</link>
    <language>UTF-8</language>
    <copyright>Copyright 2003-2008, JavaEye.com</copyright>
    <docs>http://blogs.law.harvard.edu/tech/rss</docs>
    <generator>JavaEye - 做最棒的软件开发交流社区</generator>
      <item>
        <title>一个Java的Restful服务框架，支持JPA、JAAS、分布式资源对象</title>
        <author>cnoss</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://cnoss.javaeye.com">cnoss</a>&nbsp;
          链接：<a href="http://cnoss.javaeye.com/blog/201103" style="color:red;">http://cnoss.javaeye.com/blog/201103</a>&nbsp;
          发表时间: 2008年06月07日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <strong>项目地址: <a href="http://code.google.com/p/jrest4guice/" target="_blank">http://code.google.com/p/jrest4guice/</a><br />Demo演示: <a href="http://cnoss.vicp.net/" target="_blank">http://cnoss.vicp.net/</a></strong><br /><br />当前版本：0.9.0 preview<br /><br />特点: <br /><ul><li>基于Google guice</li><li>零配置，服务的自动扫描注册</li><li>非侵入式，用户不需要实现特定的接口来实现Restful服务，只需要通过@RESTful来声明</li><li>支持Post. Get. Put. Delete操作</li><li>支持对Get操作的缓存机制，实现动态资源静态化（通过@Cache标注声明）</li><li>灵活的注入(支持上下文环境request/response/session以及参数的自动注入)</li><li>根据客户端要求返回不同类型的数据（xml/json/html）</li><li>通过@PageFlow实现对MVC module2的支持，输出结果支持Velocity、Freemarker和Spry模板引擎（当返回类型是text/html时才有效）</li><li>支持JPA，通过增强的BaseEntityManager实现实体的CRUD</li><li>支持事务，通过@Transactional注解声明事务的类型</li><li>支持JAAS，通过@RolesAllowed注解声明操作所需要的角色</li><li>支持分布式资源对象，实现业务逻辑的分布式部署</li></ul><br />下一步计划：<br /><ul><li>数据验证的支持</li><li>OSGI的支持</li><li>分布式事务的支持</li></ul><br />代码示例：<br /><pre name="code" class="java">
/**
 * @author &lt;a href="mailto:zhangyouqun@gmail.com">cnoss (QQ:86895156)&lt;/a>
 * 联系人的资源对象
 * 声明remoteable为真（可以通过@RemoteReference的注入到任一资源对象,通常用在跨应用的资源调用上）
 */
@RESTful(name = "ContactResource", remoteable = true)
@Path( { "/contact", "/contacts/{contactId}" })
public class ContactResource {
	@Inject
	private ContactServiceDomain domain;

	/**
	 * 创建新的联系人 
	 * @param contact 联系人实体
	 */
	@Post
	public String createContact(@ModelBean Contact contact) {
		return this.domain.createContact(contact);
	}

	/**
	 * 修改联系人信息 
	 * @param contact 联系人实体
	 */
	@Put
	public void putContact(@ModelBean Contact contact) {
		this.domain.updateContact(contact);
	}

	/**
	 * 显示联系人列表 
	 * PageFlow ：当服务端返回类型是Text/Html类型时，重定向用户的请求到指定的页面，实现最基本功能的MVC。
	 * 		在这里，指明当操作成功时，重定向到列表人列表页面，并使用Velocity模板进行渲染，当操作失败时，
	 * 		将用户请求重定向到操作出错页面。
	 * @param pageIndex 页码 
	 * @param pageSize 每页记录数
	 */
	@Get
	@Path("/contacts")
	@PageFlow(
			success = @PageInfo(url = "/template/contacts.vm",render=ViewRenderType.VELOCITY), 
			error = @PageInfo(url = "/template/error.vm",render=ViewRenderType.VELOCITY))
	public Page&lt;Contact> listContacts(int pageIndex, int pageSize) {
		return this.domain.listContacts(pageIndex, pageSize);
	}

	/**
	 * 显示单个联系人的信息 
	 * @param contactId 联系对象ID
	 */
	@Get
	@PageFlow(success = @PageInfo(url = "/template/contactDetail.vm"))
	@Cache //声明需要缓存结果，可以减少应用服务器及数据库的压力
	public Contact getContact(@Parameter("contactId") String contactId) {
		return this.domain.findContactById(contactId);
	}

	/**
	 * 删除指定ID的联系人 
	 * @param contactId 联系对象ID
	 */
	@Delete
	public void deleteContact(@Parameter("contactId") String contactId) {
		this.domain.deleteContact(contactId);
	}
}

/**
 * 业务领域对象
 * @author &lt;a href="mailto:zhangyouqun@gmail.com">cnoss (QQ:86895156)&lt;/a>
 *
 */
@SuppressWarnings( { "unused" })
public class ContactServiceDomain{
	private BaseEntityManager&lt;String, Contact> entityManager;

	@Inject
	private void init(EntityManager em) {
		this.entityManager = new BaseEntityManager&lt;String, Contact>(
				Contact.class, em);
	}

	@Transactional
	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","user"}) //权限声明
	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&lt;Contact> listContacts(int pageIndex, int pageSize)
			throws RuntimeException {
		return this.entityManager.pageByNamedQuery("list",
				new Pagination(pageIndex, pageSize));
	}

	@Transactional
	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 &lt;a href="mailto:zhangyouqun@gmail.com">cnoss (QQ：86895156)&lt;/a>
 * 
 */
@Path({"/testCallRemote"})
public class TestRemoteResource {
	@Inject
	@RemoteReference //注入远程资源对象的引用
	private ContactResource service;

	@Get
	@ProduceMime( {MimeType.MIME_OF_JSON,MimeType.MIME_OF_JAVABEAN})
	public Page&lt;Contact> listContacts(int pageIndex, int pageSize) {
		return this.service.listContacts(pageIndex, pageSize);
	}
}
</pre><br /><br />请大家直接从SVN中获取JRest4Guice、JRest4Guice-sample两个工程即可（使用Maven）<br /><br />真诚希望大家提出宝贵意见，联系方式： <br /><ul><li>Email：zhangyouqun@gmail.com</li><li>QQ: 86895156</li><li>MSN: zhangyouqun@hotmail.com </li></ul>
          <br/>
          <span style="color:red;">
            <a href="http://cnoss.javaeye.com/blog/201103#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Sat, 07 Jun 2008 08:34:32 +0800</pubDate>
        <link>http://cnoss.javaeye.com/blog/201103</link>
        <guid>http://cnoss.javaeye.com/blog/201103</guid>
      </item>
      <item>
        <title>向大家推荐一个轻量级的java rest 框架 JRest4Guice </title>
        <author>cnoss</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://cnoss.javaeye.com">cnoss</a>&nbsp;
          链接：<a href="http://cnoss.javaeye.com/blog/176755" style="color:red;">http://cnoss.javaeye.com/blog/176755</a>&nbsp;
          发表时间: 2008年03月27日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <span style="font-size: x-large"><span style="color: red">本帖已转向：<a href="http://www.javaeye.com/topic/201103" target="_blank">http://www.javaeye.com/topic/201103</a></span></span><br /><br /><br /><em><br />大家好，今天向大家推荐一个轻量级的java rest 框架 JRest4Guice<br /><br />项目地址： <a href="http://code.google.com/p/jrest4guice/" target="_blank">http://code.google.com/p/jrest4guice/</a><br /><br />这个项目借鉴了<a href="http://www.javaeye.com/topic/170289" target="_blank">http://www.javaeye.com/topic/170289</a>的一些思想和代码。本人在此先谢了。<br /><br />特点:<br />     1. 基于GUICE<br /><br />     2. 零配置式服务声明<br />          @Restful(uri = "/contacts")<br />          public class ContactListRestService<br /><br />     3. 服务的自动扫描注册<br />     <br />     4. 非侵入式风格，用户不需要实现特定的接口来实现Restful服务<br />          用户只要在指定的POJO上:<br />          1. 声明为@Restful，并指明访问的URI格式<br />          2. 在指定的方法上声明为@HttpMethod<br /><br />     5. 支持Rest的Post. Get. Put. Delete操作<br />          用户在指定的方法上通过@HttpMethod注解来声明方法的类型，如下:<br />          @HttpMethod(type = HttpMethodType.POST)<br />          public String createContact(String name, @RequestParameter("homePhone") String homePhone, @ModelBean Contact contact)<br /><br />          @HttpMethod<br />          public String getContact(@FirstResult int first, @MaxResults int max)<br />          注:如果没有提供HttpMethodType类型的声明，系统会自动根据方法名称的前缀来自动识别（方法名必须以get/post/put/delete开头）<br /><br />     6. 灵活的注入<br />          6.1. 支持HttpServletRequest. HttpServletResponse. ModelMap的注入<br />                 @Inject<br />               private ModelMap modelMap;<br /><br />               @Inject<br />               private HttpServletRequest request;<br /><br />               @Inject<br />               private HttpServletResponse response;<br /><br />          6.2. 支持参数的自动注入<br />               方法中的参数可以由系统自动注入，如下:<br />               public String createContact(String name, @RequestParameter("homePhone") String homePhone, @ModelBean Contact contact)<br />               注:如果参数没有任何注解，系统默认获取上下文ID为参数名称的参数值，否则通过@RequestParameter注解指定的参数名称来获取，@ModelBean可以将上下文中的参数转换成指定参数类型的Java bean<br /><br />          6.3. 支持对JndiResource的注入          <br /><br /><br />示例代码：<br /><pre name="code" class="java">
@Restful(uri = { "/contact", "/contact/{contactId}" })
public class ContactRestService {
	@Inject
	private ModelMap modelMap;

	@Inject
	private HttpServletRequest request;

	@Inject
	private HttpServletResponse response;

	@Inject
	@JndiResource(jndi = "test/ContactService")
	private ContactService service;

	@HttpMethod(type = HttpMethodType.POST)
	public String createContact(String name, @RequestParameter("homePhone") String homePhone, @ModelBean Contact contact) {
		if (contact == null)
			return HttpResult.createFailedHttpResult("-1","联系人信息不能为空").toJson();
		String contactId = null;
		try {
			contactId = this.service.createContact(contact);
			return HttpResult.createSuccessfulHttpResult(contactId).toJson();
		} catch (RemoteException e) {
			return HttpResult.createFailedHttpResult(e.getClass().getName(),e.getMessage()).toJson();
		}
	}

	@HttpMethod
	public String putContact(@RequestParameter("contactId")
	String contactId, @ModelBean
	Contact contact) {
		if (contactId == null)
			return HttpResult.createFailedHttpResult("-1","没有指定对应的联系人标识符").toJson();

		try {
			this.service.updateContact(contact);
			return HttpResult.createSuccessfulHttpResult("修改成功").toJson();
		} catch (RemoteException e) {
			return HttpResult.createFailedHttpResult(e.getClass().getName(),e.getMessage()).toJson();
		}
	}

	@HttpMethod
	public String getContact(@RequestParameter("contactId")
	String contactId) {
		try {
			Contact contactDto = this.service.findContactById(contactId);
			return HttpResult.createSuccessfulHttpResult(contactDto).toJson();
		} catch (Exception e) {
			return HttpResult.createFailedHttpResult(e.getClass().getName(),e.getMessage()).toJson();
		}
	}

	@HttpMethod
	public String deleteContact(@RequestParameter("contactId")
	String contactId) {
		try {
			this.service.deleteContact(contactId);
			return HttpResult.createSuccessfulHttpResult("删除成功").toJson();
		} catch (Exception e) {
			return HttpResult.createFailedHttpResult(e.getClass().getName(),e.getMessage()).toJson();
		}
	}
}
</pre></em>
          <br/>
          <span style="color:red;">
            <a href="http://cnoss.javaeye.com/blog/176755#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Thu, 27 Mar 2008 14:27:37 +0800</pubDate>
        <link>http://cnoss.javaeye.com/blog/176755</link>
        <guid>http://cnoss.javaeye.com/blog/176755</guid>
      </item>
  </channel>
</rss>