SpringBoot16 MockMvc的使用、JsonPath的使用、请求参数问题、JsonView、分页查询参数、JsonProperty
1 MockMvc的使用
利用MockMvc可以快速实现MVC测试
坑01:利用MockMvc进行测试时应用上下文路径是不包含在请求路径中的
1.1 创建一个SpringBoot项目
1.2 创建一个用户实体类
package cn.test.demo.base_demo.entity.po; import java.util.Date; /**
* @author 王杨帅
* @create 2018-05-05 22:03
* @desc 用户实体类
**/
public class User {
private Integer userId;
private String userName;
private String password;
private Date birthday; public Integer getUserId() {
return userId;
} public void setUserId(Integer userId) {
this.userId = userId;
} public String getUserName() {
return userName;
} public void setUserName(String userName) {
this.userName = userName;
} public String getPassword() {
return password;
} public void setPassword(String password) {
this.password = password;
} public Date getBirthday() {
return birthday;
} public void setBirthday(Date birthday) {
this.birthday = birthday;
}
}
User.java
1.3 创建一个用户控制类
package cn.test.demo.base_demo.controller; import cn.test.demo.base_demo.entity.po.User;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; import java.util.ArrayList;
import java.util.List; /**
* @author 王杨帅
* @create 2018-05-05 22:02
* @desc 用户模块控制层
**/
@RestController
@RequestMapping(value = "/user")
public class UserController { @GetMapping
public List<User> queryList() {
List<User> userList = new ArrayList<>();
userList.add(new User());
userList.add(new User());
userList.add(new User());
return userList;
} }
UserController.java
1.4 创建一个测试类
该测试类主要测试用户控制类中的相关方法
1.4.1 引入测试类注解以及日志注解
@RunWith(SpringRunner.class)
@SpringBootTest
@Slf4j
1.4.2 依赖注入WebApplicationContext
@Autowired
private WebApplicationContext wac;
1.4.3 实例化MockMvc
private MockMvc mockMvc; @Before
public void setup() {
mockMvc = MockMvcBuilders.webAppContextSetup(wac).build();
}
1.4.4 利用MockMvc对象模拟HTTP请求
@Test
public void queryList() throws Exception {
String result = mockMvc.perform(
MockMvcRequestBuilders.get("/user")
.contentType(MediaType.APPLICATION_JSON_UTF8)
)
.andExpect(MockMvcResultMatchers.status().isOk())
.andReturn().getResponse().getContentAsString();
log.info("===/" + className + "/queryList===" + result);
}
1.4.5 测试类代码汇总
package cn.test.demo.base_demo.controller; import lombok.extern.slf4j.Slf4j;
import org.junit.Before;
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.http.MediaType;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MockMvcBuilder;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext; import static org.junit.Assert.*; @RunWith(SpringRunner.class)
@SpringBootTest
@Slf4j
public class UserControllerTest { private final String className = getClass().getName(); @Autowired
private WebApplicationContext wac; private MockMvc mockMvc; @Before
public void setup() {
mockMvc = MockMvcBuilders.webAppContextSetup(wac).build();
} @Test
public void queryList() throws Exception {
String result = mockMvc.perform(
MockMvcRequestBuilders.get("/user")
.contentType(MediaType.APPLICATION_JSON_UTF8)
)
.andExpect(MockMvcResultMatchers.status().isOk())
.andReturn().getResponse().getContentAsString();
log.info("===/" + className + "/queryList===" + result);
} }
2 JsonPath
JsonPath是GitHub上的一个开源项目,主要用来对Json格式的数据进行一些处理
技巧:jsonPath是MockMvcResultMatchers中的一个静态方法
具体使用:点击前往
2.1 简单实例
@Test
public void test01() throws Exception {
mockMvc.perform(
MockMvcRequestBuilders.get("/user")
.contentType(MediaType.APPLICATION_JSON_UTF8)
)
.andExpect(MockMvcResultMatchers.status().isOk())
.andExpect(MockMvcResultMatchers.jsonPath("$.length()").value(3));
}
3 请求参数
3.1 PathVarible
主要获取请求路径中的数据
技巧01:PathVarible获取到的数据是请求路径的一部分
技巧02:@PathVariable注解中的name和value两个成员的作用是一样的,是用来解决路径名和请求处理方法形参名不一致的问题
技巧03:@PathVariable支持正则表达式,如果路径参数不满足正则表达式就会匹配失败;参考博文
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
// package org.springframework.web.bind.annotation; import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.core.annotation.AliasFor; @Target({ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface PathVariable {
@AliasFor("name")
String value() default ""; @AliasFor("value")
String name() default ""; boolean required() default true;
}
PathVariable.java
3.1.1 控制类
package cn.test.demo.base_demo.controller; import cn.test.demo.base_demo.entity.po.User;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; import java.util.ArrayList;
import java.util.List; /**
* @author 王杨帅
* @create 2018-05-05 22:02
* @desc 用户模块控制层
**/
@RestController
@RequestMapping(value = "/user")
@Slf4j
public class UserController { private final String className = getClass().getName(); @GetMapping
public List<User> queryList() {
List<User> userList = new ArrayList<>();
userList.add(new User());
userList.add(new User());
userList.add(new User());
return userList;
} @GetMapping(value = "/{id}")
public User queryInfoByUserId(
@PathVariable(name = "id") String userId
) {
System.out.println("===路径参数:" + userId);
// log.info("===/" + className + "/queryInfoByUserId===路径参数为:{}", userId);
User user = new User();
return user;
} }
UserController.java
3.1.2 测试类
package cn.test.demo.base_demo.controller; import lombok.extern.slf4j.Slf4j;
import org.junit.Before;
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.http.MediaType;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MockMvcBuilder;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext; import static org.junit.Assert.*; @RunWith(SpringRunner.class)
@SpringBootTest
@Slf4j
public class UserControllerTest { private final String className = getClass().getName(); @Autowired
private WebApplicationContext wac; private MockMvc mockMvc; @Before
public void setup() {
mockMvc = MockMvcBuilders.webAppContextSetup(wac).build();
} @Test
public void queryList() throws Exception {
String result = mockMvc.perform(
MockMvcRequestBuilders.get("/user")
.contentType(MediaType.APPLICATION_JSON_UTF8)
)
.andExpect(MockMvcResultMatchers.status().isOk())
.andReturn().getResponse().getContentAsString();
log.info("===/" + className + "/queryList===" + result);
} /**
* 测试JosnPath
* @throws Exception
*/
@Test
public void test01() throws Exception {
mockMvc.perform(
MockMvcRequestBuilders.get("/user")
.contentType(MediaType.APPLICATION_JSON_UTF8)
)
.andExpect(MockMvcResultMatchers.status().isOk())
.andExpect(MockMvcResultMatchers.jsonPath("$.length()").value(3));
} /**
* 测试:路径参数
* @throws Exception
*/
@Test
public void test02() throws Exception {
String result = mockMvc.perform(
MockMvcRequestBuilders.get("/user/123")
.contentType(MediaType.APPLICATION_JSON_UTF8)
)
.andExpect(MockMvcResultMatchers.status().isOk())
.andReturn().getResponse().getContentAsString();
System.out.println("====/" + result );
} }
UserControllerTest.java
3.2 RequestParam
主要获取请求路径后面的 K-V 键值对
技巧01:@RequestParam注解中的name和value属性的作用都是一样的,都是为了解决前端变量名和后台请求处理方法形参不一致的问题
技巧02:@RequestParam 可以指定默认值(即:指定了默认之后,即使前端不传入参数也不会报400错误,而是采用设定的默认值)
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
// package org.springframework.web.bind.annotation; import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.core.annotation.AliasFor; @Target({ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RequestParam {
@AliasFor("name")
String value() default ""; @AliasFor("value")
String name() default ""; boolean required() default true; String defaultValue() default "\n\t\t\n\t\t\n\ue000\ue001\ue002\n\t\t\t\t\n";
}
RequestParam.java
3.2.1 控制类
package cn.test.demo.base_demo.controller; import cn.test.demo.base_demo.entity.po.User;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*; import java.util.ArrayList;
import java.util.List; /**
* @author 王杨帅
* @create 2018-05-05 22:02
* @desc 用户模块控制层
**/
@RestController
@RequestMapping(value = "/user")
@Slf4j
public class UserController { private final String className = getClass().getName(); @GetMapping
public List<User> queryList() {
List<User> userList = new ArrayList<>();
userList.add(new User());
userList.add(new User());
userList.add(new User());
return userList;
} /**
* 路径参数
* @param userId
* @return
*/
@GetMapping(value = "/{id}")
public User queryInfoByUserId(
@PathVariable(name = "id") String userId
) {
System.out.println("===路径参数:" + userId);
// log.info("===/" + className + "/queryInfoByUserId===路径参数为:{}", userId);
User user = new User();
return user;
} @GetMapping(value = "/findByName")
public void findByName(
@RequestParam(value = "name") String username
) {
System.out.println("===请求参数为:/" + username); } }
UserController.java
3.2.2 测试类
package cn.test.demo.base_demo.controller; import lombok.extern.slf4j.Slf4j;
import org.junit.Before;
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.http.MediaType;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MockMvcBuilder;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext; import static org.junit.Assert.*; @RunWith(SpringRunner.class)
@SpringBootTest
@Slf4j
public class UserControllerTest { private final String className = getClass().getName(); @Autowired
private WebApplicationContext wac; private MockMvc mockMvc; @Before
public void setup() {
mockMvc = MockMvcBuilders.webAppContextSetup(wac).build();
} @Test
public void queryList() throws Exception {
String result = mockMvc.perform(
MockMvcRequestBuilders.get("/user")
.contentType(MediaType.APPLICATION_JSON_UTF8)
)
.andExpect(MockMvcResultMatchers.status().isOk())
.andReturn().getResponse().getContentAsString();
log.info("===/" + className + "/queryList===" + result);
} /**
* 测试JosnPath
* @throws Exception
*/
@Test
public void test01() throws Exception {
mockMvc.perform(
MockMvcRequestBuilders.get("/user")
.contentType(MediaType.APPLICATION_JSON_UTF8)
)
.andExpect(MockMvcResultMatchers.status().isOk())
.andExpect(MockMvcResultMatchers.jsonPath("$.length()").value(3));
} /**
* 测试:路径参数
* @throws Exception
*/
@Test
public void test02() throws Exception {
String result = mockMvc.perform(
MockMvcRequestBuilders.get("/user/123")
.contentType(MediaType.APPLICATION_JSON_UTF8)
)
.andExpect(MockMvcResultMatchers.status().isOk())
.andReturn().getResponse().getContentAsString();
System.out.println("====/" + result );
} @Test
public void test03() throws Exception {
mockMvc.perform(
MockMvcRequestBuilders.get("/user/findByName")
.param("username", "王杨帅")
.contentType(MediaType.APPLICATION_JSON_UTF8)
)
.andExpect(MockMvcResultMatchers.status().isOk());
} }
UserControllerTest.java
3.3 RequestBody
可以将前端参数封装成一个对象传到后台
技巧01:请求体中的数据会自动转化成字符串进行传输
3.3.1 新建一个数据传输类
该类主要用于整合前端传过来的数据
package cn.test.demo.base_demo.entity.dto; public class UserQueryCondition { private String username;
private Integer age;
private Integer ageTo;
private String xxx; public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public Integer getAgeTo() {
return ageTo;
}
public void setAgeTo(Integer ageTo) {
this.ageTo = ageTo;
}
public String getXxx() {
return xxx;
}
public void setXxx(String xxx) {
this.xxx = xxx;
} @Override
public String toString() {
return "UserQueryCondition [username=" + username + ", age=" + age + ", ageTo=" + ageTo + ", xxx=" + xxx + "]";
} }
UserQueryCondition.java
3.3.2 控制类
package cn.test.demo.base_demo.controller; import cn.test.demo.base_demo.entity.dto.UserQueryCondition;
import cn.test.demo.base_demo.entity.po.User;
import com.fasterxml.jackson.annotation.JsonView;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*; import java.util.ArrayList;
import java.util.List; /**
* @author 王杨帅
* @create 2018-05-05 22:02
* @desc 用户模块控制层
**/
@RestController
@RequestMapping(value = "/user")
@Slf4j
public class UserController { private final String className = getClass().getName(); @GetMapping
@JsonView(value = User.UserSimple.class)
public List<User> queryList() {
List<User> userList = new ArrayList<>();
userList.add(new User());
userList.add(new User());
userList.add(new User());
return userList;
} /**
* 路径参数
* @param userId
* @return
*/
@GetMapping(value = "/{id}")
public User queryInfoByUserId(
@PathVariable(name = "id") String userId
) {
System.out.println("===路径参数:" + userId);
// log.info("===/" + className + "/queryInfoByUserId===路径参数为:{}", userId);
User user = new User();
return user;
} /**
* 请求参数
* @param username
*/
@GetMapping(value = "/findByName")
public void findByName(
@RequestParam(value = "name") String username
) {
System.out.println("===请求参数为:/" + username); } /**
* 请求体
* @param userQueryCondition
*/
@PostMapping()
public void create(
@RequestBody UserQueryCondition userQueryCondition
) {
System.out.println("===前端获取到的数据为:" + userQueryCondition);
} }
UserController.java
3.3.3 测试类
package cn.test.demo.base_demo.controller; import lombok.extern.slf4j.Slf4j;
import org.junit.Before;
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.http.MediaType;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MockMvcBuilder;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext; import static org.junit.Assert.*; @RunWith(SpringRunner.class)
@SpringBootTest
@Slf4j
public class UserControllerTest { private final String className = getClass().getName(); @Autowired
private WebApplicationContext wac; private MockMvc mockMvc; @Before
public void setup() {
mockMvc = MockMvcBuilders.webAppContextSetup(wac).build();
} @Test
public void queryList() throws Exception {
String result = mockMvc.perform(
MockMvcRequestBuilders.get("/user")
.contentType(MediaType.APPLICATION_JSON_UTF8)
)
.andExpect(MockMvcResultMatchers.status().isOk())
.andReturn().getResponse().getContentAsString();
// log.info("===/" + className + "/queryList===" + result);
System.out.println("===/结果为:" + result);
} /**
* 测试JosnPath
* @throws Exception
*/
@Test
public void test01() throws Exception {
mockMvc.perform(
MockMvcRequestBuilders.get("/user")
.contentType(MediaType.APPLICATION_JSON_UTF8)
)
.andExpect(MockMvcResultMatchers.status().isOk())
.andExpect(MockMvcResultMatchers.jsonPath("$.length()").value(3));
} /**
* 测试:路径参数
* @throws Exception
*/
@Test
public void test02() throws Exception {
String result = mockMvc.perform(
MockMvcRequestBuilders.get("/user/123")
.contentType(MediaType.APPLICATION_JSON_UTF8)
)
.andExpect(MockMvcResultMatchers.status().isOk())
.andReturn().getResponse().getContentAsString();
System.out.println("====/" + result );
} /**
* 测试:请求参数
* @throws Exception
*/
@Test
public void test03() throws Exception {
mockMvc.perform(
MockMvcRequestBuilders.get("/user/findByName")
.param("name", "王杨帅")
.contentType(MediaType.APPLICATION_JSON_UTF8)
)
.andExpect(MockMvcResultMatchers.status().isOk());
} @Test
public void test04() throws Exception { String content = "{\"username\":\"王杨帅\",\"age\":\"24\"}";
mockMvc.perform(
MockMvcRequestBuilders.post("/user")
.content(content)
.contentType(MediaType.APPLICATION_JSON_UTF8)
)
.andExpect(MockMvcResultMatchers.status().isOk());
} }
UserControllerTest.java
3.3.4 参数验证
参考博文:点击前往
4 JsonView
需求:有的请求需要返回一个实体对象的全部字段,而有的请求只需要返回一个实体对象的部分字段;但是两个请求的数据都来自同一个实体类,怎么样才可以避免实体类重复定义
JsonView可以通过一个实体类实现多种视图显示
4.1 声明多个视图
在一个实体类中利用接口实现声明多个视图
技巧01:视图之间可以继承,如果视图A继承了视图B,那么在利用视图A进行显示时视图B对应的字段也会被显示出来
4.2 设置实例属性
在实例变量的Get方法上设置视图
package cn.test.demo.base_demo.entity.po; import com.fasterxml.jackson.annotation.JsonView; import java.util.Date; /**
* @author 王杨帅
* @create 2018-05-05 22:03
* @desc 用户实体类
**/
public class User { public interface UserSimple {};
public interface UserDetail extends UserSimple {}; private Integer userId;
private String userName;
private String password;
private Date birthday; @JsonView(value = UserSimple.class)
public Integer getUserId() {
return userId;
} public void setUserId(Integer userId) {
this.userId = userId;
} @JsonView(value = UserSimple.class)
public String getUserName() {
return userName;
} public void setUserName(String userName) {
this.userName = userName;
} @JsonView(value = UserDetail.class)
public String getPassword() {
return password;
} public void setPassword(String password) {
this.password = password;
} @JsonView(value = UserDetail.class)
public Date getBirthday() {
return birthday;
} public void setBirthday(Date birthday) {
this.birthday = birthday;
}
}
User.java
4.3 设置响应视图
在控制类中方法中设置响应视图
package cn.test.demo.base_demo.controller; import cn.test.demo.base_demo.entity.po.User;
import com.fasterxml.jackson.annotation.JsonView;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*; import java.util.ArrayList;
import java.util.List; /**
* @author 王杨帅
* @create 2018-05-05 22:02
* @desc 用户模块控制层
**/
@RestController
@RequestMapping(value = "/user")
@Slf4j
public class UserController { private final String className = getClass().getName(); @GetMapping
@JsonView(value = User.UserSimple.class)
public List<User> queryList() {
List<User> userList = new ArrayList<>();
userList.add(new User());
userList.add(new User());
userList.add(new User());
return userList;
} /**
* 路径参数
* @param userId
* @return
*/
@GetMapping(value = "/{id}")
public User queryInfoByUserId(
@PathVariable(name = "id") String userId
) {
System.out.println("===路径参数:" + userId);
// log.info("===/" + className + "/queryInfoByUserId===路径参数为:{}", userId);
User user = new User();
return user;
} @GetMapping(value = "/findByName")
public void findByName(
@RequestParam(value = "name") String username
) {
System.out.println("===请求参数为:/" + username); } }
UserController.java
5 分页查询参数
5.1 控制方法形参类型
在controller层的控制方法中利用 Pageable 对象去接收前端传过来的路径参数
技巧01:在springBoot项目中需要引入 spring-boot-starter-data-jpa 相关jar包才可以使用 Pageable 去接收分页查询参数
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
技巧02:Pageable 所在的包名为:import org.springframework.data.domain.Pageable;
技巧03:如果前端没有传入先关的参数,Pageable 是有默认值的,即使不用 @PageableDefault 指定默认值也是可以的(如果不指定:默认页码为第一页,默认每页记录数为20)
技巧04:Pagealbe 可以利用 @PageableDefault 设置默认值(即:前端不传入任何参数,直接使用开发者指定的数值),例如:
@PageableDefault(size = 14, page = 14, sort = "username", direction = Direction.DESC) Pageable pageable
5.2 前端传参
在前端直接在请求路径中利用 k-v 键值对传入即可,形如
技巧01:分页查询的参数变量必须是page、size、sort,分别代表页码、每页记录数、排序字段及其升降序;前端传入这三个参数,后台会自动封装到 Pageable 对象中
http://127.0.0.1:9999/test/page?page=12&size=23&sort=name,asc
疑惑01:后台明明时利用 Pageable 去接收前端的参数,为什么打印出来的日志信息却是一个 Page 对象;(理解:SpringMVC框架对Pageable进行了一次封装)
5.3 SpringJPA 中有直接进行分页查询的接口
参考文档:点击前往
6 JsonProperty
6.1 需求
当后台响应实体类的变量名和前台的需要的不一致时该如何解决;前端需要按照前端的变量规则来传,后端按照后端的变量规则来传,如何保证前后端的数据对应;例如:
》前端要求的对象格式
》后端要求的对象格式
6.2 解决办法
在定义后端的实体对象时利用 @JsonProperty 指定前端的变量名,例如:
package cn.xiangxu.product.VO; import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data; import javax.persistence.Column;
import java.util.List; /**
* @author 王杨帅
* @create 2018-07-23 14:22
* @desc 商品类型视图
**/
@Data
public class CategoryVO { /**
* 类目名字
*/
@JsonProperty(value = "name")
private String categoryName;
/**
* 类目编号
*/
@JsonProperty(value = "type")
private Integer categoryType; /** 商品视图列表 */
@JsonProperty(value = "foods")
private List<ProductVO> productVOList; }
6.3 测试
6.3.1 准备
》创建一个SpringBoot项目,并引入lombok、spring-boot-starter-web依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency> <!--日志、get\set\toString satrt-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<!--<version>1.18.0</version>-->
<!--<scope>provided</scope>-->
</dependency>
<!--日志、get\set\toString end-->
》编写视图类和视图类工具
》》响应视图类
技巧01:@Data注解的目的是自动生成get\set\toString等方法
坑01:利用IDEA开发时就算引入了lombok依赖,也在相关类中添加了@Data注解,但是启动应用时会报错;因为lombok会在应用打包时自动给我们生成相关方法,直接利用IDEA启动应用时那些方法还没有生成,所以会报错;解决办法是在IDEA中安装一个lombok插件
package cn.xiangxu.product.VO; import lombok.Data; /**
* @author 王杨帅
* @create 2018-07-23 13:58
* @desc 数据封装视图
**/
@Data
public class ResultVO<T> {
private Integer code;
private String msg;
private T data;
}
ResultVO
》》响应视图类工具
package cn.xiangxu.product.utils; import cn.xiangxu.product.VO.ResultVO; /**
* @author 王杨帅
* @create 2018-07-23 14:06
* @desc 响应视图工具类
**/
public class ResultVoUtil { public static ResultVO success(Object data) { ResultVO resultVO = new ResultVO();
resultVO.setCode(0);
resultVO.setMsg("请求成功");
resultVO.setData(data); return resultVO;
} }
》》数据视图类
package cn.xiangxu.product.VO; import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data; import javax.persistence.Column;
import java.util.List; /**
* @author 王杨帅
* @create 2018-07-23 14:22
* @desc 商品类型视图
**/
@Data
public class CategoryVO { /**
* 类目名字
*/
@JsonProperty(value = "name")
private String categoryName;
/**
* 类目编号
*/
@JsonProperty(value = "type")
private Integer categoryType; /** 商品视图列表 */
@JsonProperty(value = "foods")
private List<ProductVO> productVOList; }
6.3.2 测试Get请求
6.3.3 测试POST请求
6.3.4 代码汇总
package cn.xiangxu.product.controller; import cn.xiangxu.product.VO.CategoryVO;
import cn.xiangxu.product.VO.ResultVO;
import cn.xiangxu.product.utils.ResultVoUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*; /**
* @author 王杨帅
* @create 2018-07-23 15:51
* @desc 测试控制层
**/
@RestController
@RequestMapping(value = "/test")
@Slf4j
public class TestController { @GetMapping(value = "/connect")
public ResultVO connect() {
String result = "前后台连接成功";
log.info(result);
return ResultVoUtil.success(result);
} @GetMapping(value = "/test01")
public ResultVO test01() { CategoryVO categoryVO = new CategoryVO();
categoryVO.setCategoryName("熟食");
categoryVO.setCategoryType(2);
categoryVO.setProductVOList(null); return ResultVoUtil.success(categoryVO);
} @PostMapping(value = "/test02")
public ResultVO test02(
@RequestBody CategoryVO categoryVO
) {
log.info("前端传过来的参数信息为:" + categoryVO); return ResultVoUtil.success(categoryVO);
} }
SpringBoot16 MockMvc的使用、JsonPath的使用、请求参数问题、JsonView、分页查询参数、JsonProperty的更多相关文章
- FeignClient调用POST请求时查询参数被丢失的情况分析与处理
前言 本文没有详细介绍 FeignClient 的知识点,网上有很多优秀的文章介绍了 FeignCient 的知识点,在这里本人就不重复了,只是专注在这个问题点上. 查询参数丢失场景 业务描述: 业务 ...
- FastAPI(5)- get 请求 - 查询参数 Query Parameters
什么是查询参数? http://127.0.0.1:8000/get?name=xxx&age=18 http://127.0.0.1:8000/get?age=18&name=xxx ...
- EBS 开发中如何动态启用和禁止请求(Current Request)的参数
EBS 开发中如何动态启用和禁止请求(Current Request)的参数 (版权声明,本人原创或者翻译的文章如需转载,如转载用于个人学习,请注明出处:否则请与本人联系,违者必究) 我们可以使用依赖 ...
- axios 发 post 请求,后端接收不到参数的解决方案
问题场景 场景很简单,就是一个正常 axios post 请求: axios({ headers: { 'deviceCode': 'A95ZEF1-47B5-AC90BF3' }, method: ...
- SpringMVC 学习笔记(请求方法的返回值和参数)
在用注解对配置 处理器时,一般是一个方法处理一个请求,不同方法的返回类型有着不同的意义. 返回值为 ModelAndView 类型 ModelAndView 是Model 和 View 的一个集合类型 ...
- axios 发 post 请求,后端接收不到参数的解决方案(转载)
原文地址:https://www.cnblogs.com/yiyi17/p/9409249.html 问题场景 场景很简单,就是一个正常 axios post 请求: axios({ headers: ...
- flask的post,get请求及获取不同格式的参数
flask的post,get请求及获取不同格式的参数 1 获取不同格式参数 1.0 获取json参数 Demo from flask import Flask, request, jsonify ap ...
- 使用@RequestBody将请求体映射到Action方法参数中
@PostMapping("/user") public User create(@RequestBody User user){ System.out.println(user. ...
- [JavaEE]Get请求URI中带的中文参数在服务端乱码问题的解决方法
在Get请求中,如果请求参数中带有中文,如 http://localhost:8080/DinnerParty/shop/search?query=多伦多, 在服务端拿到的是乱码. 这是因为客户端提交 ...
随机推荐
- HWOJ-求字符串最后一个单词的长度
题目:给定一个字符串,求最后一个单词的长度,每个单词中间有空格. 例如:输入:hello world 输出:5 C代码:通过. #include <stdio.h> #define m ...
- python RabbitMQ队列使用
python RabbitMQ队列使用 关于python的queue介绍 关于python的队列,内置的有两种,一种是线程queue,另一种是进程queue,但是这两种queue都是只能在同一个进程下 ...
- Python 函数 -next()
next() next() 返回迭代器的下一个项目. iterator - 可迭代对象. default - 可选,用于设置在没有下一个元素时返回该默认值,如果不设置,又没有下一个元素则会触发 St ...
- 基于jwt和角色的访问控制解决方案
0,主要解决两个问题:1身份验证(防止httpclient拼接请求),2权限控制 1,身份验证使用jwt,在java就是jjwt jwt可以比较好的整合restful,对无状态客户端比较友好,(用se ...
- The type javax.xml.rpc.ServiceException cannot be resolved.It is indirectly
The type javax.xml.rpc.ServiceException cannot be resolved.It is indirectly 博客分类: 解决方案_Java 问题描述:T ...
- MyBatis缓存结构
Mybatis Cache结构图: CacheKey(statementId, sql, sqlParams,other). 上图展示了Mybatis Cache的结构: 1)每个Mapper对应一块 ...
- windows下安装ImageMagick
最近在开发过程中用到了ImageMagick,结合网上的教程做一下记录 安装的具体步骤可以参考http://blog.csdn.net/belen_xue/article/details/728962 ...
- Navicat设定mysql定时任务步骤示例
怎样在Navicat中设置,是数据库按照记录中的日期更新状态字段 其实这个很常用,比如你网站里的某条记录的日期——比如说数据库中某条活动记录的审核日期字段已经过期,亦即当前时间已经超过审核日期,那么定 ...
- android开源库收集
1. google valley Android网络通信库 git clone https://android.googlesource.com/platform/frameworks/volley ...
- Linux系统层面标配
1.MySQL中出现存SWAP,主要会是哪些原因?--物理内存切实不足--numa导致内存分配不均,出现物理内存未使用完,就出现大量swap的使用 2.MySQ中CPU负载很高,是什么原因?给出查找的 ...