J2EE 即
Java2平台企业版,它提供了基于组件的方式来设计、开发、组装和部署企业应用。J2EE使用多层分布式的应用模型,这个多层通常通过三层或四层来实现:
         1、
客户层,运行在客户计算机上的组件。
         2、
Web 层,运行在J2EE服务器上的组件。
         3、
业务层,同样是运行在J2EE服务器上的组件。
         4、
企业信息系统层(EIS),是指运行在EIS服务器上的软件系统。      
         以上层次一般也指三层应用,因分布在三个不同位置:客户计算机、J2EE服务器及后台的数据库或过去遗留下来的系统。请看图例:                                                           

          
                     
         J2EE组件
         J2EE应用程序是由组件构成的。J2EE组件是一个封装了功能的软件单元,能够与相关的一些类和文件一起组成J2EE应用程序。
         1、应用程序客户端和Applet是指运行在客户计算机上的组件。
         2、基于Java Servlet和JSP技术的组件叫Web组件,它们运行在服务器上。
         3、企业JavaBean(EJB)组件叫业务组件,同样运行在服务器上。
      J2EE客户端
         J2EE客户端可以是一个Web组件或者是一个应用程序客户端。
         1、Web客户端  
         包括两部分,首先是那些动态Web页面(HTML、XML等),这些组件运行在Web层;另一个是Web浏览器,由客户机上的浏览器从服务器接收并且解析和显示Web页面。
         2、小应用程序(Applet) 
         需要运行在客户端安装了Java虚拟机的Web浏览器上。
         3、应用程序客户端
         J2EE应用程序客户端运行在客户机上,能提供强大而灵活易用的用户界面,如使用Swing或AWT创建的图形化的用户界面(GUI)。应用程序可直接访问运行在业务层的企业Bean,如果需求允许,也可以打开HTTP连接来建立与运行在Web层上的Servlet之间的通讯。
         4、JavaBean组件架构
         在服务器和客户端两层中也可能包括了基于JavaBean的组件架构,通过JavaBean来实现数据的流动,可以是在应用程序客户或Applet与运行在J2EE服务器上的组件之间,或者是在J2EE服务器和后台数据库之间。(不过JavaBean组件并没有包含在J2EE规范里)
         5、J2EE服务的通讯
         客户层与J2EE服务器上运行的业务层之间的通讯可以是直接的,也可以通过运行在Web层中的Servlet和JSP来实现,在这种情况下,客户端运行在浏览器中。
         Web组件
         J2EE的Web组件可以是Servlet或JSP页面。在应用程序组装过程中,静态HTML页面和Applet也可以一起打包成Web组件,但这并不是J2EE规范所认可的Web组件。
         业务组件
         业务代码是指那些由位于业务层的企业Bean(EJB)执行的逻辑,它们能够解决或满足特定的商业领域的一些需求。有三种不同类型的企业Bean:会话Bean、实体Bean和消息驱动Bean。会话Bean代表客户一次短暂的会话过程,当客户执行完成后,会话Bean以及它所包含的数据也随之消失。实体Bean代表的是持久的数据,即存储在数据库表中的一行记录,即使客户终止或者服务器关闭,在J2EE底层的服务会确保实体Bean的数据被保存下来。
         企业信息系统层
         企业信息系统层处理企业信息系统的软件,包括企业组织结构系统,例如企业资源计划(ERP)、大型的事务处理、数据库系统及其他历史上遗留下来的信息系统。
         J2EE的主要技术
         
         JDBC(Java Database Connectivity): JDBC API 为访问数据库提供一种统一的方式,其接口包括在java.sql和javax.sql两个包中。
         JNDI(Java Name and Directory Interface):Java名称和目录服务,包含在javax.naming 及其子包中。它为应用程序提供标准的目录操作的方法 ,如获得对象的关联属性,根据它们的属性搜寻对象等。使用JNDI,一个J2EE应用程序可以存储和动态获取任何类型的命名Java对象。JNSI分为两种:应用程序编程接口(API)和服务供应商接口(SPI)。
         EJB(Enterprise JavaBean):参见上文。
         RMI(Remote Method Invoke):即远程方法调用,它使用了连续序列的方式在客户端和服务器端传递数据,将面向对象编程模型扩展到了客户机/服务器系统,使开发者可以用本地对象调用的语法进行远程调用。
         JSP(Java Server Pages):Java服务器页,可以在HTML代码中嵌入部分Java代码,这种文件由服务器编译成Servlet并执行,然后将产生的结果作为一个HTML文件传给浏览器。
         Servlet:Java Servlet实质上是一种小型的,与平台无关的Java类,它由容器管理并被编译成平台无关的字节代码,可以动态地加载到一个Web服务器上,并由该Web服务器运行。
         JMS(Java Message Service):Java 消息服务,是用于和企业消息传递系统相互通信的应用程序接口。企业消息传递系统又称为面向消息的中间件(Message Oriented Middle Ware, MOM),它使用松耦合的、非常灵活的方式来集成应用程序,在存储和转发的基础上支持应用程序间数据的异步传递;
