您的位置:首页 > 运维架构 > Linux

Linux下J2EE简易高效三层模式实现

2009-07-29 11:29 411 查看
本文作者:广东省Linux公共服务技术支持中心 庞劲松 6D^}r>,4

转载时需要著名出处 EUVf [Yu

q=um=S%

本案以 3#t/& )

Fedora core 5(ftp://falkor.skane.se/pub/mirrors/fedora/core/5/i386/iso/
) v <SWAbG

JDK 5.0 (http://java.sun.com/j2se/1.5.0/download.jsp
) >*ul]+

Tomcat 5.5.17 (http://www.apache.org/dist/tomcat/tomcat-5/v5.5.17/bin/
) '( *.(

PostgreSQL 8.1.4 (http://www.postgresql.org/ftp/source/v8.1.4/
,此开源项目在95年左右由华裔接手,个人比较中意) o9fW*Q~I

PostgreSQL JDBC (http://jdbc.postgresql.org/download.html
选择8.1-407 JDBC 3版本) !U/ykY

为例。 --ym
Od

首先,在PC机上安装好Fedora core 5,如果想要自己拿源码包编译安装PostgreSQL,注意C编译器一定要装全,HD空间允许的话建议完全安装。 :?QC0/y

接着配置好此机网卡,开通ssh,以便远程在Win上远程访问。 1{r]9_1*`

现在可以在Win上ssh远程登陆到Fedora,同时利用Win下的WinSCP工具(类似FTP客户端)把JDK,Tomcat,PostgreSQL等相关软件上传到Fedora的/opt目录下(本人习惯放在此目录下)。 Rv5NPkDK-

U{xUHodFY;

2%>^>?T

一、 数据层 I&uRgUb

准备工作: w90=='3~

A. 准备数据库 +{"ie+"

可以用Fedora自带的rpm包的PostgreSQL,也可自己用源码包编译安装,(我习惯用源码包编译安装同时卸载OS自带的rpm包) Cf2Q8hMk{q

1) [root@FC5 /]# rpm -aq|grep postgres //查询系统自带的PostgreSQL的rpm包 RyXe?M%p

postgresql-x.x.x-1 :p{G+w"

postgresql-libs-x.x.x-1 q~'o+/(

...... Q?F`9 )!k[

2) [root@FC5 ]# rpm -e postgresql-x.x.x-1 postgresql-x.x.x-1 ......//将列出的rpm包全部删除,如果存在依赖关系可以使用--nodeps选项开强行卸载 a*byp% }(z

3) 把获得的PostgreSQL源码包postgresql-8.1.4.tar.gz复制到/opt目录下,然后解开此源码包 Wm6}$-

[root@FC5 /]# cd /opt/ -Q(&5[ 

[root@FC5 opt]# tar zxvf ./postgresql-8.1.4.tar.gz kE%&}MD

4) 为PostgreSQL添加相应系统用户 +i<-+[^

[root@FC5 /]# useradd postgres -d /opt/postgresql-8.1.4 /B{"`b

[root@FC5 /]# chown -R postgres. postgres /opt/postgresql-8.1.4 0Q0_Y,hN

[root@FC5 /]# su - postgres @vi9C=*

5) 预编译 Eg##9l�t

[postgres@FC5 ~]$ ./configure --prefix=/opt/postgresql-8.1.4 --localstatedir=/opt/postgresql-8.1.4/data --enable-nls L3b+f# 6

