1. Overview
1.概述
In this short tutorial, we’re going to take a close look at how to work with JSON parameters in Spring MVC.
在这个简短的教程中,我们将仔细研究如何在Spring MVC中使用JSON参数。
First, we’ll start with a little bit of background on JSON parameters. Then, we’ll go down the rabbit hole to see how to send JSON parameters in POST and GET requests.
首先,我们先介绍一下JSON参数的背景。然后,我们将进入兔子洞,看看如何在POST和GET请求中发送JSON参数。
2. JSON Parameters in Spring MVC
Spring MVC中的JSON参数
Using JSON to send or receive data is a common practice among web developers. The hierarchical structure of the JSON strings offers a more compact and human-readable way to represent HTTP request parameters.
使用JSON来发送或接收数据是网络开发人员的一种常见做法。JSON字符串的分层结构为表示HTTP请求参数提供了一种更紧凑、更易于人类阅读的方式。
By default, Spring MVC provides out-of-the-box data binding for simple data types such as String. For that purpose, it uses a list of built-in property editors under-the-hood.
默认情况下,Spring MVC为诸如String等简单的数据类型提供开箱即用的数据绑定。为此,它使用了一个内置属性编辑器的列表。。
However, in real-world projects, we may want to bind more complex data types. For example, it might be handy to be able to map a JSON parameter into a model object.
然而,在现实世界的项目中,我们可能想要绑定更复杂的数据类型。例如,能够将一个JSON参数映射到一个模型对象中可能会很方便。
3. Send JSON Data in POST
在POST中发送JSON数据
Spring provides a straightforward way to send JSON data via POST requests. The built-in @RequestBody annotation can automatically deserialize the JSON data encapsulated in the request body into a particular model object.
Spring提供了一种直接的方法来通过POST请求发送JSON数据。内置的@RequestBody annotation可以自动将请求正文中封装的JSON数据反序列化为一个特定的模型对象。
In general, we don’t have to parse the request body ourselves. We can use the Jackson library to do all the heavy lifting for us.
一般来说,我们不必自己去解析请求体。我们可以使用Jackson库来为我们完成所有繁重的工作。
Now, let’s see how to send JSON data via a POST request in Spring MVC.
现在,让我们看看如何在Spring MVC中通过POST请求发送JSON数据。
Firstly, we need to create a model object to represent the passed JSON data. For instance, consider the Product class:
首先,我们需要创建一个模型对象来表示传递的JSON数据。例如,考虑Product类。
public class Product {
private int id;
private String name;
private double price;
// default constructor + getters + setters
}
Secondarily, let’s define a Spring handler method that accepts POST requests:
其次,让我们定义一个接受POST请求的Spring处理方法。
@PostMapping("/create")
@ResponseBody
public Product createProduct(@RequestBody Product product) {
// custom logic
return product;
}
As we can see, annotating the product argument with @RequestBody is enough to bind the JSON data sent from the clients.
正如我们所看到的,用@RequestBody标注产品参数,就足以绑定从客户端发送的JSON数据。
Now, we can test our POST request using cURL:
现在,我们可以使用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. Send JSON Parameter in GET
4. 在GET中发送JSON参数
Spring MVC offers @RequestParam to extract query parameters from GET requests. However, unlike @RequestBody, the @RequestParam annotation supports only simple data types such as int and String.
Spring MVC提供了@RequestParam来从GET请求中提取查询参数。然而,与@RequestBody不同,@RequestParam标注只支持简单的数据类型,如int和String。
So, to send JSON, we’ll need to define our JSON parameter as a simple string.
因此,为了发送JSON,我们需要将我们的JSON参数定义为一个简单的字符串。
The big question here is: How do we convert our JSON parameter (which is a String) into an object of the Product class?
这里的大问题是。我们如何将我们的JSON参数(是一个String)转换成Product类的对象?
The answer is pretty simple! The ObjectMapper class provided by the Jackson library offers a flexible way to convert JSON strings into Java objects.
答案是非常简单的!Jackson库提供的ObjectMapper类提供了一种将JSON字符串转换为Java对象的灵活方法。
Now, let’s see how to send a JSON parameter via a GET request in Spring MVC. First, we’ll need to create another handler method in our controller to handle GET requests:
现在,让我们看看如何在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;
}
As shown above, the readValue() method allows deserializing the JSON parameter product directly into an instance of the Product class.
如上所示,readValue()方法允许将JSON参数product直接反序列化为Product类的一个实例。
Note that we define our JSON query parameter as a String object. Now, what if we want to pass a Product object like we did when using @RequestBody?
请注意,我们将JSON查询参数定义为一个String对象。现在,如果我们想像使用@RequestBody时那样传递一个Product对象,该怎么办?
To answer this question, Spring provides a concise and flexible solution through custom property editors.
为了回答这个问题,Spring通过custom property editors提供了一个简洁而灵活的解决方案。
First, we’ll need to create a custom property editor to encapsulate the logic of converting the JSON parameter given as a String to a Product object:
首先,我们需要创建一个自定义属性编辑器,以封装将作为String的JSON参数转换为Productobject的逻辑。
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);
}
}
}
Next, let’s bind the JSON parameter to an object of Product class:
接下来,让我们把JSON参数绑定到Product类的一个对象。
@GetMapping("/get2")
@ResponseBody
public Product get2Product(@RequestParam Product product) {
// custom logic
return product;
}
Lastly, we need to add the last missing piece of the puzzle. Let’s register ProductEditor in our Spring controller:
最后,我们需要添加拼图中最后一块缺失的部分。让我们在Spring控制器中注册ProductEditor。
@InitBinder
public void initBinder(WebDataBinder binder) {
binder.registerCustomEditor(Product.class, new ProductEditor(objectMapper));
}
Bear in mind that we need to URL-encode the JSON parameter to ensure safe transport.
请记住,我们需要对JSON参数进行URL编码以确保安全传输。
So, instead of:
因此,而不是。
GET /spring-mvc-basics-4/products/get2?product={"id": 1,"name": "Asus Zenbook","price": 800}
We need to send:
我们需要发送。
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. Conclusion
5.总结
To sum it up, we saw how to work with JSON in Spring MVC. Along the way, we showcased how to send JSON parameters in POST and GET requests.
总而言之,我们看到了如何在Spring MVC中使用JSON。在此过程中,我们展示了如何在POST和GET请求中发送JSON参数。
As always, the full source code of the examples is available over on GitHub.
一如既往,这些示例的完整源代码可在GitHub上获得over。