struts2知识整理

一、struts2的基础知识

1.   struts2的使用优势

     自动封装参数

     参数校验

     结果的处理(转发和重定向)

     国际化

     显示等待页面

     表单的防止重复提交

2.   搭建struts2框架

2.1    导包

       

2.2    书写action类

public class HelloAction {
    public String hello() {
        System.out.println("Hello world!");
        return "success";
    }
}

2.3    书写src/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>
        <package name="hello" namespace="/hello" extends="struts-default">
            <action name="HelloAction" class="com.java.hello.HelloAction" method="hello">
                <result name="success">/hello.jsp</result>
         </action>
    </package>
</struts>

2.4    将struts2核心过滤器配置到web.xml中

<!-- 配置struts2核心过滤器 -->
  <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>

3.   Struts2的访问流程

        

4.   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>
    <!-- 修改常量配置的方式 -->
    <!-- i18n:国际化,解决post提交乱码 -->
    <constant name="struts.i18n.encoding" value="UTF-8"></constant>
    <!-- 指定访问action时的后缀名
        http://localhost:8080/struts2_day01/hello/HelloAction.action
     -->
    <constant name="struts.action.extension" value="action"></constant>
    <!-- 指定struts是否以开发模式运行  开发阶段使用  非开发阶段需要设为false
        1. 热加载主配置。(不需要重启即可生效)
        2. 提供更多的错误提示信息,方便开发时调试
     -->
    <constant name="struts.devMode" value="true"></constant>
    <!-- package:将action配置封装在一起,一个package中配置很多的action
            name属性:给包起个名字,起到标识作用,不能与其他包重名
            namespace属性:给action的访问路径中定义一个命名空间
            extends属性:继承一个 制定包  必须
            abstracts属性:包是否为抽象的;标识属性,标识该包不能独立运行,专门被继承
     -->
    <package name="hello" namespace="/hello" extends="struts-default">
        <!-- action元素:配置action类
            name属性:决定了Action访问资源名
            class:Action类的完整类名
            method属性:决定调用action的哪个方法来处理请求
         -->
        <action name="HelloAction" class="com.java.hello.HelloAction" method="hello">
            <!-- result元素:结果配置
                name属性:表示结果处理的名称,与Action类的返回值对应
                type属性:指定调用哪一个result类来处理结果,默认使用转发
                标签体:填写页面的相对路径
             -->
            <result name="success">/hello.jsp</result>
        </action>
    </package>
    <!-- 引入其他的struts文件 -->
    <include file="com/java/dynamic/struts.xml"></include>
    <include file="com/java/struts_default/struts.xml"></include>
</struts>

5.   动态方法的调用(两种方式)

5.1    第一种方式

     在struts.xml中配置动态方法调用是否开启,默认是个关闭的,需要开启。

    <!-- 配置动态方法调用是否开启
        默认是关闭的,需要开启
     -->
    <constant name="struts.enable.DynamicMethodInvocation" value="true"></constant>

    浏览器中访问的url为

    http://localhost:8080/struts2_day01/dynamic/Demo1Action!find.action

5.2    第二种方式

   在struts.xml中配置如下:

<package name="dynamic" namespace="/dynamic" extends="struts-default">
        <!-- 配置动态方法调用(常用方式) -->
        <action name="Demo1Action_*" class="com.java.dynamic.Demo1Action" method="{1}">
            <result name="success">/hello.jsp</result>
        </action>
</package>

通配符方式,使用{1}取出第一个星号通配的方法名

浏览器中访问的url为

http://localhost:8080/struts2_day01/dynamic/Demo1Action_delete.action

二、  struts的进阶

  1.   结果跳转的方式

  1.1    转发(默认)       

<!-- 转发(默认) -->
        <action name="Demo1Action" class="com.java.result.Demo1Action" method="execute">
            <result name="success" type="dispatcher">/hello.jsp</result>
        </action>

   1.2    重定向

 <!-- 重定向 -->
<action name="Demo2Action" class="com.java.result.Demo2Action" method="execute">
    <result name="success" type="redirect">/hello.jsp</result>
</action>

   1.3    转发到action

