需求
前端向后台发起请求时,希望某些请求需要校验token,某些请求不需要校验token,而只要在方法上加上注解的,系统会自动的去校验token参数。同时,希望系统能自动的根据我们的业务代码抛出的异常类型,抓取后返回前端自定义的异常信息
- 注解类
@Documented
@Target({ElementType.TYPE,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Login
{
}
- 自定义拦截器类
@Component
public class BaseHandlerInterceptor implements HandlerInterceptor
{
@Autowired
RequestMappingHandlerMapping handlerMapping;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception
{
return hasPermission(handler,request);
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)
throws Exception
{
}
@Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
throws Exception
{
}
private boolean hasPermission(Object handler,HttpServletRequest req) {
if (handler instanceof HandlerMethod) {
HandlerMethod handlerMethod = (HandlerMethod) handler;
// 获取方法上的注解
Login login = handlerMethod.getMethod().getAnnotation(Login.class);
// 如果方法上的注解为空 则获取类的注解
if (login == null) {
login = handlerMethod.getMethod().getDeclaringClass().getAnnotation(Login.class);
}
// 如果标记了注解,则判断权限
if (login != null) {
String token = req.getParameter("token");
if(token==null){
AssertUtils.INSTANCE.isTrue(false,"token值为空,请求服务失败");
}
if(!token.equals("45678")){
AssertUtils.INSTANCE.isTrue(false,"token校验失败");
}
}
}
return true;
}
}
- 拦截器配置类
@Configuration
public class MVCConfig implements WebMvcConfigurer
{
@Autowired
BaseHandlerInterceptor baseHandlerInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry)
{
registry.addInterceptor(baseHandlerInterceptor).addPathPatterns("/**");
}
}
- springboot 启动类
@Configuration
@EnableAutoConfiguration
@ComponentScan("com.ppamos.controller")
@ComponentScan("com.ppamos.Dispatcher")
@ComponentScan("com.ppamos.annoatations")
@ComponentScan("com.ppamos.exceptionDeal")
@ComponentScan("com.ppamos.config")
public class MyApplication {
public static void main(String[] args) throws Exception {
SpringApplication.run(MyApplication.class, args);
}
}
- 自定义异常类
public class BusinessException extends RuntimeException
{
public BusinessException(){
super();
}
public BusinessException(String msg){
super(msg);
}
public BusinessException(String msg, Throwable cause){
super(msg,cause);
}
}
- 全局异常处理类
@ControllerAdvice
@ResponseBody
public class GlobalExceptionHandler
{
//运行时异常
@ExceptionHandler(RuntimeException.class)
public Object runtimeExceptionHandler(RuntimeException ex) {
MobRes mobRes = new MobRes();
mobRes.setCode(ResponseCode.SERVER_EXCEPTION.getCode());
mobRes.setMsg(ResponseCode.SERVER_EXCEPTION.getDesc());
return mobRes;
}
@ExceptionHandler(BusinessException.class)
public Object businessExceptionHandler(BusinessException ex) {
MobRes mobRes = new MobRes();
mobRes.setCode(ResponseCode.SERVER_EXCEPTION.getCode());
mobRes.setMsg(ex.getMessage());
return mobRes;
}
}
- 断言工具类
public enum AssertUtils
{
//单例模式
INSTANCE;
public void isTrue(boolean b,String msg) throws BusinessException
{
if(b==false){
throw new BusinessException(msg);
}
}
}
- 返回码类
public class MobRes
{
private int code; //返回码
private String msg; //消息提示
public MobRes(){
this.code=ResponseCode.SUCCESS.getCode();
this.msg=ResponseCode.SUCCESS.getDesc();
}
public int getCode()
{
return code;
}
public void setCode(int code)
{
this.code = code;
}
public String getMsg()
{
return msg;
}
public void setMsg(String msg)
{
this.msg = msg;
}
}
public class CommonMobRes<T> extends MobRes
{
public CommonMobRes(T result){
this.result=result;
}
private T result;
public T getResult()
{
return result;
}
public void setResult(T result)
{
this.result = result;
}
}
public enum ResponseCode
{
SUCCESS(100, "处理成功"),
SERVER_EXCEPTION(900, "服务器异常,请您稍后访问!"),;
private Integer code;
private String desc;
ResponseCode(Integer code,String desc){
this.code=code;
this.desc=desc;
}
public Integer getCode(){
return code;
}
public String getDesc(){
return desc;
}
}
- controller类
@RestController
public class TestController {
@Autowired
private HandlerDispatcherServlet handlerDispatcherServlet;
@RequestMapping("/test")
public CommonMobRes test(@RequestParam int cmd){
return new CommonMobRes<Object>(handlerDispatcherServlet.handle(cmd));
}
@Login
@RequestMapping("/test1")
public CommonMobRes test1(@RequestParam int cmd,@RequestParam String token){
return new CommonMobRes<Object>(handlerDispatcherServlet.handle(cmd));
}
}
- 最终结果
请求1:localhost:8081/test?cmd=1
结果:
{
"code": 100,
"msg": "处理成功",
"result": "handle register request"
}
请求2:localhost:8081/test1?cmd=1
结果:
{
"code": 900,
"msg": "token值为空,请求服务失败"
}
请求3:localhost:8081/test1?cmd=1&&token=1234
结果:
{
"code": 900,
"msg": "token校验失败"
}
请求4:localhost:8081/test1?cmd=1&&token=45678
结果:
{
"code": 100,
"msg": "处理成功",
"result": "handle register request"
}
网友评论