`
cnoss
  • 浏览: 15561 次
  • 性别: 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
分享到:
评论
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

示例代码:
@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  
非常感谢 CTE 团队的杰出贡献 JRest4Guice 已经将 CTE 作为缺省模板引擎。
58 楼 cnoss 2008-09-08  
各位好,有一阵没有更新JRest4Guice了,最近做了一些调整:

  1. 将rest从核心应用中分离了出来 (重构)
  2. 增加了Struts2的插件,可以脱离JRest4Guice,在struts2中使用除了rest功能之外的所有功能(jpa、事务、权限、拦截器等)(新增)
  3. 优化了事务的声明,允许声明在类上,不用在每个方法都去声明 (增强)
  4. 增加了对自定义拦截器的支持(新增)
  5. 优化了BaseEntityManager的注入方式,不再需要通过init方式来由用户构造 (增强)
  6. 增强了对View部分处理,根据模板的扩展名自动选择渲染引擎,并增加了重定向的支持 (增强)
  7. 支持Hibernate validator(新增)
  8. 完善了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
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

  1. 也不支持Accept-Launguage,这个功能可以在模板中通过多语言标签来实现。
  2. 支持手工处理缓存这个可以实现。

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缓存的迹象,支持否?


[list=1]
  • 通过@ProduceMime显示声明所限定支持的内容表述方式,如果没有声明,系统会根据用户端的请求类型返回系统内置的(html/json/xml/javabean/text)表述形式,用户可以很方便的通过实现ResponseWriter接口来增加新的表述形式,并通过ResponseWriterRegister的registResponseWriter来注册。
  • 	@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 写道
  • 通过@Cache来声明需要对表述进行缓存,系统缺少提供了基于文件系统缓存的DefaultResourceCacheProvider实现,这个实现中通过监听实体的生命周期事件来维护cache的存活与清除。用户可以很方便的通过实现ResourceCacheProvider接口来自定义缓存的实现,并通过ResourceCacheManager的setResourceCacheProvider来设置系统的缓存提供者实现。 (注:@Cache只对Get类型的请求有效)
  • 	/**
    	 * 显示单个联系人的信息 
    	 * @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缓存的迹象,支持否?


    [list=1]
  • 通过@ProduceMime显示声明所限定支持的内容表述方式,如果没有声明,系统会根据用户端的请求类型返回系统内置的(html/json/xml/javabean/text)表述形式,用户可以很方便的通过实现ResponseWriter接口来增加新的表述形式,并通过ResponseWriterRegister的registResponseWriter来注册。
  • 	@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);
    	}
    
  • 通过@Cache来声明需要对表述进行缓存,系统缺少提供了基于文件系统缓存的DefaultResourceCacheProvider实现,这个实现中通过监听实体的生命周期事件来维护cache的存活与清除。用户可以很方便的通过实现ResourceCacheProvider接口来自定义缓存的实现,并通过ResourceCacheManager的setResourceCacheProvider来设置系统的缓存提供者实现。 (注:@Cache只对Get类型的请求有效)
  • 	/**
    	 * 显示单个联系人的信息 
    	 * @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缓存的迹象,支持否?
    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,唉

    相关推荐

      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