Struts2

Posted 雅俗共赏

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Struts2相关的知识,希望对你有一定的参考价值。

使用Struts2框架实现用登录的功能,使用struts2标签和ognl表达式简化了试图的开发,并且利用struts2提供的特性对输入的数据进行验证,以及访问ServletAPI时实现用户会话跟踪,其简单的程序运行流程图如下

 

Struts2的Action类很有意思,你可以使用3种方式来实现具体的Action类:

  1. 让你的Action类继承自ActionSupport类(项目中最常用这种方式,因为ActionSupport类中定义了很多帮助方法)
  2. 让你的Action类实现Action接口
  3. 使用POJO的方式来实现,只要Action类中有一个返回值为String的execute方法就好了(这种方式使Action类最容易被测试)

以上三种Action的实现方式都可以被struts2框架自动识别,如果你在struts.xml里面配置了一个action块但是没有配置action类的路径,这样框架默认使用ActionSupport来处理请求。

但是在实际使用struts2的过程中我发现了一个问题,一个Action只有一个execute方法来处理一类请求,如果我开发的某块功能有100个不同的请求那我岂不是要写100个Action类,每个类实现一个execute方法,这样虽然满足了一个类一个责任的设计原则,但是会不会造成“类爆炸”?后来看了struts2的文档才知道,其实我们可以使用struts2灵活的通配符配置来达到减少action类的目的:

方式一:

继承ActionSupport类,如果使用了数据校验功能,则必须继承ActionSupport。上面那个Action类就是继承了ActionSupport类。

方式二:

实现Action接口,实现execute()方法

package lps.servletAPI;

import com.opensymphony.xwork2.Action;

import javax.xml.registry.infomodel.User;

public class LoginThirdActionContextAction implements Action {
    private User user;
    @Override
    public String execute() throws Exception {

        return null;
    }
}

方式三:

:既不继承ActionSupport也不实现Action接口.(ActionSupport实现了Action接口)

public class UserAction3 {
 
    private String userName;
 
    public void setUserName(String userName) {
        this.userName = userName;
    }
    
    public String login(){
        System.out.println("UserAction3.login()"+":"+userName);
        return "success";
    }
}

Struts2的result结果集

 Struts2的Action处理用户请求后,返回一个普通字符串-------逻辑视图名,必须在Struts.xml文件中完成逻辑图

和物理视图资源的映射,才可以让系统转到实际的视图资源。

结果就是告诉Struts2框架,当Action处理结果时,系统下一步做什么。当Action返回一个普通的字符串时,系统下一步做什么。

  Struts2通过在struts.xml文件中使用<result…/>元素来配置结果。根据<result…/>元素所在位置的不同,struts2提供了两种结果:

(1)       局部结果:将<result…/>作为<action…/>元素的子元素配置。

(2)       全局结果:将<result…/>作为<global-result…/>元素的子元素配置。

首先来介绍一下局部结果,局部结果是通过在<action../>元素中指定<result…/>元素来配置的,一个<action…/>元素可以有多个<result…/>元素。这表示一个Action可以对应多个结果。

 <!--登陆的action-->
        <action name="login" class="lps.demo.LoginAction">
            <result name="success">
               /success.jsp
            </result>
            <result name="login">
                /login.jsp
            </result>
        </action>

 (1) location:该参数指定了该逻辑视图对应的实际视图资源。

(2)   parse:该参数指定是否允许在实际视图名字中使用OGNL表达式,该参数默认值为true。如果设置该参数值为false,则不允许在实际视图名中使用表达式。通常无需修改该属性值。因为通常无需指定parse参数的值。

<action name="login" class="lps.demo.LoginAction">
            <result name="login">
                /login.jsp
            </result>
        </action>

以下Struts2支持处理结果类型为转载https://blog.csdn.net/fujiakai/article/details/51897533 

 

struts2支持的处理结果类型

Struts2内建支持结果类型如下:

(1)   chain结果类型:Action链式处理的结果类型。

(2)   chart结果类型:用于整合JFreeChart的结果类型。

(3)   dispatcher结果类型:用于FreeMarker整合的结果类型。

(4)   httpheader结果类型:用于控制特殊的HTTP行为的结果类型。

(5)   jasper结果类型:用于JasperReports整合的结果类型。

(6)   jsf结果类型:用于与JSF整合的结果类型。

(7)   redirect结果类型:用于直接跳转到其他URL的结果类型。

(8)   redirect-action结果类型:用于制直接跳转到其他Action的结果类型。

(9)   stream结果类型:用于向浏览器返回一个InputStream(一般用于文件下载)。

(10)  tiles结果类型:用于与Tiles整合的结果类型。

(11)  velocity结果类型:用于与Velicity整合的结果类型。

(12)  xslt结果类型:用于与XML/XSLT整合的结果类型。

(13)  plaintext结果类型:用于显示某个页面的原始代码的结果类型。
---------------------

堆栈ValueStack

 

valueStack是struts2的值栈空间,是struts2存储数据的空间

  Strut2的Action类通过属性可以获得所有请求相关的值,要在Action类中声明与参数同名的属性或者以类名小写加属性名如:user.name,就可以获得这些参数值,在Struts2调用Action类的Action方法(默认是execute方法)之前,就会为相应的Action属性赋值。这项功能Struts2要依赖于ValueStack对象来实现,每个Action类的对象实例会拥有一个ValueStack对象,这个对象贯穿整个Action的生命周期,

  当Struts2接收到一个请求后,会先建立Action类的对象实例,但并不会立即调用Action方法,而是先将Action类的相应属性放到ValueStack实现类ONGLValueStack对象root对象的顶层节点。只是所有的属性值都是默认的值,如String类型的属性值为null,int类型的属性值为0等。在处理完上述工作后,Struts 2就会调用拦截器链中的拦截器,这些拦截器会根据用户请求参数值去更新ValueStack对象顶层节点的相应属性的值,最后会传到Action对象,并将ValueStack对象中的属性值,赋给Action类的相应属性。当调用完所有的拦截器后,才会调用Action类的Action方法。ValueStack会在请求开始时被创建,请求结束时消亡

 

值栈ValueStack

为什么进行类型转换

在基于HTTP协议的Web应用中

客户端请求的所有内容都以文本编码方式传输到服务器端,服务器端的编程语言却有着丰富的数据类型

Servlet中,类型转换工作由开发者自己完成,eg

 

 

3.valueStack底层相关的数据结构

 

 

 CompoundRoot是继承了Arraylist的集合,里面存放Action的实例、代理对象、自定义对象(Student)等数据。

 

以上是关于Struts2的主要内容,如果未能解决你的问题,请参考以下文章

struts2怎么防止sql注入

struts2请求过程源代码分析

[struts2学习笔记] 第五节 编写struts2的action代码

Struts2 s2-032远程代码执行分析

S2-053:Apache Struts2远程代码执行漏洞(中危)

struts2 s2-062 ONGL远程代码执行