Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 防止Jackson XML映射器将WSTXN添加到名称空间_Java_Xml_Jackson_Jackson Dataformat Xml - Fatal编程技术网

Java 防止Jackson XML映射器将WSTXN添加到名称空间

Java 防止Jackson XML映射器将WSTXN添加到名称空间,java,xml,jackson,jackson-dataformat-xml,Java,Xml,Jackson,Jackson Dataformat Xml,将对象序列化为XML并使用为属性指定名称空间时 @JacksonXmlRootElement(命名空间=”http://...“” Jackson将在名称空间中附加或前置“wstxns1”。例如,假设我们有这些类: VtexSkuAttributeValues.java @JacksonXmlRootElement(localName = "listStockKeepingUnitName") public class VtexSkuAttributeValues { @Jackson

将对象序列化为XML并使用为属性指定名称空间时
@JacksonXmlRootElement(命名空间=”http://...“”
Jackson将在名称空间中附加或前置“wstxns1”。例如,假设我们有这些类:

VtexSkuAttributeValues.java

@JacksonXmlRootElement(localName = "listStockKeepingUnitName")
public class VtexSkuAttributeValues {

    @JacksonXmlProperty(localName = "StockKeepingUnitFieldNameDTO", namespace = "http://schemas.datacontract.org/2004/07/Vtex.Commerce.WebApps.AdminWcfService.Contracts")
    @JacksonXmlElementWrapper(useWrapping = false)
    private VtexSkuAttributeValue[] stockKeepingUnitFieldNameDTO;

    public VtexSkuAttributeValue[] getStockKeepingUnitFieldNameDTO() {
        return stockKeepingUnitFieldNameDTO;
    }

    public void setValues(VtexSkuAttributeValue[] values) {
        this.stockKeepingUnitFieldNameDTO = values;
    }
}
@JacksonXmlRootElement(localName = "StockKeepingUnitFieldNameDTO", namespace = "http://schemas.datacontract.org/2004/07/Vtex.Commerce.WebApps.AdminWcfService.Contracts")
public class VtexSkuAttributeValue {

    private String fieldName;
    private FieldValues fieldValues;
    private int idSku;

    public int getIdSku() {
        return idSku;
    }

    public String getFieldName() {
        return fieldName;
    }

    public FieldValues getFieldValues() {
        return fieldValues;
    }

    public void setIdSku(int idSku) {
        this.idSku = idSku;
    }

    public void setFieldName(String fieldName) {
        this.fieldName = fieldName;
    }

    public void setFieldValues(FieldValues fieldValues) {
        this.fieldValues = fieldValues;
    }

    @JacksonXmlRootElement(localName = "fieldValues", namespace = "http://schemas.datacontract.org/2004/07/Vtex.Commerce.WebApps.AdminWcfService.Contracts")
    public static class FieldValues {
        @JacksonXmlProperty(namespace = "http://schemas.microsoft.com/2003/10/Serialization/Arrays")
        @JacksonXmlElementWrapper(useWrapping = false)
        public String[] string;

        public String[] getString() {
            return string;
        }

        public void setValues(String[] values) {
            this.string = values;
        }
    }
}
VtexSkuAttributeValue.java

@JacksonXmlRootElement(localName = "listStockKeepingUnitName")
public class VtexSkuAttributeValues {

    @JacksonXmlProperty(localName = "StockKeepingUnitFieldNameDTO", namespace = "http://schemas.datacontract.org/2004/07/Vtex.Commerce.WebApps.AdminWcfService.Contracts")
    @JacksonXmlElementWrapper(useWrapping = false)
    private VtexSkuAttributeValue[] stockKeepingUnitFieldNameDTO;

    public VtexSkuAttributeValue[] getStockKeepingUnitFieldNameDTO() {
        return stockKeepingUnitFieldNameDTO;
    }

    public void setValues(VtexSkuAttributeValue[] values) {
        this.stockKeepingUnitFieldNameDTO = values;
    }
}
@JacksonXmlRootElement(localName = "StockKeepingUnitFieldNameDTO", namespace = "http://schemas.datacontract.org/2004/07/Vtex.Commerce.WebApps.AdminWcfService.Contracts")
public class VtexSkuAttributeValue {

    private String fieldName;
    private FieldValues fieldValues;
    private int idSku;

    public int getIdSku() {
        return idSku;
    }

    public String getFieldName() {
        return fieldName;
    }

    public FieldValues getFieldValues() {
        return fieldValues;
    }

    public void setIdSku(int idSku) {
        this.idSku = idSku;
    }

    public void setFieldName(String fieldName) {
        this.fieldName = fieldName;
    }

    public void setFieldValues(FieldValues fieldValues) {
        this.fieldValues = fieldValues;
    }

    @JacksonXmlRootElement(localName = "fieldValues", namespace = "http://schemas.datacontract.org/2004/07/Vtex.Commerce.WebApps.AdminWcfService.Contracts")
    public static class FieldValues {
        @JacksonXmlProperty(namespace = "http://schemas.microsoft.com/2003/10/Serialization/Arrays")
        @JacksonXmlElementWrapper(useWrapping = false)
        public String[] string;

        public String[] getString() {
            return string;
        }

        public void setValues(String[] values) {
            this.string = values;
        }
    }
}
然后,我使用
XmlMapper
序列化并获得:

<listStockKeepingUnitName>
    <wstxns1:StockKeepingUnitFieldNameDTO xmlns:wstxns1="http://schemas.datacontract.org/2004/07/Vtex.Commerce.WebApps.AdminWcfService.Contracts">
        <fieldName>talle</fieldName>
        <fieldValues>
            <wstxns2:string xmlns:wstxns2="http://schemas.microsoft.com/2003/10/Serialization/Arrays">6184</wstxns2:string>
        </fieldValues>
        <idSku>258645</idSku>
    </wstxns1:StockKeepingUnitFieldNameDTO>
    <wstxns3:StockKeepingUnitFieldNameDTO xmlns:wstxns3="http://schemas.datacontract.org/2004/07/Vtex.Commerce.WebApps.AdminWcfService.Contracts">
        <fieldName>color</fieldName>
        <fieldValues>
            <wstxns4:string xmlns:wstxns4="http://schemas.microsoft.com/2003/10/Serialization/Arrays">6244</wstxns4:string>
        </fieldValues>
        <idSku>258645</idSku>
    </wstxns3:StockKeepingUnitFieldNameDTO>
</listStockKeepingUnitName>

塔勒
6184
258645
颜色
6244
258645
即使这是有效的XML,我使用的web服务也不接受它。我调试了它,这是由于Jackson出于某种原因添加的标记中的
wstxns
属性。
有没有办法阻止Jackson将其添加到标签中。我能想到的唯一解决办法是对生成的XML执行string.replaceAll,但这显然不理想。

编写
XML
Jackson
使用
javax.XML.stream.XMLStreamWriter
。您可以配置该类的实例,为名称空间定义自己的前缀,并根据需要设置默认前缀。为此,我们需要扩展
com.fasterxml.jackson.dataformat.xml.XmlFactory
类,并重写一个创建
XMLStreamWriter
实例的方法。示例实现如下所示:

class NamespaceXmlFactory extends XmlFactory {

    private final String defaultNamespace;
    private final Map<String, String> prefix2Namespace;

    public NamespaceXmlFactory(String defaultNamespace, Map<String, String> prefix2Namespace) {
        this.defaultNamespace = Objects.requireNonNull(defaultNamespace);
        this.prefix2Namespace = Objects.requireNonNull(prefix2Namespace);
    }

    @Override
    protected XMLStreamWriter _createXmlWriter(IOContext ctxt, Writer w) throws IOException {
        XMLStreamWriter writer = super._createXmlWriter(ctxt, w);
        try {
            writer.setDefaultNamespace(defaultNamespace);
            for (Map.Entry<String, String> e : prefix2Namespace.entrySet()) {
                writer.setPrefix(e.getKey(), e.getValue());
            }
        } catch (XMLStreamException e) {
            StaxUtil.throwAsGenerationException(e, null);
        }
        return writer;
    }
}
并将其用于应该用作默认名称空间的每个类和字段。例如:

@JacksonXmlProperty(localName = "StockKeepingUnitFieldNameDTO", namespace = DEF_NMS)
对于不想更改其名称的属性,可以使用:

@JacksonXmlProperty(namespace = VtexSkuAttributeValues.DEF_NMS)
上面的代码打印一些随机数据:

<listStockKeepingUnitName>
  <StockKeepingUnitFieldNameDTO xmlns="http://schemas.datacontract.org/2004/07/Vtex.Commerce.WebApps.AdminWcfService.Contracts">
    <fieldName>Name1</fieldName>
    <fieldValues>
      <a:string xmlns:a="http://schemas.microsoft.com/2003/10/Serialization/Arrays">6184</a:string>
    </fieldValues>
    <idSku>123</idSku>
  </StockKeepingUnitFieldNameDTO>
  <StockKeepingUnitFieldNameDTO xmlns="http://schemas.datacontract.org/2004/07/Vtex.Commerce.WebApps.AdminWcfService.Contracts">
    <fieldName>Name1</fieldName>
    <fieldValues>
      <a:string xmlns:a="http://schemas.microsoft.com/2003/10/Serialization/Arrays">6184</a:string>
    </fieldValues>
    <idSku>123</idSku>
  </StockKeepingUnitFieldNameDTO>
</listStockKeepingUnitName>

名称1
6184
123
名称1
6184
123
如果这不是您想要的,您可以使用该代码并尝试其他可用于配置此实例的方法


使用版本
2.9.9
创建此示例
Jackson

编写
XML
Jackson使用
javax.XML.stream.XMLStreamWriter
。您可以配置该类的实例,为名称空间定义自己的前缀,并根据需要设置默认前缀。为此,我们需要扩展
com.fasterxml.jackson.dataformat.xml.XmlFactory
类,并重写一个创建
XMLStreamWriter
实例的方法。示例实现如下所示:

class NamespaceXmlFactory extends XmlFactory {

    private final String defaultNamespace;
    private final Map<String, String> prefix2Namespace;

    public NamespaceXmlFactory(String defaultNamespace, Map<String, String> prefix2Namespace) {
        this.defaultNamespace = Objects.requireNonNull(defaultNamespace);
        this.prefix2Namespace = Objects.requireNonNull(prefix2Namespace);
    }

    @Override
    protected XMLStreamWriter _createXmlWriter(IOContext ctxt, Writer w) throws IOException {
        XMLStreamWriter writer = super._createXmlWriter(ctxt, w);
        try {
            writer.setDefaultNamespace(defaultNamespace);
            for (Map.Entry<String, String> e : prefix2Namespace.entrySet()) {
                writer.setPrefix(e.getKey(), e.getValue());
            }
        } catch (XMLStreamException e) {
            StaxUtil.throwAsGenerationException(e, null);
        }
        return writer;
    }
}
并将其用于应该用作默认名称空间的每个类和字段。例如:

@JacksonXmlProperty(localName = "StockKeepingUnitFieldNameDTO", namespace = DEF_NMS)
对于不想更改其名称的属性,可以使用:

@JacksonXmlProperty(namespace = VtexSkuAttributeValues.DEF_NMS)
上面的代码打印一些随机数据:

<listStockKeepingUnitName>
  <StockKeepingUnitFieldNameDTO xmlns="http://schemas.datacontract.org/2004/07/Vtex.Commerce.WebApps.AdminWcfService.Contracts">
    <fieldName>Name1</fieldName>
    <fieldValues>
      <a:string xmlns:a="http://schemas.microsoft.com/2003/10/Serialization/Arrays">6184</a:string>
    </fieldValues>
    <idSku>123</idSku>
  </StockKeepingUnitFieldNameDTO>
  <StockKeepingUnitFieldNameDTO xmlns="http://schemas.datacontract.org/2004/07/Vtex.Commerce.WebApps.AdminWcfService.Contracts">
    <fieldName>Name1</fieldName>
    <fieldValues>
      <a:string xmlns:a="http://schemas.microsoft.com/2003/10/Serialization/Arrays">6184</a:string>
    </fieldValues>
    <idSku>123</idSku>
  </StockKeepingUnitFieldNameDTO>
</listStockKeepingUnitName>

名称1
6184
123
名称1
6184
123
如果这不是您想要的,您可以使用该代码并尝试其他可用于配置此实例的方法


使用版本
2.9.9
创建此示例
Jackson

这似乎是缺少的部分。它允许您设置前缀和命名空间

   static class NamespaceXmlFactory extends XmlFactory {

    private final String defaultNamespace;
    private final Map<String, String> prefix2Namespace;

    public NamespaceXmlFactory(String defaultNamespace, Map<String, String> prefix2Namespace) {
        this.defaultNamespace = Objects.requireNonNull(defaultNamespace);
        this.prefix2Namespace = Objects.requireNonNull(prefix2Namespace);
    }

    @Override
    protected XMLStreamWriter _createXmlWriter(IOContext ctxt, Writer w) throws IOException {
        XMLStreamWriter2 writer = (XMLStreamWriter2)super._createXmlWriter(ctxt, w);
        try {
            writer.setDefaultNamespace(defaultNamespace);
            writer.setPrefix("xsi", "http://www.w3.org/2001/XMLSchema-instance");
            for (Map.Entry<String, String> e : prefix2Namespace.entrySet()) {
                writer.setPrefix(e.getKey(), e.getValue());
            }
        } catch (XMLStreamException e) {
            StaxUtil.throwAsGenerationException(e, null);
        }
        return writer;
    }
}
创建以下输出:


仍在尝试解决如何将其改为xsi:type=“networkObjectGroupDTO”

这似乎是丢失的部分。它允许您设置前缀和命名空间

   static class NamespaceXmlFactory extends XmlFactory {

    private final String defaultNamespace;
    private final Map<String, String> prefix2Namespace;

    public NamespaceXmlFactory(String defaultNamespace, Map<String, String> prefix2Namespace) {
        this.defaultNamespace = Objects.requireNonNull(defaultNamespace);
        this.prefix2Namespace = Objects.requireNonNull(prefix2Namespace);
    }

    @Override
    protected XMLStreamWriter _createXmlWriter(IOContext ctxt, Writer w) throws IOException {
        XMLStreamWriter2 writer = (XMLStreamWriter2)super._createXmlWriter(ctxt, w);
        try {
            writer.setDefaultNamespace(defaultNamespace);
            writer.setPrefix("xsi", "http://www.w3.org/2001/XMLSchema-instance");
            for (Map.Entry<String, String> e : prefix2Namespace.entrySet()) {
                writer.setPrefix(e.getKey(), e.getValue());
            }
        } catch (XMLStreamException e) {
            StaxUtil.throwAsGenerationException(e, null);
        }
        return writer;
    }
}
创建以下输出:


仍在尝试解决如何将其改为xsi:type=“networkObjectGroupDTO”

这些“wstxns属性”来自
JacksonXmlRootElement
注释中的
名称空间
属性。如果省略
名称空间
属性,您会得到所需的输出吗?@dnault我无法操作它,因为它是web服务所必需的。这些“wstxns属性”来自
JacksonXmlRootElement
注释中的
名称空间
属性。如果省略
namespace
属性,您会得到所需的输出吗?@dnault我无法操作它,因为它是web服务所必需的。这是一个非常好的示例,展示了Jackson XML的内部工作原理,现在我觉得我应该更好地表达我的问题。有没有办法完全防止Jackson向名称空间添加前缀?如果我设置一个空字符串作为前缀,Jackson默认为
wstxns
。如果我将它设置为null,我会得到
NullPointerException
@Morgan,
Jackson
只是其他库的包装器,在这种情况下,它只是其他库的包装器。但是,通常不能同时在全局范围中有多个默认命名空间。使用不带前缀的默认名称空间
xmlns
。如果您希望始终使用
xmlns
而不使用任何前缀,则需要在序列化期间更改默认名称空间,因此在每个级别上,无论何时需要名称空间,我们都需要将其设置为默认名称空间。我认为我的示例将允许您生成一个可接受的
XML
@Morgan,看看,了解
NamespaceContext
类以及如何使用它。看,这是一个非常好的例子,展示了Jackson XML的内部工作原理,现在我觉得我应该把我的问题写得更好。有没有办法完全防止Jackson向名称空间添加前缀?如果我设置一个空字符串作为前缀,Jackson默认为
wstxns
。如果我将它设置为null,我会得到
NullPointerException
@Morgan,
Jackson
只是其他库的包装器,在这种情况下,它只是其他库的包装器。但是,通常不能同时在全局范围中有多个默认命名空间。使用不带前缀的默认名称空间
xmlns
。如果您希望始终使用
xmlns
而不使用任何前缀,则需要在序列化期间更改默认名称空间,因此在每个级别上,无论何时需要名称空间,我们都需要将其设置为默认名称空间。我认为我的示例将允许您生成一个可接受的
XML
@Morgan,看看,阅读
namespacecoxt
类,然后