??xml version="1.0" encoding="utf-8" standalone="yes"?>
]]>
更多详情请参见:我的博客 我的生活
说明Q?/strong>具体案例的分析,详细的分析在讲解的过E中再阐qͼq䆾案例大约?4q已l完成,所以现在看h隑օ有些不符合时代潮,领会_卛_Q?/p>
概要
主要针对表department操作Q创建、更新、删除、选择
层次l构说明
共分为四?mid、midimpl、application、presentation 一般开发基于MVCl构的应用来_层次的划分是很重要的Q三层结构、于至于多层l构的演变有其一定的道理。MVC本n是模型、视图、控制的层次划分Q这h助于职能的明,加快开发效率,最重要的是pȝ的把握度和可扩展的能力?/p>
当然q里的四层划分,不是l对的,Ҏ不同的项目可以有不同的调_只是作ؓ一个参考,q是一个实际项目中保留下来的,有其一定的U学性?/p>
midQ接口和抽象c部分,是相对系l底层的功能的集中体玎ͼ相对共通性部?/p>
midimplQ是对mid层的具体现实 applicationQ具体业务逻辑、模?/p>
presentationQ表q层Qstruts的具体实现部?/p>
具体Z如此划分层次Q会具体讲解Q也请大家考虑一下?/p>
下面具体讲解StrutsSample的各个组?/strong>
c?/strong>
mid
DAOFactoryQ是采用了工厂模式来实现的,光又有DAO模式?/p>
功能Q得到DAOFactoryImplQDAOFactory的具体实玎ͼ实例Qƈ提供了两?strong>abstract
ҎQ在DAOFactoryImpl必须得以实现?/p>
DepartmentDAOQ操作表department的接口,定义了一些对表的基本操作
midimpl
DAOFactoryImpl: DAOFactory的具体实玎ͼ在DAOFactory中的两个abstractҎ也得以实
玎ͼinitQ)ҎQ取得数据源。getDepartmentDAOQ)ҎQ得到接口DepartmentDAO的具体实例DepartmentDAOImpl。除了要必须实现的方法外Q还定义了getConnectionQ)ҎQ以取得Ҏ据源的连接?/p>
DepartmentDAOImplQ接口DepartmentDAO的具体实玎ͼ表的操作具体实现?/p>
application
DepartmentQ定义了一个数据beanQ可以对照数据表departmentQ发现是对应它的一个对
象的实现?/p>
DepartmentBOQ定义了q个应用E序中所需要的业务逻辑Q比如selectDepartmentQString depidQ方法,Ҏ一个部门的ID来获得该部门的详l数据、createDepartmentQ)、updateDepartmentQ)? deleteDepartmentQ)分别对应创徏、更新、删?/p>
presentation
DepartmentForm:Form Bean表单Q收集JSP面上的元素。可以发现它和application层的DepartmentcLcM的,因ؓForm表单所攉的数据真好是? 应数据库中的字段的。(q只是个比较Ҏ的例子而已Q开发中不一定都是这LQ这里同时引甛_一个问题,居然两个cLcM的,Z么不合ƈ一下,q其中 的一个类的,q样不是q可以节省一个类吗?Q?/p>
CreateDepartmentActionQ创建部门的Actionc?/p>
DeleteDepartmentActionQ删除部门的Actionc?/p>
ListDepartmentActionQ所有部门的一个列?/p>
SelectDepartmentActionQ选择一个部?/p>
UpdateDepartmentActionQ更新部门的Actionc?/p>
资源文g
ApplicationResources.properties
JSP
index.jsp
Create
–register.jsp
–success.jsp
–failure.jsp
list
–departmentList.jsp
–failure.jsp
update
–update.jsp
–failure.jsp
struts-config.xml
<?xml version=?.0?encoding=”ISO-8859-1??>
<!DOCTYPE struts-config PUBLIC
?//Apache Software Foundation//DTD Struts Configuration 1.1//EN?/p>
“http://jakarta.apache.org/struts/dtds/struts-config_1_1.dtd?gt;
<struts-config>
<!?========== Form Bean Definitions =================================== ?gt;
<form-beans>
<!?Logon form bean ?gt;
<form-bean name=”departmentForm?/p>
type=”cn.haose.struts.presentation.DepartmentForm?gt;
</form-bean>
</form-beans>
<!?========== Action Mapping Definitions ============================== ?gt;
<action-mappings>
<action path=?create?/p>
type=”cn.haose.struts.presentation.CreateDepartmentAction?/p>
name=”departmentForm?/p>
scope=”request?/p>
input=?create/register.jsp?gt;
<forward name=”success” ?path=?create/success.jsp?>
<forward name=”failure” ?path=?create/failure.jsp?>
</action>
<action path=?list?/p>
type=”cn.haose.struts.presentation.ListDepartmentAction?/p>
>
<forward name=”success” ?path=?list/departmentList.jsp?>
<forward name=”failure” ?path=?list/failure.jsp?>
</action>
<action path=?select?/p>
type=”cn.haose.struts.presentation.SelectDepartmentAction?/p>
>
<forward name=”success” ?path=?update/update.jsp?>
<forward name=”failure” ?path=?update/failure.jsp?>
</action>
<action path=?delete?/p>
type=”cn.haose.struts.presentation.DeleteDepartmentAction?/p>
>
<forward name=”success” ?path=?list.do?>
<forward name=”failure” ?path=?update/failure.jsp?>
</action>
<action path=?update?/p>
type=”cn.haose.struts.presentation.UpdateDepartmentAction?/p>
name=”departmentForm?/p>
scope=”request?/p>
input=?update/update.jsp?gt;
<forward name=”success” ?path=?list.do?>
<forward name=”failure” ?path=?update/failure.jsp?>
</action>
</action-mappings>
<!?========== Message Resources Definitions =========================== ?gt;
<message-resources parameter=”ApplicationResources?strong>/>
</struts-config>
web.xml.
<?xml version=?.0?encoding=”UTF-8?>
<!DOCTYPE web-app PUBLIC ?//Sun Microsystems, Inc.//DTD Web Application 2.3//EN? “http://java.sun.com/dtd/web-app_2_3.dtd?gt;
<web-app id=”WebApp?gt;
<display-name>sample</display-name>
<servlet>
<servlet-name>action</servlet-name>
<servlet-class>org.apache.struts.action.ActionServlet</servlet-class>
<init-param>
<param-name>config</param-name>
<param-value>/WEB-INF/struts-config.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<!?Action Servlet Mapping ?gt;
<servlet-mapping>
<servlet-name>action</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<!?Struts Tag Library Descriptors ?gt;
<taglib>
<taglib-uri>/WEB-INF/struts-bean.tld</taglib-uri>
<taglib-location>/WEB-INF/struts-bean.tld</taglib-location>
</taglib>
<taglib>
<taglib-uri>/WEB-INF/struts-html.tld</taglib-uri>
<taglib-location>/WEB-INF/struts-html.tld</taglib-location>
</taglib>
<taglib>
<taglib-uri>/WEB-INF/struts-logic.tld</taglib-uri>
<taglib-location>/WEB-INF/struts-logic.tld</taglib-location>
</taglib>
<resource-ref>
<description>DB Connection</description>
<res-ref-name>jdbc/SAMPLE</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>
</web-app>
数据?/strong>
Tomcat 中的 server.xml
<Context path=?sample?docBase=”sample?debug=??/strong>
reloadable=”true?crossContext=”true?gt;
<Resource name=”jdbc/SAMPLE?/strong>
auth=”Container?/strong>
type=”javax.sql.DataSource?>
<ResourceParams name=”jdbc/SAMPLE?gt;
<parameter>
<name>factory</name>
<value>org.apache.commons.dbcp.BasicDataSourceFactory</value>
</parameter>
<parameter>
<name>driverClassName</name>
<value>oracle.jdbc.OracleDriver</value>
</parameter>
<parameter>
<name>url</name>
<value>jdbc:oracle:thin:@hao-se:1521:haose</value>
</parameter>
<parameter>
<name>username</name>
<value>test1</value>
</parameter>
<parameter>
<name>password</name>
<value>test1</value>
</parameter>
<parameter>
<name>maxActive</name>
<value>10</value>
</parameter>
<parameter>
<name>maxIdle</name>
<value>1</value>
</parameter>
<parameter>
<name>maxWait</name>
<value>-1</value>
</parameter>
</ResourceParams>
</Context>
最后附上运行画?/strong>
Index.jsp
Create register.jsp
Create success.jsp
Create failure.jsp
list departmentList.jsp
list failure.jsp
update update.jsp
一、 ?Z更好的理解strutsQ首先讲解FrontController模式
1、 ?阅读q尽可能的理解FrontController.docq䆾文
2、 ?提问关于前一阶段有关MVC的学习情?br />
3、 ?l合MVC的学习,谈谈FrontController在这里vC么样的作?br />
4、 ?文档中关于请求类型的通信Q映的理解
5、 ?文档中关于映,只是做了一个简单的装Q如果采用映外部化Q如XMLQ?那么具体如何现实Q请说出大体ҎQ不要求具体代码的实玎ͼ
6、 ?有关文中提及的几个问题Q你是如何理解的
二、 ?struts实例讲解
1、 ?在集成开发环境中Q创建新的工E?br />
2、 ?一般应用的层次l构
3、 ?重点说明在这个实例中接口和抽象的重要?br />
4、 ?接上一话题Qmid和midimpl层的具体实现
5、 ?有关application的一般概念,具体在这个实例中的实?br />
6、 ?presentation层(struts的集中实现部分)的讲?br />
7、 ?有关实例中用到的资源文g的说?br />
8、 ?struts-config.xml文g的配|?br />
9、 ?web.xml文g的配|?br />
10、jsp的制作,三种常标{ֺ的应?br />
11、有x据源的一般介l?br />
12、如何在集成开发环境中q行q个实例Q需掌握前一阶段有关IDE的学习)
三、发布实例到应用服务器中去(TomcatQ?br />
1、 ?Tomcat相关基础
2、 ?Tomcat安装、配|?br />
3、 ?web.xml
4、 ?server.xml
5、 ?如何发布一个具体的实例
更多详情请参见:我的博客 我的生活
概要QFront ControllerQ模式)
说明Q?br /> 讲解struts具体例子之前Q先说明一下Front Controller模式(前端控制器模?。struts是它的具体实现Q得以扩展,q且是Model2l构的完整实现?/p>
Model2l构通过一个控制组件来接受hQ这个控制组件本w可以ؓh提供服务Q也可以把这Q务分配给其他一些组件。生成响应信息的d接着被分配给适当的视囄件。实现这U要求的方式很多QFront Controller是其中一U?br />
实现前端控制器可以采取不同的{略Q一U典型的{略是用一个servlet
问题Q?/strong>如果把所有的功能集中h会出C个大而臃肿的控制器组Ӟ它将负责整个Web?br />
相关处理?br />解决Q?/strong>办法之一是用多个前端控制器Q分别负责某一斚w的处理Q?br />
另一U解x案是使用Command and ControllerQ命令与控制器)Q稍候介l)
下面是这UFront Controller模式CZE序框架实现Q?br />
public class FrontController extends HttpServlet {
protected void processRequest(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException {
RequestDispatcher dispatcher =
getServletContext().getRequestDispatcher(nextView);
dispatcher.forward(req, res);
}
protected void doGet(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException {
processRequest(req, res);
}
protected void doPost(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException {
processRequest(req, res);
}
}
在这里,它只是HttpServlet一个简单的扩充Q默认实CdoGet()和doPost()ҎQ这两个Ҏ负责把请求分配给另一个叫processRequest()的方法。这是ؓ了保证不论发Z么请求,前端控制器都能ؓ之提供服务?br /> 在processRequest()的方法中我们省去主要部分Q但实际上前端控制器先执行与请求关联的处理Q然后再把它分配l一个视囄件来生成相关? 响应信息。视囄件一般是JSP面。控制器完成了自q业务逻辑之后Q它可以通过RequestDispatcher把处理分配给一个JSP?br /> 到此你可能会提出一个问题。如果控制器要负责处理所有的hQ那么它怎么知道各请求都是什么以及如何处理呢Q(Command and ControllerQ上面问题所提到的,现在开始讲解)
Command and Controller{略
在Command and Controller{略中,处理每个具体h的逻辑被{Ud了一个单独的lg中?br />
q些额外lg各表CZ个具体的命oQ或操作Q既actionQ,q且lg中封装着执行相关操作的逻辑?br />
前端控制器把对请求的处理分配l适当的命令组件?br />操作c?/strong>
Z实现Command and Controller{略Q首先需要定义位于控制器和操作组件之间的接口?br />
public abstract class Action {
public abstract String process(HttpServletRequest req, HttpServletResponse res);
}
关于hcd的通信
q里的处理如下:FrontController Servlet和URI/controller/*之间定义了一个映?br />
<servlet>
<servlet-name>FrontController</servlet-name>
<servlet-class>com.wxhx.controller.FrontController</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>FrontController</servlet-name>
<url-pattern>/controller/*</url-pattern>
</servlet-mapping>
Z从附加\径信息中获得的字W串映射C个特定的操作实例上,当然Q同h很多{略可供选择Q其中最灉|的就是把q种映射外部化,例如可以通过一个XML文g?br />
Z单v见,我们在这里徏立一个单独的lgQ用于封装这U映?br />
public class ActionHelper {
private static HashMap actions = new HashMap();
static {
actions.put(”Login? “com.sample.LoginAction?;
}
public static Action getAction(String name) {
Action action = null;
try {
Class c = Class.forName((String) actions.get(name));
action = (Action) c.newInstance();
} catch (Exception e) {
e.printStackTrace();
}
return action;
}
}
好了Q以上就是要实现的一个简单的框架cFrontControllerQAction以及辅助的ActionHelperc?/p>
下一步是把所有这些处理插入到FrontController的processRequestҎ中,q将是Web应用E序中所有请求的单一入口Q?br />
public class FrontController extends HttpServlet {
protected void processRequest(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException {
String actionName =req.getPathInfo().substring(1);
Action action =ActionHelper.getAction(actionName);
String nextView =action.process(req, res);
RequestDispatcher dispatcher =
getServletContext().getRequestDispatcher(nextView);
dispatcher.forward(req, res);
}
protected void doGet(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException {
processRequest(req, res);
}
protected void doPost(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException {
processRequest(req, res);
}
}
具体相关内容可参见实例!
源码下蝲(index.rar)Q?/span> 资源下蝲中心
更多详情请参?我的博客 我的生活
说明Q代码的l构和风格gl上一,更好的读懂代?/p>
actionQSendMailAction 和ActiveMQ那䆾代码基本相同Q简单的用于控制邮g的发?/p>
utilQ还是Constants帔R数据
serviceQMailServicel合Spring的配|文件mail.xmlQ注入了JavaMail和velocity模板引擎Q在内部cMailThreadQ线E类Q中来发送邮?/p>
׃个类Q其它的配置信息mail.properties、mailtemplate、action.xml、struts-config.xml、web.xml和ActiveMQ发送邮件中的是cM的,可以参考一下?/p>
备注Q考虑到包的大,把lib中spring的架包去除了Q自己去下蝲一?.5的即?/p>
更多详情请参见:我的博客 我的生活
~存QCACHEQ?br />定义Q在本地攄、隐藏或存储常用信息以供快速检?
A memory area where frequently accessed data can be stored for rapid access.
好处Q提高系l响应速度、改善系l运行性能的技术?/p>
面的问?br />1、被处理的内容短旉不变Q所以短旉内可以作为静态内容进行处?br />2、在一个不太长的时间内Q被处理的内容可能或者必定生变化,所以必d他们作ؓ动态内容进行处?br />3、在合理的时间区D内可以忽略被处理内容变化后带来的媄?br />4、对q些内容的处理动作比较消耗系l性能Q媄响系l响应时闾b基数据的变更问?
例子Q系l中需要处理的基础数据Q统计报表?/p>
解决Ҏ
1、缓存信?br />当上q的基础数据或者统计报表第一ơ被讉KӞ被处理的内容被当作动态信息,基础数库从数据库中获得,l计报表也会被生成符合要求的囑Ş、文Ӟ然后q些信息都会被放入缓存信息中
2、响应信息由~存提供
当上q的基础数据或者统计报表l被讉KӞpȝ会首先查缓存信息中是否有对应的内容和我们设定的~存规则Q如果符合缓存信息存在而且W合~存规则Q给出的响应来自于~存信息Q如果没有或者缓存信息已l不W合讑֮的要求,pȝ重复上一步的动作?/p>
在步?中,多数情况下,当用戯求到达时Q被处理的内容将来自于缓存,所以大大的减少了与数据库的交互Q或者不再需要ؓ每个h都生成一ơ报表图形或者文Ӟq部分工作的减少对于降低pȝ性能消耗、提高系l稳定性和q发处理能力是非常有益的
OSCACHE
OSCache是OpenSymphonyl织提供的一个J2EE架构中Web应用层的~存技术实现组?
特点
兼容多种支持JSP的web服务器:已经通过兼容试的web服务器包括OrionServer 、Macromedia JRun 、BEA Weblogic 、IBM Websphere 、Silverstream 、Caucho Resin 、Tomcat (4.x及以上版?
可选的~存区:你可以用内存、硬盘空间、同时用内存和盘或者提供自q其他资源Q需要自己提供适配器)作ؓ~存区?br />使用内存作ؓ~存区将可以提供更好的性能
使用盘作ؓ~存区可以在服务器重起后q速恢复缓存内容?
同时使用内存和硬盘作为缓存区则可以减对内存的占用?
OSCache中按照缓存范围的不同分ؓ两种不同的方式:一U是~存JSP面中部分或者全部内容,一U是Z整个面文g的缓?
另外OSCHACHEq支持:POJO ~存 、O/R Data Access ~存 ?/p>
JSP部分内容~存
W一ơ请求到达时Q标{中的内容被处理q且~存hQ当下一个请求到达时Q缓存系l会查这部分内容的缓存是否已l失效,主要是以下几:
1. ~存旉过了cache标签讄的time或者duration属性规定的时旉
2. cron属性规定的旉比缓存信息的开始时间更晚?
3. 标签中缓存的内容在缓存后又被重新hq?
4. 其他~存期讑֮
JSP部分内容~存Q一个例?/font>
/*因ؓOSCache使用key值来标识~存内容Q用相同的key值将会被认ؓ使用相同的的~存内容Q所以用动态的key值可以自qҎ不同的角艌Ӏ不同的要求军_使用不同的缓存内?*/
<cache:cache key="<%= product.getId() %>" time="1800" refresh="<%= needRefresh %>">
/* JSP代码内容 或jsp tag*/
<% 代码%>
</cache:cache>
CashFilter实现面U缓?/font>
1、在OSCachelg中提供了一个CacheFilter用于实现面U的~存Q主要用于对web应用中的某些动态页面进行缓存,其是那些需要生成pdf格式文g/报表、图片文件等的页面,不仅减少了数据库的交互、减数据库服务器的压力Q而且对于减少web服务器的性能消耗有很显著的效果?br />2、这U功能的实现是通过在web.xml中进行配|来军_~存哪一个或者一l页面,而且q可以设|缓存的相关属性,q种Z配置文g的实现方式对于J2EE来说应该是一U标准的实现方式?br />3?br /><filter>
<filter-name>CacheFilter</filter-name>
<filter-class>com.opensymphony.oscache.web.filter.CacheFilter</filter-class>
<init-param>
<param-name>time</param-name>
<param-value>60</param-value></init-param>
<init-param>
<param-name>scope</param-name>
<param-value>session</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CacheFilter</filter-name>
<url-pattern>*.jsp</url-pattern>
</filter-mapping>