Spring Boot(三) web進階
阿新 • • 發佈:2018-11-12
一、表單驗證@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"));
}
}
右鍵方法名進行測試:下面清晰的顯示錯誤