# 1、工作原理
客户端通过HttpServletRequest向Servlet容器提交一个请求,这个请求会经过一系列的过滤器,最终被struts核心过滤器StrutsPrepareAndExecuteFilter过滤。核心过滤器过滤以后,调用访问ActionMapping,决定是否调用某一Action,如果用户请求的是jsp页面或者是其他静态资源,不会调用某Action,否则ActionMapping会将控制权委派给ActionProxy,也叫Action代理,此时Action代理会通过一个ConfigurationManager也就是配置管理器对象加载struts核心配置文件,也就是struts.xml。如果在struts.xml找到需要创建的Action,ActionProxy会创建一个Action Invocation实例,Action Invocation包括一系列的拦截器和Action,先顺序执行一些列的拦截器,然后执行Action处理,返回一个结果,通过Result返回一个视图或者调用另外某个Action。当返回这个视图以后,将之前执行过的拦截器反向执行一遍,然后通过response响应客户端的请求。
## 2、拦截器
## 3、Action处理多个请求
## 3.1、常规方式配置让一个Action处理多个请求
```xml
<!-- General Method -->
<action name="savePersonAction" class="com.mipo.controller.PersonAction" method="savePerson">
<result name="save" type="dispatcher">/person/save.jsp</result>
</action>
<action name="modifyPersonAction" class="com.mipo.controller.PersonAction" method="modifyPerson">
<result name="modify" type="dispatcher">/person/modify.jsp</result>
</action>
<action name="removePersonAction" class="com.mipo.controller.PersonAction" method="removePerson">
<result name="remove" type="dispatcher">/person/remove.jsp</result>
</action>
<action name="triggerExceptionAction" class="com.mipo.controller.PersonAction" method="triggerException" />
```
### 3.2、通配符方式配置让一个Action处理多个请求
```xml
<!-- Wildcards Method -->
<action name="*PersonAction" class="com.mipo.controller.PersonAction" method="{1}Person">
<result name="{1}" type="dispatcher">/person/{1}.jsp</result>
</action>
```
### 3.3、动态方法调用方式配置让一个Action处理多个请求
```xml
……
<!-- 启用动态方法调用 -->
<constant name="struts.enable.DynamicMethodInvocation" value="true"/>
……
<package strict-method-invocation="true">
……
```
```xml
<!-- Dynamic Method Invocation -->
<action name="personController" class="com.mipo.controller.PersonAction" method="execute">
<result name="success" type="dispatcher">/person/success.jsp</result>
<result name="save" type="dispatcher">/person/save.jsp</result>
<result name="modify" type="dispatcher">/person/modify.jsp</result>
<result name="remove" type="dispatcher">/person/remove.jsp</result>
<allowed-methods>savePerson, modifyPerson, removePerson, triggerException</allowed-methods>
</action>
```
## 4、Result 的几种方式
### 4.1、dispatcher(默认值)
>转发到某具体JSP页面,此处只能是JSP路径,不能是action地址。
```xml
<result>/main.jsp</result>
```
### 4.2、redirect
>重定向到某具体JSP页面,此处可以是JSP页面,也可以是action地址。
```xml
<result type="redirect">/main.jsp</result>
```
### 4.3、chain
>转发到某action
```xml
<result type="chain">
<param name="actionName">savePersonAction</param>
</result>
```
### 4.4、redirectAction
>重定向到某action
```xml
<result type="redirectAction">
<param name="actionName">savePersonAction</param>
</result>
```
## 5、命名空间
>package节点中有namespace属性,此属性可定义模块的访问路径。如namespace="/order" 则在访问路径中要加上命名空间 /order
## 6、Ajax
### 6.1、在pom.xml里引入如下依赖
```xml
<dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-json-plugin</artifactId>
<version>${struts2.version}</version>
<exclusions>
<exclusion>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-core</artifactId>
</exclusion>
</exclusions>
</dependency>
```
### 6.2、编写Java源文件
```java
package com.mipo.controller;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.PrintWriter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts2.ServletActionContext;
import com.mipo.vo.Person;
/**
* Struts2 之 AJAX 示例
*/
public class AjaxAction {
private InputStream is;
private String name;
private Person person;
public String execute() throws Exception {
this.is = new ByteArrayInputStream(("Hello " + this.name).getBytes("UTF-8"));
return "success";
}
/**
* 使用一般方式响应请求
*
* @param request
* @param response
* @return
* @throws Exception
*/
public void greet() throws Exception {
HttpServletRequest request = ServletActionContext.getRequest();
HttpServletResponse response = ServletActionContext.getResponse();
response.setContentType("text/html; charset=UTF-8");
PrintWriter out = response.getWriter();
out.println("Hello " + request.getParameter("name"));
out.flush();
out.close();
}
/**
* 通过struts2-json-plugin 处理 json 数据
*
* @return
* @throws Exception
*/
public String getJSON() throws Exception {
this.person = new Person("Nick", "555");
return "success";
}
public InputStream getIs() {
return is;
}
public void setIs(InputStream is) {
this.is = is;
}
public Person getPerson() {
return person;
}
public void setPerson(Person person) {
this.person = person;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
```
### 6.3、配置ajax.xml
```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>
<package name="ajax" extends="json-default">
<!-- AJAX -->
<action name="ajax">
<result>/ajax.jsp</result>
</action>
<action name="ajaxController" class="com.mipo.controller.AjaxAction" method="execute">
<result name="success" type="stream">
<param name="contentType">text/html</param>
<param name="inputName">is</param>
</result>
</action>
<action name="jsonAjaxController" class="com.mipo.controller.AjaxAction" method="getJSON">
<result name="success" type="json">
<param name="encoding">UTF-8</param>
<param name="excludeNullProperties">true</param>
<param name="root">person</param>
</result>
</action>
<action name="originAjaxController" class="com.mipo.controller.AjaxAction" method="greet" />
</package>
</struts>
```
## 7、异常处理
```xml
<global-results>
<result name="securityerror" type="redirect">/error/securityerror.jsp</result>
<result name="error" type="redirect">/error/error.jsp</result>
</global-results>
<global-exception-mappings>
<exception-mapping exception="org.apache.struts.register.exceptions.SecurityBreachException" result="securityerror" />
<exception-mapping exception="java.lang.Exception" result="error" />
</global-exception-mappings>
```