全局异常处理
GlobalException.java --RuntimeException
继承自运行时异常,直接抛出,不需要try catch
package com.example.miaosha.exception;
import com.example.miaosha.vo.RespBeanEnum;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class GlobalException extends RuntimeException {
private RespBeanEnum respBeanEnum;
}
GlobalExceptionHandler.java @ExceptionHandler
筛选异常的类型实例,对应处理异常
Exception
GlobalException
BindException
package com.example.miaosha.exception;
import com.example.miaosha.vo.RespBean;
import com.example.miaosha.vo.RespBeanEnum;
import org.springframework.validation.BindException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(Exception.class)
public RespBean ExceptionHandler(Exception e){
if(e instanceof GlobalException){
GlobalException ex=(GlobalException) e;
return RespBean.error(ex.getRespBeanEnum());
}else if(e instanceof BindException){
BindException ex=(BindException)e;
RespBean respBean = RespBean.error(RespBeanEnum.BIND_ERROR);
respBean.setMessage("参数校验异常:"+ex.getBindingResult().getAllErrors().get(0).getDefaultMessage());
return respBean;
}
return RespBean.error(RespBeanEnum.ERROR);
}
}
使用方法 UserServiceImpl.doLgoin()
//根据手机号获取用户
User user = userMapper.selectById(mobile);
if(user==null){
//return RespBean.error(RespBeanEnum.LOGIN_ERROR);
throw new GlobalException(RespBeanEnum.LOGIN_ERROR);
}
spring-validation扩展 @IsMobile
http://localhost:8080/login/toLogin
登录提交表单时,前端通过js参数校验后,通过ajax或者post请求提交,后端还需要重新校验一遍
用spring-validation,可以简化校验,同时可以自己添加校验规则
这里举例通过正则表达式,校验手机号格式
LoginVo.java
package com.example.miaosha.vo;
import com.example.miaosha.validator.IsMobile;
import lombok.Data;
import org.hibernate.validator.constraints.Length;
import javax.validation.constraints.NotNull;
@Data
public class LoginVo {
@NotNull
@IsMobile
private String mobile;
@NotNull
@Length(min = 32)
private String password;
}
@interface IsMobile.java
package com.example.miaosha.validator;
import com.example.miaosha.vo.IsMobileValidator;
import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.*;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR, ElementType.PARAMETER, ElementType.TYPE_USE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Constraint(
validatedBy = {IsMobileValidator.class}
)
public @interface IsMobile {
boolean required() default true;
String message() default "手机号码格式错误";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
IsMobileValidator.java
package com.example.miaosha.vo;
import com.example.miaosha.utils.ValidatorUtil;
import com.example.miaosha.validator.IsMobile;
import org.apache.commons.lang3.StringUtils;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
public class IsMobileValidator implements ConstraintValidator<IsMobile,String> {
private boolean required =false;
@Override
public void initialize(IsMobile constraintAnnotation) {
ConstraintValidator.super.initialize(constraintAnnotation);
required = constraintAnnotation.required();
}
@Override
public boolean isValid(String value, ConstraintValidatorContext constraintValidatorContext) {
if(required){
return ValidatorUtil.isMobile(value);
}else{
if(StringUtils.isEmpty(value)){
return true;
}else {
return ValidatorUtil.isMobile(value);
}
}
}
}
ValidatorUtil.java
package com.example.miaosha.utils;
import org.apache.commons.lang3.StringUtils;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class ValidatorUtil {
private static final Pattern mobile_pattern=Pattern.compile("[1]([3-9])[0-9]{9}$");
public static boolean isMobile(String mobile){
if(StringUtils.isEmpty(mobile)){
return false;
}
Matcher matcher = mobile_pattern.matcher(mobile);
return matcher.matches();
}
}
在LoginController 中接收LoingVo时添加注解 @Valid
@RequestMapping("/doLogin")
@ResponseBody
public RespBean doLgoin(@Valid LoginVo loginVo, HttpServletRequest request, HttpServletResponse response){
//log.info("{}",loginVo);
return userService.doLgoin(loginVo,request,response);
}
如果出现参数校验错误,则会抛出 BindException,这个时候可以在全局异常里面统一处理
参见上面 GlobalExceptionHandler.java
if(e instanceof BindException){
BindException ex=(BindException)e;
RespBean respBean = RespBean.error(RespBeanEnum.BIND_ERROR);
respBean.setMessage("参数校验异常:"+ex.getBindingResult().getAllErrors().get(0).getDefaultMessage());
return respBean;
}
前端收到的接口返回信息