--prefix参数是指定PostgreSQL的安装目录 D6;@m<C(/s

--localstatedir是指定postgres数据的存放目录 /7�[/YhSx2

--enable-nls是能够识别本地语言(enable Native Language Support) a&sEx

6) 编译,安装 /HAK*DD

[postgres@FC5 ~]$ make (+rXR%.Lx

[postgres@FC5 ~]$ make install ,5x
E:X`

7) 安装完成后需要创建初始数据库 2
_ &h|

[postgres@FC5 ~]$ ./bin/initdb -U postgres -D ./data -W -E UNICODE }h ;ehyqz

–U 指定数据库管理员名称 VZh:Ef7

-D指定数据存放目录 V-5WKNiS

-W给数据库管理员设置密码 FA{X3fM2

-E设定存放记录的编码 `e#?#;=f

8) 启动/停止数据库 maYv[M<

[postgres@FC5 ~]$ pg_ctl start(stop) -D ./data -l ./db.log -o -i V.2a St

-D 将要打开的数据库目录 CTl1 N"~o

-l 输出日志到指定文件 vPEy9y]';A

-o 传递给 postmaster 的命令行选项 4}
(@1

-i 打开 TCP/IP 联接 s3h]7,)^g

9) 创建要用到的数据库 Ao0J7 R ,R

[postgres@FC5 ~]$ createdb test_db Ru,#cy0H

M`h8`Q;+NO

B. 准备好JDK o$Rpl=

JDK的安装非常简单,只需要解开JDK包即可 !6:t5D

[root@FC5 /]# cd /opt &sF{~=T

[root@FC5 opt]# sh ./jdk-1_5_0_07-linux-i586.bin RCFI<k

输入yes接受license即可 _^;!z;PJ

这样JDK就安装到/opt/jdk1.5.0_07目录下了 2 4 Hx/

&/=<.Gd
+

开始数据层配置工作,此层基本是由容器来完成,我们只需要把数据库的JDBC驱动放在tomcat/common/lib/下(放在此目录下可以被Tomcat启动的时候自动加载,而不需要额外指定类路径), 同时配置数据库连接池相关文件就可以。 Q.~{XBv&

开始配置文件(以配置全局连接池名称为例) u*2
O`k/Zg

1 编辑tomcat/conf/server.xml文件 VM|A >Q

[root@FC5 /]# vi /opt/apache-tomcat-5.5.17/conf/server.xml 1;D+=Md

&:gFzDGj

<!-- Global JNDI resources --> RG]�< )[

<GlobalNamingResources> v7@ 
K&

...... D-"VDNo@

<!--以下是要添加的内容--> +_]Nt|8.>

<Resource name="your_db_pool" auth="Container" [mL/o@m$P

type="javax.sql.DataSource" driverClassName="org.postgresql.Driver" I^Ob.'u

url="jdbc:postgresql://127.0.0.1:5432/test_db" poXDo ewv

username="postgres" password="" maxActive="20" maxIdle="10" maxWait="-1"/> t FDB:t

<!--添加完毕--> ]xeEmv0r

...... /=c�tg|S>

</GlobalNamingResources> />iw@>z

以上添加的配置内容指定了 U9kN1g`

1) 在java程序中需要连接数据库的时候,寻找的数据连接名称为your_db_pool Q+�(7V8Nx

2) 数据库的驱动程序为org.postgresql.Driver x-N,!<

3) 该数据连接名称对应的物理数据库是本机(127.0.0.1)的5432监听端口上名为test_db的物理数据库 QTI%=e&'8

4) 连接该数据库的用户名是postgres,密码为空 
_'KvHa|&

5) toncat运行时对此数据源开启的最大连接数是20,空闲连接数是10,不限制最大等待连接 bD:g;$FtA

7~_q(z

2 编辑tomcat/conf/context.xml文件
L,28
f:

[root@FC5 /]# vi /opt/apache-tomcat-5.5.17/conf/context.xml $P~b@^c

<!-- The contents of this file will be loaded for each web application --> N]=q vDs

<Context> wwJ|R_0

<!-- Default set of monitored resources --> 9^THm2=

