与前面的一篇mybatis 3.2.7 与 spring mvc 3.x、logback整合 相比,只是web层的MVC前端框架,从spring mvc转换成struts 2.x系列,变化并不大
一、pom.xml 配置
1 <?xml version="1.0" encoding="UTF-8"?> 2 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 3 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> 4 <modelVersion>4.0.0</modelVersion> 5 <groupId>infosky</groupId> 6 <artifactId>struts2-helloworld</artifactId> 7 <packaging>war</packaging> 8 <version>1.0</version> 9 <properties> 10 <java-version>1.6</java-version> 11 <struts2.version>2.3.16.3</struts2.version> 12 <spring.version>3.2.8.RELEASE</spring.version> 13 </properties> 14 <dependencies> 15 16 <!-- db driver --> 17 <dependency> 18 <groupId>commons-dbcp</groupId> 19 <artifactId>commons-dbcp</artifactId> 20 <version>1.4</version> 21 </dependency> 22 23 24 <!-- log --> 25 <dependency> 26 <groupId>org.slf4j</groupId> 27 <artifactId>slf4j-api</artifactId> 28 <version>1.7.7</version> 29 </dependency> 30 31 <dependency> 32 <groupId>ch.qos.logback</groupId> 33 <artifactId>logback-core</artifactId> 34 <version>1.1.2</version> 35 </dependency> 36 37 <dependency> 38 <groupId>ch.qos.logback</groupId> 39 <artifactId>logback-classic</artifactId> 40 <version>1.1.2</version> 41 </dependency> 42 43 <!-- spring --> 44 <dependency> 45 <groupId>org.apache.struts</groupId> 46 <artifactId>struts2-spring-plugin</artifactId> 47 <version>2.3.16.3</version> 48 </dependency> 49 50 <dependency> 51 <groupId>org.springframework</groupId> 52 <artifactId>spring-context</artifactId> 53 <version>${spring.version}</version> 54 </dependency> 55 56 <dependency> 57 <groupId>org.springframework</groupId> 58 <artifactId>spring-beans</artifactId> 59 <version>${spring.version}</version> 60 </dependency> 61 62 <dependency> 63 <groupId>org.springframework</groupId> 64 <artifactId>spring-core</artifactId> 65 <version>${spring.version}</version> 66 </dependency> 67 68 <dependency> 69 <groupId>org.springframework</groupId> 70 <artifactId>spring-web</artifactId> 71 <version>${spring.version}</version> 72 </dependency> 73 74 <dependency> 75 <groupId>org.springframework</groupId> 76 <artifactId>spring-context</artifactId> 77 <version>${spring.version}</version> 78 </dependency> 79 80 <dependency> 81 <groupId>org.springframework</groupId> 82 <artifactId>spring-context-support</artifactId> 83 <version>${spring.version}</version> 84 </dependency> 85 86 <dependency> 87 <groupId>org.springframework</groupId> 88 <artifactId>spring-expression</artifactId> 89 <version>${spring.version}</version> 90 </dependency> 91 92 <dependency> 93 <groupId>org.springframework</groupId> 94 <artifactId>spring-jdbc</artifactId> 95 <version>${spring.version}</version> 96 </dependency> 97 98 <dependency> 99 <groupId>org.springframework</groupId> 100 <artifactId>spring-tx</artifactId> 101 <version>${spring.version}</version> 102 </dependency> 103 104 <dependency> 105 <groupId>org.springframework</groupId> 106 <artifactId>spring-aop</artifactId> 107 <version>${spring.version}</version> 108 </dependency> 109 110 111 <dependency> 112 <groupId>org.aspectj</groupId> 113 <artifactId>aspectjweaver</artifactId> 114 <version>1.7.3</version> 115 </dependency> 116 117 <dependency> 118 <groupId>aopalliance</groupId> 119 <artifactId>aopalliance</artifactId> 120 <version>1.0</version> 121 </dependency> 122 123 <!-- oracle --> 124 <dependency> 125 <groupId>com.oracle</groupId> 126 <artifactId>ojdbc6</artifactId> 127 <version>11.2.0.3</version> 128 </dependency> 129 130 <!-- mybatis --> 131 <dependency> 132 <groupId>org.mybatis</groupId> 133 <artifactId>mybatis-spring</artifactId> 134 <version>1.2.2</version> 135 </dependency> 136 137 <dependency> 138 <groupId>org.mybatis</groupId> 139 <artifactId>mybatis</artifactId> 140 <version>3.2.7</version> 141 </dependency> 142 143 <dependency> 144 <groupId>com.github.miemiedev</groupId> 145 <artifactId>mybatis-paginator</artifactId> 146 <version>1.2.15</version> 147 </dependency> 148 149 <!-- struts --> 150 <dependency> 151 <groupId>org.freemarker</groupId> 152 <artifactId>freemarker</artifactId> 153 <version>2.3.19</version> 154 </dependency> 155 156 <dependency> 157 <groupId>org.apache.struts</groupId> 158 <artifactId>struts2-core</artifactId> 159 <version>2.3.16.3</version> 160 </dependency> 161 162 <dependency> 163 <groupId>org.apache.struts.xwork</groupId> 164 <artifactId>xwork-core</artifactId> 165 <version>2.3.16.3</version> 166 </dependency> 167 168 <dependency> 169 <groupId>ognl</groupId> 170 <artifactId>ognl</artifactId> 171 <version>3.0.6</version> 172 </dependency> 173 174 <dependency> 175 <groupId>commons-beanutils</groupId> 176 <artifactId>commons-beanutils</artifactId> 177 <version>1.8.3</version> 178 </dependency> 179 180 <dependency> 181 <groupId>commons-collections</groupId> 182 <artifactId>commons-collections</artifactId> 183 <version>3.2.1</version> 184 </dependency> 185 186 <dependency> 187 <groupId>commons-fileupload</groupId> 188 <artifactId>commons-fileupload</artifactId> 189 <version>1.3</version> 190 </dependency> 191 192 <dependency> 193 <groupId>commons-io</groupId> 194 <artifactId>commons-io</artifactId> 195 <version>2.2</version> 196 </dependency> 197 198 <dependency> 199 <groupId>org.apache.commons</groupId> 200 <artifactId>commons-lang3</artifactId> 201 <version>3.1</version> 202 </dependency> 203 204 <dependency> 205 <groupId>javassist</groupId> 206 <artifactId>javassist</artifactId> 207 <version>3.12.1.GA</version> 208 </dependency> 209 210 <!-- Servlet --> 211 <dependency> 212 <groupId>javax.servlet</groupId> 213 <artifactId>servlet-api</artifactId> 214 <version>2.5</version> 215 <scope>provided</scope> 216 </dependency> 217 218 </dependencies> 219 220 <profiles> 221 <profile> 222 <!-- 开发环境 --> 223 <id>dev</id> 224 <properties> 225 <db-url>jdbc:oracle:thin:@172.21.129.51:1521:orcl</db-url> 226 <db-username>ckg_rpt</db-username> 227 <db-password>ckg_rpt</db-password> 228 </properties> 229 <!-- 默认激活本环境 --> 230 <activation> 231 <activeByDefault>true</activeByDefault> 232 </activation> 233 </profile> 234 <profile> 235 <!-- 测试环境 --> 236 <id>test</id> 237 <properties> 238 <db-url>jdbc:oracle:thin:@172.21.129.51:1521:orcl</db-url> 239 <db-username>ckg_rpt</db-username> 240 <db-password>ckg_rpt</db-password> 241 </properties> 242 </profile> 243 </profiles> 244 245 <build> 246 <resources> 247 <resource> 248 <directory>src/main/resources</directory> 249 <filtering>true</filtering> 250 </resource> 251 </resources> 252 <plugins> 253 <plugin> 254 <groupId>org.apache.maven.plugins</groupId> 255 <artifactId>maven-compiler-plugin</artifactId> 256 <version>2.5.1</version> 257 <configuration> 258 <source>1.6</source> 259 <target>1.6</target> 260 <encoding>utf-8</encoding> 261 </configuration> 262 </plugin> 263 </plugins> 264 </build> 265 <organization> 266 <name>infosky</name> 267 <url>www.infosky.com.cn</url> 268 </organization> 269 270 </project>
主要是maven的关键依赖项,不要漏掉就行
二、web.xml
1 <?xml version="1.0" encoding="UTF-8"?> 2 <web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"> 5 6 <display-name>struts2-helloworld</display-name> 7 8 <context-param> 9 <param-name>logbackConfigLocation</param-name> 10 <param-value>classpath:logback.xml</param-value> 11 </context-param> 12 <listener> 13 <listener-class>com.cnblogs.yjmyzz.util.LogbackConfigListener</listener-class> 14 </listener> 15 16 <context-param> 17 <param-name>contextConfigLocation</param-name> 18 <param-value>classpath:spring.xml</param-value> 19 </context-param> 20 <listener> 21 <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> 22 </listener> 23 24 <filter> 25 <filter-name>struts2</filter-name> 26 <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class> 27 <!-- <init-param> 28 <param-name>loggerFactory</param-name> 29 <param-value>com.opensymphony.xwork2.util.logging.slf4j.Slf4jLoggerFactory</param-value> 30 </init-param> --> 31 </filter> 32 33 <filter-mapping> 34 <filter-name>struts2</filter-name> 35 <url-pattern>/*</url-pattern> 36 </filter-mapping> 37 38 <welcome-file-list> 39 <welcome-file>index.html</welcome-file> 40 </welcome-file-list> 41 42 </web-app>
注意上面被注释的一段:虽然xwork提供了com.opensymphony.xwork2.util.logging.slf4j.Slf4jLoggerFactory这个类用于整合SLF4J兼容的各种log实现(比如:logback),但我在实际中发现,logback.xml配置文件始终不起作用,运行时一直加载的是logback的默认配置,所以建议改用自已开发的LogbackConfigListener(代码已经在上一篇2.2中给出)
解释:web.xml中主要干了3件事:监听logback配置文件、监听Spring配置文件、注册Struts2的入口Filter
三、weblogic.xml与jboss-deployment-structure.xml
在weblogic下以war包部署时,由于war是一个压缩包,不会自动展开,所以一些依赖于物理文件路径的代码,可能会有问题,比如报一些:
java.lang.IllegalStateException: Cannot set web app root system property when WAR file is not expanded
之类的错误,解决办法:在WEB-INF下放置一个名为weblogic.xml的文件
1 <?xml version="1.0" encoding="UTF-8"?> 2 <weblogic-web-app xmlns="http://www.bea.com/ns/weblogic/90"> 3 <session-descriptor> 4 <cookie-path>/</cookie-path> 5 </session-descriptor> 6 <container-descriptor> 7 <prefer-web-inf-classes>true</prefer-web-inf-classes> 8 <show-archived-real-path-enabled>true</show-archived-real-path-enabled> 9 </container-descriptor> 10 <context-root>struts2-helloworld</context-root> 11 <!-- <library-ref> <library-name>acmlibrary</library-name> </library-ref> --> 12 </weblogic-web-app>
注意:第8行<show-archived-real-path-enabled>true</show-archived-real-path-enabled>,这里告诉weblogic显示war包的真实路径,以便相关代码在取文件路径时能拿到物理路径。
同样,如果部署在jboss下时,由于jboss默认提供的SLF4J的实现与logback有冲突,需要在WEB-INF下放置jboss-deployment-structure.xml,排除jboss自带的jar包
1 <?xml version="1.0" encoding="UTF-8"?> 2 <jboss-deployment-structure> 3 <deployment> 4 <exclusions> 5 <module name="org.slf4j" /> 6 <module name="org.slf4j.impl" /> 7 <module name="org.slf4j.jcl-over-slf4j" /> 8 <module name="org.slf4j.ext" /> 9 </exclusions> 10 </deployment> 11 </jboss-deployment-structure>
三、struts2中的Action处理及相关配置
先来一个Action的基类
1 package com.cnblogs.yjmyzz.action; 2 3 import org.slf4j.Logger; 4 import org.slf4j.LoggerFactory; 5 6 import com.opensymphony.xwork2.ActionSupport; 7 8 public class BaseAction extends ActionSupport { 9 10 private static final long serialVersionUID = -4320398837758540242L; 11 protected Logger logger = LoggerFactory.getLogger(this.getClass()); 12 13 }
虽然ActionSupport中有一个LOG的实例变量,但经实践,发现用LOG对象记录的日志,不受logback.xml配置文件控制,所以这里定义一个logger,以便其子类都可以正常使用logback。
其它Action都继承它
1 package com.cnblogs.yjmyzz.action; 2 3 import org.springframework.stereotype.Component; 4 5 @Component("HelloWorldAction") 6 public class HelloWorldAction extends BaseAction { 7 8 private static final long serialVersionUID = -8827776224243873974L; 9 10 private String message; 11 12 public String execute() throws Exception { 13 14 //log sample 15 for (int i = 0; i < 1000; i++) { 16 logger.trace("logback->trace" + i); 17 logger.debug("logback->debug" + i); 18 logger.info("logback->info" + i); 19 logger.warn("logback->warn" + i); 20 logger.error("logback->error" + i); 21 } 22 23 return SUCCESS; 24 } 25 26 public String sayHi() throws Exception { 27 message = "welcome to SSH!"; 28 return SUCCESS; 29 } 30 31 public String getMessage() { 32 return message; 33 } 34 35 public void setMessage(String message) { 36 this.message = message; 37 } 38 39 }
注:类上面加上@Component注解,配合这个注释,Spring.xml主配置文件里,配置自动扫描,就不用手动一个一个bean的写配置了
1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns="http://www.springframework.org/schema/beans" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" 4 xmlns:tx="http://www.springframework.org/schema/tx" xmlns:jdbc="http://www.springframework.org/schema/jdbc" 5 xmlns:context="http://www.springframework.org/schema/context" 6 xsi:schemaLocation=" 7 http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd 8 http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd 9 http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.0.xsd 10 http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd 11 http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd" 12 default-autowire="byName"> 13 14 <context:component-scan base-package="com.cnblogs.yjmyzz"> 15 </context:component-scan> 16 17 <import resource="spring-datasource.xml" /> 18 </beans>
运行时Spring会自动注入所有Action的实例,这样在配置struts.xml时,就可以用@Component后面name值来代替完整Action类名,简化配置
1 <?xml version="1.0" encoding="UTF-8" ?> 2 <!DOCTYPE struts PUBLIC 3 "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" 4 "http://struts.apache.org/dtds/struts-2.0.dtd"> 5 <struts> 6 7 <package name="home" namespace="/home" extends="default"> 8 9 <action name="HelloWorld_*" method="{1}" class="HelloWorldAction"> 10 <result>/WEB-INF/views/home/HelloWorld.jsp</result> 11 </action> 12 13 </package> 14 </struts>
注:第9行<action name="HelloWorld_*" method="{1}" class="HelloWorldAction">的class,如果没有Spring,应该写完整路径com.cnblogs.yjmyzz.action.HelloWorldAction,但现在只需要写HelloWorldAction就行了.
四、MyBatis配置
这跟上一篇完全相同,就不再重复了
五、logback.xml配置
1 <?xml version="1.0" encoding="UTF-8" ?> 2 <configuration scan="true" scanPeriod="1800 seconds" 3 debug="false"> 4 5 <property name="USER_HOME" value="logs" /> 6 <property scope="context" name="FILE_NAME" value="test-logback" /> 7 8 <timestamp key="byDay" datePattern="yyyy-MM-dd" /> 9 10 <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> 11 <encoder> 12 <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n 13 </pattern> 14 </encoder> 15 </appender> 16 17 <appender name="file" 18 class="ch.qos.logback.core.rolling.RollingFileAppender"> 19 <file>${USER_HOME}/${FILE_NAME}.log</file> 20 21 <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy"> 22 <fileNamePattern>${USER_HOME}/${byDay}/${FILE_NAME}-${byDay}-%i.log.zip 23 </fileNamePattern> 24 <minIndex>1</minIndex> 25 <maxIndex>10</maxIndex> 26 </rollingPolicy> 27 28 <triggeringPolicy 29 class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy"> 30 <maxFileSize>5MB</maxFileSize> 31 </triggeringPolicy> 32 <encoder> 33 <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %-4relative [%thread] %-5level %logger{150} - %msg%n 34 </pattern> 35 </encoder> 36 </appender> 37 38 <logger name="com.cnblogs.yjmyzz" level="debug" additivity="true"> 39 <appender-ref ref="file" /> 40 </logger> 41 42 <root level="debug"> 43 <appender-ref ref="STDOUT" /> 44 </root> 45 </configuration>