版本
spring 3.0.5.RELEASE
struts2 2.3.15.1
mybatis 3.2.2
spring配置
<?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:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:jdbc="http://www.springframework.org/schema/jdbc" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation=" http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd"> <!--配置spring 注解 --> <context:annotation-config /> <!-- spring注解扫描的包路径 --> <context:component-scan base-package="com.xx.项目包名" /> <!-- DAO组件,可以根据导入多个,写多个import标签 --> <import resource="daoXXContext.xml" /> <!--可选项。 properties文件传入变量值,如online.location=E:/online/ --> <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <property name="location"> <value>classpath:page.properties</value> </property> </bean> <!--可选项。手工解析FreeMarker模板时候使用 --> <bean id="freeMarkerConfiguration" class="org.springframework.ui.freemarker.FreeMarkerConfigurationFactoryBean"> <property name="templateLoaderPath" value="file:${location}" /> <property name="freemarkerSettings"> <props> <prop key="classic_compatible">true</prop> <prop key="template_update_delay">0</prop> <prop key="default_encoding">UTF-8</prop> <prop key="locale">zh_CN</prop> <prop key="number_format">#</prop> </props> </property> </bean> </beans>
<?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:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:jdbc="http://www.springframework.org/schema/jdbc" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation=" http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd"> <!-- 数据源 --> <bean id="prodbDataSource" class="org.apache.commons.dbcp.BasicDataSource"> <!--oracle jdbc驱动类 --> <property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"></property> <property name="url" value="jdbc:oracle:thin:@ip:port:database_name" /> <!--mysql <property name="driverClassName" value="com.mysql.jdbc.Driver"></property> <property name="url" value="jdbc:mysql://ip:port/database_name" /> --> <property name="username" value="xx" /> <property name="password" value="xx"/> </bean> <!-- Spring的声明式事务管理 --> <!-- 设置与事务有关的各种属性 --> <tx:advice id="txAdvice" transaction-manager="txManager"> <tx:attributes> <tx:method name="insert*" propagation="REQUIRED" rollback-for="Exception"/> <tx:method name="add*" propagation="REQUIRED" rollback-for="Exception" /> <tx:method name="update*" propagation="REQUIRED" rollback-for="Exception" /> <tx:method name="del*" propagation="REQUIRED" rollback-for="Exception" /> <!-- 除了你上面定义的,其他的方法不走事务 --> <tx:method name="*" read-only="false" /> </tx:attributes> </tx:advice> <!-- 声明切入点 --> <aop:config> <aop:pointcut id="loginPointCuts" expression="execution(* com.xx.xx.service.*.*(..))" /> <aop:advisor advice-ref="txAdvice" pointcut-ref="loginPointCuts" /> </aop:config> <-- 注解事务配置,比较简单,需要在接口或实现类写@Transactional --> <!-- 事务管理配置 --> <!-- <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource" /> </bean> --> <!-- 启动事务管理 --> <!-- <tx:annotation-driven transaction-manager="transactionManager" /> --> <!-- SqlSessionFactory --> <bean id="prodbSqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="prodbDataSource" /> <!-- 数据对象包路径 --> <property name="typeAliasesPackage" value="com.xx.xx.po.prodb" /> <!-- mybatis环境配置文件位置(src\main\resources) 或者:classpath:com/xx/xx/mybatis-prodb-conf.xml(src\main\resources\com\xx\xx)--> <property name="configLocation" value="classpath:mybatis-prodb-conf.xml" /> </bean> <!-- mapper扫描配置 --> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <!-- 多个数据源时候,这个必须指定,否则随机会请求到其它库--> <property name="sqlSessionFactory" ref="prodbSqlSessionFactory"/> <!-- mapper接口包路径 --> <property name="basePackage" value="com.xx.xx.mapper.prodb" /> </bean> </beans>
struts2配置
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" "http://struts.apache.org/dtds/struts-2.0.dtd">, <struts> <constant name="struts.i18n.encoding" value="UTF-8" /> <!-全称:org.apache.struts2.spring.StrutsSpringObjectFactory---> <constant name="struts.objectFactory" value="spring" /> <!-- 装配策略 ,默认情况下框架使用的自动装配策略是name, 其它策略type、auto、constructor--> <constant name="struts.objectFactory.spring.autoWire" value="name" /> <!-- 该属性指定整合spring时,是否对bean进行缓存,值为true or false,默认为true --> <constant name="struts.objectFactory.spring.useClassCache" value="false" /> <!-- 设置url请求后缀 --> <constant name="struts.action.extension" value="do" /> <!-- 设置是否每次请求,都重新加载资源文件,默认值为false. --> <constant name="struts.i18n.reload" value="true" /> <!-- 当struts的配置文件修改后,系统是否自动重新加载该文件,默认值为false(生产环境下使用),开发阶段最好打开 --> <constant name="struts.configuration.xml.reload" value="true" /> <!-- 是否自动重新加载action --> <constant name="struts.convention.classes.reload" value="true" /> <!-- 允许动态方法调用 --> <constant name="struts.enable.DynamicMethodInvocation" value="false" /> <!-- 开发模式下使用(自动加载国际化文件,配置文件,且提升问题等级。对性能有影响,另外还带来其他问题)生产要求为false --> <constant name="struts.devMode" value="false" /> <!-- 确定搜索包的路径。只要是结尾为action的包都要搜索。--> <constant name="struts.convention.package.locators" value="action" /> <!-- 请修改此处 --> <constant name="struts.convention.package.locators.basePackage" value="com.xx.xx.action" /> <!-- 访问的地址使用小写,如:helloworld.do --> <constant name="struts.convention.action.name.lowercase" value="true" /> <!--action名字后缀--> <constant name="struts.convention.action.suffix" value="Action" /> <!--默认返回的结果类型搜索。按顺序先找velocity ,再找相关的dispatcher的jsp文件。也可配置freemarker--> <constant name="struts.convention.relative.result.types" value="velocity,dispatcher" /> <!-- 文字资源国际化常量 --> <constant name="struts.custom.i18n.resources" value="globalMessages" /> <!--指定Velocity框架的toolbox的位置--> <constant name="struts.velocity.toolboxlocation" value="/WEB-INF/tools.xml" /> <!--指定结果页面路径。 convention插件会自动在此路径中寻找文件。放到WEB-INF的目的的保护文件资源, 只能通过程序内部跳转才能访问,我们的权限拦截器或其他权限处理只要加到action上就可以了。--> <constant name="struts.convention.result.path" value="/WEB-INF/content/" /> <!--好像可以不写这3行。 simple主题时,每个UI标签只生成一个简单的HTML元素,不会生成其他额外的内容--> <constant name="struts.ui.theme" value="simple" /> <constant name="struts.ui.templateDir" value="template" /> <constant name="struts.ui.templateSuffix" value="vm" /> <!-- 在Jboss中使用convention插件,添加下面两个常量 --> <!-- <constant name="struts.convention.exclude.parentClassLoader" value="true" /> <constant name="struts.convention.action.fileProtocols" value="jar,vfsfile,vfszip" /> --> <!-- 上传文件需要配置如下两个常量,10M上限,临时目录/tmp --> <constant name="struts.multipart.maxSize" value="10701096" /> <constant name="struts.multipart.saveDir" value="/tmp" /> <!--Action类注解 @ParentPackage("default") 父包对应这个。 --> <package name="default" namespace="/" extends="json-default"> <interceptors> <!-- 登录验证拦截器 --> <interceptor name="authority" class="com.xx.xx.web.interceptor.xxSecurityInterceptor" /> <interceptor-stack name="loginStack"> <!-- 指定需要进行重复提交拦截的方法 --> <interceptor-ref name="authority"> <param name="excludeMethods"> page_audit,copy_page </param> </interceptor-ref> <interceptor-ref name="checkCurrentSite" /> <interceptor-ref name="defaultStack" /> </interceptor-stack> <interceptor-stack name="nologinStack"> <interceptor-ref name="defaultStack" /> </interceptor-stack> </interceptors> <default-interceptor-ref name="loginStack" /> <!--全局异常页面 --> <global-results> <result name="exception" type="dispatcher">/WEB-INF/content/exception.vm</result> <result name="err" type="velocity">/WEB-INF/content/error.vm</result> <result name="invalid.token" type="velocity">/WEB-INF/content/duplicated.vm</result> </global-results> <global-exception-mappings> <exception-mapping exception="java.lang.Exception" result="exception" /> </global-exception-mappings> </package> </struts>
其它配置可以参考:Struts2 convention plugin http://blog.163.com/pudi_1984_mail/blog/static/1643856162010427983652/
mybatis配置:mybatis-prodb-conf.xml
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> <settings> <setting name="cacheEnabled" value="false" /> <setting name="lazyLoadingEnabled" value="false" /> <setting name="aggressiveLazyLoading" value="true" /> <setting name="multipleResultSetsEnabled" value="true" /> <setting name="useColumnLabel" value="true" /> <setting name="autoMappingBehavior" value="FULL" /> <setting name="defaultExecutorType" value="SIMPLE" /> <setting name="defaultStatementTimeout" value="25" /> </settings> </configuration>
Sitemesh 配置: decorators.xml
位置:src\main\webapp\WEB-INF
<?xml version="1.0" encoding="UTF-8"?> <decorators defaultdir="/WEB-INF/decorators"> <!-- Any urls that are excluded will never be decorated by Sitemesh --> <excludes> <pattern>/nodecorate/*</pattern> <pattern>/styles/*</pattern> <pattern>/scripts/*</pattern> <pattern>/images/*</pattern> <pattern>/dojo/*</pattern> <pattern>/assets/*</pattern> </excludes> <decorator name="isblank" page="/decorators/blank.vm" > <pattern>/index/*</pattern> </decorator> <decorator name="main" page="/decorators/xx.vm"> <!-- <pattern>/prd/*</pattern> --> <pattern>/usr/*</pattern> <pattern>/prd/*</pattern> </decorator> </decorators>
sitemesh.xml
位置:src\main\webapp\WEB-INF
<?xml version="1.0" encoding="UTF-8" ?> <sitemesh> <property name="decorators-file" value="/WEB-INF/decorators.xml"/> <excludes file="${decorators-file}"/> <page-parsers> <parser content-type="text/html" class="com.opensymphony.module.sitemesh.parser.FastPageParser"/> </page-parsers> <decorator-mappers> <mapper class="com.opensymphony.module.sitemesh.mapper.PageDecoratorMapper"> <param name="property.1" value="meta.decorator"/> <param name="property.2" value="decorator"/> </mapper> <mapper class="com.opensymphony.module.sitemesh.mapper.FrameSetDecoratorMapper"> </mapper> <mapper class="com.opensymphony.module.sitemesh.mapper.AgentDecoratorMapper"> <param name="match.MSIE" value="ie"/> <param name="match.Mozilla [" value="ns"/> <param name="match.Opera" value="opera"/> <param name="match.Lynx" value="lynx"/> </mapper> <mapper class="com.opensymphony.module.sitemesh.mapper.PrintableDecoratorMapper"> <param name="decorator" value="isblank" /> <param name="parameter.name" value="isblank" /> <param name="parameter.value" value="true" /> </mapper> <mapper class="com.opensymphony.module.sitemesh.mapper.RobotDecoratorMapper"> <param name="decorator" value="robot"/> </mapper> <mapper class="com.opensymphony.module.sitemesh.mapper.ParameterDecoratorMapper"> <param name="decorator.parameter" value="decorator"/> <param name="parameter.name" value="confirm"/> <param name="parameter.value" value="true"/> </mapper> <mapper class="com.opensymphony.module.sitemesh.mapper.ConfigDecoratorMapper"> <param name="config" value="${decorators-file}"/> </mapper> </decorator-mappers> </sitemesh>
velocity 配置: velocity.properties
位置:src\main\webapp\WEB-INF
input.encoding = UTF-8 output.encoding =UTF-8 # ---------------------------------------------------------------------------- # VELOCIMACRO PROPERTIES # ---------------------------------------------------------------------------- # global : name of default global library. It is expected to be in the regular # template path. You may remove it (either the file or this property) if # you wish with no harm. # ---------------------------------------------------------------------------- # dev-changes by Marino webapp.resource.loader.cache = true webapp.resource.loader.modificationCheckInterval = 1 velocimacro.library.autoreload = false velocimacro.library = /WEB-INF/VM_global_library.vm velocimacro.permissions.allow.inline = true velocimacro.permissions.allow.inline.to.replace.global = false velocimacro.permissions.allow.inline.local.scope = false velocimacro.context.localscope = false #用户自定义 #userdirective=xx
配置vm宏 :VM_global_library.vm
位置:src\main\webapp\WEB-INF
## Display all queued Struts errors for a particular property #macro (errorMarkupForProperty $property) #if ($errors.exist($property) ) <div> #foreach ($er in $errors.get($property)) #if("https"==$reqscheme) <div style="color:#F00; font-size:11px; line-height:22px; height:22px; overflow:hidden; padding-left:30px; background:url(/img/login_bg.gif) no-repeat 5px -15px;">$er</div> #else <div style="color:#F00; font-size:11px; line-height:22px; height:22px; overflow:hidden; padding-left:30px; background:url(http://image.xx.com/b/img/login/login_bg.gif) no-repeat 5px -15px;">$er</div> #end #end </div> #end #end #macro(pagebargoogle $pageInfo $form) #if($pageInfo.totalCount>0) <script language="javascript"> function tp (pagenum,frm,formtype){ if(frm==null || frm==''){ frm=document.getElementById('$form'); }else{ frm=document.getElementById(frm); } document.getElementById('page').value=pagenum; frm.submit(); } //判断输入框中的只能是数字,不是数字则置空 function getPageNum(obj){ var str = obj.value; if(!validateNum(str)){ obj.value=""; } } //判断数字//wuzhonghua //由数字组成 true 否则false function validateNum(str){ var patn = /^[0-9-\/]+$/; //正则表达式,不是数字 if(patn.test(str)) return true; return false; } </script> ##google like page number by b.m #if($pageInfo.page<=6) #set($startIndex=1) #if($pageInfo.totalPage>10) #set($endIndex=10) #else #set($endIndex=$page.totalPage) #end #else #set($startIndex=$pageInfo.page - 5) #if($pageInfo.totalPage > $pageInfo.page + 4 ) #set($endIndex = $pageInfo.page + 4) #else #set($endIndex = $pageInfo.totalPage) #end #end #if($pageInfo.page < $pageInfo.totalPage) #set($nextIndex=$pageInfo.page + 1) #else #set($nextIndex=1) #end #set($prevIndex=$pageInfo.page - 1) <!--startIndex = $startIndex endIndex = $endIndex--> <div class="mould-page"> <div class="page clearfix"> <div class="number"> 共有$!{pageInfo.totalCount}条记录 每页显示$!{pageInfo.pageSize}条 </div> <div class="page-list clearfix"> <span>Page <strong>$!{pageInfo.page}</strong> of <strong>$!{pageInfo.totalPage}</strong></span> #if($prevIndex > 0) <a href="javascript:tp($prevIndex)"><<</a> #end #foreach($i in [$startIndex..$endIndex ]) #if($i == $pageInfo.page) <b>$i</b> #else <a href="javascript:tp($i)">$i</a> #end #end #if($nextIndex > 1) <a href="javascript:tp($nextIndex)">>></a> #end </div> </div> </div> #end #end
velocity工具,页面使用tools.xml
<?xml version="1.0"?> <tools> <toolbox scope="request"> <tool class="org.apache.velocity.tools.generic.ResourceTool" bundles="resources" locale="en_US"/> </toolbox> <toolbox scope="application"> <tool key="tokenHelper" class="org.apache.struts2.util.TokenHelper" /> </toolbox> <toolbox scope="application"> <tool class="org.apache.velocity.tools.generic.NumberTool"/> </toolbox> </tools>
web工程配置:web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app id="struts_blank" version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"> <display-name>Struts Blank Convention</display-name> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath*:applicationContext*.xml</param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <!-- Spring 刷新Introspector防止内存泄露 参考:http://blog.csdn.net/yakoo5/article/details/8240925--> <listener> <listener-class>org.springframework.web.util.IntrospectorCleanupListener</listener-class> </listener> <filter> <filter-name>encodingFilter </filter-name> <filter-class> org.springframework.web.filter.CharacterEncodingFilter </filter-class> <init-param> <param-name>encoding </param-name> <param-value>UTF-8 </param-value> </init-param> <init-param> <param-name>forceEncoding </param-name> <param-value>true </param-value> </init-param> </filter> <filter> <filter-name>sitemesh</filter-name> <filter-class>com.opensymphony.module.sitemesh.filter.PageFilter</filter-class> <!-- <filter-class>org.apache.struts2.sitemesh.VelocityPageFilter</filter-class> --> </filter> <!--类似老版本的FilterDispatcher-->action 参考: StrutsPrepareAndExecuteFilter的作用 http://blog.sina.com.cn/s/blog_6ac4c6cb010190ml.html --> <filter> <filter-name>struts2</filter-name> <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class> </filter> <filter-mapping> <filter-name>encodingFilter </filter-name> <url-pattern>/* </url-pattern> </filter-mapping> <filter-mapping> <filter-name>sitemesh</filter-name> <url-pattern>/*</url-pattern> <dispatcher>REQUEST</dispatcher> <dispatcher>FORWARD</dispatcher> <dispatcher>INCLUDE</dispatcher> </filter-mapping> <filter-mapping> <filter-name>struts2</filter-name> <url-pattern>*.do</url-pattern> </filter-mapping> <servlet> <servlet-name>velocity</servlet-name> <servlet-class>com.opensymphony.module.sitemesh.velocity.VelocityDecoratorServlet</servlet-class> <!-- <servlet-class>org.apache.struts2.sitemesh.VelocityDecoratorServlet</servlet-class> --> </servlet> <servlet-mapping> <servlet-name>velocity</servlet-name> <url-pattern>*.vm</url-pattern> </servlet-mapping> </web-app>
This listener should be registered as the first one in web.xml, before any application listeners such as Spring's ContextLoaderListener. This allows the listener to take full effect at the right time of the lifecycle.
IntrospectorCleanupListener应该注册为web.xml中的第一个Listener,在任何其他Listener之前注册,比如在Spring's ContextLoaderListener注册之前,才能确保IntrospectorCleanupListener在Web应用的生命周期适当时机生效。
sitemesh通过filter截取request和response,并给原始的页面加入一定的装饰(可能为header,footer...),然后把结果返回给客户端,并且被装饰的原始页面并不知道sitemesh的装饰,这也就达到了脱耦的目的。
sitemesh应用Decorator模式 :http://www.blogjava.net/gdufo/archive/2008/08/04/219996.html
相关推荐
一个简单的spring+struts2+hibernate+mybatis整合(数据库脚本放在项目资源文件的sql目录下) 因为没想好mvc用springmvc好,还是struts2好 所以没有整合进去
maven构建项目,简单的struts2、spring、mybatis结构实现,页面展示用的easyui
Eclipse+Struts2+Spring3+MyBatis3+jQuery环境搭建
struts2+spring3+hibernate4+mybatis3整合
基于注解的Spring+Struts2+Mybatis+Maven项目,Spring 3.0 Struts2 Mybatis3.0
struts2+spring+mybatis框架,附带数据库建表,适合初学者搭建环境。
该项目是本人真实项目中使用到的mina + spring+struts2 + mybatis框架,里面有详细的注释说明,以及一个完整的接收消息、入库、返回例子。对需要真实项目开发的人员来说,可以直接使用。 另外,如果需要更加详细的...
简单的SPRING3+STRUTS2+MYBATIS3开发例子,非常简单入门。
Spring+SpringMVC+Mybatis+Velocity+Maven整合
初学者Eclipse+Struts2+Spring+MyBatis环境搭建 文档教程
spring+mybatis+struts框架
【资源说明】 1、该资源包括项目的全部源码,下载可以直接使用! 2、本项目适合作为计算机、数学、电子信息等专业的课程设计、期末...隐患排查系统源码+项目说明+数据库(基于Spring3.2+Struts2.3+Mybatis+Mysql5.7)...
struts2+spring4+mybatis3框架搭建手册 struts2+spring4+mybatis3框架搭建手册
此项目介绍了以SSM(struts2+Spring3+Mybatis3)项架整合,页面采用VM(velocity)+DWZ(简单实用国产jQuery UI框架)集合
使用maven整合了struts2+spring+mybatis+springMVC四种开源框架,oracle数据库
【源码+配置教程】Maven3.2 + Spring4.0 + Spring MVC + mybatis3 整合实例 内含源码和配置教程,可直接导入MyEclipse运行
maven+springMVC+mybatis+velocity+mysql+junit项目框架搭建
Eclipse+Struts2+Spring+MyBatis+jQuery整合教程,Eclipse+Struts2+Spring+MyBatis+jQuery整合教程.
公司框架是SSH,hibernate用的越来越少,做了几年后,也懒得用了,springjdbc玩到现在,maven,mybatis没用到一直都没去接触,感慨...也当学习下,于是花了两天时间搭建了eclipse+mavaen+struts2+spring+mybatis基础环境
包内包含Struts2+Spring3+MyBatis框架整合源码+pdf整合文档 包含了SSM所需的所有jar包和相关整合文档