网站首页 > java教程 正文
第4章 Struts2拦截器
本章学习目标
· 理解拦截器的意义
· 熟练掌握Struts2拦截器的使用
· 掌握自定义拦截器的使用
拦截器是Struts2框架的一个核心组件,也是Struts2的一大特色,很多功能都是构建在内置拦截器的,如数据校验、国际化等。Struts2利用其内建的拦截器可以完成大部分操作,当内置拦截器不能满足时,开发者也可以自己扩展自定义拦截器。
使用Struts2拦截器只需在配置文件配置即可,取消拦截器只需取消其配置,这是一种插拔式的设计,具有非常好的可扩展性,掌握并熟练运用拦截器,会大大提高开发效率,本章将详细讲解拦截器的相关知识。
4.1 拦截器的概述和意义
在JavaWeb阶段学过Filter过滤器,多个Filter构成过滤器链。Filter与拦截器很像,二者都是AOP编程思想的体现,都能实现权限检查、日志记录等,但他们也稍有不同,Filter只能用于Web程序中,是Servlet规范中定义的,另外它们处理的粒度也是不同的,Filter只在Servlet前后起作用,而拦截器能深入方法前后、异常抛出前后等,因此拦截器有更强大的功能,本节将介绍拦截器的概念和意义。
4.1.1 拦截器概述
拦截器是在AOP(Aspect-Oriented Programming)中用于在某个方法或字段被访问之前,进行拦截然后在之前或之后加入某些操作,拦截器就是AOP的一种实现策略。
Webwork的中文文档的解释为拦截器是动态拦截Action调用的对象,它提供了一种机制可以使开发者可以定义在一个action执行的前后执行的代码,也可以在一个action执行前阻止其执行。同时也是提供了一种可以提取action中可重用的部分的方式。
谈到拦截器,还有一个词读者应该知道——拦截器链(Interceptor Chain,在Struts 2中称为拦截器栈Interceptor Stack)。拦截器链就是将拦截器按一定的顺序联结成一条链。在访问被拦截的方法或字段时,拦截器链中的拦截器就会按其之前定义的顺序被调用。
拦截器的调用是分开的,各个拦截器负责自己的功能,不去管其他的拦截器,这种模块的设计更好地体现了MVC的组件化设计思想。另外,拦截器与Action存在着紧密的关系,如图4.1所示。
图4.1 拦截器与Action关系图
如上图所示,用户操作浏览器向Web应用发送HttpServletRequest请求,请求经过各种过滤器的过滤并传递给核心控制器,核心控制器会调用Action映射器ActionMapper,将用户情趣转发到对应的业务逻辑控制器,此业务逻辑控制器并不是用户实现的业务控制器,而是Struts2创建的Action代理ActionProxy,用户实现的Action类仅仅是Struts2的ActionProxy的代理目标,ActionProxy通过Configuration Manager在struts.xml的配置文件中搜索被请求的Action类,ActionProxy创建一个被请求Action的实例,用来处理客户端的请求信息,如果在struts.xml配置文件存在与被请求Action相关的拦截器配置,那么该Action实例被调用的前后,这些拦截器将会被执行,Action对请求处理完毕后会返回一个逻辑视图,由此逻辑视图找对相应物理视图返回给客户端。
4.1.2 拦截器的意义
拦截器是对调用方法的改进,实际上,拦截器也是一个类,类中包含方法,只不过这个方法是特殊的方法,它会在目标方法调用之前自动执行。
如果不使用拦截器,代码中需要显式通过代码来调动目标方法,这样会造成多个程序间的冗余,这种做法明显是不合理的,违背了软件开发的基本原则,不便于后期维护和扩展。
由上可见,拦截器是解决重复性问题的重要方式,它提供了更高层次的解耦和抽象,目标代码无须手动调用目标方法,由程序自动完成,这种调用从代码层面上升到了设计层面。
4.2 Struts2拦截器
学习了拦截器的概念和意义后,接下来详细讲解如何配置和使用拦截器。
4.2.1 配置并使用Struts2拦截器
在struts-default.xml文件中定义了很多拦截器,如果要使用其中的拦截器,只需要在struts.xml文件中通过"<include file="struts-default.xml" />"将struts-default.xml文件包含进来,并继承其中的struts-default包(package),最后在定义Action时,使用"<interceptor-ref name="xxx" />"引用拦截器或拦截器栈(interceptor stack)。接下来通过一个案例演示如何配置并使用拦截器,新建动态Web工程,在web.xml中配置Struts2核心控制器,这里就不再重复演示,然后编写后台代码,如例4-1所示。
1 TimerInterceptorAction.java
2 import com.opensymphony.xwork2.ActionSupport;
3 public class TimerInterceptorAction extends ActionSupport {
4 private static final long serialVersionUID = 1L;
5 @Override
6 public String execute() {
7 try {
8 // 模拟耗时的操作
9 Thread.sleep(500);
10 } catch (Exception e) {
11 e.printStackTrace();
12 }
13 return SUCCESS;
14 }
15 }
接着编写struts.xml配置文件,如例4-2所示。
例4-1 struts.xml
1 <?xml version="1.0" encoding="UTF-8"?>
2 <!DOCTYPE struts PUBLIC
3 "-//Apache Software Foundation//DTD Struts
4 Configuration 2.5//EN"
5 "http://struts.apache.org/dtds/struts-2.5.dtd">
6 <struts>
7 <include file="struts-default.xml" />
8 <package name="InterceptorDemo"
9 namespace="/"
10 extends="struts-default">
11 <action name="timer"
12 class="com.qianfeng.struts.action.TimerInterceptorAction"
13 method="execute">
14 <interceptor-ref name="timer" />
15 <result name="success">
16 /timer.jsp
17 </result>
18 </action>
19 </package>
20 </struts>
最后编写前台页面,如例4-3所示。
例4-2 timer.jsp
1 <%@ page language="java" contentType="text/html; charset=UTF-8"
2 pageEncoding="UTF-8"%>
3 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
4 "http://www.w3.org/TR/html4/loose.dtd">
5 <html>
6 <head>
7 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
8 <title>Insert title here</title>
9 </head>
10 <body>
11 <center>
12 <h1>timer页面</h1>
13 </center>
14 </body>
15 </html>
代码编写完成后,运行项目,在浏览器的地址栏访问"http://IP:端口号/项目名/timer.action",此时会跳转到timer.jsp页面,如图4.2所示。
图4.2 timer.jsp
此时查看后台控制台,如图4.3所示。
图4.3 后台控制台
在浏览器地址栏再次访问"http://IP:端口号/项目名/timer.action",此时再次查看后台控制台,如图4.4所示。
图4.4 后台控制台
程序运行时,由于机器性能不同,消耗的时间可能不同,但无论如何,2963ms和500ms还是相差太远了,这是因为第一次访问timer.action时,Struts2需要进行一定的初始化工作。上述例子是利用timer拦截器打印了execute方法运行的时间,可以用于粗略的代码测试等。
4.2.2 Struts2拦截器栈
在实际开发中,经常需要在Action执行前同时执行多个拦截器,如用户登陆、登陆日志记录以及权限检查等,这时,可以把多个拦截器组成一个拦截器栈,在使用时,可以将栈内多个拦截器当成一个整体来引用,当拦截器栈被附加到一个Action上时,在执行Action之前必须先执行拦截器栈中的每一个拦截器,在struts.xml中配置拦截器栈的语法格式如下。
<interceptors>
<interceptor-stack name="interceptorStackName" />
<interceptor-ref name="interceptorName" />
……
</interceptor-stack />
</interceptors>
如上示例中,interceptorStackName表示配置的拦截器栈的名称,interceptorName表示拦截器的名称,另外,在一个拦截器栈中还可以包含另一个拦截器栈,接下来通过一个案例演示如何配置拦截器栈,如例4-4所示。
例4-3 struts.xml
1 <?xml version="1.0" encoding="UTF-8"?>
2 <!DOCTYPE struts PUBLIC
3 "-//Apache Software Foundation//DTD Struts
4 Configuration 2.5//EN"
5 "http://struts.apache.org/dtds/struts-2.5.dtd">
6 <struts>
7 <include file="struts-default.xml" />
8 <package name="default"
9 namespace="/"
10 extends="struts-default">
11 <!-- 声明拦截器 -->
12 <interceptors>
13 <interceptor name="interceptor1"
14 class="interceptorClass1" />
15 <interceptor name="interceptor2"
16 class="interceptorClass2" />
17 <!-- 定义拦截器栈myStack -->
18 <interceptor-stack name="myStack">
19 <interceptor-ref name="defaultStack" />
20 <interceptor-ref name="interceptor3" />
21 <interceptor-ref name="interceptor4" />
22 </interceptor-stack>
23 </interceptors>
24 </package>
25 </struts>
例4-4中,定义了拦截器栈myStack,在myStack中除了引用自定义的两个拦截器外,还引用了一个内置拦截器defaultStack,这个拦截器是必须要引入的。
4.2.3 Struts2的内置拦截器
Struts2中内置了很多拦截器,这些拦截器以name-class对的形式配置在struts-deafult.xml文件中,文件中的部分内置拦截器如图4.5所示。
图4.5 Struts2内置拦截器
图4.5中,name是拦截器的名称,class指定了该拦截器所对应的实现类,自定义的包继承了Struts2的struts-default包,就可以使用默认包中定义的内置拦截器,这些内置拦截器的含义如表4.1所示。
表4.1 Struts2内置拦截器名称及功能
表4.1中列出了Struts2内置拦截器的名称及含义,这些拦截器的使用方式同4.2.1小节讲解的一样,熟练运用这些拦截器能大大提高开发效率,若想熟练掌握这些拦截器的使用,还需要读者在实践中不断练习。
4.2.4 Struts2的默认拦截器
如果想对一个包下的Action使用相同的拦截器,则需要为该包中的每个Action都重复指定同一个拦截器,这种做法明显比较烦琐,这是可以使用默认拦截器,默认拦截器可以对其指定的包中所有的Action都起到拦截的作用。一旦为某一个包指定了默认拦截器,且包中的Action未显式指定拦截器,则会使用默认拦截器,若包中Action显式指定了某个拦截器,则该默认拦截器会被屏蔽。此时,若还想使用默认拦截器,则需要用户手动配置默认拦截器的应用,语法格式如下。
<default-interceptor-ref name="拦截器栈的名称" />
如上示例中,name属性的值必须是已存在的拦截器或拦截器栈的名称,接下来通过一个案例演示如何配置默认拦截器,如例4-5所示。
例4-4 struts.xml
1 <?xml version="1.0" encoding="UTF-8"?>
2 <!DOCTYPE struts PUBLIC
3 "-//Apache Software Foundation//DTD Struts
4 Configuration 2.5//EN"
5 "http://struts.apache.org/dtds/struts-2.5.dtd">
6 <struts>
7 <package name="default"
8 namespace="/"
9 extends="struts-default">
10 <!-- 声明拦截器 -->
11 <interceptors>
12 <interceptor name="interceptor1" class="interceptorClass1" />
13 <interceptor name="interceptor2" class="interceptorClass2" />
14 <!-- 定义拦截器栈myStack -->
15 <interceptor-stack name="myStack">
16 <interceptor-ref name="interceptor1" />
17 <interceptor-ref name="interceptor2" />
18 <interceptor-ref name="defaultStack" />
19 </interceptor-stack>
20 </interceptors>
21 <!-- 配置包下的默认拦截器 -->
22 <default-interceptor-ref name="myStack" />
23 <action name="xxx" class="xxx">
24 <result name="xxx">
25 /xxx.jsp
26 </result>
27 </action>
28 </package>
29 </struts>
例4-5中,指定了包下的默认拦截器为一个拦截器栈,该拦截器栈将会作用于包下所有的Action,另外,每个包下只能定义一个默认拦截器,如需多个拦截器作为默认拦截器,则可以将这些拦截器定义为一个拦截器栈,再将拦截器栈作为默认拦截器使用。
4.3 自定义拦截器
Struts2提供了许多拦截器,这些内置拦截器实现了大部分功能,因此,大部分Web应用的通用功能都可以通过直接使用这些拦截器完成,但也有一些系统逻辑相关的通用功能,需要自定义拦截器来实现,本节将详细讲解自定义拦截器的相关内容。
4.3.1 开发自定义拦截器
Struts2有丰富的内置拦截器,上一节中详细讲解了内置拦截器,但是有一些特殊功能内置拦截器无法实现,这时就可以自定义拦截器,开发自定义拦截器时,需要实现com.opensymphony.xwork2.interceptor.Interceptor接口。实际上,所有Struts2拦截器都直接或间接地实现了该接口,Interceptor接口源代码如下所示。
public interface Interceptor extends Serializable {
void destroy();
void init();
String intercept(ActionInvocation invocation) throws Exception;
}
如上源码中,Interceptor接口定义了三个方法,实现该接口时,需要具体去实现这三个方法,三个方法的具体含义如表4.2所示。
表4.2 Interceptor接口方法及含义
表4.2介绍了Interceptor接口的三个方法,接下来通过一个案例演示实现该接口自定义拦截器,如例4-6所示。
例4-5 MyInterceptor1.java
1 import com.opensymphony.xwork2.ActionInvocation;
2 import com.opensymphony.xwork2.interceptor.Interceptor;
3 public class MyInterceptor1 implements Interceptor {
4 private static final long serialVersionUID = 1L;
5 @Override
6 public void init() {
7 // 初始化资源
8 }
9 @Override
10 public String intercept(ActionInvocation invocation)
11 throws Exception {
12 String className = invocation.getAction().
13 getClass().getName();
14 long start = System.currentTimeMillis();
15 String result = invocation.invoke();
16 long end = System.currentTimeMillis();
17 // 输出调用所用时间
18 System.out.println(className + "用时:" +
19 (end - start) + "ms");
20 return result;
21 }
22 @Override
23 public void destroy() {
24 // 销毁资源
25 }
26 }
例4-6用Interceptor接口的方式,自定义了一个拦截器,除了实现该接口自定义拦截器外,更常用的是继承抽象拦截器类AbstractInterceptor,该类实现了Interceptor接口,提供了init()方法和destory()方法的空实现,在类中只需实现intercept()方法即可,接下来通过一个案例演示继承该类自定义拦截器,如例4-7所示。
例4-6 MyInterceptor2.java
1 import com.opensymphony.xwork2.ActionInvocation;
2 import com.opensymphony.xwork2.interceptor.AbstractInterceptor;
3 public class MyInterceptor2 extends AbstractInterceptor {
4 private static final long serialVersionUID = 1L;
5 @Override
6 public String intercept(ActionInvocation invocation)
7 throws Exception {
8 String className = invocation.getAction().
9 getClass().getName();
10 long start = System.currentTimeMillis();
11 String result = invocation.invoke();
12 long end = System.currentTimeMillis();
13 // 输出调用所用时间
14 System.out.println(className + "用时:" +
15 (end - start) + "ms");
16 return result;
17 }
18 }
例4-7中,通过继承AbstractInterceptor类实现自定义拦截器,功能与例4-6完全相同,但代码简洁了很多。
(脚下留心
intercept()方法的参数为ActionInvocation类型,该参数的invoke()方法直接调用下一个拦截器或Action中的execute()方法,实际上,这时拦截器方法还没有运行结束,因此在最后Action中的execute()方法调用结束之后,会继续调用未执行完成的代码。
4.3.2 配置自定义拦截器
编写完成自定义拦截器后,还需要在struts.xml文件中进行配置,自定义拦截器的配置只需要在<interceptor>的class属性中指定自定义的拦截器类就可以,假设有一个自定义的拦截器类为MyInterceptor,路径为com.qianfeng.acion,其配置方式的示例如下。
<interceptor name="myInterceptor"
class="com.qianfeng.acion.MyInterceptor" />
如上示例中,配置了一个名为myInterceptor的拦截器,其具体实现通过com.qianfeng.acion.MyInterceptor拦截器类来完成。
4.3.3 自定义拦截器案例
学习了如何开发自定义拦截器,这里通过一个登陆权限控制的案例,来演示自定义拦截器的使用,首先开发前台页面,这里需要三个页面,分别是welcome.jsp、login.jsp和show.jsp,编写welcome.jsp如例4-8所示。
例4-7 welcome.jsp
1 <%@ page language="java" contentType="text/html; charset=UTF-8"
2 pageEncoding="UTF-8"%>
3 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
4 "http://www.w3.org/TR/html4/loose.dtd">
5 <html>
6 <head>
7 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
8 <title>Insert title here</title>
9 </head>
10 <body>
11 <center>
12 <h1>
13 <a href="show.action" mce_href="show.action">
14 show
15 </a>
16 </h1>
17 </center>
18 </body>
19 </html>
接着编写login.jsp,如例4-9所示。
例4-8 login.jsp
1 <%@ page language="java" contentType="text/html; charset=UTF-8"
2 pageEncoding="UTF-8"%>
3 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
4 "http://www.w3.org/TR/html4/loose.dtd">
5 <html>
6 <head>
7 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
8 <title>Insert title here</title>
9 </head>
10 <body>
11 <form action="login.action" method="post">
12 User:<input type="text" name="username"><br>
13 Passoword:<input type="password" name="password"><br>
14 <input type="submit" value="登陆">
15 </form>
16 </body>
17 </html>
接着编写show.jsp,如例4-10所示。
例4-9 show.jsp
1 <%@ page language="java" contentType="text/html; charset=UTF-8"
2 pageEncoding="UTF-8"%>
3 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
4 "http://www.w3.org/TR/html4/loose.dtd">
5 <html>
6 <head>
7 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
8 <title>Insert title here</title>
9 </head>
10 <body>
11 <center>
12 <h1>欢迎光临</h1>
13 </center>
14 </body>
15 </html>
编写完前台页面后,接着编写后台代码,这里要编写四个类,分别为LoginFormAction、LoginAction、ShowAction和LoginInterceptor,其中LoginInterceptor是自定义的拦截器,检查是否登陆且用户名是否为root,密码是否为admin,如果检查都通过则放行,编写LoginFormAction如例4-11所示。
例4-10 LoginFormAction.java
1 import com.opensymphony.xwork2.ActionSupport;
2 public class LoginFormAction extends ActionSupport {
3 private static final long serialVersionUID = 1L;
4 public String exexcute() {
5 return "success";
6 }
7 }
编写LoginAction如例4-12所示。
例4-11 LoginAction.java
1 import com.opensymphony.xwork2.ActionContext;
2 import com.opensymphony.xwork2.ActionSupport;
3 public class LoginAction extends ActionSupport {
4 private static final long serialVersionUID = 1L;
5 private String username;
6 private String password;
7 public String getPassword() {
8 return password;
9 }
10 public void setPassword(String password) {
11 this.password = password;
12 }
13 public String getUsername() {
14 return username;
15 }
16 public void setUsername(String username) {
17 this.username = username;
18 }
19 private boolean isInvalid(String value) {
20 return (value == null || value.length() == 0);
21 }
22 public String execute() {
23 if (isInvalid(getUsername()))
24 return INPUT;
25 if (isInvalid(getPassword()))
26 return INPUT;
27 if (this.getUsername().equals("root")
28 && this.getPassword().equals("admin")) {
29 ActionContext.getContext().getSession().
30 put("user", getUsername());
31 ActionContext.getContext().getSession()
32 .put("password", getPassword());
33 return "success";
34 }
35 return "error";
36 }
37 }
编写ShowAction如例4-13所示。
例4-12 ShowAction.java
1 import com.opensymphony.xwork2.ActionSupport;
2 public class ShowAction extends ActionSupport {
3 private static final long serialVersionUID = 1L;
4 public String execute() {
5 return "success";
6 }
7 }
编写拦截器类LoginInterceptor如例4-14所示。
例4-13 LoginInterceptor.java
1 import java.util.Map;
2 import com.opensymphony.xwork2.Action;
3 import com.opensymphony.xwork2.ActionContext;
4 import com.opensymphony.xwork2.ActionInvocation;
5 import com.opensymphony.xwork2.interceptor.AbstractInterceptor;
6 public class LoginInterceptor extends AbstractInterceptor {
7 private static final long serialVersionUID = 1L;
8 @Override
9 public String intercept(ActionInvocation invocation)
10 throws Exception {
11 // 取得请求相关的ActionContext实例
12 ActionContext ctx = invocation.getInvocationContext();
13 Map session = ctx.getSession();
14 String user = (String) session.get("user");
15 // 如果没有登陆,或者登陆所有的用户名不是root,都返回重新登陆
16 if (user != null && user.equals("root")) {
17 return invocation.invoke();
18 }
19 ctx.put("tip", "你还没有登录");
20 return Action.LOGIN;
21 }
22 }
前台和后台代码都编写完成,还需要编写struts.xml配置文件,如例4-15所示。
例4-14 struts.xml
1 <?xml version="1.0" encoding="UTF-8"?>
2 <!DOCTYPE struts PUBLIC
3 "-//Apache Software Foundation//DTD Struts
4 Configuration 2.5//EN"
5 "http://struts.apache.org/dtds/struts-2.5.dtd">
6 <struts>
7 <package name="authority" extends="struts-default">
8 <!-- 定义一个拦截器 -->
9 <interceptors>
10 <interceptor name="authority"
11 class="com.qianfeng.struts.action.LoginInterceptor">
12 </interceptor>
13 <!-- 拦截器栈 -->
14 <interceptor-stack name="mydefault">
15 <interceptor-ref name="defaultStack" />
16 <interceptor-ref name="authority" />
17 </interceptor-stack>
18 </interceptors>
19 <!-- 定义全局Result -->
20 <global-results>
21 <!-- 当返回login视图名时,转入/login.jsp页面 -->
22 <result name="login">
23 /login.jsp
24 </result>
25 </global-results>
26 <action name="loginform"
27 class="com.qianfeng.struts.action.LoginFormAction">
28 <result name="success">
29 /login.jsp
30 </result>
31 </action>
32 <action name="login"
33 class="com.qianfeng.struts.action.LoginAction">
34 <result name="success">
35 /welcome.jsp
36 </result>
37 <result name="error">
38 /login.jsp
39 </result>
40 <result name="input">
41 /login.jsp
42 </result>
43 </action>
44 <action name="show"
45 class="com.qianfeng.struts.action.ShowAction">
46 <result name="success">
47 /show.jsp
48 </result>
49 <!-- 使用此拦截器 -->
50 <interceptor-ref name="mydefault" />
51 </action>
52 </package>
53 </struts>
代码和配置文件编写完成,运行项目,在浏览器地址栏访问http://localhost:8080/struts2_04/welcome.jsp,如图4.6所示。
图4.6 welcome.jsp
点击"show",此时被拦截器拦截,跳转到登陆页面,如图4.7所示。
图4.7 login.jsp
此时如果输入的用户名不是root或者密码不是admin,则重新跳转回login.jsp页面,输入正确的用户名和密码后,成功登陆,跳转回welcome.jsp,如图4.8所示。
图4.8 welcome.jsp
此时再次点击"show",成功跳转到show.jsp页面,如图4.9所示。
图4.9 show.jsp
如上案例中,自定义拦截器通过验证用户名和密码是否正确,实现了页面访问的权限控制,关于拦截器还有更多的功能,需要读者在实践中不断尝试和挖掘。
4.4 本章小结
本章主要介绍了拦截器的知识,包括拦截器的配置和使用方法,然后介绍了自定义拦截器的开发和配置,最后根据自定义拦截器,完成了一个登陆权限控制的案例。
4.5 习题
1.填空题
(1) 拦截器就是 的一种实现策略。
(2) 是解决重复性问题的重要方式,它提供了更高层次的解耦和抽象,目标代码无须手动调用目标方法。
(3) 在 文件中定义了很多内置拦截器。
(4) 在实际开发中,经常需要在Action执行前同时执行多个拦截器,如用户登陆、登陆日志记录以及权限检查等,这时,可以把多个拦截器组成一个 。
(5) 开发自定义的拦截器除了可以通过实现Interceptor接口,还可以继承抽象拦截器类 。
3.思考题
(1) 请简述拦截器的意义。
(2) 请简述如何配置Struts2拦截器。
(3) 请说出至少三个Struts2的内置拦截器。
(4) 请简述什么是拦截器栈。
(5) 请简述如何自定义拦截器。
猜你喜欢
- 2024-11-04 【快学springboot】12.实现拦截器
- 2024-11-04 Spring Boot 中的拦截器和过滤器到底有什么区别?
- 2024-11-04 SpringBoot中的过滤器和拦截器有什么区别?
- 2024-11-04 为什么你写的拦截器注入不了Java bean?
- 2024-11-04 使用Spring Cloud Zuul实现过滤器或拦截器功能案例
- 2024-11-04 java服务-springboot拦截器实现用户登录Token及权限校验
- 2024-11-04 Spring框架功能分为哪些模块?(spring框架有哪几部分组成)
- 2024-11-04 高级码农Spring Boot实战进阶之过滤器、拦截器的使用
- 2024-11-04 轻量级 Java 权限认证框架Sa-Token初体验(五)
- 2024-11-04 一个拦截器和一个awk命令,秒查线上超时接口
你 发表评论:
欢迎- 最近发表
- 标签列表
-
- java反编译工具 (77)
- java反射 (57)
- java接口 (61)
- java随机数 (63)
- java7下载 (59)
- java数据结构 (61)
- java 三目运算符 (65)
- java对象转map (63)
- Java继承 (69)
- java字符串替换 (60)
- 快速排序java (59)
- java并发编程 (58)
- java api文档 (60)
- centos安装java (57)
- java调用webservice接口 (61)
- java深拷贝 (61)
- 工厂模式java (59)
- java代理模式 (59)
- java.lang (57)
- java连接mysql数据库 (67)
- java重载 (68)
- java 循环语句 (66)
- java反序列化 (58)
- java时间函数 (60)
- java是值传递还是引用传递 (62)
本文暂时没有评论,来添加一个吧(●'◡'●)