У меня есть POJO вида:
@Data
public class BaseRequest {
private String type;
private Map<String, Object> details;
private Map<String, Object> signature;
}
У меня работает служба, которая принимает только тип контента: «application / x-www-form-urlencoded».
Я написал клиент на Java, который использует Spring RestTemplate для выполнения вызовов.
public String getInvoice(BaseRequest req, String url) {
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
HttpEntity<BaseRequest> httpEntity = new HttpEntity<BaseRequest>(req, headers);
String response = this.restTemplate.postForObject(url, httpEntity, String.class);
return response;
}
Однако это вызывает ошибку:
org.springframework.web.client.RestClientException: Could not write request: no suitable HttpMessageConverter found for request type [com.x.y.z.BaseRequest] and content type [application/x-www-form-urlencoded]
Это работает, если я установил тип контента как JSON:
headers.setContentType(MediaType.APPLICATION_JSON);
Я знаю, что это работает для JSON, потому что я настроил свой объект RestTemplate Bean с помощью JacksonHTTPMessageConverter. Так что я могу легко преобразовать POJO в application / json. Однако я не могу понять, как это сделать с помощью application / x-www-form-urlencoded.
Я искал это некоторое время, и единственное решение, которое я нашел, - это написать собственный конвертер для преобразования моего класса BaseRequest в Spring MultiValueMap, а затем Spring FormHttpMessageConverter автоматически обработает его. Но я не хочу этого делать. Есть ли другой способ обойти это?
Любые зацепки будут оценены. Спасибо!
Обновлено: Мой вопрос отличается от @JsonProperty не работает для Content-Type: application / x-www-form-urlencoded. Происходит преобразование о принятии данных в application / x-www-form-urlencoded и преобразовании их в POJO. Мой вопрос касается преобразования POJO в application / x-www-form-urlencoded при использовании Spring resttemplate для совершения вызовов. И, как я уже упоминал, я знаю, что могу добиться этого, написав собственный конвертер для преобразования моего POJO в Spring MultiValueMap. Однако я хочу знать, смогу ли я этого избежать.
Обновлено:
Dump of $_POST on the API when I send my data as MultiValueMap<String, Object>:
"array(0) {
}"
Dump of $_POST on the API when I send my data through Postman in the correct format:
"array(2) {
["type"]=>
string(16) "abcd"
["details"]=>
array(1) {
["template_file"]=>
string(16) "x.html"
}
}"
@dainu Код метода контроллера находится в другом сервисе, и я не могу вносить в него изменения. И этот сервис написан на PHP. Я просто выполняю вызовы API к этой службе из моей службы (написанной на Java).




Попробуйте преобразовать вложенный объект в полезную нагрузку запроса в org.springframework.util.MultiValueMap. Добавьте и реализуйте метод конвертера в вашем POJO
public class BaseRequest {
// ...
public MultiValueMap<String, Object> toMap() {
MultiValueMap<String, Object> result = new LinkedMultiValueMap<>();
result.add("type", type);
result.put("details", details);
result.put("signature", signature);
return result;
}
}
Теперь используйте его при создании запроса
HttpEntity<BaseRequest> httpEntity = new HttpEntity<BaseRequest>(req.toMap(), headers);
Это вызвано тем, что внутри FormHttpMessageConverter, который выполняет фактический метод преобразования, canRead(Class<?>, MediaType) проверяет, является ли MultiValueMap.class.isAssignableFrom(clazz), где clazz, вашим объектом полезной нагрузки. В вашем случае это не удалось, поэтому FormHttpMessageConverter пропустил.
Надеюсь, поможет!
Привет, спасибо за ответ. Как я уже упоминал в своем вопросе, я не хочу писать собственный конвертер для преобразования моего POJO в MultiValueMap. Я говорю это, потому что в MultiValueMap <String, Object>, если я вставлю детали (которые имеют тип Map <String, Object>), они не будут правильно отформатированы на сервере, поэтому сервер не сможет их проанализировать. . Я добавляю вывод $ _REQUEST на сервер, к которому выполняется этот вызов, в EDIT.
Вы можете изменить подпись MultiValueMap<String, Object> на MultiValueMap<String, String> и отформатировать объект вручную в соответствии с вашими потребностями.
да, но я не хочу этого делать, так как писать такой конвертер было бы некрасиво. Нет ли какой-нибудь библиотеки вроде Джексона, которая могла бы обработать это преобразование за меня? Или проблема, с которой я столкнулся, слишком необычна?
@Qawls, Spring уже делает это за вас, он принимает ваш запрос от объектов и выполняет все обратные вызовы преобразования / обработки / обработки. Нет ничего плохого в том, чтобы написать конкретное представление ваших данных, если ваш сервер не может обработать его иначе.
@Qawls, если вам нужен хороший красивый обходной путь, вам нужно исправить свой PHP-код, что невозможно, поэтому я рекомендую вам придерживаться рабочего решения, а не гнаться за «лучшим».
Хотел знать, есть ли что-то вроде Джексона, которое может сделать это для меня, или, может быть, что-то мне здесь не хватает. Думаю, я сам прибегну к написанию конвертера. Большое спасибо за твою помощь.
Итак, вы аннотировали свой метод контроллера с помощью «производит (application / x-www-form-urlencoded)»?