struts2-第二章-拦截器
一,回顾
(1)默认action,404问题;<default-action-ref name="action 名称"/>
(2)模块化,package,struts.xml
(3)异常配置,全局异常的作用返回,用一个package,global-result,global-exceptioni-mappings
(4)结果类型,dispatcher,redirect,chain,redirectAction;action节点的result节点的type属性
(5)访问servlet容器对象;ActionContext,ServletActionContext,ServletRequestAware,ServletContextAware
二,DRY原则
Don't Repeat Yourself 不要写重复的代码
应该将功能相似的代码封装为方法,在需要的地方直接调用方法即可,若需要修改逻辑代码,我们也只需要修改方法内部的实现就可以,大大减少了维护量,提供工作效率
三,表单重复提交
(1)Demo1Action
@Getter
@Setter
public class Demo1Action extends ActionSupport {
private String uname;
private String pname; public String login(){
System.out.println("姓名:"+uname+",密码:"+pname);
//传到数据库中,进行匹配
return SUCCESS;
}
}
(2)struts.xml
<action name="demo1Action" class="com.yujun.maven.action.Demo1Action">
<result>/demo1.jsp</result>
</action>
(3)demo1.jsp
(4)运行
当表单提交后,使用内部方式调用到页面,再次手动刷新页面时就会出现上图所示的重复提交问题;此时点击继续按钮,会发现我们后台的方法代码被重复执行一次;
解决方案:
(1)使用重定向来跳转页面
(2)使用token拦截器
四,拦截器
拦截器是动态拦截action调用的对象
提供一种机制,可以使开发者定义在一个action执行的前后执行的代码,也可以在一个action执行前阻止其执行;通过此机制可以将多个action中重复代码提取到拦截器中定义
提高代码重用性
大部分时候,拦截器底层实现都是通过"代理"方式
struts2拦截器实现相对简单,当请求达到struts2的核心过滤器,struts2查找配置,并根据配置实例化相应的拦截器,然后串成一个列表(list),最后一个一个的调用列表中的拦截器;
struts2中拦截器是可插拔的(通过配置让其可有可无),拦截器是AOP编程(面向切面)一种实现方式
struts2连接器栈,就是将拦截器按一定的顺序链接成一条链,在访问被拦截的方法或字段时,struts2拦截器链中的拦截器就会按照自己的顺序依次被调用
注意的是,拦截器执行顺序,来的是和去的时候正好相反
五,表单重复提交解决
使用token拦截器的解决方式
(1)表单页面
<!-- 防止表单重复提交 -->
<s:token></s:token>
(2)struts.xml
<action name="demo1Action" class="com.yujun.maven.action.Demo1Action">
<result>/demo1.jsp</result>
<!-- 当表单重提交时的返回值 -->
<result name="invalid.token">/demo1_fail.jsp</result>
<!-- 默认拦截器栈 -->
<interceptor-ref name="defaultStack"></interceptor-ref>
<!-- 拦截器引用,token是struts2提供的,防止表单的重复提交 -->
<interceptor-ref name="token"></interceptor-ref>
</action>
(3)demo1_fail.jsp
<h3>
你已经提交过一次表单,请勿重复提交!!!
</h3>
六,自定义拦截器(重点)
通常有三种实现方式
(1) 实现Interceptor接口
(2)继承Abstractinterceptor类
(3)继承MethodFilterInterceptor
1、Interceptor接口
(1)MyInterceptor1类
public class MyInterceptor1 implements Interceptor {
//销毁
@Override
public void destroy() {
System.out.println("MyInterceptor1.destroy...");
}
//初始化
@Override
public void init() {
System.out.println("MyInterceptor1.init...");
}
//核心
@Override
public String intercept(ActionInvocation invocation) throws Exception {
System.out.println("MyInterceptor1.intercept...start");
//把请求往下传递
String result = invocation.invoke();
System.out.println("MyInterceptor1.intercept...end");
return result;
} }
(2)struts.xml
在package节点中声名
<!-- 声明拦截器 -->
<interceptors>
<!-- name:拦截器名称,唯一,class:类全名 -->
<interceptor name="my1" class="com.yujun.maven.interceptor.MyInterceptor1"></interceptor>
</interceptors>
在action节点中使用
<action name="demo2Action" class="com.yujun.maven.action.Demo2Action">
<result>/demo2.jsp</result>
<interceptor-ref name="defaultStack"></interceptor-ref>
<interceptor-ref name="my1"></interceptor-ref>
</action>
注意,这里action中也是需要引用“defaultStack”默认拦截器栈的,因为action一旦配置拦截器,默认的拦截器栈就不会生效,这里需要我们手动配置上去
(3)demo2.jsp
<h3>
this is demo2.jsp
</h3>
(4)运行
http://127.0.0.1:8080/struts2-chapter2/demo2Action!m1.action
2、继承AbstractInterceptor类
(1)MyInterceptor2类
public class MyInterceptor2 extends AbstractInterceptor { @Override
public String intercept(ActionInvocation invocation) throws Exception {
System.out.println("MyInterceptor2.intercept...start");
String result = invocation.invoke(); //把请求往下传递
System.out.println("MyInterceptor2.intercept...end-"+result);
return result;
} }
(2)struts.xml
<!-- 声明拦截器 -->
<interceptors>
<!-- name:拦截器名称,唯一,class:类全名 -->
<interceptor name="my1" class="com.yujun.maven.interceptor.MyInterceptor1"></interceptor>
<interceptor name="my2" class="com.yujun.maven.interceptor.MyInterceptor2"></interceptor>
</interceptors>
使用
<action name="demo2Action" class="com.yujun.maven.action.Demo2Action">
<result>/demo2.jsp</result>
<interceptor-ref name="defaultStack"></interceptor-ref>
<interceptor-ref name="my1"></interceptor-ref>
<interceptor-ref name="my2"></interceptor-ref>
</action>
(3)运行
http://127.0.0.1:8080/struts2-chapter2/demo2Action!m1.action
3、继承MethodFilterInterceptor类
(1)MyInterceptor3
public class MyInterceptor3 extends MethodFilterInterceptor { @Override
protected String doIntercept(ActionInvocation invocation) throws Exception {
System.out.println("MyInterceptor3.doIntercept...start");
String result = invocation.invoke(); //把请求往下传递
System.out.println("MyInterceptor3.doIntercept...end-"+result);
return result;
} }
(2)struts.xml
<!-- 声明拦截器 -->
<interceptors>
<!-- name:拦截器名称,唯一,class:类全名 -->
<interceptor name="my1" class="com.yujun.maven.interceptor.MyInterceptor1"></interceptor>
<interceptor name="my2" class="com.yujun.maven.interceptor.MyInterceptor2"></interceptor>
<interceptor name="my3" class="com.yujun.maven.interceptor.MyInterceptor3"></interceptor>
</interceptors>
使用
<action name="demo2Action" class="com.yujun.maven.action.Demo2Action">
<result>/demo2.jsp</result>
<interceptor-ref name="defaultStack"></interceptor-ref>
<interceptor-ref name="my1"></interceptor-ref>
<interceptor-ref name="my2"></interceptor-ref>
<interceptor-ref name="my3">
<!-- 排除方法(不拦截) -->
<param name="excludeMethods">m2,m3</param>
<!-- 包含方法(拦截) -->
<param name="includeMethods">m1</param>
</interceptor-ref> </action>
4、注意
前两种方式,会拦截action中所有方法,最后一种方式,如果不配置属性,默认也是拦截所有action中方法
七、拦截器栈(链)
将一个个单独的拦截器放入列表中组成一个链
<!-- 声明拦截器 -->
<interceptors>
<!-- name:拦截器名称,唯一,class:类全名 -->
<interceptor name="my1" class="com.yujun.maven.interceptor.MyInterceptor1"></interceptor>
<interceptor name="my2" class="com.yujun.maven.interceptor.MyInterceptor2"></interceptor>
<interceptor name="my3" class="com.yujun.maven.interceptor.MyInterceptor3"></interceptor> <!-- 把拦截器封装为拦截器栈 -->
<interceptor-stack name="myStack">
<!-- 拦截器引用 -->
<interceptor-ref name="my1"></interceptor-ref>
<interceptor-ref name="my2"></interceptor-ref>
<interceptor-ref name="my3"></interceptor-ref>
</interceptor-stack>
</interceptors>
使用
<action name="demo2Action" class="com.yujun.maven.action.Demo2Action">
<result>/demo2.jsp</result>
<interceptor-ref name="defaultStack"></interceptor-ref>
<interceptor-ref name="myStack"></interceptor-ref>
作业:通过struts2拦截器,拦截器未登录
八、拦截器和过滤器的区别
(1)拦截器是基于java反射机制,而过滤器是基于函数回调
(2)过滤器依赖于servlet容器,而拦截器不依赖于servlet容器
(3)拦截器只会action起作用,而过滤器对所有请求生效(静态资源、action)
(4)拦截器可以访问action上下文、值栈的对象,而过滤器不行
(5)在action的声明周期中,拦截器可以多次调用,而过滤器只会在容器初始化时只需一次
探索:
请自行新建一个过滤器(filter),在web.xml中进行过滤器注册,在过滤器的核心方法中打印输出语句,最后请求action的目标方法(m1/m2/m3....),到底是过滤器先执行还是拦截器先执行,然后重复访问action中目标方法,再看看控制台输出情况是怎么样的?
struts2-第二章-拦截器的更多相关文章
- java struts2入门学习---拦截器学习
一.拦截器,拦截器栈 1.拦截器的作用 拦截器本质上和servlet的过滤器是一样的.在struts2中,拦截器能够对Action前后进行拦截,拦截器是一个可插拨的,你可以选择使用拦截器,也可以卸载拦 ...
- 5.Struts2中的拦截器
拦截器是Struts2中的核心,其自带很多很多的拦截器,这里主要介绍一下自定义拦截器,恩多一半情况下呢?我们不需要使用到自定义的拦截器,Struts2本身已经提 供了很多的拦截器供我们使用,对于自定义 ...
- struts2基础——自定义拦截器
一.自定义拦截器 默认的拦截器能实现的功能是有限的,Struts2 支持自定义拦截器. 二.拦截器类 1.实现 Interceptor 接口 2.继承 AbstractInterceptor 抽象类, ...
- Struts2(十四)拦截器实现权限管理
一.认识拦截器 拦截器也是一个类 拦截器可以在Action被调用之前和之后执行代码 框架很多核心功能是拦截器实现的 拦截器的特点: 拦截器自由组合,增强了灵活性.扩展性.有利于系统解耦 拦截器可以拦截 ...
- 十五、struts2中的拦截器(框架功能核心)
十五.struts2中的拦截器(框架功能核心) 1.过滤器VS拦截器 功能是一回事. 过滤器是Servlet规范中的技术,可以对请求和响应进行过滤. 拦截器是Struts2框架中的技术,实现AOP(面 ...
- Struts2透过自定义拦截器实现登录之后跳转到原页面
Struts2通过自定义拦截器实现登录之后跳转到原页面 这个功能对用户体验来说是非常重要的.实现起来其实很简单. 拦截器的代码如下: package go.derek.advice; import g ...
- Struts2笔记_拦截器
A.拦截器是什么 --- Interceptor:拦截器,起到拦截Action的作用. ---Filter:过滤器,过滤从客户端向服务器发送的请求. ---Interceptor:拦截器,拦截是客户端 ...
- Struts2的核心——拦截器
虽然以前已经学了很多的拦截器,但是在这里还是想重头梳理一下所有有关拦截器的知识,尤其是struts2中的拦截器 1:拦截器是什么? java里的拦截器是动态拦截Action调用的对象.它提供了一种机制 ...
- 模仿Struts2的Interceptor拦截器实现
模仿Struts2的Interceptor拦截器实现 public interface Invocation { public Object invoke(); } public interface ...
- struts2内置拦截器和自定义拦截器详解(附源码)
一.Struts2内置拦截器 Struts2中内置类许多的拦截器,它们提供了许多Struts2的核心功能和可选的高级特 性.这些内置的拦截器在struts-default.xml中配置.只有配置了拦截 ...
随机推荐
- [2019.03.16]使用DOM操作函数和CSS选择器来针对已有的HTML进行只凭JS的改动
刚入职的时候看到公司用的HTML日志生成工具附带的Panel,工具不够用,找个Fail还要找半天,于是自己琢磨着添砖加瓦.以前也是个半吊子前端工程师,现在可倒好,想要改页面却连页面生成的模板在哪里都不 ...
- MySQL——修改用户密码 | 移除权限
修改用户密码 '; 移除权限 REVOKE Delete, Drop ON *.* FROM `root`@`localhost`; 权限列表
- python面试题整合
面试题整合 面试题—并发编程部分
- python中方法的总结
# 1.用函数实现过滤掉集合list1=[' ','hello',None,'python' ]中的空格和空值 # 2.用函数方法实现计算集合list1 = [1,2,3,4,5]中,所有元素的和 c ...
- 工厂模式如何返回Spring的Bean
工厂返回的可以是一个具体的对象,比如造一辆车,可以返回一个自行车对象,或者汽车对象. 但是在Spring 中需要工厂返回一个具体的Service,这就是一个抽象工厂了 一种方法是反射,个人觉得这种方式 ...
- LVS负载均衡NAT模式实现
LVS负载均衡之NAT模式配置 NAT 模式架构图: 操作步骤 实验环境准备:(centos7平台) 所有服务器上配置 # systemctl stop firewalld //关闭防火墙 # sed ...
- HIS(LIS、PACS、RIS、EMR)系统简介
HIS(LIS.PACS.RIS.EMR)系统简介 HIS:医院信息系统(Hospital Information System, HIS),利用电子计算机和通讯设备,为医院所属各部 门提供病人诊疗信 ...
- netcore中的缓存介绍
Cache(缓存)是优化web应用的常用方法,缓存存放在服务端的内存中,被所有用户共享.由于Cache存放在服务器的内存中,所以用户获取缓存资源的速度远比从服务器硬盘中获取快,但是从资源占有的角度考虑 ...
- 自定义shiro实现权限验证方法isAccessAllowed
由于Shiro filterChainDefinitions中 roles默认是and, admin= user,roles[system,general] 比如:roles[system,gener ...
- HDU 2717(* bfs)
题意是在一个数轴上,每次可以一步到达当前位置数值的 2 倍的位置或者数值 +1 或数值 -1 的位置,给定 n 和 k,问从数值为 n 的位置最少多少步可以到达数值为 k 的位置. 用广搜的方法,把已 ...