I use Spring to call a REST API which reply with header that contains "Content-Type: multipart/mixed; boundary==_123456789".
My problem is that Spring try to parse the Content-Type and throw InvalidMediaTypeException due to '=' in boundary token.
Is there a way to disable this checking (or any workaround) ?
These are my logs :
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)
I found a way by using ClientHttpRequestInterceptor
to modify the boundary parameter and add double quote.
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("'")));
}
}
And configuring the 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);
}
}