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

问题描述 投票:0回答:1

在上传包含以下字段的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
    **/
}

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

java multipartform-data resteasy
1个回答
0
投票

每当我们在请求体中发送任何复杂数据时,它都会搜索有助于将请求体转换为java对象的辅助方法。

通过实现这些辅助方法,我们可以实现所需的结果。

正如java doc所说

@FormParam将请求实体主体中包含的表单参数的值绑定到资源方法参数。除非使用“编码”注释禁用此值,否则将对URL进行URL解码。可以使用DefaultValue批注指定默认值。如果请求实体主体不存在或者是不受支持的媒体类型,则使用默认值。注释参数的类型T必须:

  1. 是一种原始类型
  2. 有一个接受单个String参数的构造函数
  3. 有一个名为valueOf或fromString的静态方法接受单个String参数(例如,参见Integer.valueOf(String))
  4. Be List,Set或SortedSet,其中T满足上面的2或3。生成的集合是只读的。

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

根据第4点,如果我们在InfoModel中实现任何helper方法(valueOf或fromString),它也应该工作。但我发现了一些对我不起作用的方法。

所以我在ArrayList上创建了一个包装器,并在ListWrapper类中实现了helper方法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
     **/
}
© www.soinside.com 2019 - 2024. All rights reserved.