java - 如何转换moxy json输出?

原文 标签 java json jaxb moxy

我正在尝试做与Can I get MOXy to convert a string to a boolean when generating json几乎相同的事情。

我从xml-> object开始。对象现在包含要作为GeoJson输出的几何。

我试图在xml-bindings.xml中添加xml-java-type-adapters,但它们似乎从未运行。 package-info.java中的注释会运行,但也会影响xml-> object,而不仅仅是object-> json。那就是为什么我认为xml映射覆盖是一个好主意。

现在我有

<?xml version="1.0" encoding="UTF-8"?>
<xml-bindings package-name="se.lantmateriet.geoaccess.outrettfastighetsomrade.jaxb" xmlns="http://www.eclipse.org/eclipselink/xsds/persistence/oxm" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.eclipse.org/eclipselink/xsds/persistence/oxm http://www.eclipse.org/eclipselink/xsds/eclipselink_oxm_2_4.xsd" version="2.4">
<java-types>
    <java-type name="OutrettFastighetsomradeReferensType">
        <java-attributes>
            <xml-element java-attribute="centralpunkt">
                <xml-java-type-adapter value="se.lantmateriet.sercxi.web.controller.GeoJsonAdapter"/>
            </xml-element>
        </java-attributes>
    </java-type>
</java-types>    




和一些演示代码:

    List<OutrettFastighetsomradeReferensType> result = this.outrettFastighetsomradeReferensRepository
        .getByExternIdStartsWith(decodeUtf8String(externId));

    List<InputStream> metadata = Lists.newArrayList(new ClassPathResource("json-bindings.xml").getInputStream());

    Map<String, List<InputStream>> properties = ImmutableMap.of(JAXBContextProperties.OXM_METADATA_SOURCE, metadata);

    Jaxb2Marshaller jaxb2Marshaller = new Jaxb2Marshaller();
    jaxb2Marshaller.setLazyInit(true);
    jaxb2Marshaller.setContextPaths("se.lantmateriet.sercxi.gateway.outrettfastighetsomrade.config", "se.lantmateriet.geoaccess.jaxb.gml",
        "se.lantmateriet.geoaccess.outrettfastighetsomrade.jaxb");
    jaxb2Marshaller.setJaxbContextProperties(properties);

    jaxb2Marshaller.afterPropertiesSet();

    StringResult stringResult = new StringResult();

    Marshaller marshaller = jaxb2Marshaller.getJaxbContext().createMarshaller();

    marshaller.setProperty("eclipselink.media-type", MediaType.APPLICATION_JSON_VALUE);

    marshaller.marshal(result.get(0), stringResult);

    return stringResult.toString();


XMLAdapter:

public class GeoJsonAdapter extends XmlAdapter<PointPropertyType, Map<String, Object>> {

@Override
public Map<String, Object> unmarshal(final PointPropertyType v) throws Exception {
    return JTSGeometryToGeoJsonConverter.convertGeometryToJson(POSITION(N(v.getPoint().getPos().getValue().get(0)),
        E(v.getPoint().getPos().getValue().get(1))).toPoint());
}

@Override
public PointPropertyType marshal(final Map<String, Object> v) throws Exception {
    throw new UnsupportedOperationException();
}


}

和我想要在json输出中转换其属性centralpunkt的域对象(我在第三方jar中有此代码,无法更改):

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "OutrettFastighetsomradeReferensType", namespace = "http://namespace.lantmateriet.se/distribution/produkter/outrettfastighetsomrade/v1", propOrder = {
"objektidentitet",
"fodelsenummer",
"externId",
"fastighetsomradetyp",
"centralpunkt"
})
public class OutrettFastighetsomradeReferensType {

@XmlElement(namespace = "http://namespace.lantmateriet.se/distribution/produkter/outrettfastighetsomrade/v1", required = true)
protected String objektidentitet;
@XmlElement(namespace = "http://namespace.lantmateriet.se/distribution/produkter/outrettfastighetsomrade/v1", required = true)
protected String fodelsenummer;
@XmlElement(namespace = "http://namespace.lantmateriet.se/distribution/produkter/outrettfastighetsomrade/v1", required = true)
protected String externId;
@XmlElement(namespace = "http://namespace.lantmateriet.se/distribution/produkter/outrettfastighetsomrade/v1", required = true)
protected FastighetsomradeTypType fastighetsomradetyp;
@XmlElement(name = "Centralpunkt", namespace = "http://namespace.lantmateriet.se/distribution/produkter/outrettfastighetsomrade/v1", required = true)
protected PointPropertyType centralpunkt;


但这不起作用:-(

Caused by: javax.xml.bind.JAXBException - with linked exception:
[java.lang.NullPointerException]
at org.eclipse.persistence.jaxb.JAXBContext$ContextPathInput.createContextState(JAXBContext.java:915)
at org.eclipse.persistence.jaxb.JAXBContext$ContextPathInput.createContextState(JAXBContext.java:848)
at org.eclipse.persistence.jaxb.JAXBContext.<init>(JAXBContext.java:182)
at org.eclipse.persistence.jaxb.JAXBContextFactory.createContext(JAXBContextFactory.java:129)
at sun.reflect.GeneratedMethodAccessor43.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:137)
at javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:108)
at javax.xml.bind.ContextFinder.find(ContextFinder.java:258)
at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:412)
at org.springframework.oxm.jaxb.Jaxb2Marshaller.createJaxbContextFromContextPath(Jaxb2Marshaller.java:470)
at org.springframework.oxm.jaxb.Jaxb2Marshaller.getJaxbContext(Jaxb2Marshaller.java:443)
... 73 more
Caused by: java.lang.NullPointerException
at org.eclipse.persistence.jaxb.compiler.AnnotationsProcessor.updateGlobalElements(AnnotationsProcessor.java:3868)
at org.eclipse.persistence.jaxb.compiler.AnnotationsProcessor.postBuildTypeInfo(AnnotationsProcessor.java:735)
at org.eclipse.persistence.jaxb.compiler.AnnotationsProcessor.buildNewTypeInfo(AnnotationsProcessor.java:4746)
at org.eclipse.persistence.jaxb.compiler.AnnotationsProcessor.processReferencedClass(AnnotationsProcessor.java:838)
at org.eclipse.persistence.jaxb.compiler.AnnotationsProcessor.buildTypeInfo(AnnotationsProcessor.java:812)
at org.eclipse.persistence.jaxb.compiler.AnnotationsProcessor.postBuildTypeInfo(AnnotationsProcessor.java:734)
at org.eclipse.persistence.jaxb.compiler.XMLProcessor.processXML(XMLProcessor.java:364)
at org.eclipse.persistence.jaxb.compiler.Generator.<init>(Generator.java:104)
at org.eclipse.persistence.jaxb.JAXBContext$ContextPathInput.createContextState(JAXBContext.java:912)
... 85 more


