RestEasy - 映射传入的多部分请求中的对象列表

时间:2017-10-17 19:32:17

标签: java multipartform-data resteasy

上传包含以下字段的Multipart表单时:

Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW


------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="info"

[{"foo":"Foo Data","bar":"Bar Data"}]
------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="id"

someId
------WebKitFormBoundary7MA4YWxkTrZu0gW--

服务器抛出错误:

Unable to find a MessageBodyReader for media type: text/plain;charset=us-ascii and class type java.util.List

端点看起来像这样:

@POST
@Path("/upload")
@Consumes(MediaType.MULTIPART_FORM_DATA)
@Produces(MediaType.APPLICATION_JSON)
public Response bulkUploadPois(@MultipartForm UploadRequestModel uploadRequest) {
  ...
}

该模型用作:

public class UploadRequestModel {

    @FormParam("info")
    private List<InfoModel> info;

    @FormParam("id")
    private String id;

    /**
    * Getters/Setters
    **/
}

public class InfoModel {

  private String foo;

  private String bar;

    /**
    * Getters/Setters
    **/
}

有没有办法将信息部分解组到模型中的列表

1 个答案:

答案 0 :(得分:0)

每当我们在请求正文中发送任何复杂的数据时,它都会搜索帮助程序方法,该方法可以帮助将请求正文转换为Java对象。

通过实现这些辅助方法,我们可以达到预期的结果。

java doc

  

@FormParam绑定请求中包含的表单参数的值   实体主体为资源方法的参数。值经过URL解码   除非使用编码注释将其禁用。预设值   可以使用DefaultValue批注指定。如果要求   实体正文不存在或是不受支持的媒体类型,默认   使用值。带注释的参数的类型T必须为:

  1. 成为原始类型
  2. 具有一个接受单个String参数的构造函数
  3. 具有一个名为valueOf或fromString的静态方法,该方法接受单个String参数(例如,请参阅Integer.valueOf(String))
  4. 是列表,集合或排序集合,其中T满足上述2或3。结果集合是只读的。

例如,我们要获取InfoModel对象的列表。

根据第4点,如果我们在InfoModel内实现任何辅助方法(valueOf或fromString),则它也应正常工作。但我发现它对我不起作用。

因此,我在ArrayList上创建了一个包装器,并在ListWrapper类中实现了辅助方法 valueOf ,如下所示。它对我有用。

import org.codehaus.jackson.map.ObjectMapper;
class UploadRequestModel {

    @FormParam("info")
    private ListWrapper<InfoModel> info;

    @FormParam("id")
    private String id;

    /**
     * Getters/Setters
     **/

    public static class ListWrapper<T> extends ArrayList<T> {
        public static ListWrapper valueOf(String json) {
            ObjectMapper mapper = new ObjectMapper();
            ListWrapper obj = null;
            try {
                obj = mapper.readValue(json, ListWrapper.class);
            } catch (Exception e) {
                obj = new ListWrapper();
            }
            return obj;
        }
    }
}

class InfoModel {

    private String foo;
    private String bar;

    /**
     * Getters/Setters
     **/
}