让 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/json
1,然后只需使用 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 提供程序用于反序列化。
我有一个通过 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/json
1,然后只需使用 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 提供程序用于反序列化。