每个应用程序都只与作为中介的MOM通信。
         JTA(Java Transaction API):指定事务管理与分布式事务中涉及的其他系统之间的各种高级接口。
         JavaMail:用于存取邮件服务器的API,提供了一套用于邮件服务的抽象类。
         JAXP(Java API for XML Processing):Java XML 处理API,支持使用DOM、SAX和XSLT对XML文档进行处理。
         J2EE Connector Architecture:J2EE工具提供商提供的J2EE连接体系结构,通过它可以建立支持访问企业信息系统的资源适配器。      
        归纳几个概念:
         EJB
         即Enterprise JavaBean,一种组件架构,用于开发和部署面向对象的、分布式的、企业级的应用程序。所开发的应用程序使用EJB架构来实现可扩展性及管理事务和安全。
         EJB包括会话Bean(session bean)、实体Bean(entity bean)和消息驱动Bean(message-driven bean)。其中会话Bean分为无状态会话Bean(stateless session bean)和有状态会话Bean(stateful session bean)。而实体Bean又分为Bean管理实体Bean和容器管理实体Bean。由于这种Bean对应于数据库中的记录,所以数据库记录的任何改变也被同步到组件池中的相关Bean中,这个过程叫做持久性(persistenced),这是实体Bean最重要的一个特征。根据持久性操作方式的不同分为:容器管理持久性(Container-Managed Persistence,CMP)和Bean管理持久性(Bean-Managed Persistence,BMP)。
         容器
         即container,一个实体,它管理着组件的生命周期、安全、部署和运行时服务。每个类型的容器都只提供与相应类型的组件相关的服务,如EJB、Web、JSP、Applet和应用程序客户端。其中,EJB容器和Web容器都运行在J2EE服务器中。
         J2EE
         即Java 2 Platform Enterprise Edition,Java 2 平台企业版。是开发和部署企业应用程序的一种平台或环境。它由一系列服务、应用程序编程接口(API)、提供多层开发的功能性的协议以及基于Web的应用程序组成。
         
 
 
			posted @ 
