0
votes

I have a web service that produces MediaType.APPLICATION_XML_VALUE

In rest client, I see content-type header as application/xml;charset=ISO-8859-1

Caller has set Accept header as application/xml

Not sure what is adding charset=ISO-8859-1 in the header.

To remove charset from content-type header,

  • Tried with mentioning application/xml instead of MediaType.APPLICATION_XML_VALUE
  • Tried adding spring filter CharacterEncodingFilter
  • Tried adding spring.http.encoding.force=false in application.properties file

None of the above made any difference.

Caller


    curl -v -X POST \
      https://<URL> \
      -H 'Content-Type: application/x-www-form-urlencoded' \
      -H 'accept: application/xml' 

Java Resource


    @RequestMapping(value = "<URL>",
                    method = RequestMethod.POST, consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE,
                    produces = MediaType.APPLICATION_XML_VALUE)
    @ResponseBody
    public String processRequest(HttpServletRequest request) {
        try {
            Object response = service(request);
            if (response != null) {
                return response.toString();
            }
        } catch (Exception e) {
            logger.error(e);
        }
        return createErrorResponse(ERR_CODE).toString();
    }

// response header
200 OK
Time:1247 ms
Size:1.62 KB
Save
Download
Date →Wed, 17 Jul 2019 07:30:28 GMT
Server →Apache
Strict-Transport-Security →max-age=31536000; includeSubDomains
Content-Type →application/xml;charset=ISO-8859-1
Content-Length →1374
Via →1.1 <URL>
Keep-Alive →timeout=5, max=10000
Connection →Keep-Alive

This was working fine. Started seeing above behavior post upgrading following libraries


    jackson 2.6.0 to 2.6.3
    httpclient 4.5 to 4.5.3
    httpcomponents 4.4.1 to 4.4.6
    springframework 4.2.9 to 4.3.17

Need to know a way how to omit charset from header and what is adding it in the first place.

1
Does the charset declared in the Content-Type response header match the actual document encoding of the XML body? If so, why is this a problem?Tom Blodget
Here charset value is not the problem. As the existing system was expecting Response to have just application/xml and post spring and relevant upgrades, charset is appended to response header. This is causing failure on client side. Client side force upgrade is not possible. Hence looking for a root cause that what adds charset to response header.Cosmo Kramer
It is unfortunate that the client is non-compliant. Sorry but I don't know the solution.Tom Blodget

1 Answers

0
votes

Found the issues.

@ResponseBody annotation was converting String output to HTTP supported format.

Internally, it would append charset=ISO-8859-1 to the content-type header if not specified.

As I wanted to remove this, changed method return from String to ResponseEntity<String> ResponseEntity will take care of converting output to HTTP supported format and not the annotation. So control on converting to HTTP is now in code rather than letting spring do it. Here we can explicitly set headers that we want.

New code looks something like this :

@RequestMapping(value = "<URL>",method = RequestMethod.POST, consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE,produces = MediaType.APPLICATION_XML_VALUE)
public ResponseEntity<String> processRequest(HttpServletRequest request) {
    try {
        Object response = service(request);
        if (response != null) {
            prepareResponseEntity(response.toString());
        }
    } catch (Exception e) {
        logger.error(e);
    }
    return prepareResponseEntity(createErrorResponse(ERR_CODE).toString());
}

private static ResponseEntity<String> prepareResponseEntity (String responseBody){
    HttpHeaders responseHeaders = new HttpHeaders();
    responseHeaders.add(HeartBeatServerConstants.HEADER_CONTENT_TYPE,MediaType.APPLICATION_XML_VALUE);
    return new ResponseEntity<String>(responseBody,responseHeaders,HttpStatus.OK);  
}

Update : AbstractHttpMessageConverter of spring-web has changed between spring 4.2.9 and 4.3.17 to add charset if not present.Spring Doc