java - Jackson MixIn 将泛型类 JAXBElement<T> 替换为 getValue() 后面的 T

标签 java xml json jaxb jackson

我正在尝试使用相同的 JAXB 注释(使用 JaxbAnnotationModule )绑定(bind) XML 和 JSON。

XML <--> JAXB <--> Jackson <--> JSON

我必须使用 JAXB 注释并且不能更改它们。我的问题是一些 XML 转换为通用类 JAXBElement<T>而不是类 T直接地。这导致 JSON 输出:

{  
   "JAXBElement":{  
      "name":"{http://www.opengis.net/wps/1.0.0}Capabilities",
      "declaredType":"net.opengis.wps.v_1_0_0.WPSCapabilitiesType",
      "scope":"javax.xml.bind.JAXBElement$GlobalScope",
      "value":{  
         "ProcessOfferings":{  },
         "Languages":{  },
         "ServiceIdentification":{  },
         "ServiceProvider":{  },
         "OperationsMetadata":{  },
         "version":"1.0.0",
         "updateSequence":"1",
         "service":"WPS",
         "lang":"en-US"
      },
      "nil":false,
      "globalScope":true,
      "typeSubstituted":false
   }
}

虽然我反而想要:

{  
   "Capabilities":{  
     "ProcessOfferings":{  },
     "Languages":{  },
     "ServiceIdentification":{  },
     "ServiceProvider":{  },
     "OperationsMetadata":{  },
     "version":"1.0.0",
     "updateSequence":"1",
     "service":"WPS",
     "lang":"en-US"
   }
}

真实对象类型T由 JAXBElement 包装。这可能发生在某些根元素上,也可能嵌套在对象树中的任何位置。如果我调用 getValue()在那我会得到真实的对象。但是当 JAXBElement<T> 时我不能这样做不是根元素,因为 Jackson 是 JAXB 和 JSON 之间的唯一解释器,我既不能改变 JAXB 绑定(bind),也不能改变创建的对象(代码的其他一些部分也使用它们)。

所以我发现可能解决问题的是 MixIns :

// a mixin annotation that overrides the handling for the JAXBElement
public static interface JAXBElementMixin<T> {
    @JsonValue
    Object getValue();
}

ObjectMapper mapper = new ObjectMapper();
JaxbAnnotationModule module = new JaxbAnnotationModule();
mapper.registerModule(module);
mapper.addMixInAnnotations(JAXBElement.class, JAXBElementMixin.class);

这解决了附加元素的问题,但导致对象的名称为 JAXBElement而不是 T (以我为例 Capabilities ):

{  
  "JAXBElement":{  // <------ Should be 'Capabilities' because of type JAXBElement<Capabilities>
    "ProcessOfferings":{  },
    "Languages":{  },
    "ServiceIdentification":{  },
    "ServiceProvider":{  },
    "OperationsMetadata":{  },
    "version":"1.0.0",
    "updateSequence":"1",
    "service":"WPS",
    "lang":"en-US"
  }
}

问题:

知道我可以做什么(也许注释 JAXBElementMixin<T> )来获得正确的类型 Capabilities作为对象名称(还有其他类而不是 Capabilities 也可以作为 T 放置)?

任何其他想法如何跳过任何 JAXBElement<T> 的序列化对象树中的任何位置,并继续对其 getValue() 后面的对象进行序列化方法?

最佳答案

这不是您问题的直接答案,但可能是实现您目标的秘诀。

如果您只是想摆脱最顶层的 JAXBElement,为什么不自定义 XJC 来为您的 Capabilities 元素生成一个额外的类?

类似于:

<jaxb:bindings node="xs:element[@name='Capabilities']">
   <jaxb:class name="Capabilities"/>
</jaxb:bindings>

这应该生成一个用“@XmlRootElement”注释的类 Capabilities。因此,您将摆脱 JAXBElement

关于java - Jackson MixIn 将泛型类 JAXBElement<T> 替换为 getValue() 后面的 T,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27543072/

相关文章:

Java 问题 - ArrayList 和 Time Elapsed 函数

java - 如何测量分布式系统中的请求时间?

xml - XStream反序列化具有分层对象列表的xml

java - Jenkins Ant 构建上的自定义 PMD 规则集文件不起作用

java - 如何更改 AutoCompleteTextView 句柄背景

android - JSON解析问题——如何在一段代码中同时处理JSONArray和JSONObject

javascript - 有没有办法获取从 npm 运行的模块中的 package.json 属性?

Java:守护进程:thread.join() 未完成,之前在一个线程中抛出异常

Java - MongoDB - 将 Json 对象映射为 Java 数组

arrays - 获取通过数组中的 http 调用接收到的 json - Swift iOS