<!-- 转发到Action -->
    <action name="Demo3Action" class="com.java.result.Demo3Action" method="execute">
        <result name="success" type="chain">
            <!-- action的名称 -->
            <param name="actionName">Demo1Action</param>
            <!-- action所在的命名空间 -->
            <param name="namespace">/</param>
        </result>
    </action>

    1.4    重定向到action

<!-- 重定向到Action -->
    <action name="Demo4Action" class="com.java.result.Demo4Action" method="execute">
        <result name="success" type="redirectAction">
            <!-- action的名称 -->
            <param name="actionName">Demo1Action</param>
            <!-- action所在的命名空间 -->
            <param name="namespace">/</param>
        </result>
    </action>

   2.   访问servlet API的方式

     2.1 通过ActionContext

 1 /**
 2  * 通过ActionContext访问Servlet的API
 3  * @author vanguard
 4  *
 5  */
 6 public class Demo5Action extends ActionSupport {
 7     @Override
 8 public String execute() throws Exception {
 9         //request域 不推荐这种方式
10         Map<String, Object> request = (Map<String, Object>) ActionContext.getContext().get("request");
11         //推荐使用Action域充当request域
12         ActionContext.getContext().put("name", "requestTom");
13         //session域  ->Map
14         Map<String, Object> session = ActionContext.getContext().getSession();
15         session.put("name", "sessionJack");
16         //application域 ->Map
17         Map<String, Object> application ActionContext.getContext().getApplication();
18         application.put("name", "applicationTom");
19         //获得表单中的参数Map集合
20         Map<String, Object> parameters ActionContext.getContext().getParameters();
21         return SUCCESS;
22     }
23 }

     2.2 通过ServletActionContext访问Servlet的API    

/**
 * 通过ServletActionContext访问Servlet的API
 * @author vanguard
 *
 */
public class Demo6Action extends ActionSupport {
    @Override
    public String execute() throws Exception {
        //原生request
        HttpServletRequest request = ServletActionContext.getRequest();
        //通过request获得session
        HttpSession session = request.getSession();
        //原生response
        HttpServletResponse response = ServletActionContext.getResponse();
        //原生ServletContext对象
        ServletContext servletContext = ServletActionContext.getServletContext();
        return SUCCESS;
    }
}

     2.3 通过实现接口的方式

/**
 * 通过实现接口的方式访问Servlet的api
 * @author vanguard
 *
 */
public class Demo7Action extends ActionSupport implements ServletRequestAware {
    
    private HttpServletRequest request;
    @Override
    public String execute() throws Exception {
        System.out.println("原生request" + request);
        return SUCCESS;
    }

    @Override
    public void setServletRequest(HttpServletRequest request) {
        this.request = request;
    }
}

   3.   如何获得页面传递的参数

     3.1    属性驱动获得参数     

<form action="${pageContext.request.contextPath }/Demo8Action" method="post">
        name:<input type="text" name="name"><br>
        age:<input type="text" name="age"><br>
        birthday:<input type="text" name="birthday"><br>
        <input type="submit" value="提交" >
    </form>

      Demo8Action.java

/**
 * 属性驱动获得参数
 * @author vanguard
 *
 */
public class Demo8Action extends ActionSupport {
    //参数名称相同的属性
    private String name;
    //自动类型转换  只能转换八大基本类型以及对应的包装类
    private Integer age;
    //支持特定类型的字符串转化成Date类型    yyyy-MM-dd
    private Date birthday;
    
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }
    public Date getBirthday() {
        return birthday;
    }
    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }
    @Override
    public String execute() throws Exception {
        System.out.println("name:" + name + ",age:" + age + ",birthday:" + birthday);
        return super.execute();
    }
}

     3.2 对象驱动获得参数  

<form action="${pageContext.request.contextPath }/Demo9Action" method="post">
        name:<input type="text" name="user.name"><br>
        age:<input type="text" name="user.age"><br>
        birthday:<input type="text" name="user.birthday"><br>
        <input type="submit" value="提交" >
 </form>

     Demo9Action.java

/**
 * 使用对象驱动获得参数
 * @author vanguard
 *
 */
public class Demo9Action extends ActionSupport {
    private User user;
    
    public User getUser() {
        return user;
    }

    public void setUser(User user) {
        this.user = user;
    }

    @Override
    public String execute() throws Exception {
        System.out.println(user);
        return SUCCESS;
    }
}

    3.3 模型驱动获得参数
      

<form action="${pageContext.request.contextPath }/Demo10Action" method="post">
        name:<input type="text" name="name"><br>
        age:<input type="text" name="age"><br>
        birthday:<input type="text" name="birthday"><br>
        <input type="submit" value="提交" >
</form>

    Demo10Action.java

/**
 * 使用模型驱动获得参数
 * @author vanguard
 *
 */
public class Demo10Action extends ActionSupport implements ModelDriven<User> {
    private User user = new User();

    @Override
    public String execute() throws Exception {
        System.out.println(user);
        return SUCCESS;
    }

    @Override
    public User getModel() {
        
        return user;
    }
}    

     3.4 集合类型的封装

<form action="${pageContext.request.contextPath }/Demo11Action" method="post">
        list<input type="text" name="list"><br>
        list<input type="text" name="list[3]"><br>
        map<input type="text" name="map['key']"><br>
        map<input type="text" name="map['key']"><br>
        <input type="submit" value="提交" >
</form>

    Demo11Action.java

    

/**
 * 集合类型封装参数
 * @author vanguard
 *
 */
public class Demo11Action extends ActionSupport {
    private List<String> list;
    private Map<String, String> map;
    public List<String> getList() {
        return list;
    }
    public void setList(List<String> list) {
        this.list = list;
    }
    public Map<String, String> getMap() {
        return map;
    }
    public void setMap(Map<String, String> map) {
        this.map = map;
    }
    @Override
    public String execute() throws Exception {
        System.out.println(map);
        System.out.println(list);
        return SUCCESS;
    }
}

   2. 自定义拦截器

     2.1 自定义拦截器的创建

/**
 * 自定义Interceptor (推荐)
 * 功能:定制拦截器拦截的方法
 * 哪些方法不需要拦截 excloud
 * 哪些方法需要拦截 incloud
 * 
 * 当doInterceptor()不放行返回字符串时,不执行后续的拦截器以及Action,
 * 直接交给Result处理结果。进行页面跳转
 * @author vanguard
 *
 */
public class MyInterceptor3 extends MethodFilterInterceptor {

    @Override
    protected String doIntercept(ActionInvocation invocation) throws Exception {
        //前处理
        System.out.println("MyInterceptor的前处理");
        //放行
        String result = invocation.invoke();
        //后处理
        System.out.println("MyInterceptor的后处理");
        
        return result;
    }
}

    2.3 拦截器的配置

 1 <?xml version="1.0" encoding="UTF-8" ?>
 2 <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.1//EN" "http://struts.apache.org/dtds/struts-2.1.dtd">
 3 <struts>
 4     <constant name="struts.devMode" value="true"></constant>
 5     
 6     <package name="interceptor1" namespace="/" extends="struts-default">
 7         <!-- 1. 注册拦截器 -->
 8         <interceptors>
 9             <interceptor name="myInterceptor" class="com.java.interceptor.MyInterceptor3"></interceptor>
10             <!-- 2. 注册拦截器栈 -->
11             <interceptor-stack name="myStack">
12                 <!-- 引入自定义的拦截器(建议放在20个拦截器栈之前) -->
13                 <interceptor-ref name="myInterceptor">
14                     <!-- 指定哪些方法不拦截 -->
15                     <!-- <param name="excludeMethods">add,select</param> -->
16                     <!-- 指定哪些方法拦截 -->
17                     <param name="includeMethods">add,update</param>
18                 </interceptor-ref>
19                 <!-- 引入20个默认的拦截器栈 -->
20                 <interceptor-ref name="defaultStack"></interceptor-ref>
21             </interceptor-stack>
22         </interceptors>
23         <!-- 3. 指定包中的默认拦截器栈 -->
24         <default-interceptor-ref name="myStack"></default-interceptor-ref>
25         <action name="Demo1Action_*" class="com.java.interceptor.Demo1Action" method="{1}">
26             <!-- 为Action单独指定拦截器(栈) -->
27             <!-- <interceptor-ref name="myStack"></interceptor-ref> -->
28             <result name="success">/index.jsp</result>
29         </action>
30     </package>
31 </struts>    
原文地址:https://www.cnblogs.com/guodong-wang/p/8124090.html