Resteasy multipart / form-data кодирование с использованием pojo - PullRequest
4 голосов
/ 18 марта 2012

У меня проблемы с повторной формой и составными формами, и я надеялся, что кто-то может столкнуться с той же проблемой или иначе сможет мне помочь.

Моя цель - загрузить файл и некоторые параметры одновременно. Я попробовал это, используя @MultipartForm, аннотированный к POJO-форме:

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

Это все работает хорошо, за исключением того факта, что кодировка символов нарушена . Если я использую умлаут, он не возвращается должным образом. Принимая во внимание, что если я использую следующий метод:

@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.

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):

Ответ 2 (с использованием MultipartFormDataInput):

ü

Есть идеи? Я что-то не так делаю или это ошибка?

Заранее благодарим огромное сообщество stackoverflow. Вы уже оказали большую помощь. Даже если я впервые задаю вопрос.

1 Ответ

2 голосов
/ 23 апреля 2012

У меня та же проблема.Я прошел через код 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 (для которого у меня нет исходного кода), который содержит чтение InputStreamReader из ByteArrayInputStream, содержащего правильный UTF-8байт.Однако, когда он прочитан, он возвращает неправильные данные.Мой "nér" [110, -61, -87, 114] (который присутствует в резервной копии буфера in) становится [110, -23, 114].Затем это передается на new String(bytes, "UTF-8"), что неверно.

Я надеюсь, что это поможет кому-то, я не буду дальше, кроме как с помощью информации, которую я нашел в вопросе выше, чтобы обойти проблему с помощьюform.getFormDataMap().get("name").get(0).getBodyAsString().Спасибо за это.

...