1. 介绍
1.1 什么是拦截器(Interceptor)?
Java里的拦截器是动态拦截Action
调用的对象,它提供了一种机制可以使开发者在一个Action
执行的前后执行一段代码,也可以在一个Action
执行前阻止其执行,同时也提供了一种可以提取Action
中可重用部分代码的方式。拦截器(Interceptor
)同过滤器(Filter
)一样,都是面向切面编程(AOP
)的具体实现。
1.2 自定义拦截器使用步骤
- 第一步: 自定义一个实现了Interceptor接口的类,或者继承抽象类AbstractInterceptor。
- 第二步: 在配置文件中注册定义的拦截器,拦截指定规则的请求
2. 基于URL拦截
2.1 创建登录拦截器
新建文件: LoginVerifyInterceptor.java
继承HandlerInterceptorAdapter
抽象类
package com.hui.javalearn.common;
import com.hui.javalearn.common.enums.ResultEnum; import com.hui.javalearn.exception.ApiException; import com.hui.javalearn.service.TokenService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse;
public class LoginVerifyInterceptor extends HandlerInterceptorAdapter {
@Autowired private TokenService tokenService;
@Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) { String requestURI = request.getRequestURI(); if (isValidateUri(requestURI)) { String token = request.getHeader("TOKEN"); String uid = request.getHeader("UID"); if (!tokenService.verifyToken(uid,token)) { throw new ApiException(ResultEnum.ERROR_TOKEN_ERROR); } } return true; }
private Boolean isValidateUri(String uri){ boolean isValidateUri = true; String[] filterPathRule = { "(/user/(.*)login)|(/user/register)", "(/swagger-resources)|(/swagger-resources/(.*))|(/doc.html)|(/(.*)/bycdao-ui/(.*))", "(/error)", "((.*).css)|((.*).js)|((.*).html)|((.*).jpg)", }; for (String rule : filterPathRule) { if (uri.toLowerCase().matches(rule)) { isValidateUri = false; break; } } return isValidateUri; } }
|
拦截器方法介绍
preHandle
:用于在将请求发送到控制器( Controller
)之前执行操作。此方法应返回true
,以将响应返回给客户端。
postHandle
:方法在当前请求处理完成之后,也就是 Controller
方法调用之后执行,但是它会在DispatcherServlet
进行视图返回渲染之前被调用,所以我们可以在这个方法中对 Controller
处理之后的 ModelAndView
对象进行操作。
afterCompletion
:在DispatcherServlet
完全处理完请求后被调用,可用于清理资源等。返回处理(已经渲染了页面);
2.2 注册登录拦截器
新建文件: InterceptorConfig
package com.hui.javalearn.config;
import com.hui.javalearn.common.LoginVerifyInterceptor; import org.springframework.context.annotation.Bean; 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 InterceptorConfig implements WebMvcConfigurer {
@Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(VerifyInterceptor()).addPathPatterns("/**"); }
@Bean public LoginVerifyInterceptor VerifyInterceptor(){ return new LoginVerifyInterceptor(); } }
|
到此基于URL的拦截器就完成了!
3. 基于注解拦截
3.1 创建注解
新建自定义注解: LoginRequired.java
package com.hui.javalearn.tools.annotation;
import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target;
@Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface LoginRequired {
}
|
3.2 创建拦截器
新建文件: LoginAnnotationInterceptor.java
package com.hui.javalearn.common;
import com.hui.javalearn.common.enums.ResultEnum; import com.hui.javalearn.exception.ApiException; import com.hui.javalearn.service.TokenService; import com.hui.javalearn.tools.annotation.LoginRequired; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.method.HandlerMethod; import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.lang.reflect.Method;
public class LoginAnnotationInterceptor extends HandlerInterceptorAdapter { @Autowired private TokenService tokenService;
@Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) { if (! (handler instanceof HandlerMethod)){ return false; } HandlerMethod handlerMethod = (HandlerMethod) handler; Method method = handlerMethod.getMethod(); LoginRequired annotation = method.getAnnotation(LoginRequired.class); if (annotation != null) { String token = request.getHeader("TOKEN"); String uid = request.getHeader("UID"); if (!tokenService.verifyToken(uid,token)) { throw new ApiException(ResultEnum.ERROR_TOKEN_ERROR); } } return true; } }
|
3.3 注册拦截器
package com.hui.javalearn.config;
import com.hui.javalearn.common.LoginAnnotationInterceptor; import org.springframework.context.annotation.Bean; 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 InterceptorConfig implements WebMvcConfigurer {
@Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(LoginVerifyByAnnotation()).addPathPatterns("/**");
}
@Bean public LoginAnnotationInterceptor LoginVerifyByAnnotation(){ return new LoginAnnotationInterceptor(); } }
|
3.5 使用
package com.hui.javalearn.controller;
import com.hui.javalearn.common.ResponseResult; import com.hui.javalearn.common.enums.ResultEnum; import com.hui.javalearn.dto.response.UserResponse; import com.hui.javalearn.model.UserModel; import com.hui.javalearn.service.UserService; import com.hui.javalearn.tools.annotation.LoginRequired; import com.hui.javalearn.tools.annotation.Phone; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*;
@RestController @Api(tags = "用户模块") @RequestMapping("/user") @Validated @Slf4j public class UserController { @Autowired private UserService userService;
@ApiOperation("查询用户") @PostMapping("/getUser") @LoginRequired public ResponseResult<UserResponse> getUser(@Phone @RequestParam(value = "phone") String phone) { try { UserModel userModel = userService.searchUserByPhone(phone); UserResponse userResponse = UserResponse.model2Response(userModel); return ResponseResult.success(userResponse); } catch (Exception e) { return ResponseResult.error(ResultEnum.ERROR.getCode(), e.getMessage()); } } }
|