构建Portlet应用
在这里, myTransactionManager引用了mySessionFactory bean。 本例使用一个TransactionProxyFactoryBean,它定义了一个属性transactionManager。 这个对象很有用,它能很方便的处理你申明的事物还有Service Object。你可以通过transactionAttributes 属性来定义怎样处理。TransactionProxyFactoryBean 还有个属性target. 这将会注入我们的 Business service object(infoObjectTarget)引用, infoObjectTarget定义了 业务服务层,并且它还有个属性,将会注入我们的DAO对象(InfoObjectDAO)引用,通过这个配置,我们就将DAO对象和Service Object对象关联了起来,并在Business Service这一层提供了事务管理,在InfoObjectService中所有以find开头的方法,则以只读的事务处理机制进行处理。(设为只读型事务,可以使持久层尝试对数据操作进行优化,如对于只读事务Hibernate将不执行flush操作,而某些数据库连接池和JDBC 驱动也对只读型操作进行了特别优化。);而使用save开头的方法,将会纳入事务管理范围。如果此方法中抛出异常,则Spring将当前事务回滚,如果方法正常结束,则提交事务。
在这里,我们的DAO层是使用Hibernate实现的,如果我们将DAO层的实现技术改为JDBC,JDO,DAO等,只需要实现IInfoObjectDAO接口,并在Spring配置文件里,将infoObjectDAO bean的实现类名替换为新实现的类名即可,如此就可以将改动控制在最小的范围之内,不会因为DAO层的变化而引起程序结构大规模的改变,显得非常的灵活,具有良好的可维护性。
建立表示层(The Presentation Layer)
我们已经建立了应用程序的DAO层和Service层,现在我们需要做的就是将Service的接口暴露给表示层,使表示层能够调用到Service层的接口,并将处理结果展现给用户。在这一层,我们在本示例中将使用Struts Portlet框架编写Portlet进行展现。
设计页面流程
我们先设计一下实现本示例功能的页面操作流程:
用户访问本示例Portlet后,首先看到的是新闻列表,点击新闻链接,可以查看新闻内容,点击新建按钮,进入新建新闻页面,可以新建新闻,选择新闻后,点击编辑新闻按钮,进入编辑新闻页面,可以编辑新闻,选择新闻后,点击删除按钮,可以删除新闻。
由此,我们可以设计出Struts框架下应用需要的元素:
FormBean 表单bean
InfoObjectForm 我们在com.ibm.sample.web.forms包下建立InfoObjectForm类,用来记录一条新闻信息的Formbean对象
Action 操作
我们在 com.ibm.sample.web.actions 包中创建三个 Struts 操作。
GetInfoObjectAction
SaveInfoObjectAction
ListInfoObjectsAction
JSP
ListInfoObjects.jsp :展示新闻列表页面
ViewInfoObject.jsp : 查看新闻页面
EditInfoObject.jsp : 编辑新闻页面
整个应用的Web图如下:
图4 
实现表现层对Service层的访问
1. 配置web.xml文件
为了实现表现层对Service层的调用,我们首先需要更改web.xml文件,在里面添加如下代码:
代码清单9:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/classes/applicationContext-hibernate.xml</param-value>
</context-param>
<servlet id="servlet_12345">
<servlet-name>SpringContextServlet</servlet-name>
<servlet-class>org.springframework.web.context.ContextLoaderServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>SpringContextServlet</servlet-name>
<url-pattern>/**//*</url-pattern>
</servlet-mapping>
![]()
通过这样的配置,示例应用程序在启动的时候,会首先初始化Spring框架自带的ContextLoaderServlet,这个Servlet的作用就是读取由contextConfigLocation指定的Spring配置文件的位置,初始化Spring框架的Context对象,并将这个对象保存在ServletContext中,留待Action调用。
同时,为了解决中文输入问题,我们在web.xml中加入过滤器,过滤器的具体代码请见附件。
代码清单10:<filter>
<filter-name>SetCharacterEncodingFilter</filter-name>
<display-name>SetCharacterEncodingFilter</display-name>
<filter-class>com.ibm.sample.web.filter.SetCharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>GB2312</param-value>
</init-param>
<init-param>
<param-name>ignore</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>SetCharacterEncodingFilter</filter-name>
<url-pattern>/SetCharacterEncodingFilter</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>SetCharacterEncodingFilter</filter-name>
<servlet-name>action</servlet-name>
</filter-mapping>