有任何想法吗?

这就是我真正想要的:

<?xml version="1.0" encoding="UTF-8"?>
<xml-bindings xmlns="http://www.eclipse.org/eclipselink/xsds/persistence/oxm" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.eclipse.org/eclipselink/xsds/persistence/oxm http://www.eclipse.org/eclipselink/xsds/eclipselink_oxm_2_4.xsd" version="2.4">
<xml-java-type-adapters>
    <xml-java-type-adapter value="se.lantmateriet.sercxi.web.controller.GeoJsonAdapter" type="se.lantmateriet.geoaccess.jaxb.gml.PointPropertyType"/>
</xml-java-type-adapters>




但这似乎没有任何影响。全局级别的xml-java-type-adapter似乎没有记载?

谢谢,

/马格努斯

最佳答案

有一些问题在起作用。以下是我第一次尝试的答案:



创建XmlAdapter

因为您要尝试适应PointPropertyType类,所以您的XmlAdapter向后。代替这个。

public class GeoJsonAdapter extends XmlAdapter<PointPropertyType, Map<String, Object>> {


你应该有:

public class GeoJsonAdapter extends XmlAdapter<Map<String, Object>, PointPropertyType> {




映射为XmlAdapter的值类型

当前,在Map中使用XmlAdapter作为值类型存在问题(请参见下文)。现在,您应该使用常规的POJO。


http://bugs.eclipse.org/421680




指定程序包级别适配器

MOXy元数据(json-bindings.xml)

当您通过JAXB批注或MOXy的元数据文档在包级别指定XmlAdapter时,它将应用于该包中属于类的所有映射字段/属性。在下面的示例文档中,se.lantmateriet.sercxi.web.controller.GeoJsonAdapter XmlAdapter将应用于属于se.lantmateriet.geoaccess.jaxb.gml.PointPropertyType包中的类的forum19952922类型的字段/属性。

<?xml version="1.0" encoding="UTF-8"?>
<xml-bindings 
    xmlns="http://www.eclipse.org/eclipselink/xsds/persistence/oxm" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.eclipse.org/eclipselink/xsds/persistence/oxm http://www.eclipse.org/eclipselink/xsds/eclipselink_oxm_2_4.xsd" 
    version="2.4"
    package-name="forum19952922">
        <xml-java-type-adapters>
            <xml-java-type-adapter value="se.lantmateriet.sercxi.web.controller.GeoJsonAdapter" type="se.lantmateriet.geoaccess.jaxb.gml.PointPropertyType" />
        </xml-java-type-adapters>
</xml-bindings>


了解更多信息


http://blog.bdoughan.com/2012/02/jaxb-and-package-level-xmladapters.html




简化引导程序

下面是一个代码示例,它将帮助简化引导过程。如果指定为String的位置与相对文件位置匹配,则将加载该文件,否则,该位置将被尝试作为类路径上的资源。

    Map<String, Object> properties = new HashMap<String, Object>(2);
    properties.put(JAXBContextProperties.OXM_METADATA_SOURCE, "forum19952922/json-bindings.xml");
    properties.put(JAXBContextProperties.MEDIA_TYPE, "application/json");
    JAXBContext jc = JAXBContext.newInstance(new Class[] {Root.class}, properties);

关于java - 如何转换moxy json输出?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19952922/

相关文章:

java - 通过监视Selenium Webdriver中的网络流量来捕获Post参数

php - 当标识符以@符号开头时如何访问php中的对象?

javascript - 页面因未知原因卡住

xml - Spring MVC @ResponseBody 返回一个 Map 产生 "Error 406 NOT ACCEPTABLE"

java - JAXB 编码(marshal)一个泛型类型的 Map 结构

java - JAXB可映射XML元素

javascript - 使用nashorn从JavaScript引用现有的Java对象

java - 如何修复java.lang.UnsatisfiedLinkError:com.badlogic.gdx.physics.box2d.PolygonShape.newPolygonShape()?

java - 使用 SolrJ 过滤查询排除

javascript - 从JSON数组访问字符串值