1

I'm using resteasy 2.3.4-Final and having UTF-8 problems in calls that accept multipart/form-data. The consumers of my API are iOS and Android devices. Any string params that are sent, don't contain a charset so resteasy seems to be decoding the strings with us-ascii encoding. I've done plenty of work to fix everything else involved from the db layer up to create a filter that will force the character encoding to utf-8. This solved the problem for all form-url-encoded POSTs, but now two calls still don't work and they are both multipart/form-data calls. I understand that the consumers should send the utf-8 charset in the message parts, but I'm trying to figure out if there's any way to force everything to be decoded using UTF-8 temporarily because it would take about 2 weeks for Apple to approve an update to our application which isn't ideal, but we may have to bite the bullet on that one. Has anyone done this before and had success with multipart form uploads?

Thanks!

Adrian Rodriguez
  • 3,232
  • 2
  • 24
  • 34

3 Answers3

2

According to the RESTEasy documentation, it should be possible to override the default content type:

http://docs.jboss.org/resteasy/docs/2.3.4.Final/userguide/html_single/index.html#multipart_overwrite_default_content_type

import org.jboss.resteasy.plugins.providers.multipart.InputPart;

@Provider
@ServerInterceptor
public class ContentTypeSetterPreProcessorInterceptor implements
        PreProcessInterceptor {

    public ServerResponse preProcess(HttpRequest request,
            ResourceMethod method) throws Failure, WebApplicationException {
        request.setAttribute(InputPart.DEFAULT_CONTENT_TYPE_PROPERTY,
                "*/*; charset=UTF-8");
        return null;
    }

}
eiden
  • 2,329
  • 19
  • 19
1

Here is a workaround for encoding problem. Also please vote for this bug RESTEASY-390.

Example:

import org.apache.james.mime4j.message.BodyPart;
import org.apache.james.mime4j.message.SingleBody;
import org.jboss.resteasy.plugins.providers.multipart.InputPart;

    ...

@POST
@Path("/uploadContacts")
@Consumes(MediaType.MULTIPART_FORM_DATA)
public void uploadContacts(MultipartFormDataInput input) throws Exception {

    List<InputPart> inputParts = uploadForm.get("uploadFieldName");
    for (InputPart inputPart : inputParts) {
               // bytes extracted
               byte[] fileBytes = readByteArray(inputPart);
               // now we can read it with right encoding
               InputStreamReader reader = new InputStreamReader(new ByteArrayInputStream(fileBytes), "UTF-8");

               ...
    }
}

private byte[] readByteArray(InputPart inputPart) throws Exception {
    Field f = inputPart.getClass().getDeclaredField("bodyPart");
    f.setAccessible(true);
    BodyPart bodyPart = (BodyPart) f.get(inputPart);
    SingleBody body = (SingleBody)bodyPart.getBody();

    ByteArrayOutputStream os = new ByteArrayOutputStream();
    body.writeTo(os);
    byte[] fileBytes = os.toByteArray();
    return fileBytes;
}
Nikita Koksharov
  • 10,283
  • 1
  • 62
  • 71
1

Since org.jboss.resteasy.spi.interception.PreProcessInterceptor is deprecated, I solved the problem using javax.ws.rs.container.ContainerRequestFilter with an "injected" HttpServletRequest.

Example:

@Provider
public class MyContentTypeFilter implements ContainerRequestFilter {
  @Context
  private HttpServletRequest servletRequest;

  @Override
  public void filter(ContainerRequestContext requestContext) throws IOException {
    servletRequest.setAttribute(InputPart.DEFAULT_CONTENT_TYPE_PROPERTY, "text/plain; charset=UTF-8");
  }
}
tommy
  • 11
  • 1