本篇介绍 Spring Boot 对 Web 开发的支持。主要内容单元测试、Json的支持、请求传参方式、参数校验、自定义Filter、自定义Property
完成目标
①单元测试、Json的支持
②请求传参方式
③参数校验
④自定义Filter
⑤自定义Property
推荐博客:idea下新建Spring Boot项目并配置启动
https://blog.csdn.net/zjh_746140129/article/details/80101122
注:第一部分为代码,第二部分为增删改查操作的截图和后台sql打印,完整代码可在github下载。
github地址:https://github.com/zjh746140129/Spring-Boot2.0
项目结构截图:
一、单元测试、Json的支持
以往我们在测试 web 请求的时候,需要手动输入相关参数在页面测试查看效果,或者自己写 post 请求。在 Spring Boot 中,Spring 给出了一个简单的解决方案;使用 mockmvc 进行 web 测试,mockmvc 内置了很多工具类和方法,可以模拟 post、get 请求,并且判断返回的结果是否正确等,也可以利用print()打印执行结果
在类的上面添加@SpringBootTest,系统会自动加载 Spring Boot 容器。在日常测试中,我们就可以注入 bean 来做一些局部业务的测试。MockMvcRequestBuilders可以 post、get 请求,使用print()方法会将请求和相应的过程都打印出来
@RestController 的意思就是 controller 里面的方法都以 json 格式输出,不用再配置什么 jackjson 的了
代码片段
①编写学生类
package com.boot.model;
import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotEmpty;
import java.io.Serializable;
/**
* 学生类
* Created by zhoujh on 2018/06/11
*/
public class Student implements Serializable{
@NotEmpty(message="姓名不能为空")
private String name;
@Max(value = 100, message = "年龄不能大于 100 岁")
@Min(value= 18 ,message= "必须年满 18 岁!" )
private int age;
private String address;
public Student() {
}
public Student(String name, int age, String address) {
this.name = name;
this.age = age;
this.address = address;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}
②编写controller
package com.boot.controller;
import com.boot.model.Student;
import org.springframework.validation.BindingResult;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import javax.validation.Valid;
import java.util.ArrayList;
import java.util.List;
/**
* 学生类controller
* Created by zhoujh on 2018/06/11
*/
@RestController
public class StudentController {
@RequestMapping(value = "/getStudent", method= RequestMethod.POST)
public Student getUser() {
Student student=new Student();
student.setName("zhoujunhong");
student.setAge(25);
student.setAddress("北京市海淀区八里庄街道");
return student;
}
}
③编写单元测试(使用 mockmvc 进行 web 测试 )
package com.boot.controller;
import org.junit.Before;
import org.junit.Test;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
/**
* 学生类controller
* Created by zhoujh on 2018/06/11
*/
@SpringBootTest
public class GetStuCOntrollerTest {
private MockMvc mockMvc;
@Before
public void setUp() throws Exception {
mockMvc = MockMvcBuilders.standaloneSetup(new StudentController()).build();
}
@Test
public void getStudent() throws Exception {
mockMvc.perform(MockMvcRequestBuilders.get("/getStudent")).andDo(print());
}
@Test
public void getStudents() throws Exception {
mockMvc.perform(MockMvcRequestBuilders.post("/getStudents")).andDo(print());
}
}
④运行查看流程和结果
二、请求传参方式
使用 Spirng Boot 可以轻松的对请求做一些限制,比如为了安全只允许 POST 请求的访问。只需要在方法上添加一个配置即可
请求方式限制
①修改Controller
②再次请求
这时候再以 get 请求去访问,就会返回: Error message = Request method 'GET' not supported
传参方式一:使用 Url 进行传参,这种形式的传参地址栏会更加美观
访问:http://localhost:8088/get/zhoujunhong
传参方式二:传入一个属性 name,其直接使用对象接收
http://localhost:8088/getStudent?name=zhoujunhong
三、参数校验
参数校验在我们日常开发中非常常见,最基本的校验有判断属性是否为空、长度是否符合要求等,在传统的开发模式中需要写一堆的 if else 来处理这些逻辑,很繁琐,效率也低。使用 @Valid + BindingResult 就可以优雅地解决这些问题
①修改Controller做保存学生
②访问
http://localhost:8088/saveStudent?name=zhoujunhong
四、自定义Filter
package com.boot.filter;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
/**
* 自定义Filter
* Created by zhoujh on 2018/06/11
*/
public class WebContextFilter implements Filter {
@Override
public void destroy() {
// TODO Auto-generated method stub
}
@Override
public void doFilter(ServletRequest srequest, ServletResponse sresponse, FilterChain filterChain)
throws IOException, ServletException {
// TODO Auto-generated method stub
HttpServletRequest request = (HttpServletRequest) srequest;
System.out.println("this is MyFilter,url :"+request.getRequestURI());
filterChain.doFilter(srequest, sresponse);
}
@Override
public void init(FilterConfig arg0) throws ServletException {
// TODO Auto-generated method stub
}
}
自定义 Filter 加入过滤链
package com.boot.filter;
import org.apache.catalina.filters.RemoteIpFilter;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* 自定义 Filter 加入过滤链
* Created by zhoujh on 2018/06/11
*/
@Configuration
public class WebConfiguration {
@Bean
public RemoteIpFilter remoteIpFilter() {
return new RemoteIpFilter();
}
@Bean
public FilterRegistrationBean testFilterRegistration() {
FilterRegistrationBean registration = new FilterRegistrationBean();
registration.setFilter(new WebContextFilter());
registration.addUrlPatterns("/*");
registration.addInitParameter("paramName", "paramValue");
registration.setName("MyFilter");
registration.setOrder(1);
return registration;
}
}
请求访问查看,访问任意的 Url,都会看到控制台打印如下。说明 自定义Filter 已经对所有的 Url 进行了监控,在实际使用的过程中,常常利用这个特性进行 session 验证,判断用户是否登录,还有就是一些不用过滤的路径。
http://localhost:8088/saveStudent?name=zhoujunhong
五、自定义Property
在 Web 开发的过程中,经常需要自定义一些配置文件配置在 application.properties 中
com.boot.name = zhoujunhong
自定义配置类
package com.neo.comm;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component
public class NeoProperties {
@Value("${com.neo.title}")
private String title;
@Value("${com.neo.description}")
private String description;
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
}
编写读取Controller
package com.boot.controller;
import com.boot.common.MyProperty;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
/**
* 读取自定义property配置文件
*/
@RestController
public class ReadPropertyController {
@Resource
private MyProperty myProperty;
@RequestMapping("/ready")
public String showProperty(){
return myProperty.getName();
}
}
访问查看http://localhost:8088/ready
完整代码可以到github下载即可。