Apache struts是开源java web MVC框架. 推荐约定优于配置.
本文使用Maven进行项目管理. 可以到struts2 maven archetypes查看不同的archetype然后直接获取配置好struts2不同功能的模板项目. 可以分别把这些archetype下载到本地查看各种配置. 本文手动创建一个webapp并配置struts2.
mkdir struts2-blank
创建项目文件夹strtus2-blank
, 后续的所有路径都是基于此pom.xml
添加基本配置和插件<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.qiudeqing</groupId>
<artifactId>struts2-blank</artifactId>
<packaging>war</packaging>
<version>1.0-SNAPSHOT</version>
<name>struts2-blank Maven Webapp</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<build>
<finalName>struts2-blank</finalName>
<plugins>
<!-- Eclipse project -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-eclipse-plugin</artifactId>
<version>2.9</version>
<configuration>
<!-- Always download and attach dependencies source code -->
<downloadSources>true</downloadSources>
<downloadJavadocs>false</downloadJavadocs>
<!-- Avoid type mvn eclipse:eclipse -Dwtpversion=2.0 -->
<wtpversion>2.0</wtpversion>
</configuration>
</plugin>
<!-- Set JDK Compiler Level -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.2</version>
<configuration>
<source>${jdk.version}</source>
<target>${jdk.version}</target>
</configuration>
</plugin>
<!-- For Maven Tomcat Plugin -->
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.2</version>
<configuration>
<path>/</path>
<uriEncoding>UTF-8</uriEncoding>
</configuration>
</plugin>
</plugins>
</build>
</project>
src/main/webapp/WEB-INF/web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app 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_3_0.xsd"
version="3.0">
<display-name>struts-blank</display-name>
<welcome-file-list>
<welcome-file>/public/index.jsp</welcome-file>
</welcome-file-list>
</web-app>
src/main/webapp/public/index.jsp
<%@ page contentType="text/html; charset=UTF-8" %>
<% request.setCharacterEncoding("UTF-8");%>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="initial-scale=1.0, width=device-width, user-scalable=no">
<title>struts blank</title>
</head>
<body>
<h2>struts blank</h2>
</body>
</html>
mvn tomcat7:run
, 浏览器访问http://localhost:8080/
页面显示struts blank. 基础java web项目结构创建成功pom.xml
添加struts2和log4j2依赖<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<struts2.version>2.3.24.1</struts2.version>
<log4j2.version>2.3</log4j2.version>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-core</artifactId>
<version>${struts2.version}</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>${log4j2.version}</version>
</dependency>
</dependencies>
src/main/webapp/WEB-INF/web.xml
内添加struts2 filter<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
src/main/java/com/qiudeqing/action/HelloAction.java
package com.qiudeqing.action;
import com.opensymphony.xwork2.Action;
import com.opensymphony.xwork2.ActionSupport;
public class HelloAction extends ActionSupport {
public String execute() throws Exception {
return Action.SUCCESS;
}
}
src/main/resources/log4j2.xml
<?xml version="1.0" encoding="UTF-8"?>
<Configuration>
<Appenders>
<Console name="STDOUT" target="SYSTEM_OUT">
<PatternLayout pattern="%d %-5p [%t] %C{2} (%F:%L) - %m%n"/>
</Console>
</Appenders>
<Loggers>
<Logger name="com.opensymphony.xwork2" level="info"/>
<Logger name="org.apache.struts2" level="info"/>
<Root level="warn">
<AppenderRef ref="STDOUT"/>
</Root>
</Loggers>
</Configuration>
src/main/resources/struts.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
"http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
<constant name="struts.enable.DynamicMethodInvocation" value="false" />
<constant name="struts.devMode" value="true" />
<package name="default" namespace="/" extends="struts-default">
<action name="hello" class="com.qiudeqing.action.HelloAction" method="execute">
<result>/public/hello.jsp</result>
</action>
</package>
</struts>
src/main/webapp/public/hello.jsp
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="initial-scale=1.0, width=device-width, user-scalable=no">
<title>Document</title>
</head>
<body>
<h2>hello action with struts2</h2>
</body>
</html>
mvn tomcat7:run
浏览器访问http://localhost:8080/hello
显示hello action with struts2. web app集成struts2成功.velocity是一个java模板引擎, struts2默认支持velocity渲染结果.
velocity
依赖包<!-- begin: velocity所依赖的包 -->
<!--
velocity-tools依赖的某个包没有正确设置这个包的scope
导致它输出到lib目录造成错误, 明确声明scope防止输出到lib
-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.3</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity</artifactId>
<version>1.7</version>
</dependency>
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity-tools</artifactId>
<version>2.0</version>
</dependency>
<dependency>
<groupId>commons-beanutils</groupId>
<artifactId>commons-beanutils</artifactId>
<version>1.7.0</version>
</dependency>
<dependency>
<groupId>commons-collections</groupId>
<artifactId>commons-collections</artifactId>
<version>3.2</version>
</dependency>
<dependency>
<groupId>commons-digester</groupId>
<artifactId>commons-digester</artifactId>
<version>1.8</version>
</dependency>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.2</version>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.1</version>
</dependency>
<dependency>
<groupId>oro</groupId>
<artifactId>oro</artifactId>
<version>2.0.8</version>
</dependency>
<!-- end: velocity所依赖的包 -->
src/main/java/com/qiudeqing/action/HelloAction.java
添加属性name
package com.qiudeqing.action;
import com.opensymphony.xwork2.Action;
import com.opensymphony.xwork2.ActionSupport;
public class HelloAction extends ActionSupport {
private String name;
public String execute() throws Exception {
name = "qiu <strong>deqing</strong>";
return Action.SUCCESS;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
web.xml
添加velocity Servlet<servlet>
<servlet-name>velocity</servlet-name>
<servlet-class>org.apache.velocity.tools.view.VelocityViewServlet</servlet-class>
<init-param>
<param-name>org.apache.velocity.properties</param-name>
<param-value>velocity.properties</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>velocity</servlet-name>
<url-pattern>*.vm</url-pattern>
</servlet-mapping>
src/main/resources/velocity.properties
以下内容设置模板输入输出编码为UTF-8, 避免中文乱码
output.encoding=UTF-8
input.encoding=UTF-8
default.contentType=text/html; charset=UTF-8
src/main/webapp/public/hello.vm
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="initial-scale=1.0, width=device-width, user-scalable=no">
<title>Document</title>
</head>
<body>
<h2>转义的name: $esc.html($name)</h2>
<h2>没有转义的name: $name</h2>
</body>
</html>
src/main/resources/struts.xml
中配置action<action name="hello" class="com.qiudeqing.action.HelloAction" method="execute">
<result>/public/hello.vm</result>
</action>
mvn tomcat7:run
, 浏览器访问http://localhost:8080/hello
显示转义的name: qiu <strong>deqing</strong>
没有转义的name: qiu deqing
可以直接使用velocity generic tools
全局异常处理可以处理未捕获的异常. 在struts.xml中为package进行全局异常处理配置, 当包下面的某个action没有处理Exception时会自动使用默认异常处理
src/main/java/com.qiudeqing.action.HelloAction.java
添加error方法,抛出异常package com.qiudeqing.action;
import com.opensymphony.xwork2.Action;
import com.opensymphony.xwork2.ActionSupport;
public class HelloAction extends ActionSupport {
private String name;
public String execute() throws Exception {
name = "qiu <strong>deqing</strong>中文";
return Action.SUCCESS;
}
public String error() throws Exception {
throw new Exception();
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
src/main/webapp/public/error/error.vm
作为异常显示页面error page
src/main/resources/struts.xml
中为package配置全局异常处理result以及error action<package name="default" namespace="/" extends="struts-default">
<global-results>
<result name="error">/public/error/error.vm</result>
</global-results>
<global-exception-mappings>
<exception-mapping exception="java.lang.Exception" result="error"></exception-mapping>
</global-exception-mappings>
<action name="error" class="com.qiudeqing.action.HelloAction" method="error">
</action>
</package>
http://localhost:8080/error
显示如下内容表示配置成功error page
调试插件可以列出各个action的详细配置信息, 方便查看是否遗漏
pom.xml
中添加插件依赖<dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-config-browser-plugin</artifactId>
<version>${struts2.version}</version>
</dependency>
http://localhost:8080/config-browser/actionNames.action
可以查看项目的配置信息如果struts配置devMode
为true, 会启动一个DebuggingInterceptor
通过url传递参数debug即可显示访问的action状态, 如
http://localhost:8080/hello?debug=browser
debug可选值有xml
, console
, command,
browser`
只需要在log4j2.xml
中配置级别为debug
即可查看struts2输出的详细调试信息
添加jsp, html指令指明文件编码为UTF-8:
<%@ page contentType="text/html; charset=UTF-8" %>
<% request.setCharacterEncoding("UTF-8");%>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="initial-scale=1.0, width=device-width, user-scalable=no">
<title>Document</title>
</head>
<body>
<form action="register">
<input type="text" name="personBean.firstName" value="qiu">
<input type="text" name="personBean.lastName" value="deqing">
<input type="text" name="personBean.email" value="qiu@qiudeqing.com">
<input type="text" name="personBean.age" value="27">
<button type="submit">提交</button>
</form>
</body>
</html>
method=post
<form action="register" method="post">
<input type="text" name="personBean.firstName" value="中文">
<button type="submit">提交</button>
</form>
URIEncoding="UTF-8"
不可能所有method都用get, 中文乱码的原因是get请求的参数是添加在url上的, struts2拦截器不会对url参数进行拦截并转换. tomcat默认url编码是iso-8859-1
所以就出错了.在tomcat目录下conf/server.xml
配置Connector
添加URIEncoding="UTF-8"
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443"
URIEncoding="UTF-8"/>
这样get请求的中文也不会乱码了.