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 南一郎 阅读(2935) |
评论 (0) |
编辑 收藏
摘要: 以下是我用Swing 组件编写的记事本,功能是模仿微软的,使用了观感,自我觉得界面比Win的记事本更为好看(臭屁一下吧)。除了没有做字体选择之外,其他功能基本都有了吧。
/** **/
/**
*Author:
Zhang Zhijian *Mail: q...
阅读全文
posted @
2006-04-15 01:06 南一郎 阅读(3197) |
评论 (14) |
编辑 收藏
摘要: 我做过的一个项目,需要实现在线实时生成 Excel文件供客户端下载的需求,最初考虑的是先在服务器端生成真实的文件,然后在客户端下载该文件。后来发现这样做不但性能不够好、速度较慢,而且还要占用服务器空间。所以采取了在服务器端生成文件输出流(ServletOutputStream),通过HttpServletResponse对象设置相应的响应头,然后将此输出流传往客户端的方法实现。在实现过程中,用到了...
阅读全文
posted @
2005-12-30 10:08 南一郎 阅读(12255) |
评论 (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 南一郎 阅读(1338) |
评论 (0) |
编辑 收藏