- 浏览: 15529 次
- 性别:
- 来自: 广州
文章分类
最新评论
-
suchang1123:
@Restful(uri = { "/contact ...
向大家推荐一个轻量级的java rest 框架 JRest4Guice -
liuxiang00435057:
呵呵,最好弄个DEMO,这样便于学习框架
一个Java的Restful服务框架,支持JPA、JAAS、分布式资源对象 -
抛出异常的爱:
Readonly 写道
偶的意见就是要分开多个配置文件,减少L ...
让你的 Ibatis2 也支持Annotation -
xzj127:
太恶心了。
让你的 Ibatis2 也支持Annotation -
piggy:
不知道iBatis3什么时候出来.
让你的 Ibatis2 也支持Annotation
项目地址: http://code.google.com/p/jrest4guice/
Demo演示: http://www.rest4g.org/full
当前版本:0.9.0 preview
特点:
下一步计划:
代码示例:
请大家直接从SVN中获取JRest4Guice工程即可(使用Maven)
真诚希望大家提出宝贵意见,联系方式:
非常感谢你的支持与建议,一个人考虑的问题始终有限,而且在实际应用场景下,我们会碰到许多不可预见的问题。
BTW,我明天再回答你的问题,今天女儿眇着要睡觉。
非常感谢你的支持与建议,一个人考虑的问题始终有限,而且在实际应用场景下,我们会碰到许多不可预见的问题。
BTW,我明天再回答你的问题,今天女儿眇着要睡觉。
不支持对不同表述提供不同页面模板来渲染,我个人认为这个使用场景不多。
呵,这个场合景对现在我面向的需求来说确实很现实的,对于浏览器的请求,返回html表述,而对于程序性的调用(API),希望返回的是XML结果(我希望用更好的方式来展示我的XML,而不是默认规则生成的XML)
不支持对不同表述提供不同页面模板来渲染,我个人认为这个使用场景不多。
另外
1)支持Accept-Launguage否?譬如我可能希望根据浏览器的语言返回特定的语言的表述。
2)支持手工处理缓存证实否?譬如对于一些条件GET请求,我可能不希望返回一个大结果集以浪费带宽,而仅仅是
返回一个304 Not Modified
[list=1]通过@ProduceMime显示声明所限定支持的内容表述方式,如果没有声明,系统会根据用户端的请求类型返回系统内置的(html/json/xml/javabean/text)表述形式,用户可以很方便的通过实现ResponseWriter接口来增加新的表述形式,并通过ResponseWriterRegister的registResponseWriter来注册。
[/list]
如果我需要的多个表述都需要需要特定的处理页面(譬如对于html结果的表述和xml结果的表述),如上该如何设置?
另外
1)支持Accept-Launguage否?譬如我可能希望根据浏览器的语言返回特定的语言的表述。
2)支持手工处理缓存证实否?譬如对于一些条件GET请求,我可能不希望返回一个大结果集以浪费带宽,而仅仅是
返回一个304 Not Modified
^_^,其实我说的并不是在应用层面上的Cache,而是通过Http协议的Cache-Control“指示”请求途经的各网关服务器(譬如反向代理服务器)和用户代理服务器缓存该表述,避免请求直接到达目标服务器
这是我忽略的地方,确实没有考虑到,但这却是应该要涉及到的,谢谢你的提示与建议。最近在考虑对几个网站是否使用CDN的时候也碰到这样的问题。
通过@Cache来声明需要对表述进行缓存,系统缺少提供了基于文件系统缓存的DefaultResourceCacheProvider实现,这个实现中通过监听实体的生命周期事件来维护cache的存活与清除。用户可以很方便的通过实现ResourceCacheProvider接口来自定义缓存的实现,并通过ResourceCacheManager的setResourceCacheProvider来设置系统的缓存提供者实现。 (注:@Cache只对Get类型的请求有效)
^_^,其实我说的并不是在应用层面上的Cache,而是通过Http协议的Cache-Control“指示”请求途经的各网关服务器(譬如反向代理服务器)和用户代理服务器缓存该表述,避免请求直接到达目标服务器
[list=1]通过@ProduceMime显示声明所限定支持的内容表述方式,如果没有声明,系统会根据用户端的请求类型返回系统内置的(html/json/xml/javabean/text)表述形式,用户可以很方便的通过实现ResponseWriter接口来增加新的表述形式,并通过ResponseWriterRegister的registResponseWriter来注册。
通过@Cache来声明需要对表述进行缓存,系统缺少提供了基于文件系统缓存的DefaultResourceCacheProvider实现,这个实现中通过监听实体的生命周期事件来维护cache的存活与清除。用户可以很方便的通过实现ResourceCacheProvider接口来自定义缓存的实现,并通过ResourceCacheManager的setResourceCacheProvider来设置系统的缓存提供者实现。 (注:@Cache只对Get类型的请求有效)
[/list]
问得好,我现在将它们之间做一个简单的对比,如下:
相同点:
不同点:
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
评论
61 楼
liuxiang00435057
2012-10-20
呵呵,最好弄个DEMO,这样便于学习框架
60 楼
cnoss
2008-10-09
最新动态,新增加对IBatis的支持!!!
在支持xml配置方式的基础上增加了对annotation的支持,用户可以根据自己的喜好来选择或者两种方式并存。
详情:http://www.rest4g.org/viewthread.php?tid=12&extra=page%3D1
示例代码:
在支持xml配置方式的基础上增加了对annotation的支持,用户可以根据自己的喜好来选择或者两种方式并存。
详情:http://www.rest4g.org/viewthread.php?tid=12&extra=page%3D1
示例代码:
@IbatisDao @SuppressWarnings("unchecked") @Transactional @ResultMap(id = "accountResultMap", result = { @Result(property = "id", column = "id"), @Result(property = "firstName", column = "firstName"), @Result(property = "lastName", column = "lastName"), @Result(property = "emailAddress", column = "emailAddress") }, resultClass = Account.class) @Cachemodel(id = "account-cache", flushInterval = "24", flushOnExecute = { "insertAccount", "updateAccount", "deleteAccount" }, type = "LRU", property = { @Property(name = "size", value = "100") }) public class AccountService { @Inject private SqlMapClient sqlMapper; @Select(id = "selectAllAccounts", sql = "select * from ACCOUNT", resltMap = "accountResultMap", cacheModel = "account-cache") @Transactional(type = TransactionalType.READOLNY) public List<Account> findAll() throws SQLException { return sqlMapper.queryForList("selectAllAccounts"); } @Select(sql = "select id ,firstName,lastName,emailAddress from " + "ACCOUNT where id = #id#") @Transactional(type = TransactionalType.READOLNY) public Account getAccountById(int id) throws SQLException { return (Account) sqlMapper.queryForObject("getAccountById", id); } @Insert(id = "insertAccount", sql = "insert into ACCOUNT (id,firstName," + "lastName,emailAddress) values (#id#, #firstName#, #lastName#, " + "#emailAddress#)") public void createAccount(Account account) throws SQLException { sqlMapper.insert("insertAccount", account); } @Update(sql = "update ACCOUNT set firstName = #firstName#,lastName = " + "#lastName#,emailAddress = #emailAddress# where id = #id#") public void updateAccount(Account account) throws SQLException { sqlMapper.update("updateAccount", account); } @Delete(id = "deleteAccount", sql = "delete from ACCOUNT where id = #id#") public void deleteAccount(int id) throws SQLException { sqlMapper.delete("deleteAccount", id); } @Select(id = "queryAccounts", sql = "select * from ACCOUNT " + "<dynamic prepend=\"where\">" + " <isNotNull prepend=\"and\" property=\"firstName\">" + " firstName = #firstName#" + " </isNotNull>" + " <isNotNull prepend=\"and\" property=\"lastName\">" + " lastName = #lastName#" + " </isNotNull>" + " <isNotNull prepend=\"and\" property=\"emailAddress\">" + " emailAddress = #emailAddress#" + " </isNotNull>" + "</dynamic> " + "order by lastName", resltMap = "accountResultMap", cacheModel = "account-cache") @Transactional(type = TransactionalType.READOLNY) /** * 动态SQL查询 */ public List<Account> queryAccounts(Account account) throws SQLException { return sqlMapper.queryForList("queryAccounts",account); } }
59 楼
cnoss
2008-09-13
58 楼
cnoss
2008-09-08
各位好,有一阵没有更新JRest4Guice了,最近做了一些调整:
代码片段:
- 将rest从核心应用中分离了出来 (重构)
- 增加了Struts2的插件,可以脱离JRest4Guice,在struts2中使用除了rest功能之外的所有功能(jpa、事务、权限、拦截器等)(新增)
- 优化了事务的声明,允许声明在类上,不用在每个方法都去声明 (增强)
- 增加了对自定义拦截器的支持(新增)
- 优化了BaseEntityManager的注入方式,不再需要通过init方式来由用户构造 (增强)
- 增强了对View部分处理,根据模板的扩展名自动选择渲染引擎,并增加了重定向的支持 (增强)
- 支持Hibernate validator(新增)
- 完善了demo,增加了非AJAX环境下的使用案例(新增)
代码片段:
@Transactional//事务支持,缺省为TransactionalType.REQUIRED,可以在方法中覆写 @Interceptors({//自定义的拦截器(类级别的,作用于所有的方法,可以在方法中覆写) @Interceptor(TestInterceptor.class), @Interceptor(LogInterceptor.class) }) public class ContactService{ //注入实体管理器 @Inject private BaseEntityManager<String, Contact> entityManager; @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)); } }
57 楼
ayufox
2008-07-31
cnoss 写道
ayufox 写道
^_^希望在提供简单的模式处理一些通常的需求之外,能够提供更多的灵活性以控制可能稍微比较“变态”的需求
非常感谢你的支持与建议,一个人考虑的问题始终有限,而且在实际应用场景下,我们会碰到许多不可预见的问题。
BTW,我明天再回答你的问题,今天女儿眇着要睡觉。
56 楼
ayufox
2008-07-31
@PageFlow在实现的时候,是否可以考虑这样子:只指定后缀部分,前缀部分根据MimeType来决定,譬如配置
@PageFlow(
success = @PageInfo(url = "/contacts.vm"))
对于html表述,是/html/contacts.vm,对于XML,则是/xml/contacts.vm
@PageFlow(
success = @PageInfo(url = "/contacts.vm"))
对于html表述,是/html/contacts.vm,对于XML,则是/xml/contacts.vm
55 楼
cnoss
2008-07-31
ayufox 写道
^_^希望在提供简单的模式处理一些通常的需求之外,能够提供更多的灵活性以控制可能稍微比较“变态”的需求
非常感谢你的支持与建议,一个人考虑的问题始终有限,而且在实际应用场景下,我们会碰到许多不可预见的问题。
BTW,我明天再回答你的问题,今天女儿眇着要睡觉。
54 楼
ayufox
2008-07-31
cnoss 写道
ayufox 写道
如果我需要的多个表述都需要需要特定的处理页面(譬如对于html结果的表述和xml结果的表述),如上该如何设置?
不支持对不同表述提供不同页面模板来渲染,我个人认为这个使用场景不多。
呵,这个场合景对现在我面向的需求来说确实很现实的,对于浏览器的请求,返回html表述,而对于程序性的调用(API),希望返回的是XML结果(我希望用更好的方式来展示我的XML,而不是默认规则生成的XML)
53 楼
cnoss
2008-07-31
ayufox 写道
如果我需要的多个表述都需要需要特定的处理页面(譬如对于html结果的表述和xml结果的表述),如上该如何设置?
不支持对不同表述提供不同页面模板来渲染,我个人认为这个使用场景不多。
ayufox 写道
另外
1)支持Accept-Launguage否?譬如我可能希望根据浏览器的语言返回特定的语言的表述。
2)支持手工处理缓存证实否?譬如对于一些条件GET请求,我可能不希望返回一个大结果集以浪费带宽,而仅仅是
返回一个304 Not Modified
- 也不支持Accept-Launguage,这个功能可以在模板中通过多语言标签来实现。
- 支持手工处理缓存这个可以实现。
52 楼
ayufox
2008-07-31
^_^希望在提供简单的模式处理一些通常的需求之外,能够提供更多的灵活性以控制可能稍微比较“变态”的需求
51 楼
ayufox
2008-07-31
cnoss 写道
ayufox 写道
看了LZ的DEMO程序,问两个问题:
1.从下面配置来看,看起来似乎不支持内容协商以支持一种资源有多种表述的情形?
如果支持,是如何支持的?
@PageFlow(
success = @PageInfo(url = "/template/contacts.vm",render=ViewRenderType.VELOCITY),
error = @PageInfo(url = "/template/error.vm",render=ViewRenderType.VELOCITY))
2.没有看到能手工控制HTTP缓存的迹象,支持否?
1.从下面配置来看,看起来似乎不支持内容协商以支持一种资源有多种表述的情形?
如果支持,是如何支持的?
@PageFlow(
success = @PageInfo(url = "/template/contacts.vm",render=ViewRenderType.VELOCITY),
error = @PageInfo(url = "/template/error.vm",render=ViewRenderType.VELOCITY))
2.没有看到能手工控制HTTP缓存的迹象,支持否?
[list=1]
@Get @Path("/contacts") @PageFlow( success = @PageInfo(url = "/template/contacts.vm",render=ViewRenderType.VELOCITY), error = @PageInfo(url = "/template/error.vm",render=ViewRenderType.VELOCITY)) @ProduceMime({MimeType.MIME_OF_JAVABEAN,MimeType.MIME_OF_JSON,MimeType.MIME_OF_TEXT_HTML}) public Page<Contact> listContacts(int pageIndex, int pageSize) { return this.domain.listContacts(pageIndex, pageSize); }
[/list]
如果我需要的多个表述都需要需要特定的处理页面(譬如对于html结果的表述和xml结果的表述),如上该如何设置?
另外
1)支持Accept-Launguage否?譬如我可能希望根据浏览器的语言返回特定的语言的表述。
2)支持手工处理缓存证实否?譬如对于一些条件GET请求,我可能不希望返回一个大结果集以浪费带宽,而仅仅是
返回一个304 Not Modified
50 楼
cnoss
2008-07-31
ayufox 写道
^_^,其实我说的并不是在应用层面上的Cache,而是通过Http协议的Cache-Control“指示”请求途经的各网关服务器(譬如反向代理服务器)和用户代理服务器缓存该表述,避免请求直接到达目标服务器
这是我忽略的地方,确实没有考虑到,但这却是应该要涉及到的,谢谢你的提示与建议。最近在考虑对几个网站是否使用CDN的时候也碰到这样的问题。
49 楼
ayufox
2008-07-31
cnoss 写道
/** * 显示单个联系人的信息 * @param contactId 联系对象ID */ @Get @PageFlow(success = @PageInfo(url = "/template/contactDetail.vm")) @Cache //声明需要缓存结果,可以减少应用服务器及数据库的压力 public Contact getContact(@Parameter("contactId") String contactId) { return this.domain.findContactById(contactId); }
^_^,其实我说的并不是在应用层面上的Cache,而是通过Http协议的Cache-Control“指示”请求途经的各网关服务器(譬如反向代理服务器)和用户代理服务器缓存该表述,避免请求直接到达目标服务器
48 楼
cnoss
2008-07-31
ayufox 写道
看了LZ的DEMO程序,问两个问题:
1.从下面配置来看,看起来似乎不支持内容协商以支持一种资源有多种表述的情形?
如果支持,是如何支持的?
@PageFlow(
success = @PageInfo(url = "/template/contacts.vm",render=ViewRenderType.VELOCITY),
error = @PageInfo(url = "/template/error.vm",render=ViewRenderType.VELOCITY))
2.没有看到能手工控制HTTP缓存的迹象,支持否?
1.从下面配置来看,看起来似乎不支持内容协商以支持一种资源有多种表述的情形?
如果支持,是如何支持的?
@PageFlow(
success = @PageInfo(url = "/template/contacts.vm",render=ViewRenderType.VELOCITY),
error = @PageInfo(url = "/template/error.vm",render=ViewRenderType.VELOCITY))
2.没有看到能手工控制HTTP缓存的迹象,支持否?
[list=1]
@Get @Path("/contacts") @PageFlow( success = @PageInfo(url = "/template/contacts.vm",render=ViewRenderType.VELOCITY), error = @PageInfo(url = "/template/error.vm",render=ViewRenderType.VELOCITY)) @ProduceMime({MimeType.MIME_OF_JAVABEAN,MimeType.MIME_OF_JSON,MimeType.MIME_OF_TEXT_HTML}) public Page<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); }
[/list]
47 楼
ayufox
2008-07-31
看了LZ的DEMO程序,问两个问题:
1.从下面配置来看,看起来似乎不支持内容协商以支持一种资源有多种表述的情形?
如果支持,是如何支持的?
@PageFlow(
success = @PageInfo(url = "/template/contacts.vm",render=ViewRenderType.VELOCITY),
error = @PageInfo(url = "/template/error.vm",render=ViewRenderType.VELOCITY))
2.没有看到能手工控制HTTP缓存的迹象,支持否?
1.从下面配置来看,看起来似乎不支持内容协商以支持一种资源有多种表述的情形?
如果支持,是如何支持的?
@PageFlow(
success = @PageInfo(url = "/template/contacts.vm",render=ViewRenderType.VELOCITY),
error = @PageInfo(url = "/template/error.vm",render=ViewRenderType.VELOCITY))
2.没有看到能手工控制HTTP缓存的迹象,支持否?
46 楼
cnoss
2008-07-23
nasvel 写道
能不能简单的说一说jrest4guice和jersey的异同,除了注入框架(guice vs glassfish)以外。
问得好,我现在将它们之间做一个简单的对比,如下:
相同点:
- 两者都是基于Servlet API的实现
- 都是通过注解的方式进行资源的声明
- 都支持根据客户的请求不同返回相应的数据类型(json/xml/text等)
不同点:
- JRest4Guice支持JAAS,通过@RolesAllowed声明资源访问所需要的角色。
- JRest4Guice支持声明式事务,根据业务的需要声明事务为只读、读写等。
- JRest4Guice支持分布式资源,通过@RESTful的remoteable属性来声明是否可以被远程访问,并通过@RemoteReference来引用分布式的资源对象。
- JRest4Guice通过@PageFlow实现对MVC module2的支持,输出结果支持Velocity、Freemarker和Spry模板引擎(当返回类型是text/html时才有效)。
- JRest4Guice支持增强过的JPA与Hibernate实现,通过BaseEntityManager实现实体的CRUD。
- JRest4Guice比Jersey更简单、更灵活、更容易扩展。
45 楼
nasvel
2008-07-22
能不能简单的说一说jrest4guice和jersey的异同,除了注入框架(guice vs glassfish)以外。
44 楼
minidarkey
2008-07-14
很支持楼主的这份热情,确实,现在国内对开源的使用非常普遍,大大小小的公司都不同程度的使用了许多开源的产品,形成了对国外开源的依赖,总感觉很被动,最近无法正常访问sourceforge,给我们这些使用开源项目的人带来的非常大的不便,所以突然想到,如果今后真的不能访问国外诸大开源网站了怎么办?这时,支持与发展国内的开源项目就显得非常的重要与必要,现在国内linux社区的开源项目非常活跃,真希望j2ee社区的开源也能跟上,为我们国人开发出更多优秀的开源项目,做到楼主所期望的“从使用开源、推广开源转到动手做开源”,支持楼主!
43 楼
cnoss
2008-07-08
非常感谢楼上的关注与支持,你的支持与关注是这个项目的动力,希望更多的朋友能一起参与到中国的开源事业,我们团队的力量很弱,但千千万万的中国开源人的力量就是锐不可挡的。让我们从使用开源、推广开源转到动手做开源。fighting!!!
42 楼
cats_tiger
2008-07-06
厉害,关注中...
最喜欢这种简洁的东西了。可惜项目中还是用struts,唉
最喜欢这种简洁的东西了。可惜项目中还是用struts,唉
相关推荐
Java EE(现更名为Jakarta EE)是一个用于构建企业级应用的框架,包括了如EJB(Enterprise JavaBeans)、JPA(Java Persistence API)、JSF(JavaServer Faces)等技术,用于数据库交互、事务管理和服务层设计。...
4. **Java Persistence API (JPA)**:JPA是Java标准的ORM(对象关系映射)框架,用于简化数据库操作。它允许开发者使用Java对象而不是SQL来操作数据,通过实体类和映射文件实现数据库表的映射。 5. **Java Message ...
Hibernate是JPA的一个流行实现,提供了更丰富的功能和更高的性能。 7. **Spring框架**:Spring以其依赖注入和面向切面编程(AOP)理念,成为Java企业级开发的首选框架。Spring还提供了完整的MVC(模型-视图-控制器...
Java EE(以前称为J2EE)是Java平台上用于构建企业级分布式应用程序的框架。它提供了一个标准的、组件化的开发模型,支持多层架构,包括客户端、Web服务器、应用服务器和数据库。Java EE 5.0是这个平台的一个重要...
1. **Java企业版(Java EE)**:Java企业版,也称为Java 2 Platform, Enterprise Edition,是Java平台的一个版本,专为开发和部署多层、分布式、面向服务的Web应用程序而设计。Java EE提供了许多企业级服务,如...
Java EE(Java Platform, Enterprise Edition)是Java平台上用于构建企业级Web应用的框架集合,它提供了丰富的服务和组件,使得开发者能够快速开发出分布式、多层架构的应用程序。本教程由知名讲师郑阿奇编著,旨在...
J2EE(Java 2 Platform, Enterprise Edition)是一个用于构建分布式、多层的企业级应用程序的框架,它提供了各种服务和API,便于开发人员快速构建可扩展且健壮的应用。 在Java EE 5中,有几个关键的知识点值得我们...
2. **Java EE(企业版)**:包括了诸如EJB(Enterprise JavaBeans)、JMS(Java Message Service)、JPA(Java Persistence API)等组件,它们提供了一套完整的框架来构建分布式、多层的企业级应用。 3. **Spring...
通过这个“Java EE水果管理系统”的学习,你可以深入了解Java EE的各个组成部分,并学会如何将它们组合在一起构建一个完整的应用。实践中,你需要理解和配置应用服务器(如Tomcat、WildFly),编写Java代码,设置...
J2EE(Java 2 Platform, Enterprise Edition)是Java平台的一个版本,专为构建分布式、多层的企业级应用程序而设计。在J2EE试题中,我们通常会看到以下几个核心知识点: 1. **Java基础知识**:这是所有J2EE学习的...
Java提供了JTA(Java Transaction API)和JPA(Java Persistence API)来支持分布式事务处理。 4. **并发控制**:在高并发场景下,多个用户可能会同时操作同一购物车,因此需要处理并发问题。Java提供了...
Java EE(Java Platform, Enterprise Edition),是Java平台的一个版本,专为构建企业级应用而设计。它提供了大量的API和服务,包括但不限于:Servlet、JSP(JavaServer Pages)、EJB(Enterprise JavaBeans)、JMS...
4. 安全性:Java提供了一系列的安全机制,如JAAS(Java Authentication and Authorization Service)用于用户身份验证和权限管理,SSL/TLS协议支持加密通信,防止数据泄露。此外,还可以利用Java的过滤器(Filter)...
- **JPA(Java Persistence API)**:提供了ORM(对象关系映射)框架,如Hibernate,使Java对象可以透明地映射到数据库表。 5. **Web服务** - **JAX-WS(Java API for XML Web Services)**:用于创建和消费SOAP...
最后,Java EE的安全性也是一个重要的主题,包括认证和授权机制,如JAAS(Java Authentication and Authorization Service),以及HTTPS、SSL/TLS等网络安全协议的应用。 2019年的黑马JAVA EE全套视频,很可能是...
7. **JPA(Java Persistence API)**:JPA是Java标准的ORM(Object-Relational Mapping)框架,用于处理Java对象和关系数据库之间的映射。教程可能涵盖实体类的定义、持久化上下文的使用以及查询语言JQL。 8. **Web...
Java EE 6 提供了一个强大的事务管理框架,支持分布式事务。 **3.2 标准** - **JTA 1.1**:定义了事务服务接口。 - **JTS 1.1**:提供了一个事务服务的参考实现。 **3.3 事务的互用性** 支持与其他Java EE版本的...
8. **Java Transaction API (JTA)**:JTA为应用程序提供了一个统一的事务管理接口,支持分布式事务处理,确保数据的一致性。 9. **Java Authentication and Authorization Service (JAAS)**:JAAS提供了安全框架,...
Java EE,全称为Java Platform, Enterprise Edition,是Java平台针对企业级应用开发的版本,它提供了丰富的组件和服务,用于构建分布式、多层的企业系统。这两份试卷,"Java_EEB卷.doc"和"JAVA_EE期末复习参考题.doc...
J2EE(Java Platform, Enterprise Edition)是一个用于开发和部署多层分布式应用程序的平台,它提供了丰富的API和服务,以支持各种企业级功能,如事务管理、安全性、数据库连接池和消息队列等。 在J2EE应用框架设计...