Java 有没有办法将@xmlement ListfieldName封送到而不是缺少的节点?

Java 有没有办法将@xmlement ListfieldName封送到而不是缺少的节点?,java,jaxb,eclipselink,moxy,Java,Jaxb,Eclipselink,Moxy,我试图让MOXy或JAXB RI将空集合封送到xsi:nil元素,如下所示: 用例是: 我无法控制Axis2 SOAP端点 我是客户 Endpoint要求null集合使用xsi:nil元素,但不允许使用@XmlElementWrapper包装这些元素,因为@XmlElementWrapper将为包装元素生成所需的xsi:nil元素。 从JDK 6 r4+或最新的Metro实现开始,我只能使用JAX-WS RI。 我可以使用JAXB RI或MOXy实现。 我在日食2.5.1上 绑定类型由wsimp

我试图让MOXy或JAXB RI将空集合封送到xsi:nil元素,如下所示:

用例是:

我无法控制Axis2 SOAP端点 我是客户 Endpoint要求null集合使用xsi:nil元素,但不允许使用@XmlElementWrapper包装这些元素,因为@XmlElementWrapper将为包装元素生成所需的xsi:nil元素。 从JDK 6 r4+或最新的Metro实现开始,我只能使用JAX-WS RI。 我可以使用JAXB RI或MOXy实现。 我在日食2.5.1上 绑定类型由wsimport在构建时从服务WSDL生成。因此,任何不需要对生成的源进行后处理以进行注释修改的解决方案都是可取的。 我知道2.2.6版本的JAXB RI可能无法做到这一点,但可能我遗漏了一些东西。我检查了源代码,它基本上是非参数化的:如果它是一个列表,如果它为null,则只有在字段中存在@XmlElementWrapper时才输出任何内容。但不幸的是,这并不能解决这个问题

我尝试了MOXy及其@XmlNullPolicy注释的使用,但它似乎对集合属性没有影响。是否有其他方法为emtpty集合生成MOXy输出xsi:nil元素

我创建了一个测试用例来举例说明发生了什么。第一和第二是实际结果和我需要的结果。第三个是在第四个代码块中为实际用例启用MOXy所需的jaxb.properties文件

这是我在底部执行测试用例时得到的结果:

测试用例:

谢谢你的帮助

谢谢大家的关注

致以最良好的祝愿, Christian

为什么地图很难绘制 具有以下属性表示集合属性为null

当以下内容表示已填充的集合时:

福 酒吧 有点奇怪,因为将被解释为包含一个空条目的集合

正如您在JAXB中通常提到的,您将利用@XmlElementWrapper,并让wrapper元素指示集合为null

你能做什么 我会调整您的数据以获得您想要的XML表示。您可以通过利用封送处理前后的事件来做到这一点。如果before事件将任何空值转换为包含空值的大小为1的列表。然后在after unmarshal事件中,将包含null值的大小列表设置回null

这可以通过封送处理完成。侦听器:

或在类的回调方法中:


这似乎是一种相当奇怪的表示形式——它如何区分空集合和唯一成员为空的单例集合?
<?xml version="1.0" encoding="UTF-8"?>
<model>
   <nonCollection xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true"/>
   <nonCollectionEmptyNode/>
   <wrappedNullCollection xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true"/>
</model>
<?xml version="1.0" encoding="UTF-8"?>
<model>
   <nonCollection xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true"/>
   <nonCollectionEmptyNode/>
   <nullCollection xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true"/>
   <wrappedNullCollection xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true"/>
</model>
javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory
package test;

import java.util.List;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.XmlRootElement;
import org.eclipse.persistence.oxm.annotations.XmlMarshalNullRepresentation;
import org.eclipse.persistence.oxm.annotations.XmlNullPolicy;

/**
 * jaxb.properties containing string:
 * "javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory"
 * needs to be in the same package as this class to enable MOXy.
 */
public class XmlNullPolicyTest
{

  @XmlAccessorType(XmlAccessType.FIELD)
  @XmlRootElement
  private static class Model
  {

    /**
     * Outputs xsi:nil elements when using JAXB RI or MOXy.
     */
    @XmlElement(required = true, nillable = true)
    protected String nonCollection;


    /**
     * This is here to test if the EclipseLink implementation is actually used.
     * To enable MOXy JAXB impl put jaxb.properties containing text
     * "javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory"
     * in the same package as this class.
     *
     * Using the RI it outputs:
     * <nonCollectionEmptyNode xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true"/>
     *
     * And with MOXy, because it processes @XmlNullPolicy:
     * <nonCollectionEmptyNode/>
     */
    @XmlElement(required = true, nillable = true)
    @XmlNullPolicy(
      nullRepresentationForXml = XmlMarshalNullRepresentation.EMPTY_NODE
    )
    protected String nonCollectionEmptyNode;

    /**
     * Need this one to work. Should marshal to:
     * <nullCollection xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true"/>
     * ...if possible.
     */
    @XmlElement(required = true, nillable = true)
    @XmlNullPolicy(
      nullRepresentationForXml = XmlMarshalNullRepresentation.XSI_NIL,
      xsiNilRepresentsNull = true
    )
    private List<String> nullCollection = null;

    /**
     * Cannot use this one, since it the service expects elements unwrapped.
     * Works though as long as the list is actually null.
     */
    @XmlElement(required = true, nillable = true)
    @XmlElementWrapper(nillable = true)
    private List<String> wrappedNullCollection = null;
  }

  public static void main(String[] args)
    throws JAXBException
  {

    final JAXBContext jaxbContext =
      JAXBContext.newInstance(Model.class);

    final Marshaller marshaller =
      jaxbContext.createMarshaller();

    marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);

    marshaller.marshal(new Model(), System.out);

  }
}