Перейти к основному содержимому

Параметры JSON с Spring MVC

· 4 мин. чтения

Задача: Медиана двух отсортированных массивов

Даны два отсортированных массива размерами n и m. Найдите медиану слияния этих двух массивов.
Временная сложность решения должна быть O(log(m + n)) ...

ANDROMEDA

1. Обзор

В этом кратком руководстве мы подробно рассмотрим, как работать с параметрами JSON в Spring MVC.

Во-первых, мы начнем с небольшого количества сведений о параметрах JSON. Затем мы спустимся в кроличью нору, чтобы увидеть, как отправлять параметры JSON в запросах POST и GET.

2. Параметры JSON в Spring MVC

Использование JSON для отправки или получения данных является обычной практикой среди веб-разработчиков. Иерархическая структура строк JSON предлагает более компактный и удобочитаемый способ представления параметров HTTP-запроса.

По умолчанию Spring MVC обеспечивает готовую привязку данных для простых типов данных, таких как String . Для этой цели он использует список встроенных редакторов свойств под капотом.

Однако в реальных проектах мы можем захотеть связать более сложные типы данных. Например, может быть удобно иметь возможность сопоставить параметр JSON с объектом модели.

3. Отправьте данные JSON в POST

Spring предоставляет простой способ отправки данных JSON через запросы POST. Встроенная аннотация @RequestBody может автоматически десериализовать данные JSON, инкапсулированные в теле запроса, в конкретный объект модели.

Как правило, нам не нужно самостоятельно разбирать тело запроса. Мы можем использовать библиотеку Джексона, чтобы сделать всю тяжелую работу за нас .

Теперь давайте посмотрим, как отправлять данные JSON через запрос POST в Spring MVC.

Во-первых, нам нужно создать объект модели для представления переданных данных JSON. Например, рассмотрим класс Product :

public class Product {

private int id;
private String name;
private double price;

// default constructor + getters + setters

}

Во-вторых, давайте определим метод обработчика Spring, который принимает запросы POST:

@PostMapping("/create")
@ResponseBody
public Product createProduct(@RequestBody Product product) {
// custom logic
return product;
}

Как мы видим, аннотирования аргумента продукта с помощью @RequestBody достаточно для привязки данных JSON, отправляемых от клиентов .

Теперь мы можем протестировать наш POST-запрос с помощью cURL :

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. Отправьте параметр JSON в GET

Spring MVC предлагает @RequestParam для извлечения параметров запроса из запросов GET. Однако, в отличие от @RequestBody , аннотация @RequestParam поддерживает только простые типы данных, такие как int и String .

Итак, чтобы отправить JSON, нам нужно определить наш параметр JSON как простую строку.

Большой вопрос здесь: как нам преобразовать наш параметр JSON (который является строкой ) в объект класса Product ?

Ответ довольно прост! Класс ObjectMapper , предоставляемый библиотекой Jackson, предлагает гибкий способ преобразования строк JSON в объекты Java .

Теперь давайте посмотрим, как отправить параметр JSON через запрос GET в Spring MVC. Во-первых, нам нужно создать еще один метод-обработчик в нашем контроллере для обработки запросов 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 .

Обратите внимание, что мы определяем наш параметр запроса JSON как объект String . А что, если мы хотим передать объект Product , как при использовании @RequestBody ?

Чтобы ответить на этот вопрос, Spring предоставляет лаконичное и гибкое решение в виде пользовательских редакторов свойств .

Во- первых, нам нужно создать редактор пользовательских свойств, чтобы инкапсулировать логику преобразования параметра JSON, заданного как String , в объект 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;
}

Наконец, нам нужно добавить последнюю недостающую часть головоломки. Давайте зарегистрируем ProductEditor в нашем контроллере Spring :

@InitBinder
public void initBinder(WebDataBinder binder) {
binder.registerCustomEditor(Product.class, new ProductEditor(objectMapper));
}

Имейте в виду, что нам нужно URL-кодировать параметр JSON, чтобы обеспечить безопасную транспортировку .

Итак, вместо:

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. Вывод

Подводя итог, мы увидели, как работать с JSON в Spring MVC. Попутно мы продемонстрировали, как отправлять параметры JSON в запросах POST и GET.

Как всегда, полный исходный код примеров доступен на GitHub .