最近使用SpringBoot2.X搭建了一个项目,大部分接口都须要作登陆校验,因此打算使用注解+拦截器来实现,在此记录下实现过程。java
1、实现原理web
1. 自定义一个注解@NeedLogin,若是接口须要进行登陆校验,则在接口方法或类方法上添加该注解。
2. 登陆拦截器LoginInterceptor校验接口的方法或类上是否有@NeedLogin注解,有注解则进行登陆校验。spring
2、主要代码session
1. NeedLogin注解代码app
package com.example.helloSpringBoot.annotation; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * 登陆注解 * * @Author: Java碎碎念 */ @Target({ElementType.METHOD, ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) public @interface NeedLogin { }
2. 登陆拦截器LoginInterceptoride
package com.example.helloSpringBoot.config; import com.example.helloSpringBoot.annotation.NeedLogin; import com.example.helloSpringBoot.util.WxUserInfoContext; import org.springframework.lang.Nullable; import org.springframework.stereotype.Component; import org.springframework.web.method.HandlerMethod; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * 登陆拦截器 * * @Author: Java碎碎念 */ @Component public class LoginInterceptor implements HandlerInterceptor { //这个方法是在访问接口以前执行的,咱们只须要在这里写验证登录状态的业务逻辑,就能够在用户调用指定接口以前验证登录状态了 public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { if (handler instanceof HandlerMethod) { NeedLogin needLogin = ((HandlerMethod) handler).getMethodAnnotation(NeedLogin.class); if (null == needLogin) { needLogin = ((HandlerMethod) handler).getMethod().getDeclaringClass() .getAnnotation(NeedLogin.class); } // 有登陆验证注解,则校验登陆 if (null != needLogin) { WxUserInfoContext curUserContext = (WxUserInfoContext) request.getSession() .getAttribute("curUserContext"); //若是session中没有,表示没登陆 if (null == curUserContext) { response.setCharacterEncoding("UTF-8"); response.getWriter().write("未登陆!"); return false; } } } return true; } public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception { } public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception { } }
3. 配置拦截器post
package com.example.helloSpringBoot.config; 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; /** * WebConfig * * @Author: Java碎碎念 * */ @Configuration public class WebConfig implements WebMvcConfigurer { @Autowired private LoginInterceptor loginInterceptor; @Override public void addInterceptors(InterceptorRegistry registry) { // 自定义拦截器,添加拦截路径和排除拦截路径 registry.addInterceptor(loginInterceptor).addPathPatterns("/**"); } }
3、验证代码测试
HelloController中添加两个方法,testNeedLogin()方法添加登陆拦截,testNoLogin()方法不须要登陆拦截。blog
package com.example.helloSpringBoot.controller; import com.example.helloSpringBoot.annotation.NeedLogin; import org.springframework.web.bind.annotation.CrossOrigin; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class HelloController { /** * 测试不 须要登陆 * * */ @RequestMapping("/testNoLogin") public String testNoLogin (){ return "调用成功,此接口不须要登陆校验!-Java碎碎念!"; } /** * 测试须要登陆 * * */ @NeedLogin @RequestMapping("/testNeedLogin") public String testNeedLogin (){ return "testNeedLogin!"; } }
testNeedLogin运行截图以下:接口
testNoLogin运行截图以下:
上述三步操做完成后便可实现登陆拦截