我使用Spring来调用REST,它使用包含“Content: multipart/mixed;boundary==_123456789”的头来答复。
我的问题是,Spring试图解析内容类型,并由于边界令牌中的'=‘抛出InvalidMediaTypeException。
是否有一种方法可以禁用此检查(或任何解决方法)?
这些是我的日志:
org.springframework.http.InvalidMediaTypeException: Invalid mime type "multipart/mixed; boundary==_11204303fda4403b6a72d61500081354": Invalid token character '=' in token "=_11204303fda4403b6a72d61500081354"
at org.springframework.http.MediaType.parseMediaType(MediaType.java:620)
at org.springframework.http.HttpHeaders.getContentType(HttpHeaders.java:992)
at org.springframework.web.client.HttpMessageConverterExtractor.getContentType(HttpMessageConverterExtractor.java:136)
at org.springframework.web.client.HttpMessageConverterExtractor.extractData(HttpMessageConverterExtractor.java:93)
at org.springframework.web.client.RestTemplate$ResponseEntityResponseExtractor.extractData(RestTemplate.java:1037)
at org.springframework.web.client.RestTemplate$ResponseEntityResponseExtractor.extractData(RestTemplate.java:1020)
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:778)
at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:711)
at org.springframework.web.client.RestTemplate.postForEntity(RestTemplate.java:468)
发布于 2022-06-25 21:26:52
通过使用ClientHttpRequestInterceptor
修改边界参数并添加双引号,我找到了一种方法。
public class MultipartMixedBoundaryRewritingInterceptor implements ClientHttpRequestInterceptor {
private Pattern multipartMixedHeaderPattern = Pattern.compile("^multipart/mixed;\\s?boundary=(.*?)$");
@Override
public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException {
ClientHttpResponse response = execution.execute(request, body);
HttpHeaders responseHeaders = response.getHeaders();
// Do not use .getHeaders().getContentType() since it checks everything and raises an exception on the invalid boundary
String contentType = response.getHeaders().getFirst("Content-Type");
Matcher matcher = multipartMixedHeaderPattern.matcher(contentType);
if (contentType != null && matcher.matches()) {
String boundaryParameter = matcher.group(1);
try {
responseHeaders.getContentType();
} catch (IllegalArgumentException e) {
if (boundaryParameter != null && !isQuotedString(boundaryParameter)) {
Map<String, String> parameters = new HashMap<>();
parameters.put("boundary", String.format("\"%s\"", boundaryParameter));
MediaType fixedContentType = new MediaType(MediaType.MULTIPART_MIXED, parameters);
response.getHeaders().setContentType(fixedContentType);
}
}
}
return response;
}
private boolean isQuotedString(String s) {
return s.length() > 2 && ((s.startsWith("\"") && s.endsWith("\"")) || (s.startsWith("'") && s.endsWith("'")));
}
}
以及配置restTemplate
@Configuration
public class RestTemplateConfig {
@Bean
public RestTemplate restTemplate() {
RestTemplate restTemplate = new RestTemplate();
configureRestTemplateInterceptors(restTemplate);
return restTemplate;
}
private void configureRestTemplateInterceptors(RestTemplate restTemplate) {
List<ClientHttpRequestInterceptor> interceptors = restTemplate.getInterceptors();
if (CollectionUtils.isEmpty(interceptors)) {
interceptors = new ArrayList<>();
}
interceptors.add(new MultipartMixedBoundaryRewritingInterceptor());
restTemplate.setInterceptors(interceptors);
}
}
发布于 2022-06-21 23:32:37
RFC1341适用于电子邮件中的MIME类型。
对于HTTP,规范是用RFC2616§2.2表示的,该文档指定只有当值被用引号括起来时,“令牌分隔符”才能作为值包含。创建边界字符串的东西可能使用的是RFC1341定义,而不是(正确的) RFC2616规范。
标题应该是
multipart/mixed; boundary="=_11204303fda4403b6a72d61500081354"
顺便说一句,抛出异常的代码是方法checkToken()
中的checkToken()
。这是在最新版本中,看起来您有一个较早版本的Spring。
https://stackoverflow.com/questions/72707925
复制相似问题