让 Glassfish 的 MOXy 将 JSON 转换为 POJO

Getting Glassfish's MOXy to convert JSON to POJO

我有一个通过 MULTIPART_FORM_DATA POST 上传文件的 Web 应用程序,其中包含二进制数据和 JSON 字符串。 (JSON 字符串是使用浏览器的 JSON.stringify(obj) 函数创建的。

根据文档,Glassfish 自 4.0.1 起使用 MOXy 解组 JSON 和 XML 对象。

我的方法是这样的:

@POST
@Path("put")
@Consumes(MediaType.MULTIPART_FORM_DATA)
@Produces(MediaType.APPLICATION_JSON)
public Response put(@FormDataParam("file") List<FormDataBodyPart> bodyParts,
                    @FormDataParam("metadata") List<String> metaParts) throws JAXBException {

    JAXBContext jbc = JAXBContext.newInstance(MetaData.class);

    for (int index = 0; index < metaParts.size(); index += 1) {

        MetaData meta = null;
        String metaString = metaParts.get(index);
        if (metaString != null && !metaString.isEmpty()) {
            Unmarshaller um = jbc.createUnmarshaller();
            // um.setProperty(???, "application/json");
            meta = (MetaData) um.unmarshal(new StreamSource(new StringReader(metaString)));
        }

像这样的代码将尝试将 metaString 中的数据解析为 XML 文档,因此会抛出异常。

通过搜索可用的文档,我发现 EclipseLink MOXy 实现的解决方案似乎是

um.setProperty("eclipselink.media-type", "application/json");

这不起作用,因为 MOXy 的 Glassfish 5 实现来自 com.sun.xml。* 而不是 Eclipse。跟踪代码,似乎此实现将在 any setProperty 调用上抛出异常,因为它不支持任何特定于实现的属性。

但我知道 Sun 的 MOXy 可以做到这一点,因为它可以很好地处理我的 HTTP requests/responses。然而,我在任何地方都找不到示例或文档——条条大路通向 EclipseLink 实现。

有人知道怎么做吗?

您不需要手动解析数据。您可以做的是将 body 部分作为 FormDataBodyPart 获取,就像您已经为 "file" 部分所做的那样。从 FormDataBodyPart 开始,您需要将媒体类型设置为 application/json1,然后只需使用 bodyPart.getValueAs(POJO.class).[=21 获取 POJO =]

public Response put(@FormDataBodyPart("metadata") FormDataBodyPart metaDataPart) {
    metaDataPart.setMediaType(MediaType.APPLICATION_JSON_TYPE);
    MetaData metaData = metaDataPart.getValueAs(MetaData.class);
}

File upload along with other object in Jersey restful web service

中查看更多相关信息

1 - 在多部分请求中,每个 body 部分都有自己的 Content-Type header。如果您不设置它,它将自动被视为 text/plain 作为默认值。使用Javascript,你无法设置个别部分的content-type,所以它会默认为text/plain。但我们需要它是 application/json 以便 JAX-RS JSON 提供程序用于反序列化。