2006-04-16 01:28 南一郎 阅读(2967) | 
评论 (0) | 
编辑 收藏 
		
			
		
			
			     摘要: 以下是我用Swing 组件编写的记事本,功能是模仿微软的,使用了观感,自我觉得界面比Win的记事本更为好看(臭屁一下吧)。除了没有做字体选择之外,其他功能基本都有了吧。
		
				
				
				/** **/
				
						/**
						
								
								 *Author: 
						Zhang Zhijian   *Mail: q...  
阅读全文
			posted @ 
2006-04-15 01:06 南一郎 阅读(3248) | 
评论 (14) | 
编辑 收藏 
		
			
		
			
			     摘要: 我做过的一个项目,需要实现在线实时生成 Excel文件供客户端下载的需求,最初考虑的是先在服务器端生成真实的文件,然后在客户端下载该文件。后来发现这样做不但性能不够好、速度较慢,而且还要占用服务器空间。所以采取了在服务器端生成文件输出流(ServletOutputStream),通过HttpServletResponse对象设置相应的响应头,然后将此输出流传往客户端的方法实现。在实现过程中,用到了...  
阅读全文
			posted @ 
2005-12-30 10:08 南一郎 阅读(12335) | 
评论 (16) | 
编辑 收藏 
		
			
		
			
			
		
				
				 
		        我的一个项目使用了Hibernate3操作Oracle9i数据库,遇到一个很奇怪的问题,即在按某些使用了聚合函数的值的升序排序后,翻页到一定页数(通常是3或5)以后,显示的内容不会变化,即出现不是期望的查询结果.
        刚开始仔细排查,找不出原因.后来通过查Hibernate 包中的Oracle9Dialect及OracleDialect的源码,将Dialect换成 OracleDialect后问题解决.
       但是,问题虽解决了,根源何在呢?为什么Oracle9却要用到OracleDialect(源码注解中说这是兼容Oracle8i)的才能解决问题呢?!
      查看源码,发现两者取得分页查询字符串的方式是有点区别的(在 getlimitString()方法中).
		    在Oracle9Dialect中:
		
				
				
				  
				public
				 String getLimitString(String sql, 
				boolean
				 hasOffset) 
				
						
				
				
						{
  
  sql 
						=
						 sql.trim();
  
						boolean
						 isForUpdate 
						=
						 
						false
						;

  
						if
						 ( sql.toLowerCase().endsWith(
						"
						 for update
						"
						) ) 
						
								
						
						
								{
   sql 
								=
								 sql.substring( 
								0
								, sql.length()
								-
								11
								 );
   isForUpdate 
								=
								 
								true
								;
  }
						
						
								
								
  
  StringBuffer pagingSelect 
						=
						 
						new
						 StringBuffer( sql.length()
						+
						100
						 );

  
						if
						 (hasOffset) 
						
								
						
						
								{
   pagingSelect.append(
								"
								select * from ( select row_.*, rownum rownum_ from ( 
								"
								);
  }
						
						
								
								
								
  
						else
						 
						
								
						
						
								{
   pagingSelect.append(
								"
								select * from ( 
								"
								);
  }
						
						
								
								
  pagingSelect.append(sql);

  
						if
						 (hasOffset) 
						
								
						
						
								{
   pagingSelect.append(
								"
								 ) row_ where rownum <= ?) where rownum_ > ?
								"
								);
  }
						
						
								
								
								
  
						else
						 
						
								
						
						
								{
   pagingSelect.append(
								"
								 ) where rownum <= ?
								"
								);
  }
						
						
								
								
								
								
  
						if
						 (isForUpdate) pagingSelect.append(
						"
						 for update
						"
						);
  
  
						return
						 pagingSelect.toString();
 }
				
				
						
						
						
						
				
		 
		
				
		
		        在OracleDialect中:
		
				
				
				public
				 String getLimitString(String sql, 
				boolean
				 hasOffset) 
				
						
				
				
						{

  sql 
						=
						 sql.trim();
  
						boolean
						 isForUpdate 
						=
						 
						false
						;

  
						if
						 ( sql.toLowerCase().endsWith(
						"
						 for update
						"
						) ) 
						
								
						
						
								{
   sql 
								=
								 sql.substring( 
								0
								, sql.length()
								-
								11
								 );
   isForUpdate 
								=
								 
								true
								;
  }
						
						
								
								
  
  StringBuffer pagingSelect 
						=
						 
						new
						 StringBuffer( sql.length()
						+
						100
						 );

  
						if
						 (hasOffset) 
						
								
						
						
								{
   pagingSelect.append(
								"
								select * from ( select row_.*, rownum rownum_ from ( 
								"
								);
  }
						
						
								
								
								
  
						else
						 
						
								
						
						
								{
   pagingSelect.append(
								"
								select * from ( 
								"
								);
  }
						
						
								
								
  pagingSelect.append(sql);

  
						if
						 (hasOffset) 
						
								
						
						
								{
   pagingSelect.append(
								"
								 ) row_ ) where rownum_ <= ? and rownum_ > ?
								"
								);
  }
						
						
								
								
								
  
						else
						 
						
								
						
						
								{
   pagingSelect.append(
								"
								 ) where rownum <= ?
								"
								);
  }
						
						
								
								
								
								
  
						if
						 (isForUpdate) pagingSelect.append(
						"
						 for update
						"
						);
  
  
						return
						 pagingSelect.toString();
 }
				
				
						
						
						
						
				
		 
		
				
        两者的区别主要在于,前者:
row_ where rownum <= ?) where rownum_ > ?
后者:
where rownum_ <= ? and rownum_ > ?
		我模拟了我的出问题的查询,使用前者问题重现,使用后者不出问题.
另外是,只在升序排序时才出问题,降序则不会.
		我的语句分别如下:
*************************************************************************
第一种:
		
				
				select
				 
				*
				 
				from
				 (

 
				select
				 rownum row_num ,t.
				*
				  
				from
				(
 
				select
				 
				Sum
				(b.disp_Count) , 
				Sum
				(b.click_Count) , 
   
				Sum
				(b.total_Price) , 
				Sum
				(b.return_Cost) , 
   
				avg
				(b.rank)  , b.sta_Date   , b.keyword_Name  , 
   b.union_Name  
   
				from
				 Bid_Report b  
        
				where
				  (b.sta_Date 
				=
				'
				20051129
				'
				)  
          
				group
				 
				by
				  b.sta_Date,  b.keyword_Name,  b.union_Name 
          
				order
				 
				by
				  
				Sum
				(b.click_Count), b.sta_Date 
        ) t  
				where
				 rownum
				<=
				60
				
						
						
  ) 
				where
				 row_num 
				>
				 
				40
				
						
						
						
						
				
		 
		
				
(在Hibernate3中,Oracle9Dialect的getLimitString()方法采取类似实现方式)
		第二种:
		
				
				select
				 
				*
				 
				from
				 (

 
				select
				 rownum row_num ,t.
				*
				  
				from
				(
 
				select
				 
				Sum
				(b.disp_Count) , 
				Sum
				(b.click_Count) , 
   
				Sum
				(b.total_Price) , 
				Sum
				(b.return_Cost) , 
   
				avg
				(b.rank)  , b.sta_Date   , b.keyword_Name  , 
   b.union_Name  
   
				from
				 Bid_Report b  
        
				where
				  (b.sta_Date 
				=
				'
				20051129
				'
				)  
          
				group
				 
				by
				  b.sta_Date,  b.keyword_Name,  b.union_Name 
          
				order
				 
				by
				  
				Sum
				(b.click_Count), b.sta_Date  
        ) t  
  ) 
				where
				 row_num 
				<=
				60
				 
				and
				 row_num
				>
				40
				
						
						
						
						
				
		 
		(在Hibernate3中,OracleDialect的getLimitString()方法采取类似实现方式)
		**********************************************************************
		现在,问题是:为什么采取后者就可以解决问题了呢?这是不是Oracle9Dialect的一个bug呢?!
哪位高手能给我详析,感激不尽!!!!
			posted @ 
2005-12-30 09:41 南一郎 阅读(1372) | 
评论 (0) | 
编辑 收藏