下面是常见的请求
左侧的是常用请求,右侧的是RESTful 风格API,在url中看不出具体的详情
RESTful 特点:
1.用url来描述资源
2.使用HTTP方法描述行为(POST、GET、PUT、DELETE),使用HTTP状态码来表示不同的结果
3.使用JSON交互数据
4.RESTful只是一种风格,并不是强制的标准
------------------------------------------------------------------------
在项目imooc-security-demo中pom.xml文件添加测试jar包
<!-- 测试 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
由于在开发中会经常使用MockMvcRequestBuilders和MockMvcResultMatchers这两个类,将这两个类加入eclipse的偏好设置里面,如下
项目文件大致结构如下
User
package com.imooc.dto;
public class User {
private String username;
private String password;
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;
}
@Override
public String toString() {
return "User [username=" + username + ", password=" + password + "]";
}
}
查询条件类UserQueryCondition
package com.imooc.dto;
public class UserQueryCondition {
private String username;
private int age;
private int ageTo;
private String xxx;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public int getAgeTo() {
return ageTo;
}
public void setAgeTo(int ageTo) {
this.ageTo = ageTo;
}
public String getXxx() {
return xxx;
}
public void setXxx(String xxx) {
this.xxx = xxx;
}
}
控制类UserController
package com.imooc.web.controller;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.lang.builder.ReflectionToStringBuilder;
import org.apache.commons.lang.builder.ToStringStyle;
import org.springframework.data.domain.Pageable;
import org.springframework.data.web.PageableDefault;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import com.imooc.dto.User;
import com.imooc.dto.UserQueryCondition;
@RestController
public class UserController {
@RequestMapping(value = "/user", method = RequestMethod.GET)
//@PageableDefault注解为Pageable指定默认值3个参数,若没有参数传进来,则按照@PageableDefault默认分页配置
public List<User> query(UserQueryCondition condition, @PageableDefault(page = 2, size = 17, sort = "username,asc") Pageable pageable){
System.out.println(ReflectionToStringBuilder.toString(condition, ToStringStyle.MULTI_LINE_STYLE));
System.out.println(pageable.getPageSize());
System.out.println(pageable.getPageNumber());
System.out.println(pageable.getSort());
List<User> users = new ArrayList<User>();
users.add(new User());
users.add(new User());
users.add(new User());
return users;
}
}
测试类,模拟MVC请求
package com.imooc.web.controller;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
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.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;
@RunWith(SpringRunner.class)
@SpringBootTest
public class UserControllerTest {
@Autowired
private WebApplicationContext wac;
private MockMvc mockMvc;
/**
* 构造一个MVC环境
*/
@Before
public void setup(){
mockMvc = MockMvcBuilders.webAppContextSetup(wac).build();
}
@Test
public void whenQuerySuccess() throws Exception{
//发送模拟MVC请求
mockMvc.perform(get("/user")
.param("username", "jojo") //查询条件
.param("age", "18")
.param("ageTo", "60")
.param("xxx", "yyy")
//查询第三页 每页15条 查询结果按照年龄降序排列
//.param("size", "15")
//.param("page", "3")
//.param("sort", "age,desc")
.contentType(MediaType.APPLICATION_JSON_UTF8))
//执行上面请求后的期望
.andExpect(status().isOk())//状态码 200
.andExpect(jsonPath("$.length()").value(3));//期望返回的是一个集合 长度为3
}
}
运行测试类,控制台输出如下
com.imooc.dto.UserQueryCondition@270d5060[
username=jojo
age=18
ageTo=60
xxx=yyy
]
17
2
username,asc: ASC
当没有分页参数传递的时候,使用默认分页设置
补充:使用 JSONPath 解析 JSON 完整内容详解
JsonPath是一种简单的方法来提取给定JSON文档的部分内容
JsonPath可在Central Maven存储库中找到。 Maven用户将其添加到您的POM:
<dependency>
<groupId>com.jayway.jsonpath</groupId>
<artifactId>json-path</artifactId>
<version>2.2.0</version>
</dependency>
jsonpath操作符如下:
函数
函数可以在路径的尾部调用,函数的输出是路径表达式的输出,该函数的输出是由函数本身所决定的。
用java代码来写一个案例:
JSON数据如下
{
"store": {
"book": [
{
"category": "reference",
"author": "Nigel Rees",
"title": "Sayings of the Century",
"price": 8.95
},
{
"category": "fiction",
"author": "Evelyn Waugh",
"title": "Sword of Honour",
"price": 12.99
},
{
"category": "fiction",
"author": "Herman Melville",
"title": "Moby Dick",
"isbn": "0-553-21311-3",
"price": 8.99
},
{
"category": "fiction",
"author": "J. R. R. Tolkien",
"title": "The Lord of the Rings",
"isbn": "0-395-19395-8",
"price": 22.99
}
],
"bicycle": {
"color": "red",
"price": 19.95
}
},
"expensive": 10
}
上面的json字符串的读取案例:
String json = "...";
List<String> authors = JsonPath.read(json, "$.store.book[*].author");
如果你只想读取一次,那么上面的代码就可以了
如果你还想读取其他路径,现在上面不是很好的方法,因为他每次获取都需要再解析整个文档。所以,我们可以先解析整个文档,再选择调用路径。
String json = "...";
Object document = Configuration.defaultConfiguration().jsonProvider().parse(json);
String author0 = JsonPath.read(document, "$.store.book[0].author");
String author1 = JsonPath.read(document, "$.store.book[1].author");