Question

I've got a Web Service that is defined using the javax ws annotations to deifne the service endpoint as follows:

@GET
@Path("eventBir")
@Produces(MediaType.APPLICATION_XML)
public String getEventsBir(
        @QueryParam("applicationId") String applicationId);

The response can contain foreign characters which are getting encoded somehow to be incorrect.

An example of part of the response when it leaves the above service:

<Market name="Apuestas con hándicap en vivo">

But by the time it reaches the external application, it is being encoded somehow to give:

<Market name="Apuestas con hándicap en vivo">

I found this website that seems to have my exact issue defined. So it looks like I'm getting a UTF-8 encoded string and passing it through some code that encodes it as ISO-8859-1. However, I'm struggling with how to go about fixing it.

After my Service has returned the String, the string is passed through what I believed to be Spring created code to wrap the web service. It could also be being mangled by the web server, I'm not sure.

Is there some encoding I can do on the String before returning it? Or is there some Spring configuration I can set to set the response as UTF-8 encoded?

EDIT: Found the offending Spring Class

It looks like the offending class within the Spring wrapper for the web service is StringHttpMessageConverter

Here's the class in Grep Code

There is a default character set defined within this class of "ISO-8859-1" and this is what is parsing the response (which is in UTF-8) so I'm ending up with the issue described above.

So now I'm looking for a nice way to fix this.

Was it helpful?

Solution

As there was no encoded defined by the returned XML string, Spring used the default StringHttpMessageConverter which encodes everything as ISO-8859-1 as that is the default for HTTP responses when no other is specified.

It looks like the StringHttpMessageConverter class can be instantiated with a provided character set. This can then be set on the overall gateway for the service so that all of the end points use the desired character set.

The solution derived was to create one in the Spring Context like this:

<bean id="stringHttpMessageConverter" class="org.springframework.http.converter.StringHttpMessageConverter">
    <constructor-arg index="0" ref="utf8Charset"/>
</bean>

<bean id="utf8CharsetFactory" class="CharsetFactory"/>
<bean id="utf8Charset" factory-bean="utf8CharsetFactory" factory-method="createUTF8Charset"  /> 

Then use it within the gateway, as such:

<http:outbound-gateway request-channel="requestChannel"
    url-expression="'${bir.xml.url}' + payload.toString()" http-method="GET"
    extract-request-payload="true" expected-response-type="java.lang.String"
    charset="UTF-8" reply-timeout="30000" reply-channel="dtdRemovingTransformerChannel"
    message-converters="stringHttpMessageConverter"
    mapped-response-headers="Date, Server, Pragma, Cache-Control, SVRID, last-modified">
</http:outbound-gateway>

Obviously, this applies the UTF-8 encoding everywhere that just a String is being returned, but that is acceptable within the application.

OTHER TIPS

Try to produce utf-8 with your service:

@Produces("application/json; charset=utf-8")

instead of:

@Produces(MediaType.APPLICATION_XML)
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top