您的位置:首页 > 编程语言 > Java开发

基于 JSF+Spring + JPA 构建敏捷的Web应用[88250原创]

2008-01-31 17:43 891 查看
在开发Java Web应用时,我们经常要选择合适的框架进行开发,以提高效率和应用系统的质量。选择框架时,最难抉择的就是Web框架(持久层框架已经有JPA规范了)。

在用过众多的Web框架后,结合实际项目(在线考试系统)需要,我决定尝试一下最新的框架组合:
JSF1.2 + Spring2.5 + JPA1.0。本文以配置文件为重,介绍这三个框架的整合方法与步骤,希望对大家有用!

其实,在配置各种框架组合的时候最重要的就是配置文件。还好Spring足够强大,以Bean的方式将其他框架融合进来,用统一的方式管理,的确是很先进和优良的配置技术。
下面从前端(JSF)到后端(JPA)的顺序来给出实例配置文件:

web.xml:

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"> <context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/applicationContext.xml</param-value>
</context-param>
<context-param>
<param-name>javax.faces.STATE_SAVING_METHOD</param-name>
<param-value>client</param-value>
</context-param>
<context-param>
<param-name>com.sun.faces.validateXml</param-name>
<param-value>true</param-value>
</context-param>
<context-param>
<param-name>com.sun.faces.verifyObjects</param-name>
<param-value>false</param-value>
</context-param>
<filter>
<filter-name>UploadFilter</filter-name>
<filter-class>com.sun.webui.jsf.util.UploadFilter</filter-class>
<init-param>
<description>The maximum allowed upload size in bytes. If this is set to a negative value, there is no maximum. The default value is 1000000.</description>
<param-name>maxSize</param-name>
<param-value>1000000</param-value>
</init-param>
<init-param>
<description>The size (in bytes) of an uploaded file which, if it is exceeded, will cause the file to be written directly to disk instead of stored in memory. Files smaller than or equal to this size will be stored in memory. The default value is 4096.</description>
<param-name>sizeThreshold</param-name>
<param-value>4096</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>UploadFilter</filter-name>
<servlet-name>Faces Servlet</servlet-name>
</filter-mapping>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>2</load-on-startup>
</servlet>
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<init-param>
<param-name>javax.faces.LIFECYCLE_ID</param-name>
<param-value>com.sun.faces.lifecycle.PARTIAL</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet>
<servlet-name>ExceptionHandlerServlet</servlet-name>
<servlet-class>com.sun.errorhandler.ExceptionHandler</servlet-class>
<init-param>
<param-name>errorHost</param-name>
<param-value>localhost</param-value>
</init-param>
<init-param>
<param-name>errorPort</param-name>
<param-value>24444</param-value>
</init-param>
</servlet>
<servlet>
<servlet-name>ThemeServlet</servlet-name>
<servlet-class>com.sun.webui.theme.ThemeServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>*.htm</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>/faces/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>ExceptionHandlerServlet</servlet-name>
<url-pattern>/error/ExceptionHandler</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>ThemeServlet</servlet-name>
<url-pattern>/theme/*</url-pattern>
</servlet-mapping>
<session-config>
<session-timeout>
30
</session-timeout>
</session-config>
<welcome-file-list>
<welcome-file>faces/Page1.jsp</welcome-file>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<error-page>
<exception-type>javax.servlet.ServletException</exception-type>
<location>/error/ExceptionHandler</location>
</error-page>
<error-page>
<exception-type>java.io.IOException</exception-type>
<location>/error/ExceptionHandler</location>
</error-page>
<error-page>
<exception-type>javax.faces.FacesException</exception-type>
<location>/error/ExceptionHandler</location>
</error-page>
<error-page>
<exception-type>com.sun.rave.web.ui.appbase.ApplicationException</exception-type>
<location>/error/ExceptionHandler</location>
</error-page>
<jsp-config>
<jsp-property-group>
<url-pattern>*.jspf</url-pattern>
<is-xml>true</is-xml>
</jsp-property-group>
</jsp-config>
</web-app>

faces-config.xml:

<?xml version='1.0' encoding='UTF-8'?>

<!-- =========== FULL CONFIGURATION FILE ================================== -->

<faces-config version="1.2"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_1_2.xsd"> <application>
<variable-resolver>
org.springframework.web.jsf.DelegatingVariableResolver
</variable-resolver>
</application>

<managed-bean>
<managed-bean-name>SessionBean</managed-bean-name>
<managed-bean-class>cn.edu.ynu.sei.onlineexam.web.SessionBean</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
</managed-bean>
<managed-bean>
<managed-bean-name>Page1</managed-bean-name>
<managed-bean-class>cn.edu.ynu.sei.onlineexam.web.Page1</managed-bean-class>
<managed-bean-scope>request</managed-bean-scope>
</managed-bean>
<managed-bean>
<managed-bean-name>ApplicationBean</managed-bean-name>
<managed-bean-class>cn.edu.ynu.sei.onlineexam.web.ApplicationBean</managed-bean-class>
<managed-bean-scope>application</managed-bean-scope>
</managed-bean>
<managed-bean>
<managed-bean-name>RequestBean</managed-bean-name>
<managed-bean-class>cn.edu.ynu.sei.onlineexam.web.RequestBean</managed-bean-class>
<managed-bean-scope>request</managed-bean-scope>
</managed-bean>
</faces-config>

dispatcher-servlet.xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd">
<bean class="org.springframework.web.servlet.mvc.support.ControllerClassNameHandlerMapping"/>

<bean id="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<props>
<prop key="/index.htm">indexController</prop>
</props>
</property>
</bean>

<bean id="viewNameTranslator"
class="org.springframework.web.servlet.view.DefaultRequestToViewNameTranslator" />

<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver"
p:prefix="/WEB-INF/jsp/"
p:suffix=".jsp" />

<!--
for the majority of the controllers use the new ControllerClassNameHandlerMapping
above, but because the class used is the ParameterizableViewController we
are specifying a bean name to define the mapping as /index.htm
-->
<bean name="indexController"
class="org.springframework.web.servlet.mvc.ParameterizableViewController"
p:viewName="index" />

</beans>

applicationContext.xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource"
p:driverClassName="com.mysql.jdbc.Driver"
p:url="jdbc:mysql://localhost:3306/OnlineExamDB"
p:username="ExamDBAdmin"
p:password="javawork" />
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.TopLinkJpaVendorAdapter">
<property name="showSql" value="true"/>
<property name="generateDdl" value="true"/>
<property name="database" value="MYSQL"/>
</bean>
</property>
<property name="loadTimeWeaver">
<bean class="org.springframework.instrument.classloading.SimpleLoadTimeWeaver"/>
</property>
</bean>

<tx:annotation-driven />

<bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor"/>

<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor"/>

<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory"/>
<property name="dataSource" ref="dataSource"/>
</bean>

<!-- 用户业务服务 -->
<bean id="userService" class="cn.edu.ynu.sei.onlineexam.business.impl.GenericUserService" />

<!-- 用户数据持久化服务 -->
<bean id="userDAO" class="cn.edu.ynu.sei.onlineexam.persistence.impl.UserDAO">
<property name="entityManagerFactory" ref="entityManagerFactory"/>
</bean>

<!-- 试卷问题数据持久化服务 -->
<bean id="questionDAO" class="cn.edu.ynu.sei.onlineexam.persistence.impl.QuestionDAO">
<property name="entityManagerFactory" ref="entityManagerFactory"/>
</bean>

<!-- 试卷数据持久化服务 -->
<bean id="examPaperDAO" class="cn.edu.ynu.sei.onlineexam.persistence.impl.ExamPaperDAO">
<property name="entityManagerFactory" ref="entityManagerFactory"/>
</bean>

<!-- 考试数据持久化服务 -->
<bean id="examinationDAO" class="cn.edu.ynu.sei.onlineexam.persistence.impl.ExaminationDAO">
<property name="entityManagerFactory" ref="entityManagerFactory"/>
</bean>
</beans>

context.xml:

<?xml version="1.0" encoding="UTF-8"?>
<Context path="/OnlineExam">
<Resource auth="Container"
driverClassName="com.mysql.jdbc.Driver"
maxActive="20"
maxIdle="10"
maxWait="-1"
name="jdbc/ExamDB"
password="javawork"
type="javax.sql.DataSource"
url="jdbc:mysql://localhost:3306/OnlineExamDB"
username="ExamDBAdmin"/>
<Loader>
loaderClass="org.springframework.instrument.classloading.tomcat.TomcatInstrumentableClassLoader"
</Loader>

</Context>

persistence.xml:

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="1.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"> <persistence-unit name="OnlineExamPU" transaction-type="RESOURCE_LOCAL">
<provider>oracle.toplink.essentials.PersistenceProvider</provider>
<class>cn.edu.ynu.sei.onlineexam.entity.AbstractUser</class>
<class>cn.edu.ynu.sei.onlineexam.entity.Examination</class>
<class>cn.edu.ynu.sei.onlineexam.entity.Question</class>
<class>cn.edu.ynu.sei.onlineexam.entity.QuestionKey</class>
<class>cn.edu.ynu.sei.onlineexam.entity.QuestionOption</class>
<class>cn.edu.ynu.sei.onlineexam.entity.Student</class>
<class>cn.edu.ynu.sei.onlineexam.entity.Teacher</class>
<class>cn.edu.ynu.sei.onlineexam.entity.ExamPaper</class>
<exclude-unlisted-classes>true</exclude-unlisted-classes>
<properties>
<property name="toplink.ddl-generation" value="drop-and-create-tables"/>
</properties>
</persistence-unit>
</persistence>

至此,配置文件介绍完毕了。具体的源代码没必要一一给出,只需了解IoC/ DI 的机制,运用Spring2.5 和JPA Entity Annotation注入来完成我们的应用。
值得一提的是,我认为一个典型的OO实践者都不会想要自己动手建立数据库(Schema),还有各种表、表之间的约束。JPA 为我们提供了完整的ORM规范,可以根据Entities自动生成数据库,相当方便。
加之Sprng2.5也可以用Annotation来简化配置,何乐而不为呢?
另外,关于JSF的争论持续了很多年(2004至今,一直靠各大厂商支撑着),但我认为这一组件式的Web框架技术很适合作为快速开发,也在一定程度上兼顾了后期的可维护性,很难得的Web框架。在NetBeans6里也得到了较好的支持(不过Bugs不断),相信JSF在实际应用中是有很广阔的前景的!

好了,本次框架组合的实例到此结束了,大家有什么问题欢迎跟帖评论 :-)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: