jaxb 编组时出现 javax.xml.bind.PropertyException

Posted

技术标签:

【中文标题】jaxb 编组时出现 javax.xml.bind.PropertyException【英文标题】:javax.xml.bind.PropertyException when jaxb marshalling 【发布时间】:2017-10-10 05:59:24 【问题描述】:

我正在尝试将对象列表编组为 xml。 方法如下:

import com.sun.xml.bind.marshaller.NamespacePrefixMapper;
import javax.xml.bind.Marshaller;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;

public class ItemMarshaller

    public String marshallItems(final List<Items> items)
    
        try
        
            final JAXBContext context = JAXBContext.newInstance("com.project.jaxb.items");
            final Marshaller m = context.createMarshaller();
            m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);

            m.setProperty("com.sun.xml.bind.namespacePrefixMapper", new NamespacePrefixMapper()
            
                @Override
                public String getPreferredPrefix(String uri, String suggestion, boolean requirePrefix)
                
                    return "";
                
            );

            final StringWriter writer = new StringWriter();
            m.marshal(items, writer);

            return writer.toString();
        
        catch (final JAXBException e)
        
            ErrorLogger.LOGGER.error("Marshalling failed.", e); //$NON-NLS-1$
        

        return null;
    

当我调用 m.setProperty("com.sun.xml.bind.namespacePrefixMapper", new NamespacePrefixMapper() 时,我收到以下错误:

javax.xml.bind.PropertyException: name: com.sun.xml.bind.namespacePrefixMapper value: com.project.ItemMarshaller$1@eb6e072
at javax.xml.bind.helpers.AbstractMarshallerImpl.setProperty(AbstractMarshallerImpl.java:358)
at com.sun.xml.internal.bind.v2.runtime.MarshallerImpl.setProperty(MarshallerImpl.java:527)

现在,如果我使用 Internal 类: com.sun.xml.internal.bind.marshaller.NamespacePrefixMapper;

相反,它有效。然而,这个项目是使用 maven 构建的,当你依赖一个内部类时它会抱怨。使用内部类也是一个坏主意,至少有人告诉我。

我该如何解决这个问题?

【问题讨论】:

【参考方案1】:

选项 1: 使用 package-info.java 文件中的注解代替 NamespacePrefixMapper 类:

@javax.xml.bind.annotation.XmlSchema(
        namespace = "http://www.example.com/schema/impl", 
        elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED,
        xmlns=@XmlNs(prefix="ns0", namespaceURI="http://www.example.com/schema/impl")
    )
package com.abc.schema.impl;

选项 2: 在 Maven 中,我添加了以下构建依赖项:

<!-- https://mvnrepository.com/artifact/com.sun.xml.bind/jaxb-impl -->
<dependency>
    <groupId>com.sun.xml.bind</groupId>
    <artifactId>jaxb-impl</artifactId>
    <version>2.2.4-1</version>
</dependency>

这使您可以使用 com.sun.xml.bind.marshaller.NamespacePrefixMapper。

【讨论】:

以上是关于jaxb 编组时出现 javax.xml.bind.PropertyException的主要内容,如果未能解决你的问题,请参考以下文章

编组时出现 JAXB 错误

Java 11 包 javax.xml.bind 不存在 [重复]

2021-8-15 SpringBoot 出现 javax.xml.bind.JAXBContext 错误

接受 SDK 许可时出现“java.lang.NoClassDefFoundError: javax/xml/bind/annotation/XmlSchema”

NoClassDefFoundError:由于缺少依赖关系,无法加载类groovy.xml.jaxb.JaxbGroovyMethods javax / xml / bind / Unmarshall

完美解决javax.xml.bind.JAXBContext