前言
本人在学习Spring Boot 2.x基础教程:JSR-303实现请求参数校验教程时,
发现按照此教程编码下来,结果不一致,教程中是可以直接返回校验不合格具体的字段信息的,
而本人的却不返回信息,经过研究发现是SpringBoot2的版本不一致导致的;
下面是本人的SpringBoot2的环境信息
一、SpringBoot2的版本
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.6.7</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
这个版本是需要添加校验依赖的
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
目的是引入这个依赖
<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId>
<version>6.2.3.Final</version>
<scope>compile</scope>
</dependency>
二、环境
package com.chenheng.controller;
import com.chenheng.global.R;
import com.chenheng.pojo.User;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.validation.Valid;
import java.util.HashMap;
import java.util.Map;
/**
* @author chenheng
* @date 2022/5/3 15:59
*/
@RequestMapping("/users")
@RestController
public class UserController {
@PostMapping("/addUser")
public R addUser(@Valid @RequestBody User user){
Map<Long, User> map = new HashMap<>();
map.put(user.getId(), user);
return R.success();
}
}
三、现象
这里发现没有得到想要的提示
四、解决办法
4.1、统一异常处理-GlobalExceptionHandler
SpringBoot统一异常处理参考:
统一异常处理
这里需要特别注意一下:
@RestControllerAdvice这个注解,等同于@ControllerAdvice和@ResponseBody
@RestControllerAdvice只需要放在类上,而类上若使用@ControllerAdvice,则方法上必须要使用@ResponseBody
在这里稍不注意,就进坑了。
出坑参考链接:Springboot捕获全局异常:MethodArgumentNotValidException
参考@RestControllerAdvice与@ControllerAdvice的区别
其实类似于@RestController和@Controller的区别
参考@RestController 和 @Controller 的区别
package com.chenheng.exception;
import com.chenheng.global.R;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.BindingResult;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException;
import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;
/**
* @author chenheng
* @date 2022/5/3 16:13
* 统一异常处理
*/
@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(value = HttpRequestMethodNotSupportedException.class)
public R handleValidException(HttpRequestMethodNotSupportedException exception, HttpServletRequest req) {
log.error("HttpRequestMethodNotSupportedException{},{},{}",
exception.getClass(),
exception.getMessage(),
req.getRequestURI());
return R.error();
}
@ExceptionHandler(value = MethodArgumentNotValidException.class)
public R handleValidException(MethodArgumentNotValidException exception) {
log.error("数据校验异常,异常类型{},出现问题{}", exception.getClass(), exception.getMessage());
Map<String, String> map = new HashMap<>();
BindingResult bindingResult = exception.getBindingResult();
bindingResult.getFieldErrors().forEach(fieldError -> {
map.put(fieldError.getField(), fieldError.getDefaultMessage());
});
return R.error(map);
}
@ExceptionHandler(value = MethodArgumentTypeMismatchException.class)
public R handleValidException(MethodArgumentTypeMismatchException exception) {
log.warn("参数类型错误", exception);
return R.error(R.CommonCode.ERROR, "参数类型错误");
}
@ExceptionHandler(value = BizException.class)
public R handleBizException(BizException e) {
log.warn(e.getMessage());
return R.error(R.CommonCode.ERROR, e.getMessage());
}
@ExceptionHandler(value = Throwable.class)
public R handleException(Throwable throwable) {
log.error("未知异常",throwable);
return R.error(R.CommonCode.ERROR,R.CommonMessage.ERROR);
}
}
4.2、返回类-R
package com.chenheng.global;
import org.slf4j.MDC;
/**
* @author chenheng
* @date 2022/5/4 9:19
*/
public class R<T> {
// 通用的状态码
public abstract class CommonCode {
public static final String SUCCESS = "0"; // 获取数据成功状态码
public static final String ERROR = "1"; // 请求失败
public static final String IS_EXIST = "10000"; // 数据已存在
public static final String INVALID_TOKEN = "20000"; // token有误
public static final String PARAM_ERROR = "20001"; // 参数传递错误状态码
public static final String NO_DATA = "20002"; //没有数据
public static final String RESULT_DUPLICATE = "20003";//重复提交
public static final String DELETE_FAILE = "20004";//删除失败
public static final String POINT_EXCEED_LIMIT = "20005"; //预置位已用完
public static final String NO_PRIVILEGE = "20006"; //没有权限
public static final String NO_SUPPORT = "20007"; //不支持
}
// 通用的消息
public abstract class CommonMessage {
public static final String SUCCESS = "SUCCESS"; // 获取数据成功
public static final String ERROR = "ERROR"; // 请求失败
public static final String IS_EXIST = "IS_EXIST";
public static final String INVALID_TOKEN = "INVALID_TOKEN"; // token有误
public static final String PARAM_ERROR = "PARAM_ERROR"; // 参数传递错误
}
public R() {}
private Boolean isError;
private T data;
private String code;
private String message;
private String requestId;
public Boolean getIsError() {
return isError;
}
public void setIsError(Boolean isError) {
this.isError = isError;
}
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public R(Boolean isError, T data, String code, String message) {
this.isError = isError;
this.data = data;
this.code = code;
this.message = message;
}
public static<T> R<T> getInstance(Boolean isError, T data, String code, String message){
return new R<T>(isError, data, code, message);
}
public static<T> R<T> invalidToken(){
return getInstance(true, null, R.CommonCode.INVALID_TOKEN, R.CommonMessage.INVALID_TOKEN);
}
public static<T> R<T> paramError(){
return getInstance(true, null, R.CommonCode.PARAM_ERROR, R.CommonMessage.PARAM_ERROR);
}
public static<T> R<T> success(){
return getInstance(false, null, R.CommonCode.SUCCESS, R.CommonMessage.SUCCESS);
}
public static<T> R<T> success(T data){
return getInstance(false, data, R.CommonCode.SUCCESS, R.CommonMessage.SUCCESS);
}
public static<T> R<T> success(String code, String message, T data){
return getInstance(false, data, code, message);
}
public static<T> R<T> error(){
return getInstance(true, null, R.CommonCode.ERROR, R.CommonMessage.ERROR);
}
public static<T> R<T> error(String code, String message){
return getInstance(true, null, code,message);
}
public static<T> R<T> error(T data){
return getInstance(true, data, R.CommonCode.ERROR, R.CommonMessage.ERROR);
}
public static<T> R<T> error(String code, String message,T data){
return getInstance(true, data, code,message);
}
public String getRequestId(){
return MDC.get("TRACE_ID");
}
}