總結一下Spring中一些解析json數據的技巧。
@RequestBody注解
@RequestBody注解常用來處理content-type不是默認的application/x-www-form-urlcoded編碼的內容,比如application/json或者是application/xml等。一般情況下來說常用其來處理application/json類型。
@RequestBody的修飾對象的控制器方法形參,一般用於修飾JavaBean形參,其可以將請求體中的JSON字符串綁定到修飾的bean上。也可以修飾字符串,會將請求體的參數以key1=value1&key2=value2&...的格式復制給String控制器參數。
修飾JavaBean時,json字符串要與JavaBean的屬性對應,且可以修飾List集合類型的形參,這時前端要以json數組的形式發送數據,且要指定content-type為application/json類型。
接收json對象字符串示例
JavaBean:
public class Role {
private int id;
private String roleName;
//getter、setter、toString
}
public class Person {
private String name;
private Integer age;
private List<Role> roles;
//getter、setter、toString
}
Controller:
@RestController
public class DataResolveController {
@PostMapping("/doJsonObject")
public String resolveJsonObject(@RequestBody Person person){
System.out.println(person);
return "ok";
}
}
在前端發送Ajax:
- 注意發送ajax請求時,contentType要指定為
application/json。 - person對象的屬性與Person類一一對應,其中roles的屬性值是一個json對象數組。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Index</title>
<script src="https://cdn.staticfile.org/jquery/2.1.1/jquery.min.js"></script>
</head>
<body>
<h1>Test @RequestBody</h1>
<button id="send">send ajax</button>
<script>
$("#send").click(function () {
var person = {
"name":"白小純",
"age":"20",
"roles":[
{"id":"1","roleName":"醫生"},
{"id":"2","roleName":"老師"}
]};
$.ajax({
type: "POST",
url: "doJsonObject",
contentType: "application/json; charset=utf-8",
data: JSON.stringify(person),
dataType: "json",
});
})
</script>
</body>
</html>
點擊按鈕,后台輸出:
Person{name='白小純', age=20, roles=[Role{id=1, roleName='醫生'}, Role{id=2, roleName='老師'}]}
接收json數組示例
控制器:
@RequestMapping("/sendarray")
@ResponseBody
public String testReceiveArray(@RequestBody List<Integer> array){
System.out.println(array);
return "success";
}
Ajax代碼(jQuery):
- 這里發送json數組可以直接使用字符串形式,如下。也可以先創建一個變量
var array = [1,2,3,5],再通過JSON.stringify(array)轉換為json數據。
$(function () {
$("#btn1").click(function () {
//var array = [1,2,3,5];
//JSON.stringify(array)
$.ajax({
url: "sendarray",
type: "post",
data: "[1,2,3]",
dataType: "text",
contentType: "application/json;charset=UTF-8",
success: function (result) {
alert(result);
}
})
})
});
服務端輸出:[1, 2, 3]。
List的元素也可以是其他的JavaBean。
使用Jackson處理json
Jackson簡介
來自參考連接
Jackson 是當前用的比較廣泛的,用來序列化和反序列化 json 的 Java 的開源框架。Jackson 社區相對比較活躍,更新速度也比較快, 從 Github 中的統計來看,Jackson 是最流行的 json 解析器之一 。 Spring MVC 的默認 json 解析器便是 Jackson。 Jackson 優點很多。 Jackson 所依賴的 jar 包較少 ,簡單易用。與其他 Java 的 json 的框架 Gson 等相比, Jackson 解析大的 json 文件速度比較快;Jackson 運行時占用內存比較低,性能比較好;Jackson 有靈活的 API,可以很容易進行擴展和定制。
Jackson 的 1.x 版本的包名是 org.codehaus.jackson ,當升級到 2.x 版本時,包名變為 com.fasterxml.jackson。
Jackson 的核心模塊由三部分組成。
- jackson-core,核心包,提供基於"流模式"解析的相關 API,它包括 JsonPaser 和 JsonGenerator。 Jackson 內部實現正是通過高性能的流模式 API 的 JsonGenerator 和 JsonParser 來生成和解析 json。
- jackson-annotations,注解包,提供標准注解功能;
- jackson-databind ,數據綁定包, 提供基於"對象綁定" 解析的相關 API ( ObjectMapper ) 和"樹模型" 解析的相關 API (JsonNode);基於"對象綁定" 解析的 API 和"樹模型"解析的 API 依賴基於"流模式"解析的 API。
依賴
對於SpringMVC項目,需要導入依賴(maven):
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.9.6</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.9.6</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.6</version>
</dependency>
對於SpringBoot項目,依賴spring-boot-starter-web中就包括了Jackson的依賴。所以無需導入。
JSON字符串-》對象
Jackson的一個主要類就是ObjectMapper,通過該類的readValue()方法可以將json字符串解析為指定對象。
示例:
JavaBean使用上述的Person和Role。
@Test
void testJackson() throws JsonProcessingException {
ObjectMapper mapper = new ObjectMapper();
String personJson = "{\"name\":\"白小純\", \"age\":\"20\", \"roles\":[{\"id\":\"1\",\"roleName\":\"醫生\"}, " +
"{\"id\":\"2\",\"roleName\":\"老師\"}]}";
Person person = mapper.readValue(personJson, Person.class);
System.out.println(person);
}
輸出:
Person{name='白小純', age=20, roles=[Role{id=1, roleName='醫生'}, Role{id=2, roleName='老師'}]}
對象-》json字符串
通過ObjectMapper對象的writeValueAsString()方法實現。
示例:
public void testObjectToJson() throws JsonProcessingException {
ObjectMapper mapper = new ObjectMapper();
Person person = new Person();
List<Role> roles = new ArrayList<>();
Role role1 = new Role();
Role role2 = new Role();
role1.setId(1);
role1.setRoleName("學生");
role2.setId(2);
role2.setRoleName("班長");
roles.add(role1);
roles.add(role2);
person.setAge(20);
person.setName("王大錘");
person.setRoles(roles);
String personStr = mapper.writeValueAsString(person);
System.out.println(personStr);
}
輸出:
{"name":"王大錘","age":20,"roles":[{"id":1,"roleName":"學生"},{"id":2,"roleName":"班長"}]}
JSON數組《-》Lsit
readValue()方法可以解析JSON對象數組字符串為List集合,同樣的,writeValueAsString()方法可以將List集合中的多個對象解析為Json對象數組字符串。
示例:
注意readValue()方法的第二個參數
public void testJsonTOList() throws JsonProcessingException {
String rolesStr = "[{\"id\":1,\"roleName\":\"快遞員\"},{\"id\":2,\"roleName\":\"程序員\"}]";
ObjectMapper mapper = new ObjectMapper();
List<Role> roles = mapper.readValue(rolesStr, new TypeReference<List<Role>>() {});
System.out.println(roles);
String jsonArray = mapper.writeValueAsString(roles);
System.out.println(jsonArray);
}
輸出:
[Role{id=1, roleName='快遞員'}, Role{id=2, roleName='程序員'}]
[{"id":1,"roleName":"快遞員"},{"id":2,"roleName":"程序員"}]
References
Jackson使用詳解--掘金 三分惡(想要深入了解Jackson可以看這篇博客,巨詳細)
