ResponseEntity<> должен вернуть несколько объектов. Как это осуществить?
Необходимо вернуть детали по id продукта и их количество. Прошу оценить код.
@RestController @RequestMapping("/api/v1/details") public class DetailRestControllerV1 < private final DetailService detailService; public DetailRestControllerV1(DetailService detailService) < this.detailService = detailService; >@GetMapping("/byproduct/") public ResponseEntity getDetailsByProduct(@PathVariable("id") Long productId) < if (productId == null) < return new ResponseEntity<>(HttpStatus.BAD_REQUEST); > List details = detailService.findDetailsByProductId(productId); if (details.isEmpty()) < return new ResponseEntity<>(HttpStatus.NOT_FOUND); > int countDetails = details.size(); DetailsAndDetailsCountContainer container = new DetailsAndDetailsCountContainer(); container.setDetails(details); container.setCountDetails(countDetails); return new ResponseEntity<>(container, HttpStatus.OK); >
> Сам объект
@Data public class DetailsAndDetailsCountContainer < private Listdetails; private int countDetails; >
Насколько правильное это решение и есть ли альтернативы?
Отслеживать
задан 11 фев 2021 в 9:16
Николай дерягин Николай дерягин
7 2 2 бронзовых знака
Вы изобрели обычный wrapper, что является правильным и достаточно стандартным подходом.
11 фев 2021 в 9:41
1 ответ 1
Сортировка: Сброс на вариант по умолчанию
Если на другой стороне полноценный JSON парсер (Java, JavaScript, TypeScript. ), то можно возвращать ResponseEntity> , список на той стороне десериализуется в список или массив, в зависимости от языка, а у него будет длина.
public class DataList < private Listitems; private int count; DataList(List items) < this.items = items; this.count = items.size(); >> ResponseEntity> getDetailsByProduct(. ) < . return new ResponseEntity<>(new DataList(details), HttpStatus.OK); >
Использование Spring ResponseEntity для управления HTTP-ответом
Используя Spring, у нас обычно есть много способов достичь одной и той же цели, включая точную настройку HTTP-ответов.
В этом кратком руководстве мы увидим, как установить тело, статус и заголовки HTTP-ответа с помощью ResponseEntity .
2. Сущность ответа
ResponseEntity представляет весь ответ HTTP: код состояния, заголовки и тело . В результате мы можем использовать его для полной настройки HTTP-ответа.
Если мы хотим его использовать, мы должны вернуть его из конечной точки; Весна позаботится об остальном.
ResponseEntity — это универсальный тип. Следовательно, мы можем использовать любой тип в качестве тела ответа:
@GetMapping("/hello") ResponseEntityString> hello() return new ResponseEntity>("Hello World!", HttpStatus.OK); >
Поскольку мы указываем статус ответа программно, мы можем возвращать разные коды статуса для разных сценариев:
@GetMapping("/age") ResponseEntityString> age( @RequestParam("yearOfBirth") int yearOfBirth) if (isInFuture(yearOfBirth)) return new ResponseEntity>( "Year of birth cannot be in the future", HttpStatus.BAD_REQUEST); > return new ResponseEntity>( "Your age is " + calculateAge(yearOfBirth), HttpStatus.OK); >
Кроме того, мы можем установить заголовки HTTP:
@GetMapping("/customHeader") ResponseEntityString> customHeader() HttpHeaders headers = new HttpHeaders(); headers.add("Custom-Header", "foo"); return new ResponseEntity>( "Custom header set", headers, HttpStatus.OK); >
Кроме того, ResponseEntity предоставляет два вложенных интерфейса компоновщика : HeadersBuilder и его субинтерфейс BodyBuilder . Поэтому мы можем получить доступ к их возможностям через статические методы ResponseEntity .
Самый простой случай — это ответ с телом и кодом ответа HTTP 200:
@GetMapping("/hello") ResponseEntityString> hello() return ResponseEntity.ok("Hello World!"); >
Для самых популярных кодов состояния HTTP мы получаем статические методы:
BodyBuilder accepted(); BodyBuilder badRequest(); BodyBuilder created(java.net.URI location); HeadersBuilder?> noContent(); HeadersBuilder?> notFound(); BodyBuilder ok();
Кроме того, мы можем использовать методы состояния BodyBuilder (состояние HttpStatus) и состояния BodyBuilder (состояние int) для установки любого состояния HTTP.
Наконец, с помощью ResponseEntity BodyBuilder.body(T body) мы можем установить тело ответа HTTP:
@GetMapping("/age") ResponseEntityString> age(@RequestParam("yearOfBirth") int yearOfBirth) if (isInFuture(yearOfBirth)) return ResponseEntity.badRequest() .body("Year of birth cannot be in the future"); > return ResponseEntity.status(HttpStatus.OK) .body("Your age is " + calculateAge(yearOfBirth)); >
Мы также можем установить собственные заголовки:
@GetMapping("/customHeader") ResponseEntityString> customHeader() return ResponseEntity.ok() .header("Custom-Header", "foo") .body("Custom header set"); >
Поскольку BodyBuilder.body() возвращает ResponseEntity вместо BodyBuilder, это должен быть последний вызов.
Обратите внимание, что с помощью HeaderBuilder мы не можем установить какие-либо свойства тела ответа.
При возврате объекта ResponseEntity из контроллера мы можем получить исключение или ошибку при обработке запроса и хотели бы вернуть информацию об ошибке пользователю, представленному в виде некоторого другого типа, скажем, E .
Spring 3.2 поддерживает глобальный @ExceptionHandler с новой аннотацией @ControllerAdvice , которая обрабатывает такие сценарии. Для более подробной информации обратитесь к нашей существующей статье здесь .
Хотя ResponseEntity очень мощен, мы не должны злоупотреблять им. В простых случаях есть другие варианты, которые удовлетворяют наши потребности и приводят к более чистому коду.
3. Альтернативы
3.1. @ResponseBody
В классических приложениях Spring MVC конечные точки обычно возвращают обработанные HTML-страницы. Иногда нам нужно только вернуть фактические данные; например, когда мы используем конечную точку с AJAX.
В таких случаях мы можем пометить метод обработчика запроса с помощью @ResponseBody , и Spring обрабатывает результирующее значение метода как само тело ответа HTTP .
3.2. @ResponseStatus
Когда конечная точка успешно возвращается, Spring предоставляет ответ HTTP 200 (ОК). Если конечная точка выдает исключение, Spring ищет обработчик исключений, который сообщает, какой статус HTTP использовать.
Мы можем пометить эти методы с помощью @ResponseStatus, и поэтому Spring возвращает с пользовательским HTTP-статусом .
Дополнительные примеры см. в нашей статье о пользовательских кодах состояния .
3.3. Управляйте ответом напрямую
Spring также позволяет нам напрямую обращаться к объекту javax.servlet.http.HttpServletResponse ; нам нужно только объявить его как аргумент метода:
@GetMapping("/manual") void manual(HttpServletResponse response) throws IOException response.setHeader("Custom-Header", "foo"); response.setStatus(200); response.getWriter().println("Hello World!"); >
Поскольку Spring предоставляет абстракции и дополнительные возможности поверх базовой реализации, мы не должны манипулировать ответом таким образом .
4. Вывод
В этой статье мы обсудили несколько способов манипулирования ответом HTTP в Spring и рассмотрели их преимущества и недостатки.
Как обычно, примеры доступны на GitHub .
- 1. Введение
- 2. Сущность ответа
- 3. Альтернативы
- 3.1. @ResponseBody
- 3.2. @ResponseStatus
- 3.3. Управляйте ответом напрямую
Подготовка к Spring Professional Certification. Spring REST
Сегодняшняя статья рассмотрит основные вопросы про REST в Spring. Она будет особенно полезна для начинающих программистов.
Официальный гид от Pivotal, в котором написано про темы для подготовки.

