Spring拦截器 全局异常处理 token验证 限制方法访问时间 (多种玩法)

目录

1. 配置全局拦截器(实现handlerInterceptor) 

-> 应用场景一 (token 验证) 

-> 应用场景二: 限制访问时间(不在规定时间内不能访问)

 spring中添加拦截配置(实现WebMvcConfigurer)

简化方法 ,使用注解放行路径

在拦截器interceptor中添加一段代码 

 注意 测试的时候如果出现问题,放行这两个路径后再试

随便写一个方法测试

2. 其他玩法(拦截器写全局, spring配置类写特殊路径):

组合参数解释:

addPathPatterns("/provider/*"): 

excludePathPatterns:  

 全局异常处理


设计:

设置限制时间这种业务逻辑, 应该放到配置中心或者控制台中

1. 配置全局拦截器(实现handlerInterceptor) 

放行规则 interceptor 全部路径放行(前提 拦截器返回true)

-> 应用场景一 (token 验证) 

注意: 解析jwt( 这块暂时不记录, 等待链接)

-> 应用场景二: 限制访问时间(不在规定时间内不能访问)

注意: 其中Io操作建议封装 <----这有句话

package com.jt.provider.inceptor;

import com.alibaba.fastjson.JSON;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;
import java.time.LocalTime;
import java.util.HashMap;
import java.util.Map;

/**
 * @Author pzy
 * @Version 0.1.0
 */
public class TimeAccessInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request,
                             HttpServletResponse response,
                             Object handler) throws Exception {

        LocalTime now = LocalTime.now();//jdk1.8中的对象
        int hour = now.getHour();
        System.out.println(hour);


        //全局拦截器这么写
        String requestURI = request.getRequestURI();
        if ("/provider/sentinel01".equals(requestURI)) {
            if (hour<=10||hour>=14){
                  response.setContentType("application/json");
                  response.setCharacterEncoding("utf-8");
                PrintWriter out = response.getWriter();


                Map map = new HashMap<>();
                map.put("status",500);
                map.put("msg","请勿在此时间段访问,10-16点访问");
                map.put("data",null);

                String jsonStr = new ObjectMapper().writeValueAsString(map);

                out.println(jsonStr);
                out.flush();
                out.close();

                return false;
            }
            return true;
        }

        if(hour<=6||hour>=22)throw new RuntimeException("请在6~10点进行访问");

        return true;
    }
}

 spring中添加拦截配置(实现WebMvcConfigurer)

package com.jt.provider.inceptor.config;

import com.jt.provider.inceptor.TimeAccessInterceptor;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

/**
 * @Author pzy
 * @Version 0.1.0
 */
@Configuration
public class SpringWebConfig implements WebMvcConfigurer {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new TimeAccessInterceptor())
                .addPathPatterns("/**");
    }
}

 上述的拦截全部路径, 单独放行某一路径非常好用.有uri(需要的 直接返回true)

简化方法 ,使用注解放行路径

/**
 * @Author pzy
 * @Version 0.1.0
 *
 * 特权放行路径注解 痛苦一次 舒服
 */
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface PrivilegeCross {

    String value() default "";

}

在拦截器interceptor中添加一段代码 

解释: 添加注解处理逻辑, 这块咋玩都行 

        try {
            HandlerMethod handlerMethod = (HandlerMethod) handler;
            Method method = handlerMethod.getMethod();
            PrivilegeCross annotation = method.getAnnotation(PrivilegeCross.class);
            if (Objects.nonNull(annotation)) {
                return true;
            }
        } catch (ClassCastException e) {

            log.error("ClassCastException error!!!");
          
        }catch (Exception e){
            e.printStackTrace();
        }

 注意 测试的时候如果出现问题,放行这两个路径后再试

(正常不会出现这个问题)

(拦截器中填写, 返回true表示直接放行)

if("/favicon.ico".equals(requestURI))return true;

if("/error".equals(requestURI))return true;

随便写一个方法测试

    @PrivilegeCross(value = "放行路径测试!!!")
    @GetMapping("/runScheduleMethod")
    public SystemResult runScheduleMethod() { 

        return null;

    }

 拦截器放行即为成功

2. 其他玩法(拦截器写全局, spring配置类写特殊路径):

实战中用到的:  在数据库中直接写路径(对应权限id, 更加直接的限制用户操作,更能分不同路径进行统一处理, 当然aop/filter都可以)

(全局的拦截器配置,局部的路径拦截)

package com.jt.provider.inceptor;

import com.alibaba.fastjson.JSON;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;
import java.time.LocalTime;
import java.util.HashMap;
import java.util.Map;

/**
 * @Author pzy
 * @Version 0.1.0
 */
public class TimeAccessInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request,
                             HttpServletResponse response,
                             Object handler) throws Exception {

        LocalTime now = LocalTime.now();//jdk1.8中的对象

        int hour = now.getHour();
        int minute = now.getMinute();
        int second = now.getSecond();
        System.out.println("现在是: --->"+hour+":"+minute+":"+second);
        //souf

        if(hour<=6||hour>=15)throw new RuntimeException("请在6~10点进行访问");

        return true;
    }
}

spring拦截器配置

package com.jt.provider.inceptor.config;

import com.jt.provider.inceptor.TimeAccessInterceptor;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;

/**
 * @Author pzy
 * @Version 0.1.0
 */
@Configuration
public class SpringWebConfig implements WebMvcConfigurer {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {

        List list = new CopyOnWriteArrayList<>();
        list.add("/provider/sentinel01");
        list.add("/provider/sentinel02");

        registry.addInterceptor(new TimeAccessInterceptor())
                .addPathPatterns("/provider/*")
                //.excludePathPatterns("/provider/sentinel01")
                .excludePathPatterns(list)
        ;
    }
}

组合参数解释:

addPathPatterns("/provider/*"): 

             provider路径下的全部路径都需要走拦截器

excludePathPatterns:  

             放行list集合中的路径(可以写一个,也可以写多个, 这块也可以从数据库中查出来放行路径) 


 全局异常处理(这块仔细写,前面抛出的异常可以省略写)

package com.jt.provider.exception;

import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.RestControllerAdvice;

/**
 * @Author pzy
 * @Version 0.1.0
 * 全局异常处理
 */
@RestControllerAdvice
public class AllExceptionHandler {

    @ExceptionHandler({RuntimeException.class})
    public String ExceptionHandler(Exception e) {
        System.out.println("我是全局异常处理");
        e.printStackTrace();
        return "==> 我是全局异常处理 <===" + e.getMessage();
    }
}

你可能感兴趣的:(nacos,spring,java,后端)