共计 4039 个字符,预计需要花费 11 分钟才能阅读完成。
在学校做一个校企合作项目,注册登录这一块需要对注册登录进行输入合法的服务器端验证,因为是前后端分离开发,所以要求返回 JSON 数据。
方法有很多,这觉得用全局异常处理比较容易上手
全局异常处理
首先来创建一个 sprIngboot 的 web 项目或模块,目录结构如下
实体类 User.java
@Data
public class User {
private String userName;
private String passwold;
}
实体类 UserResult.java 把数据封装到这里返回到客户端
@Data
@NoArgsConstructor
@AllArgsConstructor
public class UserResult {
private int code;
private String msg;
}
接下来自定义异常,都继承自 Exception
UserNullException.java 当用户名为空抛出这个异常
public class UserNullException extends Exception{public UserNullException() {super("用户名不能为空");
}
}
PasswoldNullException.java 当密码为空抛出这个异常
public class PasswoldNullException extends Exception {public PasswoldNullException() {super("密码不能为空");
}
}
UserNamePasswordNullException.java 当用户名和密码都为空抛出这个异常
public class UserNamePasswordNullException extends Exception {public UserNamePasswordNullException() {super("请输入用户名和密码");
}
}
UserNameValidationException.jva 当输入不符合要求的用户名时抛出此异常
public class UserNameValidationException extends Exception{public UserNameValidationException() {super("请输入 6 到 16 位的数字或字母组合");
}
}
UserNamePasswordNullException.java 当输入的密码不符合要求时抛出这个异常
public class UserNamePasswordNullException extends Exception {public UserNamePasswordNullException() {super("请输入用户名和密码");
}
}
通过注解的方式捕获异常
- @Controller + @ExceptionHandler
- @ControllerAdvice + @ExceptionHandler
若返回的不是页面,把 @Controller 换成 @RestController,@ControllerAdvice 换成 @RestControllerAdvice, 也可以在 @Controller 类下的方法那里加上 @ResponseBody
@Controller + @ExceptionHandler
@Controller:注解此类是 Controller 类
@ExceptionHandler:此注解注解到类的方法上,当此注解里定义的异常抛出时,此方法会被执行。如果 @ExceptionHandler 所在的类是 @Controller,则此方法只作用在此类。如果 @ExceptionHandler 所在的类是 @ControllerAdvice,则此方法会作用在全局
在这里我只进行了全局异常的捕获,就是只用了 @RestControllerAdvice, 对全部 controller 层进行了异常监控,任何控制层抛出常,只要 @RestControllerAdvice 类下 @ExceptionHandler 注解的 value 值指定有的都会被执行
@RestControllerAdvice
public class UserExceptionHandler {@ExceptionHandler(value = UserNullException.class)
public @ResponseBody UserResult userNull(HttpServletRequest request,Exception ex)
{UserResult userResult=new UserResult();
userResult.setCode(9);
userResult.setMsg(ex.getMessage());
return userResult;
}
@ExceptionHandler(value = PasswoldNullException.class)
public UserResult passwordNull(HttpServletRequest request,Exception ex)
{UserResult userResult=new UserResult();
userResult.setCode(10);
userResult.setMsg(ex.getMessage());
return userResult;
}
@ExceptionHandler(value = UserNamePasswordNullException.class)
public @ResponseBody UserResult namePassNull(HttpServletRequest request,Exception ex)
{UserResult userResult=new UserResult();
userResult.setCode(11);
userResult.setMsg(ex.getMessage());
return userResult;
}
@ExceptionHandler(value = UserNameValidationException.class)
public @ResponseBody UserResult UserNameValidation(HttpServletRequest request,Exception ex)
{UserResult userResult=new UserResult();
userResult.setCode(12);
userResult.setMsg(ex.getMessage());
return userResult;
}
@ExceptionHandler(value = PasswordValidationException.class)
public @ResponseBody UserResult PasswordValidation(HttpServletRequest request,Exception ex)
{UserResult userResult=new UserResult();
userResult.setCode(13);
userResult.setMsg(ex.getMessage());
return userResult;
}
}
在这里 SignInController.java 是全局异常捕获类
@RestControllerAdvice
@RequestMapping(value = "user/api")
public class SignInController {@PostMapping(value = "/sign_in")
public UserResult signIn(@RequestBody User user) throws Exception {if (user.getUserName()==null&&user.getPasswold()==null)
{throw new UserNamePasswordNullException();
}else if (user.getUserName()==null)
{throw new UserNullException();
}else if (user.getPasswold()==null)
{throw new PasswoldNullException();
}else {if (userNameRegex(user.getUserName())==false){throw new UserNameValidationException();
}else if (passRegex(user.getPasswold())==false){throw new PasswordValidationException();
}
}
return new UserResult(0,"登录成功");
}
/**
* 正则表达式:验证规则
*/
public static final String REGEX_PASSWORD = "^[a-zA-Z0-9]{6,16}$";
/**
* 手机号
*/
String PHONE_NUMBER_REG = "^(13[0-9]|14[579]|15[0-3,5-9]|16[6]|17[0135678]|18[0-9]|19[89])\\d{8}$";
public boolean userNameRegex(String userName)
{return Pattern.matches(REGEX_PASSWORD, userName);
}
public boolean passRegex(String password)
{return Pattern.matches(REGEX_PASSWORD, password);
}
}
加为要求前端传的是 JSON 数据,所以对象参数前务必加上 @RequestBody 这个注解 (踩过坑)
项目中加入了 swagger 配置 (swagger 简单使用),这里用来输入几条数据进行测试
github 代码
个人网站