实体类 ,使用Validated 常用注解
package com.example.springbootmybatis.advice.domain;
import com.example.springbootmybatis.advice.validate.Phone;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotEmpty;
public class MyEntry {
@NotEmpty(message = "姓名不能为空")
private String name;
@Min(value = 1 , message = "age < 1 cat not allow")
private Integer age;
@Phone(message="手机号格式不对") //自定义注解校验
private String phone;
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
// @NotEmpty(message = "性别不能为空")
private Integer sex;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public Integer getSex() {
return sex;
}
public void setSex(Integer sex) {
this.sex = sex;
}
@Override
public String toString() {
return "RequestForm{" +
"name='" + name + '\'' +
", age=" + age +
", phone='" + phone + '\'' +
", sex=" + sex +
'}';
}
}
异常处理类
package com.example.springbootmybatis.advice.controllerAdvice;
import com.example.springbootmybatis.advice.customException.ParamException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.validation.BindException;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.HandlerMapping;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.nio.charset.Charset;
import java.sql.SQLException;
import java.util.HashSet;
import java.util.Objects;
import java.util.Set;
@RestControllerAdvice
public class ControllerExceptionHandleAdvice {
private final static Logger logger = LoggerFactory.getLogger(ControllerExceptionHandleAdvice.class);
@ExceptionHandler
public String handler(HttpServletRequest req, HttpServletResponse res, Exception e) {
logger.info("Restful Http请求发生异常...");
String msg;
if (e instanceof NullPointerException) {
logger.error("代码00:" + e.getMessage(), e);
msg = "发生空指针异常";
} else if (e instanceof IllegalArgumentException) {
logger.error("代码01:" + e.getMessage(), e);
msg = "请求参数类型不匹配";
} else if (e instanceof SQLException) {
logger.error("代码02:" + e.getMessage(), e);
msg = "数据库访问异常";
} else if (e instanceof BindException) {
BindingResult bindingResult = ((BindException) e).getBindingResult();
logger.error("BindException ===> " + bindingResult.getFieldError().getDefaultMessage());
msg = "输入有误:" + Objects.requireNonNull(bindingResult.getFieldError()).getDefaultMessage();
} else {
logger.error("代码99:" + e.getMessage(), e);
msg = "服务器代码发生异常,请联系管理员";
}
return handlerException(msg, req);
}
/**
* 拦截JSON参数校验
*/
@ResponseStatus(HttpStatus.OK)
@ExceptionHandler(MethodArgumentNotValidException.class)
public String bindException(MethodArgumentNotValidException e,HttpServletRequest req) {
logger.info("拦截JSON参数校验" + req.getContentType());
BindingResult bindingResult = e.getBindingResult();
FieldError fieldError = bindingResult.getFieldError();
logger.error("fieldError.getDefaultMessage()===> ", fieldError.getDefaultMessage());
return handlerException(fieldError.getDefaultMessage(), req);
}
/**
* 处理自定义异常
*/
@ResponseStatus(HttpStatus.OK)
@ExceptionHandler(ParamException.class)
public String bindException(ParamException e,HttpServletRequest req) {
logger.error("自定义异常", e);
return handlerException("错误", req);
}
/**
* 处理响应乱码问题
* @param req
* @return
*/
private String handlerException(String message, HttpServletRequest req){
Set<MediaType> mediaTypeSet = new HashSet<>();
MediaType mediaType = new MediaType("application", "json", Charset.forName("utf-8"));
mediaTypeSet.add(mediaType);
req.setAttribute(HandlerMapping.PRODUCIBLE_MEDIA_TYPES_ATTRIBUTE, mediaTypeSet);
//AbstractMessageConverterMethodProcessor#getProducibleMediaTypes springMVC这个方法会调用这个设置的参数。
return message;
}
}
测试Controller
package com.example.springbootmybatis.advice.controller;
import com.example.springbootmybatis.advice.customException.ParamException;
import com.example.springbootmybatis.advice.domain.MyEntry;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletResponse;
@RestController
// 处理乱码
@RequestMapping(produces = "application/json;charset=UTF-8")
public class TestController {
/**
* JSON请求
*/
@PostMapping("/jsonRequest")
public String jsonRequest(@Validated @RequestBody MyEntry entry, HttpServletResponse response){
// 业务逻辑处理
return entry.toString();
}
/**
* 测试自定义异常
*/
@GetMapping("/customException")
public String customException() throws Exception {
if (!false) {
throw new ParamException("自定义异常测试");
} // 业务逻辑处理
return "";
}
/**
* 测试自定义异常
*/
@GetMapping("/hz")
public String hz() throws Exception {
System.out.println("@GetMapping(/hz)");
return "乱码";
}
}
自定义校验注解类
package com.example.springbootmybatis.advice.validate;
import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.*;
/**
* 自定义参数校验注解,加在指定的需要校验的字段上
*/
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD,ElementType.PARAMETER})
@Constraint(validatedBy = PhoneValidator.class) //这里需要指定参数校验的具体实现类
public @interface Phone {
String message() default "号码错误";
// 固定模板
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
自定义校验匹配器
package com.example.springbootmybatis.advice.validate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import java.util.regex.Pattern;
public class PhoneValidator implements ConstraintValidator<Phone, String> {
private final static Logger logger = LoggerFactory.getLogger(PhoneValidator.class);
@Override
public boolean isValid(String s, ConstraintValidatorContext constraintValidatorContext) {
if (StringUtils.isEmpty(s)) {
return true;
}
String pattern = "^[1][3,4,5,7,8][0-9]{9}$";
return Pattern.matches(pattern, s);
}
}
自定义异常
package com.example.springbootmybatis.advice.customException; /** * 自定义异常类 */ public class ParamException extends RuntimeException{ private String code; public ParamException(String code) { this.code = code; } public ParamException(String code, Object message) { super(message.toString()); this.code = code; } public String getCode() { return this.code; } }
依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>