【springBoot】统一功能处理

拦截器

拦截器的实现

  1. 定义拦截器
  2. 把拦截器注册到项目中

定义拦截器:

@Component
@Slf4j
public class LoginInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        log.info("登录拦截器校验...");
        //返回true表示放行, 返回false 表示拦截
        HttpSession session = request.getSession();
        UserInfo userInfo = (UserInfo) session.getAttribute(Constants.SESSION_USER_KEY);
        if (userInfo!=null && userInfo.getId()>=0){
            return true;
        }
        response.setStatus(401);
        return false;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        log.info("目标方法执行后");
    }
}

注册拦截器:

@Configuration
public class WebConfig implements WebMvcConfigurer {
    @Autowired
    private LoginInterceptor loginInterceptor;
    private static List<String> excludePath = Arrays.asList("/user/login",
        "/css/**",
        "/js/**",
        "/pic/**",
        "/**/*.html",
        "/test/**");
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(loginInterceptor)
                .addPathPatterns("/**") // /** 表示所有方法添加拦截器
                .excludePathPatterns(excludePath);
    }
}
拦截路径 含义 举例
/* ⼀级路径 能匹配/user,/book,/login,不能匹配/user/login
/** 任意级路径 能匹配/user,/user/login,/user/reg
/book/* /book下的⼀级路径 能匹配/book/addBook,不能匹配/book/addBook/1,/book
/book/** /book下的任意级路径 能匹配/book,/book/addBook,/book/addBook/2,不能匹 配/user/login

统一数据格式返回

返回数据的格式:

@Data
public class Result {
    /**
     * 业务状态码
     */
    private ResultCode code;  //0-成功  -1 失败  -2 未登录
    /**
     * 错误信息
     */
    private String errMsg;
    /**
     * 数据
     */
    private T data;

    public static  Result success(T data){
        Result result = new Result();
        result.setCode(ResultCode.SUCCESS);
        result.setErrMsg("");
        result.setData(data);
        return result;
    }
    public static  Result fail(String errMsg){
        Result result = new Result();
        result.setCode(ResultCode.FAIL);
        result.setErrMsg(errMsg);
        result.setData(null);
        return result;
    }
    public static  Result fail(String errMsg,Object data){
        Result result = new Result();
        result.setCode(ResultCode.FAIL);
        result.setErrMsg(errMsg);
        result.setData(data);
        return result;
    }
    public static  Result unlogin(){
        Result result = new Result();
        result.setCode(ResultCode.UNLOGIN);
        result.setErrMsg("用户未登录");
        result.setData(null);
        return result;
    }
}

统一数据格式封装:

  1. 创建一个类,并添加@ControllerAdvice
  2. 实现ResponseBodyAdvice接口,并重写supports和beforelBodyWrite(统一对象就是此方法中实现的)
/**
 * 实现统一数据返回的保底类
 * 说明:在返回数据之前,检测数据的类型是否为统一的对象,如果不是,封装成统一的对象
 */
@ControllerAdvice
public class ResponseAdvice implements ResponseBodyAdvice {
    /**
     * 开关,如果是true才会调用beforeBodyWrite
     */
    @Override
    public boolean supports(MethodParameter returnType, Class converterType) {
        return true;
    }
    /**
     * 对数据格式进行效验和封装
     */
    @Autowired
    private ObjectMapper objectMapper;
    @SneakyThrows//异常抛出,相当于方法上throw一个异常
    @Override
    public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {
        //进行了统一对象的封装,直接返回body
        if (body instanceof Result){
            return body;
        }
        //字符串类型特殊处理。手动对其进行ajax类型的转化
        if (body instanceof String){
            return objectMapper.writeValueAsString(Result.success(body));
        }
        //未进行封装的对其进行统一封装
        return Result.success(body);
    }
}

统一异常处理

异常统一封装:

  1. 创建一个类,并在类上标识@ControllerAdvice
  2. 添加方法@ExceptionHandler来订阅异常

@ResponseBody,如果你在统一异常处理中没有使用@ResponseBody注解,并且返回的结果是一个普通的Java对象而不是响应体,可能会导致控制台循环输出的问题。这通常是因为Spring Boot尝试使用默认的ExceptionResolver去处理异常时,发现无法序列化返回的对象,而进入循环。

@ResponseBody
@Slf4j
@ControllerAdvice
public class ErrorHandler {
    @ExceptionHandler
    public Result excption(NullPointerException e){
        log.error("发生异常,e:{}",e);
        return Result.fail("NullPointerException异常,请联系管理员");
    }
    @ExceptionHandler
    public Result excption(ArithmeticException e){
        log.error("发生异常,e:{}",e);
        return Result.fail("ArithmeticException异常,请联系管理员");
    }
    @ExceptionHandler
    public Result excption(Exception e){
        log.error("发生异常,e:{}",e);
        return Result.fail("Exception异常,请联系管理员");
    }
}

如果后端返回的结果是String类型,当我们使用统一结果返回时,返回的是JSON字符串
conten-type是text/html,我们需要把他转为JSON
如果后端进行转换:

@RequestMapping(value = "/addBook", produces = "application/json")

produces = "application/json"表示HTTP响应的数据类型是application/json

你可能感兴趣的:(springboot,spring,boot,python,后端)