Java后端的本质就是获取上传的数据、处理后保存到数据库、有需求时再获取数据并返回给前端。
一个好的项目结构是一个好的开始,我做了以下操作,分别是
- 数据获取绑定
- 参数校验
- 统一异常处理
- 统一返回结果
- 状态码枚举
- 一些基础类
数据获取绑定:
SpringMVC中有三个注解可以获取数据并绑定到参数上:
-
@RequestParam:获取url或者请求体中数据,但请求体的Content-Type需要为application/x-www-form-urlencoded格式,它是POST请求的默认格式。
-
@RequestBody:获取请求体中的数据,一般用于处理application/json类型的数据。
-
@Pathvariable:获取url中占位符所在的数据
自定义参数类型转换:
这里是一个日期类型的演示:
自定义转换类:
public class DateConverter implements Converter<String,Date> {
@Override
public Date convert(String dateStr) {
if(dateStr!=null){
Date date = null;
try {
date = new SimpleDateFormat("yyyy-MM-dd").parse(dateStr);
} catch (ParseException e) {
e.printStackTrace();
}
return date;
}
return null;
}
}
配置:
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addFormatters(FormatterRegistry registry) {
registry.addConverter(dateConverter());
}
@Bean
public DateConverter dateConverter(){
return new DateConverter();
}
}
试验:
public class UriController {
@PostMapping("date")
public Person date(@RequestBody Person person){
return person;
}
}
public class Person {
private String name;
private String age;
private Date date;
}
参数校验:
Bean Validation是Java定义的一套基于注解的数据校验规范 ,SpringBoot已经集成好了,我们直接拿过来用就好。
导包:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
添加你需要的注解到对应的类字段上面
public class UserRegisterVM {
@NotBlank
private String userName;
@NotBlank
private String password;
@NotNull
private Integer userLevel;
}
再到Controller中添加@valid开启验证。
@PostMapping("update")
public Result updateUser(@RequestBody @Valid UserUpdateVM vm){
...
return Result.ok();
}
常用的注解有:
注解 | 校验功能 |
---|---|
校验是否符合Email格式 | |
@Max | 最大值 |
@Min | 最小值 |
@Negative | 负数(不包括0) |
@NegativeOrZero | 负数或0 |
@NotBlank | 不为null并且包含至少一个非空白字符 |
@NotEmpty | 不为null并且不为空 |
@NotNull | 不为null |
@Null | 为null |
@PastOrPresent | 必须是过去的时间,包含现在 |
@PositiveOrZero | 正数或0 |
@Size | 校验容器的元素个数 |
统一异常处理:
@ControllerAdvice
public class ExceptionHandlerController {
// 捕获自定义的异常
@ResponseBody
@ExceptionHandler(Exception.class)
public Result handle(Exception e){
...
return new Result(SystemCode.InnerError.getCode(),SystemCode.InnerError.getMessage());
}
/*
* @Description: 捕获validation验证失败抛出的异常
* @Date: 2021/3/21
*/
@ExceptionHandler(MethodArgumentNotValidException.class)
@ResponseBody
public Result handler(MethodArgumentNotValidException e) {
...
return new Result(SystemCode.ParameterValidError.getCode(), errorMsg);
}
}
统一返回结果:
public class Result<T> {
private int code;
private String message;
private T response;
}
让我们再补一点状态枚举
public enum SystemCode {
OK(1, "成功"),
AccessTokenError(400, "用户登录令牌失效"),
UNAUTHORIZED(401, "用户未登录"),
AuthError(402, "用户名或密码错误"),
InnerError(500, "系统内部错误"),
ParameterValidError(501, "参数验证错误"),
AccessDenied(502,"用户没有权限访问");
int code;
String message;
SystemCode(int code, String message) {
this.code = code;
this.message = message;
}
public int getCode() {
return code;
}
public String getMessage() {
return message;
}
}
再给结果类添加一些静态方法:
public class Result<T> {
private int code;
private String message;
private T response;
public Result(int code, String message) {
this.code = code;
this.message = message;
}
public Result(int code, String message, T response) {
this.code = code;
this.message = message;
this.response = response;
}
public static Result ok(){
SystemCode ok = SystemCode.OK;
return new Result(ok.getCode(),ok.getMessage());
}
public static<F> Result<F> ok(F data){
SystemCode ok = SystemCode.OK;
return new Result<>(ok.getCode(),ok.getMessage(),data);
}
public static Result fail(Integer code,String message){
return new Result(code,message);
}
}
一些基础类:
BaseController、BaseEntity、BaseService、BasePage、PageResult。
代码生成器:
使用intelllij IDEA编辑器推荐使用Easy-Code插件,好用,点赞! DEA的EasyCode插件