<WatchedResource>WEB-INF/web.xml</WatchedResource> `@&K@s}<a

<!-- Uncomment this to disable session persistence across Tomcat restarts --> _&UO*y= i

<!-- ;x!c)P/

<Manager pathname="" /> c<XHh/r

--> !ua| ](

<!--以下是添加的内容--> -bQXiW8

<ResourceLink global="your_db_pool" name="your_db_pool" type="javax.sql.DataSource"/> N fhT1

<!--添加完毕--> HLj"

</Context> lbZ:Z3xj

o?@'$s

现在已经可以启动Tomcat了,但是为了方便我喜欢自己写一个shell来启动和停止tomcat a bU0}%R

[root@FC5 /]# vi /opt/apache-tomcat-5.5.17/bin/opt_tomcat.sh +V A,k

Mm
o5#!uB

#!/bin/sh .f4,&^l[;W

export JAVA_HOME=/opt/jdk1.5.0_07 rj[gvdo

case "$1" in 03hD<F.df

'start') )7xQDL

# Start the Tomcat Server: `;gqug}tW+

cd /opt/apache-tomcat-5.5.17/bin '%l} " J?_

$PWD/startup.sh >> ../logs/running.log 2>&1 & W7T*WO�

echo 8MaRB><3Q

;; t {=RA

'stop') 
}2 l#+

# Stop the Tomcat Server: IFPtU5|2o

cd /opt/apache-tomcat-5.5.17/bin 0Vavo

$PWD/shutdown.sh nOQq7%&

;; +OJid=

'restart') AX|VEs91

# Restart the Tomcat Server: >OYt3e "o

stop y$O8c>7 n

sleep 2 Z| QZ1N I

start FhQ' y#}

;;  ^nHy.#8

*) !6d+8Ak_

echo "Usage: daemon.sh { start | stop | restart }" Fl= Q%l9$

exit 1 fw�Zdu/

esac wLk1BG

exit 0 /
4-(�M

#D]r[Dh

要想直接运行刚才编写的shell脚本,记着要给该脚本文件赋予可执行权限 /&i$,/CM~

[root@FC5 /]# chmod 755 /opt/apache-tomcat-5.5.17/bin/opt_tomcat.sh RmK~/PFU

现在可以通过带参数来实现启动/停止/重启tomcat了 }jLL


[root@FC5 /]# /opt/apache-tomcat-5.5.17/bin/opt_tomcat.sh start(stop/restart) 4k"HUsS_

;1?H.4o` [

!F="n/[

二、业务处理层 4)Lz0R(

此层需要2个java类,一个用于取连接,一个用于执行SQL语句并返回结果 qf-sdS

zMa Y3
s

1 取数据连接的类 ConnectionUtil.java nffD8x:xIk

[W}&PHm

package com.db; _t 6187bw

_-Q]owS

import java.sql.*; yUT*l'

import javax.naming.*; hnQO`W5-X

import javax.sql.*; q"a eG`Ua#

Hy/ zk&F

public class ConnectionUtil { [?lD GL�1

private static Object poolLock = new Object(); 8(@a[w@

private static DataSource connectionPool; DPx"rfo

private Connection conn = null; &MkxCNq

private Context ctx = null; Cs/hg1[o

^U3X4Hg=

public Connection getConnection() { q$^Lpd4

w;9,7QWx

synchronized (poolLock) { C/"`-W 

if (connectionPool == null) { % (
e^

try { T,3 +>$R

InitialContext ctx = new InitialContext();
TmA['J

connectionPool = (DataSource) ctx.lookup("your_db_pool"); 0NK r C

} cyi7!zGc

catch (Exception e) { i;CCVH/sp

//打印错误信息 5Yn+0i=K

return null; s Pi]jk0

} )j P>


} 8rh0YE=Y

}//synchronized ~WHAk

try { .]h5#[_:Q>

conn = connectionPool.getConnection(); #*.q8"u

conn.setAutoCommit(false); oHJz3i;q3

}catch (SQLException e) { 'Rh,j�8l

//打印错误日志 8Mbc($�1,

} ).[=r)

}//end getConnection() |7u�gJw'

}AcB7Um%9

} 9%b!PVi

!nig @Dbw

2 执行SQL语句并返回结果的类 SQLExecute.java w/uVc.M6

1O}Z=x]gM

