struts2 订阅
Struts2是一个基于MVC设计模式的Web应用框架,它本质上相当于一个servlet,在MVC设计模式中,Struts2作为控制器(Controller)来建立模型与视图的数据交互。Struts 2是Struts的下一代产品,是在 struts 1和WebWork的技术基础上进行了合并的全新的Struts 2框架。其全新的Struts 2的体系结构与Struts 1的体系结构差别巨大。Struts 2以WebWork为核心,采用拦截器的机制来处理用户的请求,这样的设计也使得业务逻辑控制器能够与ServletAPI完全脱离开,所以Struts 2可以理解为WebWork的更新产品。虽然从Struts 1到Struts 2有着太大的变化,但是相对于WebWork,Struts 2的变化很小。 展开全文
Struts2是一个基于MVC设计模式的Web应用框架,它本质上相当于一个servlet,在MVC设计模式中,Struts2作为控制器(Controller)来建立模型与视图的数据交互。Struts 2是Struts的下一代产品,是在 struts 1和WebWork的技术基础上进行了合并的全新的Struts 2框架。其全新的Struts 2的体系结构与Struts 1的体系结构差别巨大。Struts 2以WebWork为核心,采用拦截器的机制来处理用户的请求,这样的设计也使得业务逻辑控制器能够与ServletAPI完全脱离开,所以Struts 2可以理解为WebWork的更新产品。虽然从Struts 1到Struts 2有着太大的变化,但是相对于WebWork,Struts 2的变化很小。
信息
外文名
Struts 2
类    别
框架
理    解
WebWork+struts1的的更新产品
解    释
Struts的下一代产品
Struts 2发展历史
2000年5月发展至今,Struts1已经成为了一个高度成熟的框架,不管是稳定性还是可靠性都得到了广泛的证明。市场占有率超过20%,拥有丰富的开发人群,几乎已经成为了事实上的工业标准。但是随着时间的流逝,技术的进步,Struts1的局限性也越来越多地暴露出来,并且制约了Struts1的继续发展。对于Struts1框架而言,由于与JSP/Servlet耦合非常紧密,因而导致了一些严重的问题。首先,Struts1支持的表现层技术单一。由于Struts1出现的年代比较早,那个时候没有FreeMarker、Velocity等技术,因此它不可能与这些视图层的模版技术进行整合。其次,Struts1与Servlet API的严重耦合,使应用难于测试。最后,Struts1代码严重依赖于Struts1 API,属于侵入性框架。从目前的技术层面上看,出现了许多与Struts1竞争的视图层框架,比如JSF、Tapestry和spring MVC等。这些框架由于出现的年代比较近,应用了最新的设计理念,同时也从Struts1中吸取了经验,克服了很多不足。这些框架的出现也促进了Struts的发展。Struts1已经分化成了两个框架:第一个是在传统的Struts1的基础上,融合了另外的一个优秀的Web框架WebWork的Struts2。Struts 2虽然是在Struts1的基础上发展起来的,但是实质上是以WebWork为核心的。Struts2为传统的Struts1注入了WebWork的先进的设计理念,统一了Struts1和WebWork两个框架。Struts1分化出来的另外一个框架是Shale。这个框架远远超出了Struts1原有的设计思想,与原有的Struts1关联很少,使用了全新的设计思想。Shale更像一个新的框架而不是Struts1的升级。
收起全文
精华内容
参与话题
问答
  • Struts2框架学习总结(从入门到精通)

    千次阅读 多人点赞 2019-01-04 14:43:23
    Struts2入门 struts2概述 struts2入门案例 struts2底层执行过程 struts2相关配置 struts2的action创建 struts2的action方法访问 Struts2数据操作 Struts2值栈 Struts2拦截器

    一、Struts2入门

    struts2概述

    1. javaee三层中的web层
    2. 在struts1和webwork基础上的全新的框架
    3. 解决一些问题
      ①当功能很多,会创建很多的servlet,那么维护起来不方便,在javaweb阶段我们是通过BaseServlet的的底层反射来实现的
      在这里插入图片描述
    4. struts2版本
      在这里插入图片描述
      目前比较稳定的版本
    5. web层框架
      ①struts2
      ②springMVC

    struts2入门案例

    1. 从lib目录中导入jar包,但是里面可能上百个jar包,你可以从app目录(里面是一些案例,最好从blank案例中拿)中找到里面的web-inf->lib下的jar包进行copy
      在这里插入图片描述
      在这里插入图片描述
      关于jar包详情可参考:https://blog.csdn.net/For_ZZHacker/article/details/85675995
    2. 创建action(这里的action就相当于javaweb学的servlet)

    ① 每次访问servlet的时候都会默认执行service方法(写一个servlet:写一个类的时候需要继承httpservlet类,然后重写里面的方法(例如doget,dopost),然后再web.xml中配置访问servlet的路径)
    ② 每次访问action的时候都会默认执行execute方法(同样需要配置action的访问路径,见下一步)

    在这里插入图片描述

    1. 配置action类的访问路径
      ① 创建struts2的核心配置文件,该配置文件的名称和位置是固定的,跟hibernate的配置文件一样。位置在src下面,文件名称叫struts.xml
      ② 引入dtd的约束
      在这里插入图片描述
      在这里插入图片描述
      访问路径为:http://127.0.0.1:8080/项目名/hello.action
      (action可加可不加,常用浏览器例如火狐,谷歌,IE没问题,杂牌浏览器还是加上后面的action有可能会出错)
      注意:此时访问会出现404问题,一个可能是服务器启动报异常了,另一个就是没有配置过滤器!!!
    2. 配置struts2的过滤器(在web.xml中配置)
      (struts2已经帮我们封装好了过滤器,我们只需要配置一下即可)
      在这里插入图片描述
      在这里插入图片描述
      此时再去访问就会访问成功!!!
    3. 小总结:通过一个案例我们知道了使用框架我们可以少些很多的代码,他给我们封装了许多代码,但是我们需要去配置运用这些封装好了的类。
      另外:struts.xml里面有许多的action,web.xml就定义了一个过滤器

    struts2底层执行过程

    1. 几个概念
      过滤器是在启动服务器的时候创建的,servlet默认是在第一次访问的时候创建的
      框架的学习反射是重点!!!!
      在这里插入图片描述

    2. 查看过滤器源代码

      在这里插入图片描述
      里面有init方法,doFilter方法,destroy方法
      ①过滤器在服务器启动的时候就会执行,创建过滤器时候执行init方法

    • init方法中加载struts2自带的配置文件和自己创建的配置文件(struts.xml,web.xml)
    • 在这里插入图片描述
    • 在这里插入图片描述
    • 在这里插入图片描述
    • 在这里插入图片描述
    • 在这里插入图片描述
    • 现在再来看一下第二个加载的配置文件是什么在这里插入图片描述
    • 在这里插入图片描述
    • 在这里插入图片描述
    • 在这里插入图片描述

    小总结:我们开发的时候只需要关心struts.xml,web.xml这两个需要自己配的配置文件即可

    struts2相关配置

    struts2的核心配置文件struts.xml

    在这里插入图片描述
    在这里插入图片描述
    最大的标签是<struts> 里面有3个常用标签从大到小<package><action><results>,以及里面的属性.
    ① package标签

    • 类似一个代码包,区别不同的action,要配置action,必须首先写package标签,在package标签中才能配置action
    • package标签属性
      - name属性:用来区分不同的package,随便起名
      - extends属性:就是个继承的意思在这里插入图片描述
      - namespace属性:不写默认也是“/”,最好写上。
      在这里插入图片描述

    ② action标签

    • action标签主要配置action的访问路径
    • action的标签属性
      - name属性:区分不同的action;package标签中的namespace属性和这里的name属性构成了访问路径
      - class属性:全路径=包名+类名,通过反射的原理去执行该类的
      - method属性:在这里插入图片描述

    ③ result标签

    • 根据你的action中的方法返回值,将页面定位到指定的页面或action上
    • result标签的属性
      - name属性:和你方法的返回值要一样
      在这里插入图片描述
      里面的“/”代表的是当前项目的根目录
      - type属性
      在这里插入图片描述
      有4个值:dispatcher(默认),redirect,chain,redirectAction
      dispatcher(默认)和redirect:result标签中“/”代表的是项目根路径,不写就代表当前路径下
      chain和redirectAction:result标签中“/”没有任何意义,不需要写,写了就是多余,也就是只能从当前路径去指定页面!!!
      chain:只能转发到同一命名空间下的Action
      redirect:可以重定向到action中去,也可以重定向到显示页面中去

    转发后页面变了,但是地址栏并没变,本质来讲转发就是同一个请求,重定向是又一次新的请求(相当于2次请求)

    struts2常量配置

    1. struts2框架,帮我们实现一部分功能,struts2里面有常量,在常量里面封装一部分功能。
    2. struts2默认的常量位置(记住)
      在这里插入图片描述
    3. 修改struts2默认常量值
      ① 常用方法
      在这里插入图片描述
      该标签写<struts>下面,和<package>标签同级
      ② 还有2种方式(了解)
      在这里插入图片描述
    4. 常用常量
      在这里插入图片描述
      在这里插入图片描述

    分模块开发

    1. 每个人自己的模块配置文件单独开发,最后合并引入到核心配置文件中就行,这样就不会将我们的核心配置文件给弄乱了。在这里插入图片描述

    在这里插入图片描述

    struts2的action创建

    action的编写方式

    1. action编写的3种方式在这里插入图片描述
    2. 创建类,实现Action接口方式(将一些常用的返回值定义为常量例如SUCCESS=“success”),不常用在这里插入图片描述在这里插入图片描述
    3. 创建类,继承类ActionSupport,常用
      在这里插入图片描述
      当然也可以用那些常量,因为也实现了interface Action
      在这里插入图片描述

    struts2的action方法访问(重点)

    1. 一共三种方式实现
      第一种:使用action标签的method属性,在这个属性里面写执行的action的方法,不写默认执行execute()方法
      在这里插入图片描述
      第二种:使用通配符的方式实现
      在这里插入图片描述
      第三种:动态访问实现(不用)
      在这里插入图片描述
      在这里插入图片描述
      在这里插入图片描述
    2. 一个错误演示
      在这里插入图片描述
      在这里插入图片描述
      在这里插入图片描述
    3. 一个action访问不同方法的例子
    • 普通方式在这里插入图片描述
    • 使用通配符的方式
      在这里插入图片描述
      在这里插入图片描述
      在这里插入图片描述
      在这里插入图片描述
    1. 又是一个struts2应用的案例
      在这里插入图片描述
      在这里插入图片描述

    二、Struts2数据操作

    结果页面的配置

    1. 全局结果页面
      使用global-results标签将result标签写这里面,global-results标签位于package标签里面,此时action标签默认就有global-results标签中包含的result标签
      在这里插入图片描述
    2. 局部结果页面
      在这里插入图片描述
    3. result标签type属性
      在这里插入图片描述
      在这里插入图片描述

    在action获取表单提交的数据

    1. 使用ActionContext类获取
      在这里插入图片描述
      在这里插入图片描述
    • 一个例子来演示
    • 创建表单,提交表单到action里面在这里插入图片描述
    • 在这里插入图片描述
    1. 使用ServletActionContext类获取
      在这里插入图片描述
      在这里插入图片描述
    2. 使用接口注入方式获取(实现不同的接口,例如ServletRequestAware接口里面有个方法可以设置出request对象)

    让action实现接口,为了得到request对象,需要新建一个成员变量来进行赋值的,然后在execute方法中才能使用
    ware:器皿,物品—》容器
    在这里插入图片描述

    在这里插入图片描述
    request用的多,session经典案例是用在登录的时候,context用的少

    struts2提供获取表单数据方式(减少了代码,替代了上面的方式例如:ServletActionContext)

    原始的写法获取表单数据并封装到实体类中(麻烦费劲,但是有效稳定)
    在这里插入图片描述

    1. 属性封装(会用即可)
      在这里插入图片描述
      在这里插入图片描述
    2. 模型驱动封装(重点)
      在这里插入图片描述
      在这里插入图片描述

    在这里插入图片描述

    1. 表达式封装(也可以认为是属性封装的特例,因为写法原理一样)
      在这里插入图片描述
      在这里插入图片描述

    struts2获取数据封装到集合中

    1. 封装到list集合
      在这里插入图片描述
    2. 封装到map集合
      在这里插入图片描述

    扩展-表达式封装和模型驱动比较

    相同点:都封装到实体类中
    不同点:模型驱动只能封装到同一个实体类对象中,表达式封装可以封装到不同实体类中
    在这里插入图片描述
    在这里插入图片描述

    案例-添加客户功能

    在这里插入图片描述
    在这里插入图片描述

    三、Struts2值栈

    OGNL概述

    1. web阶段用EL表达式在jsp页面中来获取域对象里面的值
    2. ognl表达式比EL表达式功能更强大
      在这里插入图片描述

    (1)在struts2里面操作值栈数据
    (2)一般把ognl在struts2操作:和struts2标签一起使用操作值栈

    EL表达式,OGNL表达式(从表单获取数据三种方式中的表达式方式(隶属于属性封装方式))
    html标签,jstl标签,struts2标签

    1. OGNL不是struts2的一部分,单独的项目,经常和struts2一起使用
      (1)使用ognl时候首先导入jar包,struts2提供了ognl的jar包

    OGNL入门案例

    在这里插入图片描述

    什么是值栈

    在这里插入图片描述
    在这里插入图片描述

    获取值栈对象

    在这里插入图片描述
    在这里插入图片描述

    值栈内部结构

    在这里插入图片描述

    在这里插入图片描述
    在这里插入图片描述

    在这里插入图片描述
    在这里插入图片描述

    下图中root部分是个栈,栈里面有2个元素,因为没有操作值栈,所以栈顶元素是当前值栈所在action的一个引用(为了方便操作的),当你往栈里面放东西就会放到栈顶的位置上。
    在这里插入图片描述

    向值栈放数据

    1 向值栈放数据多种方式
    第一种 获取值栈对象,调用值栈对象里面的 set 方法

    在这里插入图片描述
    在这里插入图片描述
    第二种 获取值栈对象,调用值栈对象里面的 push方法

    在这里插入图片描述
    在这里插入图片描述

    第三种 在action定义变量,生成变量的get方法(好处是减少空间的分配了)
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    向值栈放对象

    在这里插入图片描述

    向值栈放list集合

    在这里插入图片描述
    在这里插入图片描述

    从值栈获取数据

    1 使用struts2的标签+ognl表达式获取值栈数据
    (1)<s:property value=”ognl表达式”/>

    获取字符串

    1 向值栈放字符串
    在这里插入图片描述
    2 在jsp使用struts2标签+ognl表达式获取
    在这里插入图片描述

    获取对象

    在这里插入图片描述

    获取list集合

    在这里插入图片描述
    在这里插入图片描述
    第三种方式使用struts2的iterator标签类似于jstl的foreach标签
    在这里插入图片描述
    在这里插入图片描述
    想使用context里面的数据需要加个“#”,将数据放到context这样的操作目的是为了方便取值,不占用root部分,提高效率
    在这里插入图片描述
    这里注意一下application,其实就是ServletContext对象,记得这个applicatIon域中是共享的

    foreach+EL表达式的方式(需要jstl.jar包和standard.jar,并且在开头引入c标签taglib uri是jstl/core)
    在这里插入图片描述

    其他操作

    在这里插入图片描述
    ognl的数组获取值的写法先写下标,再写数组名,中间有点号,值栈的栈顶就是0号位置,依次向下排,所有的都会放到这个top数组,不是只有push这种没有key的。
    注意:很多种写法都用<s:property value="ognl表达式">来获取,实质上这个标签是从栈顶先来寻找符合的值,找到就直接显示,不管后面符合该表达式的值了。

    EL表达式获取值栈数据(为什么能取到)

    如果数据在值栈中虽然能取到,但是性能很低,因为有多余操作,例如先去域对象中找等等。
    先看例子:能够取到值栈中的数据
    在这里插入图片描述
    在这里插入图片描述
    先解释一个词wrap:包起来,穿外衣,缠绕—》本质就是增强的意思
    源码里面会有这个词,以及wrapper可以理解为包装器和增强器
    EL表达式中就是对request进行了增强,本质就是对getAttubute进行了增强
    看源码首先从struts2的过滤器中开始看-----》找到里面有个doFilter方法—》再看到这个doFilter方法中的request被增强了使用wrapRequest(oldRequest)方法
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    最后这个选中的ActionContext.put,又将标志值(看好了不是attribute,只是一个标志而已)放到了值栈的第二部分context中去了,其实这个context中包含request对象的引用,Httpsession对象的引用,servletContext对象的引用等等(也因此可以用ognl表达式获取到域对象中的数据),此时put进去就和这些域对象平起平坐了。

    ActionContext.getContext.put(String,Object)是把对象放到了StackContext中,这个对象跟request,session等一样,它们平起平坐,但这些都不是root对象(这些是context对象),所以要通过#访问。

    request.setAttribute(String,Object)就是把值放到request范围,而StackConext里含有request对象,所以可以通过#request.*来访问。

    OGNL的#、%使用

    #使用

    在这里插入图片描述

    %使用

    在这里插入图片描述
    注意是表单标签
    上面这个图就相当于html中的input标签,所以一般不用ognl的表单标签,因为性能低,不如直接用html的表单标签
    在这里插入图片描述

    案例-显示所有信息列表(用值栈来存数据,以前用的域对象)

    首先想到3种方式set,put,直接定义成员变量方式,第三种最常用
    在这里插入图片描述

    四、Struts2拦截器(interceptor)

    拦截器的概述

    1. 拦截器是struts2里面的概念
    2. struts2框架封装的功能都是在拦截器里面
    3. 在没有自定义拦截器的情况下,每次执行action,默认只会执行默认的拦截器
      下图是常量的位置:
      在这里插入图片描述
      下图是struts2里面默认拦截器的位置:
      在这里插入图片描述
      这个文件结构跟自己定义的struts.xml结构差不多
      其中的package标签名字就是struts-default,还定义了result-type,默认是dispatcher
      在这里插入图片描述
      这里还指定了默认的拦截器栈
      在这里插入图片描述

    在这个文件中<interceptors>里面定义了大量的<interceptor>这些就是定义的拦截器,还有一些拦截器栈
    在这里插入图片描述
    下图这些只是引用<interceptor-ref>,真正的定义拦截器是在上面定义的
    在这里插入图片描述
    4. 拦截器的执行时间:
    在action创建之后,执行action中的方法之前 ,执行的拦截器,可以通过在默认的随便一个拦截器上打个断点来验证,会发现先到拦截器中的断点,再到action中的具体方法中的断点上

    追踪一个拦截器看一下(就拿这个模型驱动的拦截器来演示一下):
    这里是xml文件,用ctrl+鼠标左键不能连接到,先选中用ctrl+shift+t来找到该类
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    百度解释拦截器:
    一、概述:
    java里的拦截器是动态拦截Action调用的对象。它提供了一种机制可以使开发者可以定义在一个action执行的前后执行的代码,也可以在一个action执行前阻止其执行,同时也提供了一种可以提取action中可重用部分的方式。在AOP(Aspect-Oriented Programming)中拦截器用于在某个方法或字段被访问之前,进行拦截然后在之前或之后加入某些操作。
    二、原理:
    大部分时候,拦截器方法都是通过代理的方式来调用的。Struts 2的拦截器实现相对简单。当请求到达Struts 2的ServletDispatcher时,Struts 2会查找配置文件,并根据其配置实例化相对的拦截器对象,然后串成一个列表(list),最后一个一个地调用列表中的拦截器。Struts2拦截器是可插拔的,拦截器是AOP的一种实现。Struts2拦截器栈就是将拦截器按一定的顺序联结成一条链。在访问被拦截的方法或字段时,Struts2拦截器链中的拦截器就会按其之前定义的顺序被调用。
    三、定义一个拦截器
    自定义一个拦截器需要三步:
    1 .自定义一个实现Interceptor接口(或者继承自AbstractInterceptor)的类。
    2 .在struts.xml中注册上一步中定义的拦截器。
    3 .在需要使用的Action中引用上述定义的拦截器,为了方便也可将拦截器定义为默认的拦截器,这样在不加特殊声明的情况下所有的Action都被这个拦截器拦截。
    四、与过滤器的区别:
    过滤器可以简单理解为“取你所想取”,忽视掉那些你不想要的东西;拦截器可以简单理解为“拒你所想拒”,关心你想要拒绝掉哪些东西,比如一个BBS论坛上拦截掉敏感词汇。
    1.拦截器是基于java反射机制的,而过滤器是基于函数回调的。
    2.拦截器不依赖于servlet容器,而过滤器依赖于servlet容器。
    3.拦截器只对action起作用,而过滤器几乎可以对所有请求起作用。
    4.拦截器可以访问action上下文、值栈里的对象,而过滤器不能。
    5.在action的生命周期里,拦截器可以多起调用,而过滤器只能在容器初始化时调用一次。

    拦截器底层原理

    1 拦截器底层使用两个原理
    第一个 aop思想(aop的底层是动态代理)
    (0)后面在spring里面把aop做更深层次分析
    (1)文字描述:
    Aop是面向切面(方面)编程:有个基本功能,需要扩展功能,不通过修改源代码方式扩展功能。
    (2)画图分析:
    在这里插入图片描述
    第二个 责任链模式
    (1)在java中有很多的设计模式,责任链模式是其中的一种
    (2)责任链模式和过滤链很相似的
    责任链模式:
    要执行多个操作,有添加、修改、删除三个操作。
    首先执行添加操作,添加操作执行之后 做类似于放行操作,执行修改操作,修改操作执行之后做类似于放行操作,执行删除操作
    过滤链:一个请求可有多个过滤器进行过滤,每个过滤器只有做放行才能到下一个过滤器
    在这里插入图片描述
    2 aop思想和责任链模式如何应用到拦截器里面?

    (1)文字描述:

    • 拦截器在action对象创建之后,action的方法执行之前执行

    • 在action方法执行之前执行默认拦截器,执行过程使用aop思想,在action没有直接调用拦截器的方法,使用配置文件方式进行操作

    • 在执行拦截器时候,执行很多的拦截器,这个过程使用责任链模式
      – 假如执行三个拦截器,执行拦截器1,执行拦截器1之后做放行操作,执行拦截器2,执行拦截器2之后做放行,执行拦截器3,执行拦截器3之后放行,执行action的方法

    (2)画图分析
    在这里插入图片描述

    3 查看源代码
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    源码主要步骤:
    在这里插入图片描述

    重要概念

    1 过滤器和拦截器区别
    (1)过滤器:服务器启动时创建,过滤器理论上可以任意内容,比如html、jsp、servlet、图片路径
    (2)拦截器:拦截器只可以拦截action

    2 Servlet和action区别
    (1)servlet默认第一次访问时候创建,创建一次,单实例对象
    (2)action每次访问时候创建,创建多次,多实例对象

    自定义拦截器

    在这里插入图片描述

    自定义登录拦截器

    1 需求:在项目中,有很多的action的超链接,实现只有是登录的状态,才可以点击action的超链接实现功能,如果不是登录状态,点击action超链接返回到登录页面

    2 登录的状态:使用session域对象实现
    (1)登录成功之后,把数据放到session里面
    (2)判断session是否有值,可以知道是否是登录状态

    3 实现登录的基本功能
    (1)查询数据库判断用户名和密码
    在这里插入图片描述
    此时可以在jsp页面用EL表达式来获取到session域中的信息
    在这里插入图片描述

    4 添加登录拦截器功能
    (1)判断是否登录:判断session里面是否有名称是username的值
    (2)拦截器实现过程
    第一步 创建类,继承MethodFilterInterceptor类
    第二步 重写MethodFilterInterceptor类里面的方法写拦截器逻辑
    在这里插入图片描述
    第三步 配置action和拦截器关系(注册拦截器)
    (1)在要拦截的action标签所在的package标签里面声明拦截器

    在这里插入图片描述

    (2)在具体的action标签里面使用声明的拦截器
    在这里插入图片描述
    (3)struts2里面执行很多的默认拦截器,但是如果在action里面配置自定义拦截器,
    问题:默认的拦截器不会执行了,如果没有到默认拦截器中的功能也可以不引用。
    解决:把默认拦截器手动使用一次
    在这里插入图片描述
    5 配置的拦截器,会对action里面所有的方法都进行拦截
    (1)在action里面有login的登录的方法,这个方法不需要拦截,如果这个方法都拦截,问题是,永远登录不进去了

    (2)解决:让login方法不进行拦截
    这里就是为什么要继承MethodFilterIntercepor类的原因了,如果继承的是AbstractInterceptor类需要用反射的方法才让实现让一些方法不拦截,而继承这个类直接就可以使用配置的方式来实现,如下:

    • 直接通过配置方式让action里面某些方法不进行拦截,多个方法用逗号分隔
      在这里插入图片描述
      6 如果登录状态,直接到功能页面,如果不是登录显示登陆页面
      登录之后出现小问题:
      在这里插入图片描述
      原因:
      在这里插入图片描述
      解决:设置打开的位置是在父窗口中打开,这个target在以前a标签中见过
      在这里插入图片描述

    struts2的标签库

    0 struts2标签使用jsp页面中

    1 s:property: 和ognl表达式在jsp页面中获取值栈数据

    2 s:iterator: 获取值栈list集合数据,表示list集合

    3 s:debug: 查看值栈结构和数据

    Struts表单标签(会用)

    1 html表单标签
    (1)form : action、method、enctype(上传用过)
    (2)输入项

    • 大部分在input里面封装 type=”值”
    • text:普通输入项
    • password:密码输入项
    • radio:单选输入项
    • checkbox:复选输入项
    • file:文件上传项
    • hidden:隐藏项
    • button:普通按钮
    • submit:提交按钮
    • image:图片提交(点击图片,提交表单)
    • reset:重置
    • select:下拉输入项
    • textarea:文本域

    2 在struts2里面对应html表单标签大部分都有

    而且可以通过查看源代码的方式来看这些标签装换成html标签的样子

    不能在标签的前面写该标签的名字,否则不在一行上,因为它会装换成
    html标签的时候是用的table->tr->td,要用label标签写名字
    在这里插入图片描述在这里插入图片描述在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    用map的格式可以解决显示的值和value对应的值不一样的情况!!!
    在这里插入图片描述

    在这里插入图片描述在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    缺少两个知识点

    1 struts2文件上传

    2 错误处理机制

    五、一些实用小细节

    1. 当你用eclipse复制一个项目的时候,不但需要修改项目的名,还需要修改项目的上下文路径,也就是你访问的时候需要输入的访问项目的名称。
      右键-》properties
      在这里插入图片描述
    2. 关于页面刷新
      我用的是chrome浏览器:
      F5:刷新网页,重新显示当前页面内容
      Ctrl+F5(Ctrl+Shift+R):重新加载当前网页而不使用缓存内容,缓存虽然加快了显示的速度,但是修改后可能不会正常显示。效果是忽略缓存,强行刷新网页(包括重载js),重新请求
      Shift+F5:用过重新载入新的js脚本,跟ctrl+F5 一样
      Ctrl+Shift+Del 清除Google浏览器缓存的快捷键

    F5和Ctrl+F5原理,可参看:https://www.cnblogs.com/cxd4321/archive/2009/03/11/1408425.html
    关于客户端的刷新功能,可参看:
    http://www.cnblogs.com/volnet/archive/2012/11/02/2752019.html

    1. eclipse一些使用问题
      在这里插入图片描述
      直接启动tomcat也会自动运行publish(发布),但是有时项目很大会有问题,但是最保险的方式是先publish,再start.关闭的时候最好先stop,再start,虽然restart这个功能可以用。
    2. 关于注释
      在这里插入图片描述
      图中是jsp的注释,可以在jsp标签中随便注释,为所欲为。

    <!-- -->是html的标签,不能注释掉里面的jstl标签和ognl标签,否则会报错!!!!

    展开全文
  • Struts2框架的基本使用

    万次阅读 多人点赞 2017-04-29 08:48:48
    前面已经介绍过了MVC思想,Struts2是一个优秀的MVC框架,大大降低了各个层之间的耦合度,具有很好的扩展性。从本篇开始我们学习Struts2的基本用法,本篇主要包括以下内容: Struts2的下载安装 理解整个框架的运行...

         前面已经介绍过了MVC思想,Struts2是一个优秀的MVC框架,大大降低了各个层之间的耦合度,具有很好的扩展性。从本篇开始我们学习Struts2的基本用法,本篇主要包括以下内容:

    • Struts2的下载安装
    • 理解整个框架的运行流程
    • 自定义实现Action
    • 自定义配置处理结果

    一、下载和安装Struts2
         登录Apache官网 http://struts.apache.org/download.cgi#struts23163 下载最新版本的Struts,当然建议下载2.3版本的,因为2.5版本刚出来,有些示例应用并不是很全。解压压缩包,得到Struts2的源码及示例代码。
    这里写图片描述

    apps目录中主要是官方提供的Struts2的实例代码,对于我们的学习是很有用的。docs中主要是有关Struts2的相关文档内容。lib目录中主要存放了有关Struts2的核心类库,以及第三方插件库。src中包含了Struts2的全部源代码。

    二、理解Struts2的运行流程
         下面演示一个完整的使用Struts2的实例,目的不是具体的代码,重点在于理解整个框架的运作流程。首先我们需要从apps目录中的struts2-blank示例项目中拷贝出整个lib目录。(这是使用Struts2最基本的jar包,没必要从Struts2的lib中一个一个找,因为你也不知道哪些是必需的),我们将他们导入到我们的项目中。

    这里写图片描述

    这是整个Struts2的请求和响应流程,下面看具体代码中是如何体现的。

    //web.xml,首先在web.xml中添加如下代码,拦截所有请求,即所有请求现在全部归Struts2框架管了
    <filter>
            <filter-name>struts</filter-name>
            <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
    </filter>
    <filter-mapping>
            <filter-name>struts</filter-name>
            <url-pattern>/*</url-pattern>
    </filter-mapping>
    //编写Action充当控制器
    public class LoginAction extends ActionSupport {
        private String username;
        private String password;
        public String getUsername(){
            return this.username;
        }
        public void setUsername(String s){
            this.username = s;
        }
        public String getPassword(){
            return this.password;
        }
        public void setPassword(String s){
            this.password = s;
        }
    
        public String execute() throws Exception{
    
            if(getUsername().equals("walker")&&getPassword().equals("yam")){
                return SUCCESS;
            }
            return ERROR;
        }
    }
    //新建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="walker" extends="struts-default">
            <action name="login" class="MyPackage.LoginAction">
                <result name="error">/error.jsp</result>
                <result name="success">/index.jsp</result>
            </action>
        </package>
    </struts>
    /*login.jsp*/
    <html>
      <head>
        <title>login</title>
      </head>
      <body>
        <form method="post" action="login">
            姓名:<input type="text" name="username" /><br />
            密码:<input type="password" name="password" /><br />
            <input type="submit" value="提交"/>
        </form>
      </body>
    </html>

    我们访问login.jsp页面,

    这里写图片描述

    提交之后会请求URL为login的页面,框架拦截器拦截,搜索Struts.xml中该URL所对应的Action控制器,转向具体的控制器,在我们写的LoginAction控制器中,我们获取表单提交的参数并做简单判断,返回字符串success或者error给核心拦截器。核心拦截器读取Struts.xml中的配置查找控制器返回的字符串对应的具体视图位置,forward视图页面响应用户。
    这里写图片描述

    这就是一个简单的Struts2框架的请求和响应过程,可以看到整个框架的核心是主拦截器和各种控制器Action,下面我们具体看看控制器的相关知识。

    三、自定义实现Action
         在Action中使用实例变量来封装请求的参数,正如上面的例子所示:我们在login.jsp页面提交的username和password两个参数,对应于LoginAction中的两个参数,在核心拦截器跳转LoginAction时,将两个请求参数自动赋值给LoginAction的两个实例变量。需要注意的是,对于LoginAction中的这两个实例变量,是需要提供setter和geter方法的,我们的核心拦截器在跳转LoginAction的时候也是通过setter方法来对具体的实例参数进行赋值的。
         我们想要自定义xxxAction控制器,需要继承Action接口,并实现其中的方法。

    public interface Action {
        String SUCCESS = "success";
        String NONE = "none";
        String ERROR = "error";
        String INPUT = "input";
        String LOGIN = "login";
    
        String execute() throws Exception;
    }

    我们可以看到在Action接口中定义了几个常用的字符串,这些字符串会被用于对应物理视图位置,详细的内容后文介绍。此处有一个execute方法,这个方法就类似于我们JavaSE中的main方法,一旦核心拦截器拦截请求跳转到Action页面,会默认执行execute方法。细心的读者可能发现,上述的例子中并没有继承Action接口,而是继承了ActionSupport类。其实ActionSupport类还是继承了Action接口并实现了execute方法,只是ActionSupport类还为我们默认的实现了一些其他的工具函数,方便我们使用,所以基本上在自定义Action的时候会继承ActionSupport类来减轻编码难度。

         Struts2中的Action没有任何和Servlet API耦合的地方,也就是在Action控制器中没有关于任何可直接操作Servlet API的接口调用。对于各个模块之间的分离,Struts还是做的很优秀的。那我们在Action控制器中没法直接操作Servlet的一些对象,例如:request,response等,但是Struts2框架提供了一个工具类,可以为我们提供这些对象。ActionContext:

    static ThreadLocal<ActionContext> actionContext = new ThreadLocal();
    //通过静态工厂创建ActionContext实例对象
    public static ActionContext getContext() {
            return (ActionContext)actionContext.get();
        }
    
    //以map的形式设置application范围内的共享数据
    public void setApplication(Map<String, Object> application)
    //获取application范围内的共享数据
    public Map<String, Object> getApplication()
    //以map的形式设置session范围内的共享数据
    public void setSession(Map<String, Object> session)
    //获取session范围内的共享数据
    public Map<String, Object> getSession()
    //获取request范围内的指定的参数值
    public Object get(String key)
    //向request范围内添加一个key-value的参数
    public void put(String key, Object value)
    //获取request的所有请求参数
    public Map<String, Object> getParameters()
    //向request范围内添加一批请求参数
    public void setParameters(Map<String, Object> parameters)

    我们往往通过ActionContext的静态方法,通过本地线程ThreadLocal获取ActionContext实例,此ActionContext封装了有关Servlet操作的各种API调用方法。我们看一个简单的使用:

    public class LoginAction extends ActionSupport {
        private String username;
        private String password;
        public String getUsername(){
            return this.username;
        }
        public void setUsername(String s){
            this.username = s;
        }
        public String getPassword(){
            return this.password;
        }
        public void setPassword(String s){
            this.password = s;
        }
        public String execute() throws Exception{
            if(getUsername().equals("walker")&&getPassword().equals("yam")){
                ActionContext ac = ActionContext.getContext();
                ac.put("login","登录成功");
                return SUCCESS;
            }
            return ERROR;
        }
    }
    <html>
      <head>
        <title></title>
      </head>
      <body>
        <p><%=request.getAttribute("login")%></p>
        <h1>this is the index page</h1>
      </body>
    </html>

    结果如下:

    这里写图片描述

    以上我们演示了如何通过ActionContext 这个工具类来完成对Servlet API的调用。其实还可以使用ServletActionContext这个工具类来直接获取到原Servlet的pageContext,request,response等对象。具体的大家可以自行研究。

    四、Action的配置
         以上我们完成了对xxxAction控制器的编写,但是如果想要我们的核心拦截器能够在用户请求URL时,找到对应的Action控制器,我们需要学会在Struts.xml中配置。之前我们介绍过,web.xml是用来配置整个web应用的,那么我们的struts.xml就是用来配置整个框架的。struts.xml应该被创建并放置在类的加载文件夹中,使用IDE的话,就创建在src文件夹下,在编译的时候会被拷贝到WEB-INF/classes中。

    这里写图片描述

    对于上述的示例,该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="walker" extends="struts-default">
            <action name="login" class="MyPackage.LoginAction">
                <result name="error">/error.jsp</result>
                <result name="success">/index.jsp</result>
            </action>
        </package>
    </struts>

         这里的头部的一些东西没必要自己敲,依然从官方给的示例中拷贝即可。至于元素Struts中的内容才是需要自己添加配置的。除去根元素,我们看到的第一个元素是package ,在Struts中使用包来配置Action,也就是所有的Action都必须被配置在一个包下面,当然一个包中也是可以配置多个Action的。
         package元素中可以配置以下属性:

    • name:该属性指定了该包的唯一标识,是必须属性
    • extends:该属性指定了该包可以继承别的包,当然别的包中的所有Action这里都是可用的了,非必须属性
    • namespace:该属性指定了该包下的所有Action的命名空间,主要用于区分同名的Action,非必须属性
    • abstract:指定了该包是一个抽象的包,抽象的包中是不能定义Action的,但是可以有大量的类型定义、拦截器定义等

    从上面给出的Struts.xml中,我们可以看出来,该包继承了struts-default包,这是struts2-core-2.3.32.3.jar 中的文件,部分内容如下:

    这里写图片描述

    被声明为抽象包之后,其中就定义了一堆拦截器和类型,具体的我们后面介绍,此处只需要知道,我们可以通过包的继承了来继承其他包中的一些Action获取拦截器。由于该包是配置普通Action的基础,所以一般我们在自定义package的时候会继承该包。
         接下来我们简单看看namespace的使用,我们在Struts.xml中可以定义多个包,每个包下面也是可以定义多个Action的,那么如果某两个不同的包下面出现同名的Action,框架就自然无法选择调用哪个Action来处理请求。如果我们指定了命名空间,那么在请求该包下的Action的时候,就需要带上命名空间的值,这样就可以避免这种冲突。具体看如下例子:

        <package name="walker" extends="struts-default" namespace="a">
            <action name="login" class="MyPackage.LoginAction">
                <result name="error">/error.jsp</result>
                <result name="success">/index.jsp</result>
            </action>
        </package>
        <package name="yam" extends="struts-default" namespace="b">
            <action name="login" class="MyPackage.LoginAction">
                <result name="error">/error.jsp</result>
                <result name="success">/index.jsp</result>
            </action>
        </package>

    我们看这两个包,他们下面配置了相同的Action,但是当时他们具有不同的命名空间,所以不会产生冲突。例如:我们请求walker包下的login action的URL为:

    /a/login

    而yam包下的login action的请求URL为:

    /b/login

    以上我们演示package包下的一些属性的作用,需要注意一点的是:如果没有指定namespace的值,则该包下的所有Action都处于默认的命名空间下,此处默认的命名空间和 namespace=”/” 是有区别的,后者表示该包处于根命名空间下,而前者中则包含了所有没有指定namespace值的包。如果框架在根命名空间或者别的命名空间下找不到指定的Action,则会前往默认命名空间下查找指定了Action。

    限于篇幅,未完待续。。

    展开全文
  • Struts2视频_全面开战

    万人学习 2015-05-12 16:23:30
    本Java视频教程对 Struts2 庞杂的技术点进行抽丝剥茧,提炼出企业开发的核心技术和重要技能。每个技术点都配备案例和代码,对于拦截器、Struts2 运行流程分析、值栈等技术点的讲授更是深入解析源代码,授之以渔。
  • Struts2的基本原理与实现

    千次阅读 热门讨论 2018-12-25 21:28:46
    Struts2是什么 Struts2是一个基于MVC设计模式的Web应用框架,它本质上相当于一个servlet,在MVC设计模式中,Struts2作为控制器(Controller)来建立模型与视图的数据交互。Struts 2是Struts的下一代产品,是在 ...

    Struts2是什么

    百度说的

    Struts2是一个基于MVC设计模式的Web应用框架,它本质上相当于一个servlet,在MVC设计模式中,Struts2作为控制器(Controller)来建立模型与视图的数据交互。Struts 2是Struts的下一代产品,是在 struts 1和WebWork的技术基础上进行了合并的全新的Struts 2框架。其全新的Struts 2的体系结构与Struts 1的体系结构差别巨大。Struts 2以WebWork为核心,采用拦截器的机制来处理用户的请求,这样的设计也使得业务逻辑控制器能够与ServletAPI完全脱离开,所以Struts 2可以理解为WebWork的更新产品。虽然从Struts 1到Struts 2有着太大的变化,但是相对于WebWork,Struts 2的变化很小。

    我说的

        上面这是百度写的,百度写的太啰嗦了,简单的来说,Struts2就是一个框架,它是属于web层的一个框架,是Struts1的一个升级版,但是它和Struts1来相比,提供了太多的增强和改进,怎么运行的呢,就是实现了Servlet的功能,来进行控制页面跳转
        同时这也是基于MVC设计模式的Web应用框架,Struts2的控制功能就相当于MVC中的Controller的功能,用来控制页面的转向。

    为什么说Struts2实现了Servlet的功能?

    因为Struts2可以理解为下图,这里介绍了前端控制器模型,形象的体现了Struts2实现了Servlet的功能
    在这里插入图片描述

    Struts2的优缺点

    优点

    1. 实现了MVC模式,层次结构清晰,使程序员只需关注业务逻辑的实现。
    2. 丰富的标签库,大大提高了开发的效率。
    3. Struts2提供丰富的拦截器实现。
    4. 通过配置文件,就可以掌握整个系统各个部分之间的关系。
    5. 异常处理机制,只需在配置文件中配置异常的映射,即可对异常做相应的处理。
    6. Struts2的可扩展性高。
    7. 面向切面编程的思想在Strut2中也有了很好的体现。

    缺点

    1. Struts2中Action中取得从jsp中传过来的参数时还是有点麻烦。
    2. 校验还是感觉比较繁琐,感觉太烦乱,也太细化了,如果校验出错的只能给用户提示一些信息。
    3. 安全性有待提高。

    优缺点来自这里

    拦截器和过滤器

    过滤器(Filter):当你有一堆东西的时候,你只希望选择符合你要求的某一些东西。定义这些要求的工具,就是过滤器。

    拦截器(Interceptor):在一个流程正在进行的时候,你希望干预它的进展,甚至终止它进行,这是拦截器做的事情。

    这里不做详细介绍,百度一下

    Struts执行流程图

    在这里插入图片描述
    图片来自这里(这篇博客写的非常的好,强烈推荐!!)

    Warning!!!

    千万不要错过!!!具体详细的Struts2的详细介绍参考网站:tutorialspoint
    别说英文网站我看不懂,我四级都没过的渣渣靠着翻译都没问题!!!

    这个Demo可以运行的起来

    在这里插入图片描述

    导入jar包

    在这里插入图片描述

    配置Struts2核心过滤器:web.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app version="2.5" 
    	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_2_5.xsd">
      <display-name></display-name>	
      <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
      </welcome-file-list>
      
      <!-- 配置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>
      
    </web-app>
    

    编写Action类:HelloAction.java

    package com.banana.struts.demo1;
    /*
     * Struts2的Action类
     */
    public class HelloAction {
    	public String execute(){
    		System.out.print("HelloAction执行了......");
    		return "success";
    	}
    }
    

    编写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>
    	<!-- Struts2为了管理Action的配置,通过包进行管理 -->
    	<!-- 配置Struts2的包 -->
    	<package name="hello" extends="struts-default" namespace="/">
    		<!-- 配置Action -->
    		<action name="hello" class="com.banana.struts.demo1.HelloAction">
    		<!-- 页面的跳转 -->
    			<result name="success">/demo1/success.jsp</result>
    		</action>
    	</package>
    </struts>
    

    添加页面:demo1.jsp、success.jsp

    demo1.jsp
    <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
    <%
    String path = request.getContextPath();
    String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
    %>
    
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
    <html>
      <head>
        <base href="<%=basePath%>">
        <title>My JSP 'demo1' starting page</title>
      </head>
      
      <body>
        <h1>Struts2的入门</h1>
        <h3><a href="${ pageContext.request.contextPath }/hello.action">Struts2的入门</a></h3>
      </body>
      
    </html>
    
    success.jsp
    <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
    <%
    String path = request.getContextPath();
    String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
    %>
    
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
    <html>
      <head>
        <base href="<%=basePath%>">
        <title>success page</title>
      </head>
      
      <body>
        跳转成功 <br>
      </body>
    </html>
    

    页面跳转逻辑

    在这里插入图片描述

    总结一下

    其实我感觉Struts2,就是实现了页面的转向,转到该转的地方,不要转到不该转的地方,取代了Servlet的功能。
    另外,继续学习,如果文中有错误请多多指教。

    展开全文
  • struts2的核心和工作原理

    万次阅读 多人点赞 2014-05-30 16:49:59
    在学习struts2之前,首先我们要明白使用struts2的目的是什么?它能给我们带来什么样的好处? 设计目标  Struts设计的第一目标就是使MVC模式应用于web程序设计。在这儿MVC模式的好处就不在提了。 技术优势  Struts2...

        在学习struts2之前,首先我们要明白使用struts2的目的是什么?它能给我们带来什么样的好处?

    设计目标

        Struts设计的第一目标就是使MVC模式应用于web程序设计。在这儿MVC模式的好处就不在提了。

    技术优势

        Struts2有两方面的技术优势,一是所有的Struts2应用程序都是基于client/server HTTP交换协议,The Java Servlet API揭示了Java Servlet只是Java API的一个很小子集,这样我们可以在业务逻辑部分使用功能强大的Java语言进行程序设计。

        二是提供了对MVC的一个清晰的实现,这一实现包含了很多参与对所以请求进行处理的关键组件,如:拦截器、OGNL表达式语言、堆栈。


        因为struts2有这样目标,并且有这样的优势,所以,这是我们学习struts2的理由,下面,我们在深入剖析一下struts的工作原理。

    工作原理

        Suruts2的工作原理可以用下面这张图来描述,下面我们分步骤介绍一下每一步的核心内容


        一个请求在Struts2框架中的处理大概分为以下几个步骤 

        1、客户端初始化一个指向Servlet容器(例如Tomcat)的请求

        2、这个请求经过一系列的过滤器(Filter)(这些过滤器中有一个叫做ActionContextCleanUp的可选过滤器,这个过滤器对于Struts2和其他框架的集成很有帮助,例如:SiteMesh Plugin) 

        3、接着FilterDispatcher被调用,FilterDispatcher询问ActionMapper来决定这个请是否需要调用某个Action 

           FilterDispatcher是控制器的核心,就是mvc中c控制层的核心。下面粗略的分析下我理解的FilterDispatcher工作流程和原理:FilterDispatcher进行初始化并启用核心doFilter

    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException ...{
            HttpServletRequest request = (HttpServletRequest) req;
            HttpServletResponse response = (HttpServletResponse) res;
            ServletContext servletContext = filterConfig.getServletContext();
            // 在这里处理了HttpServletRequest和HttpServletResponse。
            DispatcherUtils du = DispatcherUtils.getInstance();
            du.prepare(request, response);//正如这个方法名字一样进行locale、encoding以及特殊request parameters设置
            try ...{
                request = du.wrapRequest(request, servletContext);//对request进行包装
            } catch (IOException e) ...{
                String message = "Could not wrap servlet request with MultipartRequestWrapper!";
                LOG.error(message, e);
                throw new ServletException(message, e);
            }
                    ActionMapperIF mapper = ActionMapperFactory.getMapper();//得到action的mapper
            ActionMapping mapping = mapper.getMapping(request);// 得到action 的 mapping
            if (mapping == null) ...{
                // there is no action in this request, should we look for a static resource?
                String resourcePath = RequestUtils.getServletPath(request);
                if ("".equals(resourcePath) && null != request.getPathInfo()) ...{
                    resourcePath = request.getPathInfo();
                }
                if ("true".equals(Configuration.get(WebWorkConstants.WEBWORK_SERVE_STATIC_CONTENT)) 
                        && resourcePath.startsWith("/webwork")) ...{
                    String name = resourcePath.substring("/webwork".length());
                    findStaticResource(name, response);
                } else ...{
                    // this is a normal request, let it pass through
                    chain.doFilter(request, response);
                }
                // WW did its job here
                return;
            }
            Object o = null;
            try ...{
                //setupContainer(request);
                o = beforeActionInvocation(request, servletContext);
    //整个框架最最核心的方法,下面分析
                du.serviceAction(request, response, servletContext, mapping);
            } finally ...{
                afterActionInvocation(request, servletContext, o);
                ActionContext.setContext(null);
            }
        }
    du.serviceAction(request, response, servletContext, mapping);
    //这个方法询问ActionMapper是否需要调用某个Action来处理这个(request)请求,如果ActionMapper决定需要调用某个Action,FilterDispatcher把请求的处理交给ActionProxy
     
    public void serviceAction(HttpServletRequest request, HttpServletResponse response, String namespace, String actionName, Map requestMap, Map parameterMap, Map sessionMap, Map applicationMap) ...{ 
            HashMap extraContext = createContextMap(requestMap, parameterMap, sessionMap, applicationMap, request, response, getServletConfig());  //实例化Map请求 ,询问ActionMapper是否需要调用某个Action来处理这个(request)请求
            extraContext.put(SERVLET_DISPATCHER, this); 
            OgnlValueStack stack = (OgnlValueStack) request.getAttribute(ServletActionContext.WEBWORK_VALUESTACK_KEY); 
            if (stack != null) ...{ 
                extraContext.put(ActionContext.VALUE_STACK,new OgnlValueStack(stack)); 
            } 
            try ...{ 
                ActionProxy proxy = ActionProxyFactory.getFactory().createActionProxy(namespace, actionName, extraContext); 
    //这里actionName是通过两道getActionName解析出来的, FilterDispatcher把请求的处理交给ActionProxy,下面是ServletDispatcher的 TODO: 
                request.setAttribute(ServletActionContext.WEBWORK_VALUESTACK_KEY, proxy.getInvocation().getStack()); 
                proxy.execute(); 
             //通过代理模式执行ActionProxy
                if (stack != null)...{ 
                    request.setAttribute(ServletActionContext.WEBWORK_VALUESTACK_KEY,stack); 
                } 
            } catch (ConfigurationException e) ...{ 
                log.error("Could not find action", e); 
                sendError(request, response, HttpServletResponse.SC_NOT_FOUND, e); 
            } catch (Exception e) ...{ 
                log.error("Could not execute action", e); 
                sendError(request, response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e); 
            } 
    } 


     

        4、如果ActionMapper决定需要调用某个Action,FilterDispatcher把请求的处理交给ActionProxy 

        5、ActionProxy通过ConfigurationManager询问框架的配置文件,找到需要调用的Action类 ,这里,我们一般是从struts.xml配置中读取。

        6、ActionProxy创建一个ActionInvocation的实例。

        7、ActionInvocation实例使用命名模式来调用,在调用Action的过程前后,涉及到相关拦截器(Intercepter)的调用。

        下面我们来看看ActionInvocation是如何工作的:

        ActionInvocation是Xworks 中Action 调度的核心。而对Interceptor 的调度,也正是由ActionInvocation负责。ActionInvocation 是一个接口,而DefaultActionInvocation 则是Webwork 对ActionInvocation的默认实现。

        Interceptor的调度流程大致如下:

        1.ActionInvocation初始化时,根据配置,加载Action相关的所有Interceptor。

        2. 通过ActionInvocation.invoke方法调用Action实现时,执行Interceptor。

        Interceptor将很多功能从我们的Action中独立出来,大量减少了我们Action的代码,独立出来的行为具有很好的重用性。XWork、WebWork的许多功能都是有Interceptor实现,可以在配置文件中组装Action用到的Interceptor,它会按照你指定的顺序,在Action执行前后运行。

        这里,我们简单的介绍一下Interceptor

        在struts2中自带了很多拦截器,在struts2-core-2.1.6.jar这个包下的struts-default.xml中我们可以发现:

    <interceptors>
               <interceptor name="alias"class="com.opensymphony.xwork2.interceptor.AliasInterceptor"/>
               <interceptor name="autowiring"class="com.opensymphony.xwork2.spring.interceptor.ActionAutowiringInterceptor"/>
               <interceptor name="chain"class="com.opensymphony.xwork2.interceptor.ChainingInterceptor"/>
               <interceptor name="conversionError"class="org.apache.struts2.interceptor.StrutsConversionErrorInterceptor"/>
               <interceptor name="clearSession"class="org.apache.struts2.interceptor.ClearSessionInterceptor"/>
               <interceptor name="createSession"class="org.apache.struts2.interceptor.CreateSessionInterceptor"/>
               <interceptor name="debugging"class="org.apache.struts2.interceptor.debugging.DebuggingInterceptor"/>
               <interceptor name="externalRef"class="com.opensymphony.xwork2.interceptor.ExternalReferencesInterceptor"/>
               <interceptor name="execAndWait"class="org.apache.struts2.interceptor.ExecuteAndWaitInterceptor"/>
               <interceptor name="exception"class="com.opensymphony.xwork2.interceptor.ExceptionMappingInterceptor"/>
               <interceptor name="fileUpload"class="org.apache.struts2.interceptor.FileUploadInterceptor"/>
               <interceptor name="i18n"class="com.opensymphony.xwork2.interceptor.I18nInterceptor"/>
               <interceptor name="logger"class="com.opensymphony.xwork2.interceptor.LoggingInterceptor"/>
               <interceptor name="modelDriven"class="com.opensymphony.xwork2.interceptor.ModelDrivenInterceptor"/>
               <interceptor name="scopedModelDriven"class="com.opensymphony.xwork2.interceptor.ScopedModelDrivenInterceptor"/>
               <interceptor name="params"class="com.opensymphony.xwork2.interceptor.ParametersInterceptor"/>
               <interceptor name="actionMappingParams"class="org.apache.struts2.interceptor.ActionMappingParametersInteceptor"/>
               <interceptor name="prepare"class="com.opensymphony.xwork2.interceptor.PrepareInterceptor"/>
               <interceptor name="staticParams"class="com.opensymphony.xwork2.interceptor.StaticParametersInterceptor"/>
               <interceptor name="scope"class="org.apache.struts2.interceptor.ScopeInterceptor"/>
               <interceptor name="servletConfig"class="org.apache.struts2.interceptor.ServletConfigInterceptor"/>
               <interceptor name="sessionAutowiring"class="org.apache.struts2.spring.interceptor.SessionContextAutowiringInterceptor"/>
               <interceptor name="timer"class="com.opensymphony.xwork2.interceptor.TimerInterceptor"/>
               <interceptor name="token"class="org.apache.struts2.interceptor.TokenInterceptor"/>
               <interceptor name="tokenSession"class="org.apache.struts2.interceptor.TokenSessionStoreInterceptor"/>
               <interceptor name="validation"class="org.apache.struts2.interceptor.validation.AnnotationValidationInterceptor"/>
               <interceptor name="workflow"class="com.opensymphony.xwork2.interceptor.DefaultWorkflowInterceptor"/>
               <interceptor name="store"class="org.apache.struts2.interceptor.MessageStoreInterceptor"/>
               <interceptor name="checkbox"class="org.apache.struts2.interceptor.CheckboxInterceptor"/>
               <interceptor name="profiling"class="org.apache.struts2.interceptor.ProfilingActivationInterceptor"/>
               <interceptor name="roles"class="org.apache.struts2.interceptor.RolesInterceptor"/>
               <interceptor name="jsonValidation"class="org.apache.struts2.interceptor.validation.JSONValidationInterceptor"/>
               <interceptorname="annotationWorkflow"class="com.opensymphony.xwork2.interceptor.annotations.AnnotationWorkflowInterceptor"/>


        对于sturts2自带的拦截器,使用起来就相对比较方便了,我们只需要在struts.xml的action标签中加入<interceptor-ref name=" logger " />并且struts.xml扩展struts-default,就可以使用,

       如果是要自定义拦截器,首先需要写一个拦截器的类:

    package ceshi;
    import com.opensymphony.xwork2.ActionInvocation;
    import com.opensymphony.xwork2.interceptor.AbstractInterceptor;
     
    publicclassAuthorizationInterceptor extends AbstractInterceptor {
     
        @Override
        public Stringintercept(ActionInvocation ai)throws Exception {
           
               System.out.println("abc");
                return ai.invoke();
               
        }
     
    }

    并且在struts.xml中进行配置

    <!DOCTYPEstruts PUBLIC
    "-//Apache SoftwareFoundation//DTD Struts Configuration 2.0//EN"
    "http://struts.apache.org/dtds/struts-2.0.dtd">
     
     
    <struts>
        <package name="test"extends="struts-default">
         <interceptors>
          <interceptor name="abc"class ="ceshi.AuthorizationInterceptor"/>
        </interceptors>
            <action name="TestLogger"class="vaannila.TestLoggerAction">
               <interceptor-refname="abc"/>
               <result name="success">/success.jsp</result>
               </action>
        </package>
    </struts>
    


        8、一旦Action执行完毕,ActionInvocation负责根据struts.xml中的配置找到对应的返回结果。返回结果通常是(但不总是,也可能是另外的一个Action链)一个需要被表示的JSP或者FreeMarker的模版。在表示的过程中可以使用Struts2 框架中继承的标签。在这个过程中需要涉及到ActionMapper


    在上述过程中所有的对象(Action,Results,Interceptors,等)都是通过ObjectFactory来创建的。

     

    Struts2和struts1的比较

        struts2相对于struts1来说简单了很多,并且功能强大了很多,我们可以从几个方面来看:

        从体系结构来看:struts2大量使用拦截器来出来请求,从而允许与业务逻辑控制器 与 servlet-api分离,避免了侵入性;而struts1.x在action中明显的侵入了servlet-api.

        从线程安全分析:struts2.x是线程安全的,每一个对象产生一个实例,避免了线程安全问题;而struts1.x在action中属于单线程。

        性能方面:struts2.x测试可以脱离web容器,而struts1.x依赖servlet-api,测试需要依赖web容器。

        请求参数封装对比:struts2.x使用ModelDriven模式,这样我们 直接 封装model对象,无需要继承任何struts2的基类,避免了侵入性。

        标签的优势:标签库几乎可以完全替代JSTL的标签库,并且 struts2.x支持强大的ognl表达式。

        当然,struts2和struts1相比,在 文件上传,数据校验 等方面也 方便了好多。在这就不详谈了。

        

        一个比较优秀的框架可以帮着我们更高效,稳定的开发合格的产品,不过我们也不要依赖框架,我们只要理解了思想,设计模式,我们可以自己扩展功能,不然 就要 永远让别人牵着走了!

     

    展开全文
  • Struts2 入门学习总结一

    万次阅读 多人点赞 2018-09-10 20:51:42
    一、Struts2简介 Struts2是一个基于MVC设计模式的Web应用框架,它本质上相当于一个servlet,在MVC设计模式中,Struts2作为控制器(Controller)来建立模型与视图的数据交互。Struts2是Struts的下一代产品,这个框架...
  • Struts2(一)——总体介绍

    万次阅读 多人点赞 2014-03-05 19:44:10
    这篇博客开始将总结一下有关框架...(Struts1/2, WebWork, Spring MVC……) 关注数据关系的容器框架 (Spring, GUICE……) 关注数据操作的持久层框架(Hibernate,IBatis……)   当然了,各个公司可能也有
  • struts2框架简介

    千次阅读 2018-03-27 20:19:46
    一.struts2框架的开发准备 1.介绍 struts2是实现的MVC模式的JavaEE企业级的轻侵入性.轻量级的表现层web开源框架,提供了开发,发布,到维护过程中的支持. 2.需要资源下载 在apache的官网开开源软件中进行下载...
  • Struts2面试问题

    千次阅读 2018-09-27 19:10:52
    转载自 Struts2面试问题 1.什么是Struts2? Apache Struts2是一个用Java构建Web应用程序的开源框架。Struts2基于OpenSymphony WebWork框架。它从Struts1中得到了很大的改进,使其更加灵活,易于使用和扩展。...
  • Struts2学习总结

    万次阅读 2019-04-01 20:30:26
    Struts2轻量级的MVC框架,主要解决了请求分发的问题,重心在控制层和表现层。低侵入性,与业务代码的耦合度很低。Struts2实现了MVC,并提供了一系列API,采用模式化方式简化业务开发过程。 1、运行在web层.负责...
  • Struts2工作原理以及核心思想

    万次阅读 多人点赞 2017-07-07 14:42:42
    Struts2JAVA基础学完,肯定是要面临三大框架的学习的,作为初学者,了解三大框架的原理,设计目的是首要任务,只有在把握了框架的设计目的以后,才能有针对性的取学习使用框架,这里从strue2框架开始,介绍三大框架...
  • 这次练习的是一个很简单的内容:将文件上传到服务器。主要功能就是把文件上传到服务器中指定的路径。 开发环境和工具 配置Java开发环境的Windows操作系统,MyEclipse 2014/2016,Tomcat 7.0/8.0/9.0. 实现...
  • struts2文件上传设置上传文件类型

    千次阅读 2017-04-08 09:54:25
    e:/images/        image/jpeg,image/jpg    jpg,jpeg,gif    /index.jsp
  • struts2文件上传及下载

    千次阅读 2018-07-16 23:18:19
    struts2文件上传功能通过commons-fileupload来实现 jsp表单需要为post提交,并且enctype="multipart/form-data" &lt;html&gt; &lt;head&gt; &lt;meta http-equiv="Content-...
  • struts2 文件上传 获取文件为null

    千次阅读 2017-09-20 11:37:09
    struts2文件上传,跳转后台,action获取文件失败,原因: 1、页面的name名 应与action中的属性一致 2、struts.xml文件 配置拦截器时,应配置文件类型以及默认栈defaultStack      application/pdf,text/...
  • struts2文件上传与错误信息国际化

    千次阅读 2014-04-23 15:46:19
    struts.xml文件 <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.1.7//EN" "http://struts.apache.org/dtds/struts-2.1.7.dtd"> <constant name="struts.cu
  • 如何自学Struts2Struts2文件上传和数据库访问[视频]
  • 通过配置action我们来实现用struts2上传文件的效果,xml配置如下 如此,我们发现,上传大小小于2M的文件是可以的,但是超过2M之后就会报错。查看文件上传的拦截器FileUploadInterceptor,发现有属性 那么在...
  • Struts2框架实现文件上传

    万次阅读 2018-04-24 10:59:54
    Struts2框架实现文件上传开发环境系统:Windows10 版本1709JDK:1.8.0_161 32位IDE: Spring Tool Suite 3.7.3 32位Struts2版本:2.3.24服务器版本:apache-tomcat-7.0.52 单文件的上传环境搭建导入必要的jar包 必须有...
  • Struts2文件上传-fileUpload拦截器

    千次阅读 2014-06-26 21:30:19
    Struts2自带了文件上传拦截器方便进行文件上传,要使用这个功能,必须给使用了Struts2框架的工程添加commons.io包,然后在struts.xml里进行以下设置: 在标签之外添加,这句指定了上传文件的临时存放目录,以这句...

空空如也

1 2 3 4 5 ... 20
收藏数 356,667
精华内容 142,666
关键字:

struts2