如何使用UTF-8获取重新安装MultipartFormDataInput以解码字符串?

时间:2012-06-26 20:51:54

标签: java tomcat jboss resteasy

我正在使用resteasy 2.3.4-Final并且在接受multipart / form-data的调用中遇到UTF-8问题。我的API的消费者是iOS和Android设备。发送的任何字符串参数,不包含字符集,因此resteasy似乎用us-ascii编码解码字符串。我已经做了很多工作来修复db层中涉及的所有其他内容,以创建一个强制字符编码为utf-8的过滤器。这解决了所有form-url编码的POST的问题,但现在两个调用仍然不起作用,它们都是多部分/表单数据调用。我知道消费者应该在消息部分发送utf-8字符集,但是我想弄清楚是否有任何办法迫使所有内容暂时使用UTF-8解码,因为Apple需要大约2周的时间批准我们的应用程序的更新,这是不理想的,但我们可能不得不咬紧牙关。有没有人以前做过这个并且多部分表单上传成功了?

谢谢!

3 个答案:

答案 0 :(得分:2)

根据RESTEasy文档,应该可以覆盖默认内容类型:

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;
    }

}

答案 1 :(得分:1)

以下是编码问题的解决方法。也请为此投票 bug RESTEASY-390

示例:

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;
}

答案 2 :(得分:1)

由于org.jboss.resteasy.spi.interception.PreProcessInterceptor已被弃用,我使用javax.ws.rs.container.ContainerRequestFilter并使用“注入”HttpServletRequest来解决问题。

示例:

@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");
  }
}