package com.db; H9]tw ;

!E/T;vG

import java.sql.*; mA;/:@;z{

lYyZHViN

public class SQLExecute { *^,BN?'_

ConnectionUtil connectionUtil = new ConnectionUtil(); c.wj@,6

private Connection conn = connectionUtil.getConnection(); WLl'tkrUi+

//返回查询(select)结果方法 W#i(nE}/

public ResultSet executeQuery(String sql){ V#v{V= A

if(conn==null){//没有拿到连接 ,iLs+X

return null; vG
XV
e

} aWo~,HQp

ResultSet rs = null; 6 %)$y)wE

Statement stmt = null; 5Rb;3RT/=

try { @*W42E

//允许记录集指针跳转 rs.last(); rs.previous(); m".
@g) ;k

stmt = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_READ_ONLY); k{?~8 5+

rs = stmt.executeQuery(sql); nGHLl mN

}catch (SQLException e) { HRr@>q,+

//打印出错日志 `TNc"VxH

return null;
M_ WG=R

} b?=fYQH2

return rs; {-)o7S
)|

} d.j_emmmnU

//返回执行(insert,update,delete)结果方法 H/<|Aj6

public int executeUpdate(String sql) { gO}F
[!->

int i=0; 5Mpv~PEK9

try { )6fwrN

Statement stmt = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_READ_ONLY); 5tkI'15

i = stmt.executeUpdate(sql); /yPW'f;e;i

conn.commit(); 1!3R{W

}catch (SQLException e) { /"c"xkP

//打印出错日志 I^nk]f)

i=-1; W^L- zf5g

} eB/k:x7V

return i; [3"M.E$T"

} F.Lh{=<uI

//事务处理方法 $fx^b)Cf

public int executeUpdatePre(String sql) { G/sif#b

int i=0; Ua@'<6L2W]

try { daA}r`+a

Statement stmt = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_READ_ONLY);  V `zp O

i = stmt.executeUpdate(sql);
@dL2t!z

}catch (SQLException e) { C [zz0

//打印出错日志 Q.x}gQv*.

i=-1; ~}Bpni>

} +j 1f=$,W

return i; +A?j/LQ

} ]3NI 4


//事务提交 j
Gt:i,^

public boolean Commit() { uC,#$8

boolean b = false; *}@3*V

try { H'M^U|]?

if(conn != null) conn.commit(); X<"NJ3[@X;

b = true; C?gVjv$O

}catch (SQLException e) { WdzG_fa

//打印出错日志 Vy/n p

return false; `_7,vCbDr

} qpyH~+FD

return b; x34;o=a

} 5@rN& }#

//关闭数据连接方法 #*
/:

public boolean closeConn() { I.k5m9Bz

boolean b = false; 73 @^)

try { y`#[^bZ

if(conn != null) conn.close(); t+t,_O-

}catch (SQLException e1) { Gg8:Q*c

//打印出错日志 T~-}Ts

return false;
`qac[�X

} &�g2rL{P

return b; 1<&NC
sNX

} n,5bi.?

_^7:5P[

} '';7
>ivEv

)z
XQ-{TR

3 在Bean中的调用,bean1.java :cQ~�#j(<Y

jv:[>)

package com.app1; R9 /|mb6

DA$_=0

import java.sql.*; _!*8>

import com.db.*; (epbPpk

fP*1h8b#iZ

public class bean1 { =ce`Bs P

/*返回SQL执行的String*/ wHUx2z)

