SSH 项目框架筹建
SSH 项目框架搭建
spring2.5 + hibernate3.0 + struts2.1 +(oracle9i)
简单说下框架的基本信息
package com.isoftstone.ssh.po ; 这个包是所有hibernate映射关系包,因为SSH架构里面我把hibernate交给spring管理 省去了hibernate.cfg.xml的映射文件导入问题。 只需要把对应的POJO和*.hbm.xml放到该包下面即可。 在spring里面做了配置如下: <property name="mappingDirectoryLocations"> <list> <value>classpath:/com/isoftstone/ssh/po</value> </list> </property> 一些hibernate的常用配置也做了相应配置,编码如下: <property name="hibernateProperties"> <props> <prop key="hibernate.dialect">org.hibernate.dialect.Oracle9Dialect</prop> <prop key="hibernate.show_sql">true</prop> <prop key="hibernate.hbm2ddl.auto">update</prop> <prop key="hibernate.format_sql">true</prop> <prop key="hibernate.autoReconnect">true</prop> <!-- <prop oracle的BLOB,CLOB配置 key="hibernate.connection.SetBigStringTryClob">true</prop> --> </props> </property> hibernate使用的jdbc连接,交给spring管理,用apache的DBCP org.apache.commons.dbcp.BasicDataSource
配置数据源如下: <!-- 配置数据源 apache-dbcp <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"> <property name="driverClassName" value="com.mysql.jdbc.Driver"></property> <property name="url" value="jdbc:mysql://localhost:3306/SSH"></property> <property name="username" value="root"></property> <property name="password" value="root"></property> </bean> --> 这里我们采用动态的配置,故注释掉以上配置 采用jdbc.properties属性文件配置 jdbc.properties如下: dataSource.driverClassName=oracle.jdbc.driver.OracleDriver dataSource.url=jdbc:oracle:thin:@127.0.0.1:1521:orcl dataSource.username=***** dataSource.password=***** 动态配置前需要加载该文件,在spring中配置如下: <!-- 加载数据库属性文件 jdbc.properties --> <bean id="configBean" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <property name="location"> <value>classpath:conf/jdbc.properties</value> </property> </bean>
其他的还有一些事物的配置,事物我们采用spring的声明式事物,一些灵活的代码,可以采用spring的编程式事物。 简单说下spring的事物: 1、编程式事物 spring 提供了几个关于事物处理的类 TransactionDefinition // 事物属性定义 TransactionStatus // 代表了当前事物,可以提交,回滚 PlatformTransactionManager // spring 提供的用户管理事物的基础接口 下面写了个DEMO,如下: private PlatformTransactionManager transactionManager; /*** 事物控制 transactionManager **/ DefaultTransactionDefinition def = new DefaultTransactionDefinition(); def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED); TransactionStatus status = this.transactionManager.getTransaction(def); try{ //dosomething ... transactionManager.commit(status); }catch{ transactionManager.rollback(status); e.printStackTrace(); } 编程式的比较灵活,但是代码量大,存在重复代码比较多; 声明式的比编程式的更灵活。 编程式主要使用 transcationTemplate. 省略了部分的提交,回滚,一系列的事物 对象定义,需注入事物管理对象。 transactionTemplate.execute(new TransactionCallback(){ public Object doInTransaction(TransactionStatus ts) { // dosomething.... } }); ------------------ 声明式: 使用 TransactionProxyFactoryBean : (org.springframework.transaction.interceptor.TransactionProxyFactoryBean) PROPAGATION_REQUIRED - 支持当前事物,如果当前没有事物,就新建一个事物。 等等.... 具体事物配置根据项目需要。以下事物DEMO,仅供参考: <!-- 配置事务管理器 --> <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"> <property name="sessionFactory"> <ref bean="sessionFactory"/> </property> </bean> <!-- 配置事务的传播特性 --> <tx:advice id="txAdvice" transaction-manager="transactionManager"> <tx:attributes> <tx:method name="save*" propagation="REQUIRED"/> <tx:method name="delete*" propagation="REQUIRED"/> <tx:method name="update*" propagation="REQUIRED"/> <tx:method name="*" read-only="false"/> </tx:attributes> </tx:advice> <!-- 那些类的哪些方法参与事务 --> <aop:config> <aop:pointcut id="allManagerMethod" expression="execution(* com.projectName.*.service.*.*(..))"/> <aop:advisor pointcut-ref="allManagerMethod" advice-ref="txAdvice"/> </aop:config>
另外就是拦截器的配置了 这里就不多说了,我把代码贴出来(拦截器就是AOP的一种策略实现)
<!-- interceptor start --> <interceptors> <interceptor name="authority" class="com.isoftstone.ssh.util.MyInterceptor"></interceptor> <!-- 拦截器栈 --> <interceptor-stack name="myDefault"> <interceptor-ref name="defaultStack"></interceptor-ref> <interceptor-ref name="authority"></interceptor-ref> </interceptor-stack> </interceptors> <!-- interceptor end --> <!-- global-results start --> <global-results> <result name="error">/pages/error.jsp</result> </global-results>
/** * MyInterceptor.java * com.isoftstone.ssh.util * * Function: TODO * * ver date author * ────────────────────────────────── * May 16, 2011 程仁银 * * Copyright (c) 2011, All Rights Reserved. */ package com.isoftstone.ssh.util; import java.util.Map; import com.opensymphony.xwork2.Action; import com.opensymphony.xwork2.ActionContext; import com.opensymphony.xwork2.ActionInvocation; import com.opensymphony.xwork2.interceptor.AbstractInterceptor; /** * ClassName:MyInterceptor * Project: * Company: isoftStone * * @author 程仁银 * @version * @since Ver 1.1 * @Date May 16, 2011 8:44:44 AM * @see */ public class MyInterceptor extends AbstractInterceptor { @Override public String intercept(ActionInvocation invocation) throws Exception { System.out.println(" ... MyInterceptor ......"); ActionContext context = invocation.getInvocationContext(); Map session = context.getSession(); String user = (String)session.get("USER"); if(null != user && user.equals("using")) { System.out.println("用户:"+ user + "已登录!"); return invocation.invoke(); } else { return Action.ERROR; } } }
项目中大家都写自己的action、service、dao信息等,比如说都写在application_context.xml中,在版本控制再好的情况下,难免会出项冲突,代码丢失等。 这里我采用分割application_context.xml文件的形式,比如说,你写user这个模块,那么你就建立个单独的application_user.xml文件或者struts_user.xml.这样就不会出现版本冲突了。 application_*.xml的形式,我在web.xml中做如下配置: <!-- 装载spring的xml文件 --> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:conf/spring/application_*.xml</param-value> </context-param> struts.xml中的配置如下: <struts> <constant name="struts.devMode" value="true" /> <constant name="struts.i18n.encoding" value="UTF-8"></constant> <include file="conf/struts/struts_regist.xml"></include> <include file="conf/struts/struts_login.xml"></include> </struts> 这样就OK了。
由于需要拦截jsp页面,我写了个filter,代码如下:
<!-- filter jspFilter--> <filter> <filter-name>MyFilter</filter-name> <filter-class>com.isoftstone.ssh.util.MyFilter</filter-class> </filter> <filter-mapping> <filter-name>MyFilter</filter-name> <url-pattern>*.jsp</url-pattern> </filter-mapping>
/** * MyFilter.java * com.isoftstone.ssh.util * * Function: TODO * * ver date author * ────────────────────────────────── * May 17, 2011 程仁银 * * Copyright (c) 2011, All Rights Reserved. */ package com.isoftstone.ssh.util; import java.io.IOException; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * ClassName:MyFilter * Project: * Company: isoftStone * * @author 程仁银 * @version * @since Ver 1.1 * @Date May 17, 2011 3:16:36 AM * @see */ public class MyFilter implements Filter{ public void init(FilterConfig filter) throws ServletException { System.out.println("****************** 过滤器初始化 ******************"); } public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { HttpServletRequest request = (HttpServletRequest)req; HttpServletResponse response = (HttpServletResponse)res; req.setCharacterEncoding("UTF-8"); String uri = request.getRequestURI(); System.out.println("URL = "+ uri); // 定义可以访问的 jsp if(uri.endsWith("/MyJsp.jsp")){ chain.doFilter(request,response); }else{ request.getRequestDispatcher("/index.jsp").forward(request,response); } } public void destroy() { System.out.println("**************** 过滤器销毁 ****************"); } }
还有一点,比如说用户数据插入、注册等情况,有重复提交的情况,strut2提供了token拦截机制,代码如下:
。。。。。。。。。。 <td colspan="2"> <input type="submit" value="提交" /> <!-- 防止重复提交 --> <s:token></s:token> </td>
<!-- 配置action,class与spring-xml中bean的名称对应 --> <action name="login" class="login" method="toLogin"> <result name="success">/index.jsp</result> <result name="faild">/index.jsp</result> <interceptor-ref name="myDefault"></interceptor-ref> <!-- 防止重复提交 --> <interceptor-ref name="token"></interceptor-ref> <!--配置错误页面,指定name="invalid.token"--> <result name="invalid.token">/pages/error.jsp</result> </action>
这样基本SSH框架就搭建好了,代码我将后期上传。 如果你要优化的话,那就看个人或者项目需要了,再做相应的配置JSTL,ERROR_PAGES等。