HTTP request from android yields UnsupportedCharsetException: bocu-1
===

I have a Spring Integration http inbound gateway listeneing for PUT requests from a web client. The targetted web client in particular is an android application we're developing that uses RestTemplate from Spring Android. The payload is of type text/plain and the request parameters are specified in the URL.

When I log the call I receive on the server, I see the exception:

    SEVERE: Servlet.service() for servlet [rest] in context with path [] threw exception [Request processing failed; nested exception is java.nio.charset.UnsupportedCharsetException: bocu-1] with root cause
    java.nio.charset.UnsupportedCharsetException: bocu-1
        at java.nio.charset.Charset.forName(Charset.java:543)
        at org.springframework.http.HttpHeaders.getAcceptCharset(HttpHeaders.java:188)
        at org.springframework.integration.http.support.DefaultHttpHeaderMapper.getHttpHeader(DefaultHttpHeaderMapper.java:751)
        at org.springframework.integration.http.support.DefaultHttpHeaderMapper.toHeaders(DefaultHttpHeaderMapper.java:326)
        at org.springframework.integration.http.support.DefaultHttpHeaderMapper.toHeaders(DefaultHttpHeaderMapper.java:61)
        at org.springframework.integration.http.inbound.HttpRequestHandlingEndpointSupport.doHandleRequest(HttpRequestHandlingEndpointSupport.java:336)
        at org.springframework.integration.http.inbound.HttpRequestHandlingMessagingGateway.handleRequest(HttpRequestHandlingMessagingGateway.java:95)
        at org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter.handle(HttpRequestHandlerAdapter.java:49)
        at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:923)
        at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:852)
        at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:882)
        at org.springframework.web.servlet.FrameworkServlet.doPut(FrameworkServlet.java:800)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:644)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
        at org.springframework.web.filter.ShallowEtagHeaderFilter.doFilterInternal(ShallowEtagHeaderFilter.java:58)
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:311)



As you can see it's receiving this charset in the accept-charset header of the HTTP request. There are a few things I've tried so far:

 * Adding support for BOCU-1 charset in the services project doesn't seem to be trivial. I've added icu4j to my pom.xml but I think there's more that needs to be done and I'm not sure where to start.

 * Setting the "accept-charset" header before calling restTemplate.exchange(...) in the mobile client doesn't seem to affect anything. This makes me think that the header is being set in the inbound gateway, but I can "curl -T file.txt" the service just fine without encountering this error (unless I explicitly set the accept-charset to bocu-1. This indicates that something is different about the service call from Android versus from cURL.

 * Attempting to create an &lt;int-http:header /&gt; entry in the inbound gateway to override the accept-charset header doesn't seem to do anything.

 * I've attempted a wire-tap logger for the inbound request channel to print out the entire message as it's received, but the exception is triggered before anything is printed out.

 * When the request payload is of type 'image/jpeg' the service is called just fine without any exception.

Without further ado, relevant integration-context.xml:

    <int:channel id="receiveChannel"/>
    <int:channel id="responseChannel"/>
    
    <!-- ... -->

    <int-http:inbound-gateway request-channel="receiveChannel"
                              reply-channel="responseChannel"
                              path="/service/{entityType:(?:photo|text)}"
                              supported-methods="PUT">
        <int-http:header name="entityType" expression="'service' + 
            T(org.apache.commons.lang3.text.WordUtils).capitalize(
                #pathVariables.entityType)"/>
        <int-http:header name="requestParams" expression="#requestParams"/>
    </int-http:inbound-gateway>

    <!-- router and service activator outside the scope of the current problem -->

And here's code that calls the service (from the mobile client Android code):

    String textPayload = "asdf";
    HttpHeaders headers = new HttpHeaders();
    headers.setAuthorization(/*authorization*/);
    // headers.add("accept-charset", "utf-16"); // doesn't seem to affect anything
    HttpEntity<String> entity = new HttpEntity<String>(textPayload, headers);
    restTemplate.exchange(url, HttpMethod.PUT, entity, ExpectedResponse.class, /* request params */);

Here's what I used to call the service correctly:

    curl -u user:pass 'http://localhost:8080/service/text?param1=asdf&param2=hjkl&param3=0' -T ~/database_notes.txt -H 'content-type:text/plain' -v

Any ideas on where to begin with this? Thanks in advance!