gpt4 book ai didi

java - 通过 REST 模板发送 json 文件时出现 415 不支持的媒体类型

转载 作者:行者123 更新时间:2023-12-05 05:15:26 31 4
gpt4 key购买 nike

我正在尝试通过 REST 模板发送一个 json 文件。当我通过 POST man 作为 MULTIPART_FORM_DATA 发送它时,它工作正常。我应该给出的名称是特定的(比如说 aaa)。附截图screenshot postman 。但是当我在另一个计算器中指定的代码中尝试相同的代码时 post ,我收到 415 Unsupported Media Type 错误

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

请不要将其标记为重复,因为指定的答案对我不起作用。不共享代码,因为我的代码与 this 完全相同除了

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);

以下是来自服务器 Controller 的代码。服务器端代码使用 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种情况下调试服务器端代码时:

  1. postman 请求

enter image description here

  1. 客户端代码请求

enter image description here

当我从 POSTMAN 发帖并且内容类型为 application/octet-stream 时,我发现文件 iteam 的内容类型为 application/json 当请求来自客户端代码时。

在我的客户端代码中,我将 JSONObject 创建为

JSONObject json = new JSONObject();
json.append("myKey", "myValue");

并将其转换为字节数组作为

json.toString().getBytes("UTF-8")

那我关注了this .我的代码的不同之处在于,我将我的 JSONObject 作为字节流发送,因为我无法创建文件(性能问题)。

而且我不能将 JSONObject 作为字符串发送,因为服务器期望文件和 aaa 的 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 ...
}
}

当我发送文件时相同的代码有效(注意 fileaaa 是两个不同的东西,尽管它们都是 multipart/form-data服务器端。文件只是一个任何时间的文件(图像/文本/pdf),但aaajson数据文件 )

再调试一点之后,我观察到服务器端 Controller 期望文件内容为 json,因为 Jackson 尝试将该 json 反序列化为 MyRequest 对象。当我从 POSTMAN 发送帖子时,它具有 json 内容,因此按预期工作,但从客户端代码来看,内容是 byteArray,并且它没有反序列化为 MyRequest 对象.不确定如何解决这个问题

最佳答案

终于解决了这个问题。正如问题中提到的,在从 POSTMAN vs 代码发送请求时,具有不同内容类型的多部分文件是我开始的地方。如果有人有任何问题,我会详细解释。

    public Optional<JSONObject> save(byte[] multipartFile, String fileName) {
MultiValueMap<String, Object> body = new LinkedMultiValueMap<>();
Resource content = new MultipartByteArrayResource(multipartFile , fileName);

HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<Resource> requestEntityBody = new HttpEntity<Resource>(content, headers);
body.add("aaa", requestEntityBody);
String result = "";
JSONParser parser = new JSONParser();
JSONObject json = null;


HttpHeaders requestHeaders = new HttpHeaders();
HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(body, requestHeaders);
ResponseEntity<String> response = null;
try {
RestTemplate restTemplate = customizeRestTemplate(); //I have defined this in different config file in my actual code
response = restTemplate.exchange(url , HttpMethod.POST , requestEntity , String.class);
result = (response != null && response.getBody() != null) ? response.getBody().toString() : result;
json = (JSONObject) parser.parse(result);
LOG.info( "Response:", response );

} catch (Exception exception) {
LOG.error("Error , exception);
return Optional.empty();
}
return Optional.ofNullable(json);
}

public class MultipartByteArrayResource extends ByteArrayResource{

private String fileName;

public MultipartByteArrayResource(byte[] byteArray , String filename) {
super(byteArray);
this.fileName = filename;
}

public String getFilename() {
return fileName;
}

public void setFilename(String fileName) {
this.fileName= fileName;
}

}

public RestTemplate customizeRestTemplate() {

SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory();
requestFactory.setReadTimeout(10000);
requestFactory.setConnectTimeout(10000);

RestTemplate restTemplate = new RestTemplate(requestFactory);
List<HttpMessageConverter<?>> messageConverters = new ArrayList<HttpMessageConverter<?>>();
messageConverters.add(new FormHttpMessageConverter());
messageConverters.add(new StringHttpMessageConverter());
restTemplate.setMessageConverters(messageConverters);
return restTemplate;
}

}

关于java - 通过 REST 模板发送 json 文件时出现 415 不支持的媒体类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51527666/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com