拦截器的编写(十一)

本文详细介绍了在Struts2.0中编写拦截器的两种方式,包括代码编写、配置步骤以及运行效果展示。同时,给出了一个具体例子,讲解如何拦截所有方法并配置全局跳转页面,以确保只有已登录用户才能访问特定方法。

	1. 编写拦截器,需要实现Interceptor接口,实现接口中的三个方法
		protected String doIntercept(ActionInvocation invocation) throws Exception {
			// 获取session对象
			User user = (User) ServletActionContext.getRequest().getSession().getAttribute("existUser");
			if(user == null){
				// 说明,没有登录,后面就不会执行了
				return "login";
			}
			return invocation.invoke();
		}
	
	2. 需要在struts.xml中进行拦截器的配置,配置一共有两种方式
		<!-- 定义了拦截器 第一种方式
		<interceptors>
			<interceptor name="DemoInterceptor" class="com.itheima.interceptor.DemoInterceptor"/>
		</interceptors>
		-->
		
		<!-- 第二种方式:定义拦截器栈 -->
		<interceptors>
			<interceptor name="DemoInterceptor" class="com.itheima.interceptor.DemoInterceptor"/>
			<!-- 定义拦截器栈 -->
			<interceptor-stack name="myStack">
				<interceptor-ref name="DemoInterceptor"/>
				<interceptor-ref name="defaultStack"/>
			</interceptor-stack>
		</interceptors>
		
		<action name="userAction" class="com.itheima.demo3.UserAction">
			<!-- 只要是引用自己的拦截器,默认栈的拦截器就不执行了,必须要手动引入默认栈 
			<interceptor-ref name="DemoInterceptor"/>
			<interceptor-ref name="defaultStack"/>
			-->
			
			<!-- 引入拦截器栈就OK -->
			<interceptor-ref name="myStack"/>
		</action>

一、方式一

1.1 代码

拦截器的代码:

package com.ken.interceptor;

import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.AbstractInterceptor;

/**
 * 编写简单的拦截器
 *
 */
public class DemeIncerceptor extends AbstractInterceptor {
	
	private static final long serialVersionUID = 6410603239475356232L;

	/**
	 * intercept用来拦截的
	 */
	@Override
	public String intercept(ActionInvocation invocation) throws Exception {
		System.out.println("Action方法执行之前...");

		// 执行下一个拦截器 拦截器
		String result = invocation.invoke();

		System.out.println("Action方法执行之后...");

		return result;
	}
}
目标Action
package com.ken.action3;

import com.opensymphony.xwork2.ActionSupport;

public class UserAction extends ActionSupport {

	@Override
	public String execute() throws Exception {
		System.out.println("我是Action, 我正常执行...");
		return NONE;
	}
}

1.2 配置

	<package name="demo3" namespace="/" extends="struts-default">
		<interceptors>
			<!-- 定义了拦截器 -->
			<interceptor name="demeIncerceptor" class="com.ken.interceptor.DemeIncerceptor" />
		</interceptors>
		<action name="userAction" class="com.ken.action3.UserAction">
			<!-- 只要是引用了自己的拦截器,默认栈的拦截器就不执行了,必须要手动引入默认栈 -->
			<interceptor-ref name="demeIncerceptor" />
			<interceptor-ref name="defaultStack" />
		</action>
	</package>


1.3 运行效果




二、方式二

2.1 代码

同上

2.2 配置

	<package name="demo3" namespace="/" extends="struts-default">
		<!-- 定义了拦截器
		<interceptors>
			<interceptor name="demeIncerceptor" class="com.ken.interceptor.DemeIncerceptor" />
		</interceptors>
		-->
		
		<!--第二种方式:定义拦截器栈 -->
		<interceptors>
			<interceptor name="demeIncerceptor" class="com.ken.interceptor.DemeIncerceptor"/>
			<!-- 定义拦截器栈 -->
			<interceptor-stack name="myStack">
				<interceptor-ref name="demeIncerceptor"/>
				<interceptor-ref name="defaultStack" />
			</interceptor-stack>
		</interceptors>
		
		<action name="userAction" class="com.ken.action3.UserAction">
			<!-- 只要是引用了自己的拦截器,默认栈的拦截器就不执行了,必须要手动引入默认栈 
			<interceptor-ref name="demeIncerceptor" />
			<interceptor-ref name="defaultStack" />
			-->
			
			<!-- 引入拦截器栈 -->
			<interceptor-ref name="myStack"/>
		</action>
	</package>

2.3 运行效果

同上

三、例子

需求:访问方法的时候都拦截一下,看看是不是已经登录。

我们可以拦截所有方法,除了登录方法。由于AbstractInterceptor会拦截所有方法,所以,我们选择MethodFilterInterceptor,它里面有excludeMethods 和includeMethods 。

