Нет. Запрос даже не доходит до Rest Controller сервера. Он достигает перехватчика на стороне сервера и дает сбой при десериализации по методу RestController. Пример кода также прикреплен со стороны сервера
аюсь отправить файл JSON через шаблон REST. Когда я отправляю его через POST man как MULTIPART_FORM_DATA, он работает нормально. Имя, которое я должен дать, является конкретным (скажем,ааа). Прикрепленный скриншотПОСТМАН. Но когда я пытаюсь сделать то же самое в коде, как указано в другом стеке потокаПочта, Я получаю 415 Unsupported Media Type error как
org.springframework.web.client.HttpClientErrorException: 415 Unsupported Media Type
at org.springframework.web.client.DefaultResponseErrorHandler.handleError(DefaultResponseErrorHandler.java:91) ~[spring-web-4.1.9.RELEASE.jar:4.1.9.RELEASE]
at org.springframework.web.client.RestTemplate.handleResponse(RestTemplate.java:616) ~[spring-web-4.1.9.RELEASE.jar:4.1.9.RELEASE]
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:572) ~[spring-web-4.1.9.RELEASE.jar:4.1.9.RELEASE]
at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:532) ~[spring-web-4.1.9.RELEASE.jar:4.1.9.RELEASE]
at org.springframework.web.client.RestTemplate.postForObject(RestTemplate.java:332) ~[spring-web-4.1.9.RELEASE.jar:4.1.9.RELEASE]
at
Пожалуйста, не отмечайте его как дубликат, так как указанный ответ не сработал для меня. Не делиться кодом, так как мой код точно такой же, какэто Кроме
requestParamerterMap.add("attachment", resource);
где мой код
requestParamerterMap.add("aaa", resource);
После отладки со стороны сервера похоже, что запрос достигает сервера. Я смог увидеть ниже ошибку на стороне сервера:
[{error=Unsupported Media Type, exception=org.springframework.web.HttpMediaTypeNotSupportedException, message=Content type 'application/octet-stream' not supported, status=415, timestamp=1532557180124}] as "application/json" using [org.springframework.http.converter.json.MappingJackson2HttpMessageConverter@74d4827a]
Итак, из журналов на стороне сервера я не уверен, где тип контента добавляется как application / octet-stream, так как я установил тип контента как
headers.setContentType(MediaType.MULTIPART_FORM_DATA);
Ниже приведен код от контроллера сервера. Серверный код использует Spring boot.
@RequestMapping(method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE,consumes = {"multipart/form-data"})
@ResponseBody
public MyResponse uploadPhoto(@RequestPart(value = "aaa", required = false) Optional<MyRequest> myRequest,
@RequestPart(value = "file", required = false) Optional<MultipartFile> file,
HttpServletRequest request) {
//some logic
return myResponse;
}
В коде сервера есть перехватчик, и я вижу, что мой запрос имеет тип содержимого multipart / form-data. Не доходит до RestController
Когда я отлаживал код на стороне сервера в 2 случаях:
ПОСТМАН запросзапрос кода клиентаЯ понял, что у файла iteam тип контента:Применение / JSON когда я публикуюПОЧТАЛЬОН и тип контента былПрименение / октет-поток когда запрос идет откод на стороне клиента.
В моем клиентском коде я создаю JSONObject как
JSONObject json = new JSONObject();
json.append("myKey", "myValue");
и преобразовать его в байтовый массив как
json.toString().getBytes("UTF-8")
тогда я следовалэто , Разница в моем коде в том, что я отправляю свой JSONObject в виде потока байтов, поскольку не могу создать файл (проблемы с производительностью).
И я не могу отправить JSONObject в виде строки, так как сервер ожидает данные multipart-form-data дляи файл и ааа
Я создал restTemplate как
public RestTemplate myRestTemplate() {
SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory();
requestFactory.setReadTimeout(HTTP_CLIENT_TIMEOUT);
requestFactory.setConnectTimeout(HTTP_CLIENT_TIMEOUT);
RestTemplate restTemplate = new RestTemplate(requestFactory);
List<HttpMessageConverter<?>> messageConverters = new ArrayList<HttpMessageConverter<?>>();
messageConverters.add(new FormHttpMessageConverter());
messageConverters.add(new StringHttpMessageConverter());
restTemplate.setMessageConverters(messageConverters);
return restTemplate;
Вот код на стороне клиента, который вызывает сервис:
public Optional<JSONObject> callService(byte[] multipartFile) {
MultiValueMap<String, Object> body = new LinkedMultiValueMap<>();
InputStream stream = new ByteArrayInputStream(multipartFile);
MultipartByteArrayResource resource = new MultipartByteArrayResource(multipartFile,fileName);
body.add("aaa", resource);
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.MULTIPART_FORM_DATA);
HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(body, headers);
try {
response = restTemplate.postForObject(url, requestEntity , String.class);
} catch (Exception exception) {
LOG.error("Error", exception);
return Optional.empty();
}
}
public class MultipartInputStreamFileResource extends InputStreamResource {
private final String filename;
MultipartInputStreamFileResource(InputStream inputStream, String filename) {
super(inputStream);
this.filename = filename;
}
@Override
public String getFilename() {
return this.filename;
}
@Override
public long contentLength() throws IOException {
return -1; // we do not want to generally read the whole stream into memory ...
}
}
И тот же код работает, когда я отправляю файл (примечаниефайл а такжеааа это две разные вещи, хотя обемногочастному / форм-данных, на стороне сервера.файл это простофайл любого времени (изображение / текст / pdf) ноааа являетсяфайл данных JSON)
После небольшой отладки я заметил, что контроллер на стороне сервера ожидает, что содержимое файла будет json, поскольку Джексон пытается десериализовать этот json дляМой запрос объект. Когда я отправляю сообщение из POSTMAN, оно имеет контент json, работающий должным образом, но из кода на стороне клиента, контентByteArray,и его не десериализоватьМой запрос объект. Не уверен, как это исправить