SpringBoot堅持學習第一天:傳參校驗配置測試
一、SpringBoot產生的背景
Spring Boot 誕生一方面是因為 Spring 自身發展所遇到的問題,另一方面在微服務思想誕生之際,急需要一款快速開發工具來實現微服務技術落地,在這樣的背景下誕生了 Spring Boot。
正是由於 Spring IoC 和 Spring Aop 兩個強大的功能才有了 Spring,Spring 生態不斷的發展才有了 Spring Boot,使用 Spring Boot 讓 Spring 更易用更有生命力,Spring Cloud 是基於 Spring Boot 開發的一套微服務架構下的服務治理方案。
Spring Boot 整體的設計思想是:約定優於配置。依賴此設計思路,Spring Boot 進行了大刀闊斧的改革,讓開發、測試、部署更為便捷。眾多的 Starters 成就了 Spring Boot 的發展,讓使用 Spring Boot 開發專案變得更加簡單。
二、SpringBoot模擬傳送URL
@RunWith(SpringRunner.class) 代表執行一個 Spring 容器
@SpringBootTest public class HelloTest { private MockMvc mockMvc; @Before public void setUp() throws Exception { //載入某個Controller資源 mockMvc = MockMvcBuilders.standaloneSetup(new HelloController()).build(); } @Test public void getHello() throws Exception { //模擬一個URL mockMvc.perform(MockMvcRequestBuilders.post("/hello?name=小明") //設定JSON資料格式,防止亂碼 .accept(MediaType.APPLICATION_JSON_UTF8)).//andDo(print()); //判斷伺服器返回的JSON資料是否有字串“微笑” andExpect(MockMvcResultMatchers.content().string(Matchers.containsString("微笑"))); } @Test public void getUser() throws Exception { //獲取JSON資料標準寫法 String responseString = mockMvc.perform(MockMvcRequestBuilders.post("/getUser")) .andReturn().getResponse().getContentAsString(); System.out.println("result : "+responseString); } //對映到User實體 @Test public void saveUsers() throws Exception { mockMvc.perform(MockMvcRequestBuilders.post("/saveUser") .param("name","") .param("age","666") .param("pass","test") ); } }
在測試階段,如果後臺需要的是一個@RequestBody對映的實體,可以將其先暫時去掉,模擬傳送表單資料。測試通過後,可以將@RequestBody再添加回去。
三、傳參
若不在方法上指明 method = RequestMethod.GET 或者 method = RequestMethod.POST,即如果不進行設定預設兩種方式的請求都支援。
(1)我們傳入一個屬性 name,直接使用物件接收也可以支援。
輸入:http://localhost:8080/getUser?name=abc&pass=123 @RequestMapping(name = "/getUser") public User getUser(User user) { return user; } 返回JSON資料:{"name":"abc","age":0,"pass":"123"}
(2)使用 URL 進行傳參
輸入:http://localhost:8080/get/abc
@RequestMapping(value = "get/{name}", method = RequestMethod.GET)
public String get(@PathVariable String name) {
return name;
}
頁面顯示:abc
四、校驗實體錯誤資訊
Java實體上有部分約束。
import org.hibernate.validator.constraints.Length;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
public class User {
@NotEmpty(message = "姓名不能為空")
private String name;
@Max(value = 100, message = "年齡不能大於100歲")
@Min(value = 18, message = "必須年滿18歲!")
private int age;
@NotEmpty(message = "密碼不能為空")
@Length(min = 6, message = "密碼長度不能小於6位")
private String pass;
...
@Valid 引數前面新增 @Valid 註解,代表此物件使用了引數校驗;
BindingResult 引數校驗的結果會儲存在此物件中,可以根據屬性判斷是否校驗通過,校驗不通過可以將錯誤資訊打印出來。 在請求到此方法體的時候,就已經觸發校驗事件了,校驗結果存放在BindingResult物件中。
@RequestMapping("/saveUser")
public void saveUser(@Valid User user, BindingResult result) {
System.out.println("user:" + user);
if (result.hasErrors()) {
List<ObjectError> list = result.getAllErrors();
for (ObjectError error : list) {
System.out.println(error.getCode() + "-" + error.getDefaultMessage());
}
}
}
user:[email protected]
NotEmpty-姓名不能為空
Max-年齡不能大於100歲
Length-密碼長度不能小於6位
五、自定義 Filter
自定義 Filter 兩個步驟:
實現 Filter 介面,實現其中的 doFilter() 方法;
新增 @Configuration 註解,將自定義 Filter 加入過濾鏈。
public class MyFilter implements Filter {
@Override
public void doFilter(ServletRequest servletRequest,
ServletResponse servletResponse, FilterChain filterChain)
throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) servletRequest;
System.out.println("this is MyFilter,url :" + request.getRequestURI());
filterChain.doFilter(servletRequest, servletResponse);
}
}
@Configuration
public class WebConfiguration {
@Bean
public FilterRegistrationBean testFilterRegistration() {
FilterRegistrationBean registration = new FilterRegistrationBean();
//加入過濾器
registration.setFilter(new MyFilter());
//配置攔截規則
registration.addUrlPatterns("/*");
registration.setName("MyFilter");
//設定攔截器優先順序,越小優先順序越高
registration.setOrder(6);
return registration;
}
}
六、讀取配置檔案
同時存在 application.yml 和 application.properties,並且裡面配置相同,application.properties 的配置會覆蓋 application.yml。
#resources/application.properties
neo.title=標題
neo.description=描述
# 讀取多個配置檔案 , 匹配配置檔案中 neo 開頭
@Component
@ConfigurationProperties(prefix="neo")
public class NeoProperties {
private String title;
private String description;
//get set..
}
@RunWith(SpringRunner.class)
@SpringBootTest
public class PropertiesTest {
@Value("${neo.title}")
private String title;
@Resource
private NeoProperties properties;
@Test
public void testSingle2(){
System.out.println(title);
System.out.println(properties.getTitle());
System.out.println(properties.getDescription());
}
}
標題
標題
描述
七、自定義配置檔案
# resources / other.properties
other.title=other title
other.blog=other blog
@Component
@ConfigurationProperties(prefix="other")
@PropertySource("classpath:other.properties")
public class OtherProperties {
private String title;
private String blog;
//get set
}
@RunWith(SpringRunner.class)
@SpringBootTest
public class PropertiesTest {
@Resource
private OtherProperties properties;
@Test
public void test(){
System.out.println(properties.getBlog());
System.out.println(properties.getTitle());
}
}
other blog
other title