3.1 拦截器编写

package com.ken.interceptor;

import org.apache.struts2.ServletActionContext;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.MethodFilterInterceptor;

public class UserInterceptor extends MethodFilterInterceptor {

	private static final long serialVersionUID = -597288551062770495L;

	/**
	 * 进行拦截的方法
	 */
	@Override
	protected String doIntercept(ActionInvocation invocation) throws Exception {
		// 获得session对象
		User user = ServletActionContext.getRequest().getSession().getAttribute("existUser");
		if (user == null) {
			// 说明,没有登录
			return "login";
		}

		// 放行
		return invocation.invoke();
	}
}

3.2 配置全局跳转页面

<global-results>标签配置全局的跳转页面


3.3 配置interceptor

		<interceptors>
			<interceptor name="userInterceptor" class="com.ken.interceptor.UserInterceptor"/>
		</interceptors>
	
		<global-results>
			<result name="login">/login.html</result>
		</global-results>
	
		<!-- 配置Action -->
		<action name="hello" class="com.ken.action.HelloAction" method="sayHello">
			<!-- 配置跳转的页面,路径的写法:在struts2框架中,不管是转发还是重定向都不用写项目名 -->
			<!-- name中的ok叫做逻辑视图名称 -->
			<result name="ok">/demo1/success.jsp</result>
			<interceptor-ref name="userInterceptor">
				<param name="excludeMethods">login</param>
			</interceptor-ref>
			<interceptor-ref name="defaultStack"/>
		</action>
这里的关键是interceptory-ref里面的excludeMethods。


### 在 Java 中使用 JWT 编写拦截器的示例 在 Java 项目中,可以使用 JWT(JSON Web Token)实现基于令牌的身份验证,并通过拦截器来验证每个请求中的 JWT 是否有效。以下是一个完整的示例,展示如何编写一个 JWT 拦截器[^1]。 #### 1. 添加依赖项 首先,在项目的 `pom.xml` 文件中添加必要的依赖项,例如 `jjwt` 库用于生成和解析 JWT。 ```xml <dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt</artifactId> <version>0.9.1</version> </dependency> ``` #### 2. 创建 JWT 工具类 创建一个工具类用于生成和解析 JWT。 ```java import io.jsonwebtoken.Claims; import io.jsonwebtoken.Jwts; import io.jsonwebtoken.SignatureAlgorithm; public class JwtUtil { private static final String SECRET_KEY = "secretKey"; public String generateToken(String username) { return Jwts.builder() .setSubject(username) .signWith(SignatureAlgorithm.HS256, SECRET_KEY.getBytes()) .compact(); } public Claims extractAllClaims(String token) { return Jwts.parser() .setSigningKey(SECRET_KEY.getBytes()) .parseClaimsJws(token) .getBody(); } } ``` #### 3. 实现拦截器 创建一个拦截器类,用于拦截 HTTP 请求并验证 JWT 的有效性。 ```java import org.springframework.stereotype.Component; import org.springframework.web.servlet.HandlerInterceptor; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @Component public class JwtInterceptor implements HandlerInterceptor { private final JwtUtil jwtUtil; public JwtInterceptor(JwtUtil jwtUtil) { this.jwtUtil = jwtUtil; } @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { String authHeader = request.getHeader("Authorization"); if (authHeader != null && authHeader.startsWith("Bearer ")) { String token = authHeader.substring(7); try { jwtUtil.extractAllClaims(token); // 解析 JWT 并验证其有效性 return true; // 如果解析成功,则继续处理请求 } catch (Exception e) { response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Invalid JWT Token"); return false; // 如果解析失败,则返回错误响应 } } else { response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Missing or invalid Authorization header"); return false; } } } ``` #### 4. 注册拦截器 在 Spring 配置类中注册自定义拦截器。 ```java import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @Configuration public class WebConfig implements WebMvcConfigurer { private final JwtInterceptor jwtInterceptor; @Autowired public WebConfig(JwtInterceptor jwtInterceptor) { this.jwtInterceptor = jwtInterceptor; } @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(jwtInterceptor) .addPathPatterns("/api/**") // 拦截以 /api 开头的所有请求 .excludePathPatterns("/api/auth/login"); // 排除登录接口 } } ``` #### 5. 测试拦截器 启动应用程序后,可以通过发送带有 `Authorization: Bearer <token>` 头部的请求来测试拦截器的功能。如果 JWT 无效或缺失,拦截器将返回 401 状态码。 --- ### 注意事项 - 确保 `SECRET_KEY` 是安全的,并且在生产环境中不硬编码[^2]。 - 可以扩展 `JwtUtil` 类以支持更多功能,例如设置令牌过期时间、刷新令牌等。 - 在拦截器中捕获所有可能的异常,以确保系统稳定性。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值