1. 概述
在这个简短的教程中,我们将仔细研究如何在Spring MVC中使用 JSON 参数。
首先,我们将从 JSON 参数的一些背景知识开始。然后,我们将深入研究如何在 POST 和 GET 请求中发送 JSON 参数。
2. Spring MVC中的JSON参数
使用JSON发送或接收数据是 Web 开发人员的常见做法。JSON 字符串的层次结构提供了一种更紧凑和人类可读的方式来表示 HTTP 请求参数。
默认情况下,Spring MVC 为String等简单数据类型提供开箱即用的数据绑定。为此,它在后台使用了一系列内置属性编辑器。
然而,在实际项目中,我们可能希望绑定更复杂的数据类型。例如,将 JSON 参数映射到模型对象可能会很方便。
3. POST发送JSON数据
Spring 提供了一种通过 POST 请求发送 JSON 数据的直接方式。内置的@RequestBody注解可以自动将请求体中封装的JSON数据反序列化为特定的模型对象。
一般来说,我们不必自己解析请求体。我们可以使用Jackson 库为我们完成所有繁重的工作。
现在,让我们看看如何在Spring MVC中通过 POST 请求发送 JSON 数据。
首先,我们需要创建一个模型对象来表示传递的 JSON 数据。例如,考虑Product类:
public class Product {
private int id;
private String name;
private double price;
// default constructor + getters + setters
}
其次,让我们定义一个接受 POST 请求的 Spring 处理程序方法:
@PostMapping("/create")
@ResponseBody
public Product createProduct(@RequestBody Product product) {
// custom logic
return product;
}
如我们所见,使用@RequestBody注解产品参数足以绑定从客户端发送的 JSON 数据。
现在,我们可以使用cURL测试我们的 POST 请求:
curl -i
-H "Accept: application/json"
-H "Content-Type: application/json"
-X POST --data
'{"id": 1,"name": "Asus Zenbook","price": 800}' "http://localhost:8080/spring-mvc-basics-4/products/create"
4. GET方式发送JSON参数
Spring MVC 提供@RequestParam来从 GET 请求中提取查询参数。但是,与@RequestBody不同的是, @RequestParam注解仅支持简单的数据类型,例如int和String。
因此,要发送 JSON,我们需要将 JSON 参数定义为一个简单的字符串。
这里的大问题是:我们如何将 JSON 参数(它是一个String)转换为Product类的对象?
答案很简单!Jackson 库提供的ObjectMapper类提供了一种将 JSON 字符串转换为Java对象的灵活方法。
现在,让我们看看如何在Spring MVC中通过 GET 请求发送 JSON 参数。首先,我们需要在控制器中创建另一个处理程序方法来处理 GET 请求:
@GetMapping("/get")
@ResponseBody
public Product getProduct(@RequestParam String product) throws JsonMappingException, JsonProcessingException {
Product prod = objectMapper.readValue(product, Product.class);
return prod;
}
如上所示,readValue()方法允许将 JSON 参数product直接反序列化为Product类的实例。
请注意,我们将 JSON 查询参数定义为String对象。现在,如果我们想像使用@RequestBody时那样传递一个Product对象怎么办?
为了回答这个问题,Spring 通过自定义属性编辑器提供了一种简洁灵活的解决方案。
首先,我们需要创建一个自定义属性编辑器来封装将作为String给出的 JSON 参数转换为Product 对象的逻辑:
public class ProductEditor extends PropertyEditorSupport {
private ObjectMapper objectMapper;
public ProductEditor(ObjectMapper objectMapper) {
this.objectMapper = objectMapper;
}
@Override
public void setAsText(String text) throws IllegalArgumentException {
if (StringUtils.isEmpty(text)) {
setValue(null);
} else {
Product prod = new Product();
try {
prod = objectMapper.readValue(text, Product.class);
} catch (JsonProcessingException e) {
throw new IllegalArgumentException(e);
}
setValue(prod);
}
}
}
接下来,让我们将 JSON 参数绑定到Product类的对象:
@GetMapping("/get2")
@ResponseBody
public Product get2Product(@RequestParam Product product) {
// custom logic
return product;
}
最后,我们需要添加最后一块缺失的拼图。让我们在 Spring 控制器中注册ProductEditor:
@InitBinder
public void initBinder(WebDataBinder binder) {
binder.registerCustomEditor(Product.class, new ProductEditor(objectMapper));
}
请记住,我们需要对 JSON 参数进行 URL 编码以确保安全传输。
所以,而不是:
GET /spring-mvc-basics-4/products/get2?product={"id": 1,"name": "Asus Zenbook","price": 800}
我们需要发送:
GET /spring-mvc-basics-4/products/get2?product=%7B%22id%22%3A%201%2C%22name%22%3A%20%22Asus%20Zenbook%22%2C%22price%22%3A%20800%7D
5.总结
总而言之,我们看到了如何在Spring MVC中使用 JSON。一路上,我们展示了如何在 POST 和 GET 请求中发送 JSON 参数。
与往常一样,本教程的完整源代码可在GitHub上获得。