springboot自定义拦截器和自定义参数解析器HandlerMethodArgumentResolver,自定义注解实现客户端接口用户身份确认获取

说明

客户端的接口一般都是需要用户登录才能访问信息的,验证用户身份是否登录,获取用户信息。一般做法就是客户端把token存进header中,服务器查询token是否失效和正确(服务器存token可以存进redis中,也可以使用JWT),然后通过token获取用户信息并正常访问接口。

自定义拦截器

拦截器和过滤器的区别就不过多描述了,我的理解就是拦截器是在具体的方法层次(springmvc)拦截做逻辑处理,过滤器是针对请求做的逻辑处理,过滤器先于拦截器执行。

先自定义一个注解@ApiAuth,表示接口权限认证

/**
 * 自定义注解接口权限认证
 */
@Target(ElementType.METHOD)// 作用于方法上
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ApiAuth {

}

然后再自定义拦截器,需要继承HandlerInterceptorAdapter,里面有三个方法,我们就重写preHandle()方法,该方法会在控制器方法执行前执行。返回值为true走正常逻辑,false不再继续执行。

@Component
public class ApiAuthInterceptor extends HandlerInterceptorAdapter {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        if (handler instanceof HandlerMethod) {

            HandlerMethod handlerMethod = (HandlerMethod) handler;
            Method method = handlerMethod.getMethod();
            ApiAuth annotation = method.getAnnotation(ApiAuth.class);

            if (annotation != null) {
                String token = request.getHeader(Constants.AUTH_TOKEN);
                if (checkAuth(token)) {

                    return true;
                } else {
                    // 这里就是返回json数据,AjaxResult是我自定义的返回json数据的方法
                    AjaxResult ajaxResult = AjaxResult.error("没有权限,请登录!");
                    ServletUtils.renderString(response, JSON.marshal(ajaxResult));
                    return false;
                }
            } else {

                return true;
            }
        } else {

            return super.preHandle(request, response, handler);
        }
    }

    /**
     * 校验用户访问权限
     * @param token
     * @return
     */
    private boolean checkAuth(String token) {

        // 可以使用redis存取token,判断token值是否有效
        // 也可以用JWT存取token       
        
        if (token) {// 判断token是否有效,自己写方法实现
            return false;
        }

        return true;
    }


}

自定义参数解析器

先自定义取值标签@UserInfo,用于根据token取值

/**
 * 自定义注解获取用户信息
 * 作用于方法里的参数上面
 * 用于获取的用户的信息,如果是long,则获取userId,如果是User对象,则获取用户对象
 */
@Target(ElementType.PARAMETER)// 作用于方法里的参数上
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface UserInfo {
}

自定义参数解析器,实现HandlerMethodArgumentResolver,url请求进来走完拦截器后会在进入方法前执行supportsParamet()方法。

public class UserInfoHandlerMethodArgumentResolver implements HandlerMethodArgumentResolver {

    /**
     * url请求进来后走完其他一些拦截器等之后会在进入方法之前执行supportsParameter依次传入要请求方法的参数
     * @param methodParameter
     * @return
     */
    @Override
    public boolean supportsParameter(MethodParameter methodParameter) {
        if (methodParameter.hasParameterAnnotation(UserInfo.class)) {
            return true;
        }
        return false;
    }

    /**
     * supportsParameter()返回值为true时,会执行本方法
     * @param methodParameter
     * @param modelAndViewContainer
     * @param nativeWebRequest
     * @param webDataBinderFactory
     * @return
     * @throws Exception
     */
    @Override
    public Object resolveArgument(MethodParameter methodParameter, ModelAndViewContainer modelAndViewContainer, NativeWebRequest nativeWebRequest, WebDataBinderFactory webDataBinderFactory) throws Exception {
        HttpServletRequest request = nativeWebRequest.getNativeRequest(HttpServletRequest.class);

        String token = request.getHeader(Constants.AUTH_TOKEN);
        System.out.println("parameter:" + token);
        Class parameterType = methodParameter.getParameterType();
        if (parameterType.isAssignableFrom(SysUser.class)) {
            SysUser user = new SysUser();
            user.setUserId(1L);
            user.setUserName("昂克");

            return user;
        } else if (parameterType.isAssignableFrom(Long.class)) {
            // getUserId(token)
            Long userId = 1L;

            return userId;
        }

        return null;
    }
}

springboot配置自定义拦截器和参数解析器

@Configuration
public class ResourcesConfig implements WebMvcConfigurer
{
   
    @Autowired
    private ApiAuthInterceptor apiAuthInterceptor;

    /**
     * 自定义拦截规则
     */
    @Override
    public void addInterceptors(InterceptorRegistry registry)
    {
        registry.addInterceptor(apiAuthInterceptor).addPathPatterns("/**");
    }

    /**
     * 自定义参数解析器
     * @param resolvers
     */
    @Override
    public void addArgumentResolvers(List resolvers) {
        resolvers.add(new UserInfoHandlerMethodArgumentResolver());
    }
}

测试

@RestController()
@RequestMapping("api")
public class ApiTestController extends BaseController {

    @ApiAuth
    @GetMapping("test")
    public AjaxResult test(@UserInfo Long id, @UserInfo SysUser user) {
        Map map = new HashMap();
        map.put("id", id);
        map.put("user", user);

        return success(map);
    }

}

 

你可能感兴趣的:(Java,springboot,springboot,拦截器,自定义注解,自定义注解设置参数)