版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/menglinjie/article/details/81154661
一、表单验证@Valid
示例:@Min @Valid标识属性为需要验证的属性,BindingResult打印错误信息
Girl实体类:
package com.mlj.girl.domain;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.validation.constraints.Min;
@Entity
public class Girl {
@Id
@GeneratedValue
private Integer id;
private String cupSize;
@Min(value = 18,message = "禁止未成年入内!")//规定最小值
private Integer age;
public Girl() {
}
// 必须有无参构造
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getCupSize() {
return cupSize;
}
public void setCupSize(String cupSize) {
this.cupSize = cupSize;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
}
controller:
package com.mlj.girl.controller;
import com.mlj.girl.Repository.GirlRepository;
import com.mlj.girl.domain.Girl;
import com.mlj.girl.domain.Result;
import com.mlj.girl.service.GirlService;
import com.mlj.girl.utils.ResultUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import java.util.List;
@RestController
public class GirlController {
@Autowired
private GirlRepository girlRepository;
@Autowired
private GirlService girlService;
* 添加
*
* @return
*/
@PostMapping(value = "/girls")
public Result<Girl> girlAdd(@Valid Girl girl, BindingResult bindingResult) {
if (bindingResult.hasErrors()) {
System.out.println(bindingResult.getFieldError().getDefaultMessage());
// return ResultUtil.error(1, bindingResult.getFieldError().getDefaultMessage());
return null;
}
System.out.println(girl.getAge().toString());
Girl girl1 = girlRepository.save(girl);
return ResultUtil.success(girl1);
}
}
其他验证规则:
限制 说明
@Null 限制只能为null
@NotNull 限制必须不为null
@AssertFalse 限制必须为false
@AssertTrue 限制必须为true
@DecimalMax(value) 限制必须为一个不大于指定值的数字
@DecimalMin(value) 限制必须为一个不小于指定值的数字
@Digits(integer,fraction) 限制必须为一个小数,且整数部分的位数不能超过integer,小数部分的位数不能超过fraction
@Future 限制必须是一个将来的日期
@Max(value) 限制必须为一个不大于指定值的数字
@Min(value) 限制必须为一个不小于指定值的数字
@Past 限制必须是一个过去的日期
@Pattern(value) 限制必须符合指定的正则表达式
@Size(max,min) 限制字符长度必须在min到max之间
@Past 验证注解的元素值(日期类型)比当前时间早
@NotEmpty 验证注解的元素值不为null且不为空(字符串长度不为0、集合大小不为0)
@NotBlank 验证注解的元素值不为空(不为null、去除首位空格后长度为0),不同于@NotEmpty,@NotBlank只应用于字符串且在比较时会去除字符串的空格
@Email 验证注解的元素值是Email,也可以通过正则表达式和flag指定自定义的email格式
二、使用AOP处理请求
在学习Spring时已经学习了AOP,以日志处理为例
spring-AOP+自定义注解实现日志管理(注解方式实现)
三、统一异常处理和统一返回值
Result类:统一返回对象。定义错误代码,提示信息,返回具体内容(没有则为空)
package com.mlj.girl.domain;
public class Result<T> {
private Integer code;//错误码
private String msg;//提示信息
private T data;//具体内容
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
}
ResultUtil工具类,减少代码重复
package com.mlj.girl.utils;
import com.mlj.girl.domain.Result;
public class ResultUtil {
/**
* 成功且有返回值
*
* @param object
* @return
*/
public static Result success(Object object) {
Result result = new Result();
result.setCode(0);
result.setMsg("成功");
result.setData(object);
return result;
}
/**
* 成功无返回值
*
* @return
*/
public static Result success() {
return success(null);
}
/**
* 失败
*
* @param code
* @param msg
* @return
*/
public static Result error(Integer code, String msg) {
Result result = new Result();
result.setCode(code);
result.setMsg(msg);
return result;
}
}
成功时返回:
/**
* 添加
*
* @return
*/
@PostMapping(value = "/girls")
public Result<Girl> girlAdd(@Valid Girl girl, BindingResult bindingResult) {
Girl girl1 = girlRepository.save(girl);
return ResultUtil.success(girl1);
}
失败时进行异常处理
除了系统异常还有其他非系统异常,比如用户输入格式错误导致的异常等,需要自定义异常来进行区分
为了将异常信息与错误码对应起来并且易于管理,这里使用枚举
ResultEnum
package com.mlj.girl.enums;
public enum ResultEnum {
UNKONW_ERROR(-1, "未知错误"),
SUCCESS(0, "成功"),
PRIMARY_SCHOOL(100, "还在上小学"),
MIDDLE_SCHOOL(101, "还在上初中");
private Integer code;//错误码
private String msg;//错误信息
ResultEnum(Integer code, String msg) {
this.code = code;
this.msg = msg;
}
public Integer getCode() {
return code;
}
public String getMsg() {
return msg;
}
}
自定义异常GirlException类
package com.mlj.girl.exception;
import com.mlj.girl.enums.ResultEnum;
public class GirlException extends RuntimeException {
private Integer code;//错误码
public GirlException(ResultEnum resultEnum) {
super(resultEnum.getMsg());
this.code = resultEnum.getCode();
}
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
}
进行异常捕捉,用于捕捉系统抛出的异常
ExceptionHandle
import com.mlj.girl.domain.Result;
import com.mlj.girl.exception.GirlException;
import com.mlj.girl.utils.ResultUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
@ControllerAdvice
public class ExceptionHandle {
private final static Logger logger = LoggerFactory.getLogger(ExceptionHandle.class);
@ExceptionHandler(value = Exception.class)
@ResponseBody
public Result handle(Exception e) {
// 判断是否是自定义异常
if (e instanceof GirlException) {
GirlException girlException = (GirlException) e;
return ResultUtil.error(girlException.getCode(), girlException.getMessage());
} else {
//系统异常在控制台打印
logger.error("【系统异常】{}",e);
return ResultUtil.error(-1, "未知错误");
}
}
}
制造异常进行测试:
在service中
public void getAge(Integer id) throws Exception {
Girl girl = girlRepository.findById(id).get();
Integer age = girl.getAge();
if (age < 10) {
//抛出异常,指定异常类型
throw new GirlException(ResultEnum.PRIMARY_SCHOOL);
} else if (age > 10 && age < 16) {
throw new GirlException(ResultEnum.MIDDLE_SCHOOL);
}
}
结果:
四、单元测试
在需要测试的文件内右键=》go to =>test=>creatNewTest
勾选需要测试的方法
自动生成的测试文件
service层测试:
package com.mlj.girl;
import com.mlj.girl.domain.Girl;
import com.mlj.girl.service.GirlService;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
//在测试环境下,底层使用junit测试工具
@RunWith(SpringRunner.class)
@SpringBootTest
public class GirlServiceTest {
@Autowired
private GirlService girlService;
@Test
public void findOneTest() {
Girl girl = girlService.findOne(17);
Assert.assertEquals(new Integer(34),girl.getAge());
}
}
controller层测试:
用到@AutoConfigureMockMvc注解 MockMvc类
package com.mlj.girl.controller;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
import static org.junit.Assert.*;
@RunWith(SpringRunner.class)
@SpringBootTest
@AutoConfigureMockMvc
public class GirlControllerTest {
@Autowired
private MockMvc mockMvc;
@Test
public void girlList() throws Exception {
mockMvc.perform(MockMvcRequestBuilders.get("/girls"))
.andExpect(MockMvcResultMatchers.status().isOk())
.andExpect(MockMvcResultMatchers.content().string("aa"));
}
}
右键方法名进行测试:下面清晰的显示错误