public static String getSQLString(String sql){ -e{.p

String str=""; DzIz0J[

SQLExecute sqlExecute=new SQLExecute(); OYFBWP>

ResultSet rs=sqlExecute.executeQuery(sql); &@@[Bh*

try{ Gva--k__[

if(rs.next()) str=rs.getString(1); ;v8uF|5X[

}catch(SQLException e){ Y3P 2, 

//打印出错日志 >_~F97M

}finally{ NY. XF/D

sqlExecute.closeConn(); !t8s?k50

return str; GGBmtd.19

} Gl>!!<-VE

} &5}Y2yhGL

} K@ZK^I~_

#^IJxO` :

4 在Servlet中的调用,servlet1.java (CClF`fD

说到servlet不得不提到WEB-INF/web.xml,因为此文件的重要功能之一就是用来配置servlet的类名和http访问的路径的映射关系的 a9?A%Uq

<web-app> c '50:jKf

<!--先定义类路径为com.app1.servlet1的类的类名为servlet1 --> H'q9G_Ge0

<servlet> 23DO7Ud

<servlet-name>servlet1</servlet-name> QD5)J1$

<servlet-class>com.app1.servlet1</servlet-class> Z+b!/)>

</servlet> -ms}3>;pI

<!--再定义类名为servlet1的servlet的http访问路径,把此访问路径指向http://ip:port/
用户应用项目(若有)/dir1/servlet1.do --> /(^Fh<}_

<servlet-mapping> ^
i(>>q|)

<servlet-name>servlet1</servlet-name> sB@BlO9b

<url-pattern>/dir1/servlet1.do</url-pattern> Kp(

</servlet-mapping>
qJ"�X

</web-app> 1 ^>cBtF

ip[/^b'L

(W_QC,W~q

package com.app1; ~O X |/;

/** ]a23z5#Q

此servlet用于从数据库中获取某张表的记录集,然后把记录集传递给位于表现层的theJsp.jsp页面 A@d~M
K{

*/ 5(#9={$C

import java.io.*; �h_+SR�

import java.util.*; ne4BS[Vi

import javax.servlet.*; 0x#0p7`

import javax.servlet.http.*; uuo(.!uZ

import com.db.*; +{;+FRqz

IWB>(uN

public class servlet1 extends HttpServlet { Z= `HHcxhK

public void init() throws ServletException { >_vs3:�5:

} .08r;<.Ofv

//Process the HTTP Get request -dlRCo21]U

public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { +u)d_PW

RequestDispatcher dispatcher = null; 8#+g1J=
y

SQLExecute sqlExecute = new SQLExecute();//此时已经获取数据连接 X9lAvj'&

ResultSet rs=sqlExecute.executeQuery("select * from tab1"); J}*Lqjl;k

request.setAttribute("theRS", rs); Gu `z..,`

dispatcher = ZTlm%w}

request.getRequestDispatcher("theJsp.jsp"); i,<,}


dispatcher.forward(request, response);//转向上一行指定的jsp页面 R%Q.%EK

sqlExecute.closeConn(); //最后关闭连接 2rkf $)QM

} |WNYvT$

//Process the HTTP Post request t??.H&@Tn

public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { AYgOkYn#?G

doGet(request, response); AyhdK[yz[$

} "$@q ".hI

//Clean up resources $2jp&yz}

public void destroy() { T5XK'Cj{

} V/|2Yg2

) -g`6H$X[

d>k56wdm7

三、表现层 Fr-S+JP/

在此层中由theJsp.jsp页面接受来自servlet1的数据计算结果,并且在页面中显示出来 1tms'T3

<%@page contentType="text/html; charset=GBK" session="true" language="java"%> 2&!,E"GHet

<%@page import="java.sql.*"%> 816(E}

<% 4�J4j)

ResultSet theRS = (ResultSet)request.getAttribute("theRS");  n:^n=uPQ

while(theRS.next()){ IR:GvmqyT

out.print(theRS.getInt(1)+" "+theRS.getString(2)+"<br>"); q�{W)aR<

} E%ipGXY3cx

%> ' v&(Kq{y<

twrF

y3s"joJ7

以上就是在Linux下一个简单的J2EE三层模式的实现,如有不当之处请严厉指出,同时也希望能对初学者有一些小小的帮助,欢迎各界人事来此论坛交流!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: