一、Struts2是什么
Struts2是在WebWork2基础发展而来的。和Struts1一样, Struts2也是基于MVC的web层框架。
那么既然有了Struts1,为何还要Struts2?
Struts2和Struts1虽然都是基于MVC的Web框架,但是它们的实现机制完全不同。
Struts1是基于Servlet的实现,并且Struts1的API过分依赖容器,导致了Action开发、测试都非常繁琐,而Struts2是基于过滤器的实现,API不再依赖容器,测试过程中不必再模拟Web容器环境,开发、测试较Struts1都有很大的进步。
Struts1的Action是单例模式所有请求共享一个ActionServlet,所以线程必须是安全的,而Struts2每个请求都会绑定一个Action,不再有线程安全问题。
Struts2开始支持注解并提供了更为强大的OGNL标签库以及值栈,从类到页面的开发都更加简洁高效。
 
Struts2和Struts1都是基于MVC的Web层框架,所以,他们工作原理还是一样的,都是对请求进行拦截、分发、处理,之后返回页面,只不过他们的实现机制不同罢了。
因此,Struts2的工作原理就不再过多介绍,下面我们来看如何使用Sturts2搭建一个Web开发环境。
 
二、Struts2的使用
让我们先用Sturts2 展示一个Helloworld。
1、创建web项目struts2_helloworld,添加Struts2的依赖支持
struts2-core-2.3.8.jar
xwork-core-2.3.8.jar
commons-lang3-3.1.jar
ognl-3.0.6.jar
javassist-3.11.0.GA.jar
asm-3.3.jar
asm-commons-3.3.jar
asm-tree-3.3.jar
freemarker-2.3.19.jar
commons-fileupload-1.2.2.jar
commons-io-2.3.jar
2、在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配置文件struts.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.1//EN"
    "http://struts.apache.org/dtds/struts-2.1.dtd">
<struts>
    <package name="default" namespace="/" extends="struts-default">
        <action name="hello" class="com.boya.struts2.web.HelloAction">
            <result>
                /helloWorld.jsp
            </result>
        </action>
    </package>
</struts>
注意,与Struts1不同,Struts2的配置文件并不放在WEB-INF目录下,而需要放置在src源码根目录下
4、创建Action类
public class HelloAction {
    public String execute() {
        return "success";
    }
}
5、创建返回页面helloWorld.jsp
 
现在就完成了一个简单的Struts2应用。启动Web服务器,访问:
就可以看到我们创建的helloWorld.jsp页面了。
 
三、Sturts2的配置介绍
1、在web.xml配置Strut2过滤器拦截
Sturts1是通过servlet映射实现的对请求的拦截,Struts2是通过Filter完成的对请求拦截。前者会在ActionSerlvet中加载核心配置文件,后者会在StrutsPrepareAndExecuteFilter过滤器中加载。因此,与Struts1不同的是,我们要在web.xml里面配置Struts2的Filter来拦截请求。
配置方式见上文。
        
2、Strtus2核心配置文件
Struts2的默认配置文件是struts.xml,需要放置在源码根目录下。
struts.xml中的action标签和Struts1中的作用一样,都是定义了一种映射关系。package标签则表明以包的形式来管理action和拦截器,通常情况下,按将逻辑相关一组业务Action作为一个模块放在同一个package下管理。
 
package有以下属性;
name:包名称,其他包使用name继承当前包,不能重复
namespace:定义当前包的命名空间,匹配请求URL的路径部分,不同的命名空间下可以有重名的action
extends:当前包继承的父包,继承之后,当前包拥有父包中所定义的任意类、拦截器等
abstract:定义当前包为一个抽象的包,也就是说不能有action元素在当前包中
 
action属性:
name:action名称,用来匹配请求URL
class:对应的具体Action实现类,默认为ActionSupport
method:执行action时调用的方法,默认执行execute(),也可以在URL中动态指定,例如:
    <a href="${ctx}/system/user!add">添加用户</a>
 
result标签:定义action的返回跳转页面
name:定义页面跳转名称,默认为success。在action中返回一个对应name的字符串,就会返回到对应的jsp页面
type:设置返回结果类型,默认为dispatcher,用于返回jsp页面
 
3、URL映射机制
Struts1中,我们是使用path来映射URL请求的。在Struts2中是使用namespace + action的name来映射URL的。
例如:
    namespace="/system" ,
    action设置name为"/user"
    那么这个action对应的URL就是 http://主机地址/工程名/system/user
 
namespace寻址机制:
对于我们的一个URL请求,例如http://主机地址/工程名/path1/path2/path3/user
Struts2会自动将URL中的后缀,以及Host和工程名去掉,将/path1/path2/path3这部分认为是namespace,首先会查找namespace="/path1/path2/path3",如果这个命名空间查找不到,会继续查找namespace="/path1/path2",仍然没有的话,会继续查找上一级命名空间,直到查找到namespace="/"为止。
查找到命名空间,会在该命名空间的package下查找name="/user"的action。最后将这个请求交给action对应的业务处理类处理。
namespace默认为"",当在其他namespace中映射不到的时候,都在这个namespace中寻找。
 
Struts2是用namespace和actionName来唯一区别一个Action,因此,在同一个namespace下不能配置同名的action,在不同的namespace下,可以有重名action。
 
4、映射方式配置
在web.xml的过滤器映射中除了这样配置:
<filter-mapping>
    <filter-name>struts2</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>
也可以使用扩展名配置:
<filter-mapping>
    <filter-name>struts2</filter-name>
    <url-pattern>*.action</url-pattern>
</filter-mapping>
 
action是struts2默认支持的扩展名。/*在完成*.action的基础映射功能下,提供了额外的支持
    a、用于访问classpath中特定的静态资源(如果是/struts、或者/static开始的资源,则在classpath下查找特定的包下面的匹配资源;)
    b、支持无后缀的action请求
 
使用/*方式映射时:
    访问/struts或/static目录,不希望加载strtus的静态资源的配置方式
    <constant name="struts.serve.static" value="false" />
    希望强制使用扩展名映射的配置方式
    <constant name="struts.action.extension" value="action" />
    同样可以使用上面的配置修改struts2的默认扩展名
    <constant name="struts.action.extension" value="do" />
    不希望映射某个目录时(目录需要是一个正则表达式,因此需要使用.*的方式表示)
    <constant name="struts.action.excludePattern" value="/dwr/.*,/noaction/.*" />
 
5、Action的方法映射
    a、Action的方法映射可以通过method指定,未指定method方法时,默认执行execute()方法
    b、映射方法还可以在URL中动态指定(动态方法调用DMI)
        例如访问 http://localhost:8080/struts2_helloworld/hello!print 会调用hello对应的Action中的print()方法
        注:可以使用struts.enable.DynamicMethodInvocation参数配置DMI的开启关闭,默认为开启
        <constant name="struts.enable.DynamicMethodInvocation" value="false" />  
    c、使用通配符映射
        <action name="*_*" class="com.boya.struts2.web.{1}Action" method="{2}">
            <result>
                /{0}.jsp
               </result>

</action>

        使用{1}{2}{3}...{9}的顺序来匹配*,{0}匹配整体
        注:Struts2的通配符配置方式,极不灵活,不推荐使用
 
6、设置返回结果类型
    返回结果类型可以通过result标签的type属性配置,默认类型为dispatcher,用于返回jsp页面。常用的返回结果类型有redirect、chain、json等
 
    redirect类型配置(重定向到一个新的URL请求):
        <result name="success" type="redirect">/hello.jsp?name=${name}</result> <!--重定向到一个jsp页面-->
        <result name="success" type="redirect">/hello.action</result> <!--重定向到一个acton请求-->
    redirectAction类型配置(重定向到其他action):
            <result type="redirectAction">
                <param name="namespace">/</param>    <!--重定向Action所在的命名空间,默认为当前命名空间-->

<param name="actionName">user</param> <!--重定向的Action名称-->

<param name="method">login</param>    <!--重定向Action的方法名称-->

                <param name="name">boya</param>        <!--重定向传参-->
                <param name="password">123456</param> <!--重定向传参-->
            </result>
    chain类型配置,配置类似redirectAction(链到其他action,也就是转发操作):
        <result type="chain">
            <param name="namespace">/</param> <!--Action所在的命名空间,默认为当前命名空间-->

<param name="actionName">user</param> <!--Action名称-->

<param name="method">login</param> <!--Action的方法名称-->

        </result>
 
    json类型配置
    a、添加struts2-json-plugin-2.3.8.jar
    b、Action代码(省略getter、setter方法,省略User实体类):
public class JsonAction extends ActionSupport {
    private Map<String,Object> dataMap;
    
    public String json() {
        dataMap = new HashMap<String, Object>();
        User user = new User();
        user.setName("张三");
        user.setAge(50);
        dataMap.put("user", user);
        return SUCCESS;
    }
}
    c、配置struts.xml

<package name="json" extends="struts-default,json-default" >
    <action name="json" class="com.boya.struts2.web.JsonAction">
        <result type="json">
            <param name="root">dataMap</param>
        </result>
    </action>
</package>
    package需要继承"json-default"
    result类型需要配置为json    
    result参数:
        root:指定返回属性,默认返回所有有返回值的getter方法的值
        excludeNullProperties:是否返回值为空的属性,值为boolean类型
        ignoreHierarchy:是否忽略父类属性,值为boolean类型
        includeProperties:指定返回root中的哪些属性,值为正则表达式,可使用逗号分隔设置多个
        excludeProperties:指定排除root中的哪些属性,值为正则表达式,可使用逗号分隔设置多个     
 
    d、返回内容:
        {"user":{"age":22,"name":"张三"}}
   
excludeProperties和includeProperties的验证区别:

首先,假设dataMap中返回结果为:{"users":[{"age":22,"name":"张三","password":"123456"},{"age":40,"name":"李四","password":"654321"}]}

设置了排除或包含的属性后,以上结果需要验证的元素有users、users[0]、users[0].age、users[0].name、users[0].password、users[1]、users[1].age、users[1].name、users[1].password
如果要排除password属性,需要设置<param name="excludeProperties">users.*\.password</param> ,excludeProperties是将正则表达式作为整体分别匹配以上各元素,这样就会把password排除掉。
如果要只包含name属性,则不能设置为<param name="includeProperties">users.*\.name</param>,includeProperties会将正则表达式拆为users.*、users.*\.name(对分隔符,数组索引符合,对象属性间的点连接符等进行分割处理),这两个正则分别与上面各元素匹配,而users.*就会匹配全部元素,所以无法排除。
要精确包含name属性,需要设置为:<param name="includeProperties">users\[\d+\]\.name</param> ,而这时,正则表达式会被拆为users, users\[\d+\], users\[\d+\]\.name ,最终只输出name属性。
 
四、Action处理
1、接收参数
    a、使用属性来接收参数
        例如,在UserAction中定义如下属性,并添加getter、setter方法
        private String name;

private String password;

        jsp使用对应名称的控件
        用户名<input type="text" name="name"><br>
        密码<input type="password" name="password"><br>
这样就可以把提交的参数值传给UserAction的属性。
 
也可以通过URL将参数值传递给Action,如:
    
    b、使用DomainModel接收参数
        例如,在UserAction中添加实体Bean类型的属性,同样需要添加getter、setter方法
            private User user;
        jsp的控件名称使用“对象.属性”形式,如
        用户名<input type="text" name="user.name"><br>
        密码<input type="password" name="user.password"><br>
        这样,提交的参数会自动封装如user对象中。在Action方法中,使用user.getName()就可以获取提交的用户名
        
        使用URL传递参数就是这样的形式:
 
2、获取web容器的request和session
    Struts2不像Struts1那样依赖容器,默认情况下,request、session这些容器对象都是隐藏的,并且Struts2层分别使用RequestMap、SessionMap对request、session进行封装,是我们可以使用Map的key-value形式对request、session进行操作。我们可以获取RequestMap来作为request使用,也可以像传统web开发那样获取一个HttpServletRequest对象。
  
    a、非IoC方式
        这种方式主要是利用了com.opensymphony.xwork2.ActionContext类以及org.apache.struts2.ServletActionContext类,分别用于获取RequestMap和HttpServletRequest对象。
        获取RequestMap、SessionMap对象
        Map request = (Map)ActionContext.getContext().get("request");
        Map session = ActionContext.getContext().getSession();
        获取HttpServletRequest、HttpSession对象        
        HttpServletRequest request = ServletActionContext.getRequest();
        HttpSession session = request.getSession();
    b、IoC方式
        这种方式类似SpringIoc控制反转,是使用依赖注入的方式获得request和session对象的。
        获取RequestMap、SessionMap对象,Action需要实现RequestAware, SessionAware接口
    private Map request;
    private Map session;
    
    @Override
    public void setRequest(Map request) {
        this.request = request;
    }
 
    @Override
    public void setSession(Map session) {
        this.session = session;

}

        获取HttpServletRequest、HttpSession对象,Action需要实现ServletRequestAware接口    
    private HttpServletRequest request;
    private HttpSession session;
 
    @Override
    public void setServletRequest(HttpServletRequest request) {
        this.request = request;
        this.session = request.getSession();
    }
 

Struts2 教程的更多相关文章

  1. 孔浩老师的 Struts2 教程听课笔记(思维导图)

    最近有空重头学习了一遍孔浩老师的 Struts2 教程,重新写了一份听课笔记.后面常用 form 标签.服务器端验证.异常处理因为时间问题,没有来得及整理.后续我会抽空补上.最近忙着准备笔试.面试. ...

  2. Struts2教程

    一.初识Struts2 Struts2是一个基于MVC设计模式的Web应用框架,它本质上相当于一个servlet,在MVC设计模式中,Struts2作为控制器(Controller)来建立模型与视图的 ...

  3. struts2教程&实例

    1.第一个struts2项目 参考官方配置 http://struts.apache.org/getting-started/ github地址:https://github.com/unbeliev ...

  4. struts2官方 中文教程 系列四:Action

    先贴个本帖的地址,免得其它网站被爬去了struts2教程 官方系列四:Action  即 http://www.cnblogs.com/linghaoxinpian/p/6905521.html 下载 ...

  5. struts2官方 中文教程 系列六:表单验证

    先贴个本帖的地址,以免被爬:struts2教程 官方系列六:表单验证  即 http://www.cnblogs.com/linghaoxinpian/p/6906720.html 下载本章节代码 介 ...

  6. struts2官方 中文教程 系列五:处理表单

    先贴个本帖的地址,免得其它网站被爬去了struts2教程 官方系列五:处理表单  即 http://www.cnblogs.com/linghaoxinpian/p/6906298.html 下载本章 ...

  7. Struts2之初识

    Struts2教程 第一章 初识Struts2 主页:http://struts.apache.org/ 优势:用户请求,模块处理,页面展现.适用于企业级开发,便于维护. 配置:web.xml中添加的 ...

  8. struts2,spring,ibatis学习

    1.1 什么是struts2? MVC思想给网站设计带来了巨大的好处,但是MVC毕竟只是一种思想,不同的程序员写出来的基于MVC思想的应用,风格可能不一样.影响程序的标准化,Struts是为了规范MV ...

  9. HowToDoInJava 其它教程 2 · 翻译完毕

    原文:HowToDoInJava 协议:CC BY-NC-SA 4.0 欢迎任何人参与和完善:一个人可以走的很快,但是一群人却可以走的更远. ApacheCN 学习资源 目录 JMS 教程 JMS 教 ...

随机推荐

  1. XSS前端防火墙

    前一段时间,在EtherDream大神的博客里看到关于XSS防火墙的一系列文章,觉得很有意思.刚好科创要做一个防火墙,就把XSS前端防火墙作为一个创新点,着手去实现了. 在实现过程中,由于各种原因,比 ...

  2. C语言关键字-volatile

    1.C语言关键字volatile     C 语言关键字volatile(注意它是用来修饰变量而不是上面介绍的__volatile__)表明某个变量的值可能在外部被改变,因此对这些变量的存取 不能缓存 ...

  3. easyBCD安装双系统,简单便捷,亲测好用

    一 准备工作(在WIN7下操作完成) 1   从官网http://www.ubuntu.com/上下载镜像文件,大小接近700M.下载EasyBCD最新版安装之.特别声明:EasyBCD是一款很优秀的 ...

  4. mybatis 中mapper 的namespace有什么用

    原文:http://zhidao.baidu.com/link?url=ovFuTn7-02s7Qd40BOnwHImuPxNg8tXJF3nrx1SSngNY5e0CaSP1E4C9E5J6Xv5f ...

  5. no appropriate service handler found The Connection descriptor used by the client was: localhost:1521:myorcl

    参考网址:http://www.2cto.com/database/201205/133542.html http://www.cnblogs.com/kerrycode/p/4244493.html ...

  6. uva 10940

    数学 打了个表 找一下规律.... #include <cstdio> int a[30]; void init() { a[1]=2;a[2]=4;a[3]=8;a[4]=16;a[5] ...

  7. Host Definition

    Description: A host definition is used to define a physical server, workstation, device, etc. that r ...

  8. 李洪强漫谈iOS开发[C语言-012]-C语言基本数据类型

    // //  main.m //  08 - 基本数据类型 // //  Created by vic fan on 16/7/16. //  Copyright © 2016年 李洪强. All r ...

  9. N-Queens leetcode java

    题目: The n-queens puzzle is the problem of placing n queens on an n×n chessboard such that no two que ...

  10. easyui源码翻译1.32--datagrid(数据表格)

    前言 此前网上有easyui1.25的源码  应该算是比较老的版本  之后又经历了1.26 . 1.3. 1.31. 1.32 .1.33.1.34  1.33开始支持css3 算是又一个转折  但是 ...