Оглавление
- Внедрение зависимостей, контейнер, IoC, бины
- AOP (аспектно-ориентированное программирование)
- JDBC, транзакции, JPA, Spring Data
- Spring Boot
- Spring MVC
- Spring Security
- REST
- Тестирование
Spring REST — это часть Spring MVC. Поэтому многое из Spring MVC будет применяться в REST и наоборот. Для более подробного ознакомления со Spring MVC можно прочитать эту статью.
Для чего был создан REST?
Чтобы понять концепцию REST, нужно разобрать акроним на его составляющие:
- Representational — ресурсы в REST могут быть представлены в любой форме — JSON, XML, текст, или даже HTML — зависит от того, какие данные больше подходят потребителю
- State — при работе с REST вы должны быть сконцентрированы на состоянии ресурса, а не на действиях с ресурсом
- Transfer — REST включает себя передачу ресурсных данных, в любой представленной форме, от одного приложения другому.
REST это передача состояний ресурса между сервером и клиентом.
Что такое ресурс?
Ресурс в REST — это все, что может быть передано между клиентом и сервером.
Вот несколько примеров ресурсов:- Новость
- Температура в Санкт-Петербурге в понедельник в 4 утра
- Зарплата сотрудника
- Выборка из базы данных
- Результат поиска
Что обозначает CRUD?
Действия в REST определяются http-методами.
Get , Post , Put , Delete , Patch , и другие.Самые часто-используемые обозначаются аббревиатурой CRUD:
- Create — POST
- Read — GET
- Update — PUT
- Delete — DELETE
REST безопасен? Как вы можете защитить его?
По умолчанию REST не защищен.
Вы можете настроить безопасность с помощью Basic Auth, JWT, OAuth2
Что такое save operations?
Это операции, которые не модифицируют ресурсы. Вот их список:
Что такое идемпотентая операция? Почему идемпотентность важна?
Идемпотентые методы — это методы, при каждом вызове которых результат будет одинаковый.
То есть, результат после 1 вызова такого метода будет такой же, как и результат после 10 вызовов этого метода.
Это важно для отказоустойчевого API. Предположим, что клиент хочет обновить ресурс с помощью POST-запроса? Если POST не идемпотентный метод, то при многократном вызове возникнут непредвиденные обновления ресурса. Используя идемпотентные методы, вы ограждаете себя от многих ошибок.
REST хорошо масштабируется?
Да. REST хорошо масштабируется потому что он не хранит состояние.
Это значит что он не хранит информацию о пользовательских сессиях на сервере.
Информация о клиенте не должна хранится на стороне сервера, а должна передаваться каждый раз туда, где она нужна. Вот что значит ST в REST, State Transfer. Вы передаете состояние, а не храните его на сервере.
REST также интероперабельный — это значит, что на нем могут взаимодействовать разные программы написанные на разных языках. Это исходит из 2ух факторов:
- Интероперабельные HTTP-клиенты. Разные клиенты должны отправлять одинаковые http-запросы.
- Интероперабельность на уровне медиа-типов. Различные клиенты должны корректно отправлять и получать одни и те же ресурсы.
Что такое HttpMessageConverter?
HttpMessageConverter конвертирует запрос в объект и наоборот.
Spring имеет несколько реализаций этого интерфейса, а вы можете создать свою.
В этом случае DispatcherServlet не использует Model и View.
В REST вообще не существует Model и View. Есть только данные, поставляемые контроллером, и представление ресурса, когда сообщение конвертируется из медиа-типа(json, xml. ) в объект.
BufferedImageHttpMessageConverter — конвертирует BufferedImage в(из) код изображения.
Jaxb2RootElementHttpMessageConverter — конвертирует xml в(из) объект, помеченный jaxb2 аннотациями. Регистрируется, если jaxb2 находится в classpath.
MappingJackson2HttpMessageConverter — конвертирует JSON в(из) объект. Регистрируется, если Jackson 2 находится в classpath.
StringHttpMessageConverter — конвертирует все медиа-файлы в text/plain.
Как работает аннотация @RestController?
@RestController ставится на класс-контроллер вместо @Controller . Она указывает, что этот класс оперирует не моделями, а данными. Она состоит из аннотаций @Controller и @RequestBody .
@Controller @ResponseBody public interface RestControllerЗачем нужна @ResponseBody?
Аннотация @ResponseBody ставится на методы, которые работают с данными, а не с моделями. Ее не требуется указывать явно, если используется @RestController .
Обычные методы возвращают Model , а методы аннотированные @ResponseBody возвращают объекты, которые конвертируются в медиа-файлы с помощью HttpMessageConverter .
Что делает аннотация @RequestMapping?
Эта аннотация служит для маппинга запросов на классы-контроллеры и методы.
Раньше ее использовали для методов класса, чтобы указать URI, http-метод, тип отправляемых данных, и т.п. В более новых версиях Spring ее заменили на аннотации @GetMapping , @PostMapping , и т.п.Теперь она используется только для указания URI до класса-контроллера.
Что за аннотации @GetMapping, @PostMapping, @DeleteMapping и прочие?
Это более узкие аннотации для маппинга http-методов.
- @GetMapping — Обрабатывает get-запросы
- @PostMapping — Обрабатывает post-запросы
- @DeleteMapping — Обрабатывает delete-запросы
- @PutMapping — Обрабатывает put-запросы
- @PatchMapping — Обрабатывает patch-запросы
Все написанное ниже характерно также и для других аннотаций.
Аннотация @GetMapping — это просто аннотация которая содержит @RequestMapping(method = RequestMethod.GET).
Она также позволяет более глубоко настроить метод-обработчик.
Ее параметры(они конвертируются в аналогичные параметры @RequestMapping):- path — URI
- headers — заголовки
- name — имя обработчика
- params — параметры
- produces — тип возвращаемых данных(JSON, XML, текст). Используется в REST
- consumes — тип принимаемых данных. Используется в REST
По умолчанию аннотация принимает путь до метода.
@GetMapping(«managers») = @GetMapping(path = «managers»)
Зачем используется аннотация @RequestParam?
Эта аннотация используется для того, чтобы методы обработчики могли получить параметры из http-запроса.
Запрос с параметрами: http://localhost:8080/getByName/name=Ivan .
Следующий код поместит в переменную name строку Ivan .@GetMapping("getByName") public User getUserByName(@RequestParam("name") String name) < //some logic >Зачем нужна аннотация @PathVariable?
Эта аннотация получает определенную часть из URI.
Следующий код поместит в переменную id значение 23 .
@GetMapping("getById/") public User getUserById(@PathVariable("id") String id) < //some logic >Что обозначают разные коды для http-ответов?
POST — 200 OK, 201 Created, 204 No Content
PUT — 200 OK, 201 Created, 204 No Content
DELETE — 204 No Content, 202 Accepted
Зачем нужна аннотация @ResponseStatus?
Она позволяет устанавливать код ответа. Обычно Spring сам устанавливает нужный код ответа, но бывают моменты, когда это нужно переопределить.
@PostMapping @ResponseStatus(HttpStatus.CREATED) public void add(. )
Вместо использования аннотации можно возвращать ResponseEntity и вручную устанавливать код ответа.
Не рекомендуется использовать ResponseEntity и @ReponseStatus вместе.
Что такое ResponseEntity?
Это специальный класс, который представляет http-ответ. Он содержит тело ответа, код состояния, заголовки. Мы можем использовать его для более тонкой настройки http-ответа.
Он является универсальным типом, и можно использовать любой объект в качестве тела:
@GetMapping("/hello") ResponseEntity hello()Зачем нужны @RequestBody?
Вы можете использовать аннотацию @RequestBody на параметре метода, для того чтобы тело запроса конвертировалось в этот параметр.
@PostMapping("accounts") //Например, запрос с JSON конвертируется в объект Account public void handle(@RequestBody Account account)Вы можете использовать @Validated вместе с @RequestBody , для проверки пришедшего запроса.
Что такое RestTemplate? Какие у него преимущества?
RestTemplate это специальный клиент в Spring для отправки http-запросов. Он предоставляет удобные API для легкого вызова конечных точек REST’а в одну строку.
RestTemplate restTemplate = new RestTemplate(); String fooResourceUrl = "http://localhost:8080/spring-rest/foos"; ResponseEntity response = restTemplate.getForEntity(fooResourceUrl + "/1", String.class);Более подробно об использовании можно узнать в этой статье.
REST клиенты
RestTemplate предусматривает API более высокого уровня в отличие от клиентских библиотек HTTP. Он позволяет с легкостью вызывать конечные точки REST в одной строке. Он раскрывает следующие группы перегруженных методов:
Получает представление через метод GET.
Получает ResponseEntity (то есть статус, заголовки и тело) через GET.
Получает все заголовки для ресурса через метод HEAD.
Создает новый ресурс через метод POST и возвращает заголовок Location из ответа.
Создает новый ресурс через метод POST и возвращает представление из ответа.
Создает новый ресурс через метод POST и возвращает представление из ответа.
Создает или обновляет ресурс через метод PUT.
Обновляет ресурс через метод PATCH и возвращает представление из ответа. Обратите внимание, что HttpURLConnection из JDK не поддерживает метод PATCH , но Apache HttpComponents и другие – поддерживают.
Удаляет ресурсы по указанному URI-идентификатору через метод DELETE.
Получает допустимые HTTP-методы для ресурса через метод ALLOW.
Более обобщенная (и менее консервативная) версия предыдущих методов, которая обеспечивает дополнительную гибкость, если это необходимо. Он принимает RequestEntity (включая HTTP-метод, URL-адрес, заголовки и тело в качестве вводных данных) и возвращает ResponseEntity .
Эти методы позволяют использовать ParameterizedTypeReference вместо Class для задания типа ответа с помощью дженериков.
Наиболее обобщенный способ выполнения запроса, с полным контролем над подготовкой запроса и извлечением ответа через интерфейсы обратного вызова.
Инициализация
Конструктор по умолчанию использует java.net.HttpURLConnection для выполнения запросов. Можно перейти на другую HTTP-библиотеку с реализацией ClientHttpRequestFactory . Имеется встроенная поддержка для:
- Apache HttpComponents
- Netty
- OkHttp
Например, чтобы перейти на Apache HttpComponents, можно сделать следующее:
RestTemplate template = new RestTemplate(new HttpComponentsClientHttpRequestFactory());Каждая ClientHttpRequestFactory открывает параметры конфигурации, специфичные для базовой клиентской HTTP-библиотеки – например, для учетных данных, пула соединений и другой информации.
Обратите внимание, что реализация java.net для HTTP-запросов может привести к исключению при доступе к статусу ответа, который представляет собой ошибку (например, 401). Если это проблема, то переключитесь на другую HTTP-библиотеку клиента.
URI-идентификаторы
Многие методы RestTemplate принимают URI-шаблон и переменные URI-шаблона либо как аргумент переменной String , либо как Map .
В следующем примере используется аргумент переменной String :
String result = restTemplate.getForObject( "https://example.com/hotels//bookings/", String.class, "42", "21");В следующем примере используется Map :
Map vars = Collections.singletonMap("hotel", "42"); String result = restTemplate.getForObject( "https://example.com/hotels//rooms/", String.class, vars);Помните, что URI-шаблоны автоматически кодируются, как показано в следующем примере:
restTemplate.getForObject("https://example.com/hotel list", String.class); // Результат запроса по "https://example.com/hotel%20list"Можно использовать свойство uriTemplateHandler шаблона RestTemplate для настройки кодирования URI-идентификаторов. Кроме того, можно подготовить java.net.URI и передать его в один из методов RestTemplate , который принимает URI .
Подробнее о работе с URI-идентификаторами и их кодировании см. в разделе «URI-ссылки».
Заголовки
Вы можете использовать методы exchange() для задания заголовков запроса, как показано в следующем примере:
String uriTemplate = "https://example.com/hotels/"; URI uri = UriComponentsBuilder.fromUriString(uriTemplate).build(42); RequestEntity requestEntity = RequestEntity.get(uri) .header("MyRequestHeader", "MyValue") .build(); ResponseEntity response = template.exchange(requestEntity, String.class); String responseHeader = response.getHeaders().getFirst("MyResponseHeader"); String body = response.getBody();Можно получать заголовки ответа через множество вариантов методов RestTemplate , которые возвращают ResponseEntity .
Тело
Объекты, передаваемые в методы RestTemplate и возвращаемые из них, преобразуются в сырое содержимое и обратно с помощью HttpMessageConverter .
При методе POST объект ввода сериализуется в тело запроса, как показано в следующем примере:
URI location = template.postForLocation("https://example.com/people", person);Вам не нужно явно устанавливать заголовок Content-Type для запроса. В большинстве случаев можно найти совместимый преобразователь сообщений на основе типа исходного Object , и выбранный преобразователь сообщений будет устанавливать тип содержимого соответствующим образом. Если необходимо, то можно использовать методы exchange , чтобы явно указать заголовок запроса Content-Type , а это, в свою очередь, влияет на то, какой преобразователь сообщений будет выбран.
При методе GET тело ответа десериализуется в Object вывода, как показано в следующем примере:
Person person = restTemplate.getForObject("https://example.com/people/", Person.class, 42);Заголовок Accept запроса явно устанавливать не требуется. В большинстве случаев на основе ожидаемого типа ответа можно найти совместимый преобразователь сообщений, который затем поможет заполнить заголовок Accept . При необходимости можно использовать методы exchange для явного указания заголовка Accept .
По умолчанию RestTemplate регистрирует все встроенные преобразователи сообщений в зависимости от результатов проверок classpath, которые помогают определить, какие дополнительные библиотеки преобразования присутствуют. Вы также можете задать используемые преобразователи сообщений явным образом.
Преобразование сообщений
Модуль spring-web содержит контракт HttpMessageConverter для чтения и записи тела HTTP-запросов и ответов через InputStream и OutputStream . Экземпляры HttpMessageConverter используются на стороне клиента (например, в RestTemplate ) и на стороне сервера (например, в REST-контроллерах Spring MVC).
Конкретные реализации для основных типов медиа (MIME) предусмотрены во фреймворке и по умолчанию регистрируются в RestTemplate на стороне клиента и в RequestMappingHandlerAdapter на стороне сервера.
Реализации HttpMessageConverter описаны в следующих разделах. Для всех преобразователей используется тип среды передачи данных по умолчанию, но вы можете переопределить его, установив свойство бина supportedMediaTypes . В следующей таблице описана каждая реализация:
Реализация HttpMessageConverter , которая способна читать и записывать экземпляры String из запроса и ответа HTTP. По умолчанию этот преобразователь поддерживает все типы текстовых сред передачи данных ( text/* ) и записывает их под заголовком Content-Type для text/plain .
Реализация HttpMessageConverter , которая может читать и записывать данные формы из HTTP-запроса и ответа. По умолчанию этот преобразователь читает и записывает тип среды передачи данных application/x-www-form-urlencoded . Данные формы считываются из и записываются в MultiValueMap . Преобразователь также может записывать (но не читать) многокомпонентные данные, считанные из MultiValueMap . По умолчанию поддерживается multipart/form-data . Начиная с версии Spring Framework 5.2, для записи данных формы могут поддерживаться дополнительные многокомпонентные подтипы. Для получения более подробной информации обратитесь к javadoc по FormHttpMessageConverter .
Реализация HttpMessageConverter , которая способна читать и записывать байтовые массивы из запроса и ответа HTTP. По умолчанию этот преобразователь поддерживает все типы сред передачи данных ( */* ) и записывает их под заголовком Content-Type для application/octet-stream . Можно переопределить это, установив свойство supportedMediaTypes и переопределив getContentType(byte[]) .
Реализация HttpMessageConverter , которая способна читать и записывать XML, используя абстракции Marshaller и Unmarshaller из Spring, находящиеся в пакете org.springframework.oxm . Для использования этого преобразователя требуется наличие Marshaller и Unmarshaller . Вы можете внедрить их через конструктор или свойства бина. По умолчанию конвертер поддерживает форматы text/xml и application/xml .
An HttpMessageConverter implementation that can read and write JSON by using Jackson’s ObjectMapper . You can customize JSON mapping as needed through the use of Jackson’s provided annotations. When you need further control (for cases where custom JSON serializers/deserializers need to be provided for specific types), you can inject a custom ObjectMapper through the ObjectMapper property. By default, this converter supports application/json .
Реализация HttpMessageConverter , которая способна читать и записывать XML с помощью XmlMapper расширения Jackson XML. Вы можете настраивать XML-отображение по мере необходимости с помощью JAXB или аннотаций, предоставляемых библиотекой Jackson. Если вам нужен дополнительный контроль (в случаях, когда необходимо предоставить пользовательские сериализаторы/десериализаторы XML для определенных типов), вы можете внедрить кастомный XmlMapper через свойство ObjectMapper . По умолчанию преобразователь поддерживает формат application/xml .
Реализация HttpMessageConverter , которая способна читать и записывать javax.xml.transform.Source из запроса и ответа HTTP. Поддерживаются только DOMSource , SAXSource и StreamSource . По умолчанию конвертер поддерживает форматы text/xml и application/xml .
Реализация HttpMessageConverter , которая способна читать и записывать java.awt.image.BufferedImage из запроса и ответа HTTP. Этот преобразователь считывает и записывает тип среды передачи данных, поддерживаемый API ввода-вывода Java.
Представления Jackson JSON
Можно задавать Представление в формате JSON через билиотеку Jackson для сериализации исключительно подмножества свойств объекта, как показано в следующем примере:
MappingJacksonValue value = new MappingJacksonValue(new User("eric", "7!jd#h23")); value.setSerializationView(User.WithoutPasswordView.class); RequestEntity requestEntity = RequestEntity.post(new URI("https://example.com/user")).body(value); ResponseEntity response = template.exchange(requestEntity, String.class);Многокомпонентность
Для отправки многокомпонентных данных необходимо предоставить MultiValueMap , значениями которого могут быть Object для содержимого компонента, Resource для файлового компонента или HttpEntity для содержимого компонента с заголовками. Например:
MultiValueMap parts = new LinkedMultiValueMap<>(); parts.add("fieldPart", "fieldValue"); parts.add("filePart", new FileSystemResource(". logo.png")); parts.add("jsonPart", new Person("Jason")); HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_XML); parts.add("xmlPart", new HttpEntity<>(myBean, headers));В большинстве случаев не требуется задавать Content-Type для каждого компонента. Тип содержимого определяется автоматически на основе HttpMessageWriter , выбранного для сериализации, или, в случае Resource , на основе расширения файла. При необходимости можно явно указать MediaType с использованием функции-обёртки HttpEntity .
Когда MultiValueMap будет готова, можно передать ее в RestTemplate , как показано ниже:
MultiValueMap parts = . ; template.postForObject("https://example.com/upload", parts, Void.class);Если MultiValueMap содержит хотя бы одно не- String значение, то Content-Type устанавливается в multipart/form-data с помощью FormHttpMessageConverter . Если MultiValueMap имеет String значения, то Content-Type по умолчанию принимает значение application/x-www-form-urlencoded . При необходимости Content-Type также можно задать явным образом.
Использование шаблона AsyncRestTemplate (устарело)
Шаблон AsyncRestTemplate является устаревшим. Во всех случаях, предусматривающих использование AsyncRestTemplate , используйте WebClient.