Resteasy使用POJO进行multipart/form-data编码

5
我有一个问题涉及resteasy和multipart表单,希望有人能够与我有相同的问题或者能够提供帮助。
我的目标是同一时间上传文件和参数。我试着使用@MultipartForm注释POJO-Form来实现:
@PUT
@Path("/userdebug1/{userId}")
@Consumes("multipart/form-data")
@Produces("application/json;charset=UTF-8")
public String updateUserDebug1( @MultipartForm UserRequestForm request )
{
    return request.getName();
}

使用UserRequestForm表单:

public class UserRequestForm 
{
    @FormParam("name")
    String name;

    @FormParam("blob")
    @PartType("application/octet-stream")
    byte[] image;

    public String getName() 
    {
        return name;
    }

    public void setName(String n) 
    {
        this.name =n;
    }

    public byte[] getImage() 
    {
        return image;
    }

    public void setImage(byte[] image) 
    {
        this.image = image;
    }
}

这一切都很好,只是存在一个问题:字符编码出现了问题。如果我使用umlaut(一种德文特殊字符)则无法正确返回。然而,如果我使用以下方法:

@PUT
@Path("/userdebug2/{userId}")
@Consumes("multipart/form-data")
@Produces("application/json;charset=UTF-8")
public String updateUserDebug2(MultipartFormDataInput form) 
{
    try {
        return form.getFormDataMap().get("name").get(0).getBodyAsString();
    } catch (IOException e) {
        e.printStackTrace();
    }
    return "error";
}

我使用charlesproxy将相同的请求发送到两个URL。这是其中一个URL。另一个仅由URL不同。

PUT /api/v1/userdebug1/A4BE364C-15F8-59B0-87C3-DCA0A123644A HTTP/1.1
Host: localhost:8081
Content-Type: multipart/form-data; charset=utf-8; boundary=0xKhTmLbOuNdArY-5C999EAA-3828-4919-98B7-19D4FD738814
Accept-Encoding: gzip
Connection: close
Content-Length: 205

--0xKhTmLbOuNdArY-5C999EAA-3828-4919-98B7-19D4FD738814
Content-Disposition: form-data; name="name"
Content-Type: text/plain;charset=utf-8

ü
--0xKhTmLbOuNdArY-5C999EAA-3828-4919-98B7-19D4FD738814--

响应1(使用POJO表单):

第二个响应(使用MultipartFormDataInput):

ü

有什么想法吗?我是做错了什么还是这是一个bug?
非常感谢stackoverflow社区的帮助。即使这是我第一次提问,你们已经给了我很大的帮助。

我已经升级到2.3.5.Final版本,问题已经得到解决。 - bert
1个回答

3

我遇到了同样的问题。经过分析resteasy代码,我发现问题出现在org.jboss.resteasy.plugins.providers.ProviderHelper.readString(InputStream, MediaType)中。

public static String readString(InputStream in, MediaType mediaType) throws IOException
{
  byte[] buffer = new byte[1024];
  ByteArrayOutputStream builder = new ByteArrayOutputStream();
  int wasRead = 0;
  do
  {
     wasRead = in.read(buffer, 0, 1024);
     if (wasRead > 0)
     {
        builder.write(buffer, 0, wasRead);
     }
  }
  while (wasRead > -1);
  byte[] bytes = builder.toByteArray();

  String charset = mediaType.getParameters().get("charset");
  if (charset != null) return new String(bytes, charset);
  else return new String(bytes, "UTF-8");
}   

输入流in是一个org.jboss.resteasy.plugins.providers.multipart.MultipartInputImpl$ReaderBackedInputStream(我似乎没有它的源代码),它包含从ByteArrayInputStream读取正确UTF-8字节的InputStreamReader。但是,当它被读取时,它返回了错误的数据。我的"nér"[110, -61, -87, 114](存在于支持in的缓冲区中)变成了[110, -23, 114]。然后将其传递给new String(bytes, "UTF-8"),这是错误的。
我希望这可以帮助某些人,除了使用我在上面问题中找到的信息form.getFormDataMap().get("name").get(0).getBodyAsString()来绕过此问题之外,我没有任何进展。谢谢。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接