2017-09-13 86 views
0

我测试和解组下面的Java对象:JAXB解组集(集)

框架类:

@XmlRootElement (name = "framework") 
@XmlAccessorType(XmlAccessType.FIELD) 
@Entity 
public class Framework implements Comparable<Framework>, Serializable { 
    private static final long serialVersionUID = 1L; 
    @XmlTransient 
    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    private Long id; 
    private String frameworkName; 
    private String frameworkVersion; 
    private String frameworkDescription; 
    @XmlElementWrapper(name = "framework-domains") 
    private Set<FrameworkDomain> frameworkDomainList = new HashSet<>(); 
    @XmlElementWrapper(name = "framework-comments") 
    private Set<Comment> comments = new HashSet<>(); 

(只包含的getter,setter和功能没有任何附加注释的nuber)

域类:

@XmlRootElement(name = "domain") 
@XmlAccessorType(XmlAccessType.FIELD) 
@Entity 
public class FrameworkDomain implements Comparable<FrameworkDomain>, Serializable { 

    private static final long serialVersionUID = 1L; 
    @XmlTransient 
    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    private Long id; 
    private String domainName; 
    private String domainDescription; 
    @XmlElementWrapper(name = "domain-requirements") 
    private Set<Requirement> domainRequirements = new HashSet<>(); 
    @XmlElementWrapper(name = "domain-comments") 
    private Set<Comment> domainComments = new HashSet<>(); 

要求CLA SS:

@XmlRootElement(name = "requirement") 
@XmlAccessorType(XmlAccessType.FIELD) 
@Entity 
public class Requirement implements Comparable<Requirement>, Serializable { 

    private static final long serialVersionUID = 1L; 
    @XmlTransient 
    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    private Long id; 
    private String requirementName; 
    private String requirementDescription; 
    private String requirementGuidance; 
    @XmlElementWrapper(name = "sub-requirements") 
    private Set<Requirement> requirementSubrequirementList = new HashSet<>(); 
    @XmlElementWrapper(name = "testing-procedures") 
    private Set<TestingProcedure> requirementTestingProceduresList = new HashSet<>(); 
    @XmlElementWrapper(name = "requirement-comments") 
    private Set<Comment> comments = new HashSet<>(); 

编组和解组代码:

public static String exportFramework(Framework f) { 
    java.io.StringWriter s = new java.io.StringWriter(); 
    try { 
     JAXBContext jc = JAXBContext.newInstance(Framework.class); 

     Marshaller marshaller = jc.createMarshaller(); 
     marshaller.setProperty(Marshaller.JAXB_ENCODING, "utf-8"); 
     marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); 

     marshaller.marshal(f, s); 
    } catch (Exception ex) { 
     ex.printStackTrace(); 
    } 

    return s.toString(); 
} 

public static Framework importFramework(java.io.InputStream xml) { 
    intelicompliance.model.Framework f = null; 

    try { 
     JAXBContext jc = JAXBContext.newInstance(Framework.class); 

     Unmarshaller unmarshaller = jc.createUnmarshaller(); 
     f = (intelicompliance.model.Framework) unmarshaller.unmarshal(xml); 
    } catch (JAXBException ex) { 
     ex.printStackTrace(); 
    } 

    return f; 
} 

当我名帅我已经创建了一个对象,它会生成以下XML:

<?xml version="1.0" encoding="utf-8" standalone="yes"?> 
<framework> 
    <frameworkName>PCI DSS</frameworkName> 
    <frameworkVersion>3.3</frameworkVersion> 
    <frameworkDescription>The Payment Card Industry Data Security Standard (PCI DSS) is a proprietary information security standard for organizations that handle branded credit cards from the major card schemes including Visa, MasterCard, American Express, Discover, and JCB.</frameworkDescription> 
    <framework-domains> 
     <frameworkDomainList> 
      <domainName>Domain 1a</domainName> 
      <domainDescription>Build and Maintain a Secure Network and Systems</domainDescription> 
      <domain-requirements></domain-requirements> 
      <domain-comments></domain-comments> 
     </frameworkDomainList> 
     <frameworkDomainList> 
      <domainName>Domain 2a</domainName> 
      <domainDescription>Protect Cardholder Data</domainDescription> 
      <domain-requirements/> 
      <domain-comments/> 
     </frameworkDomainList> 
     <frameworkDomainList> 
      <domainName>Domain 3a</domainName> 
      <domainDescription>Maintain a Vulnerability Management Program</domainDescription> 
      <domain-requirements/> 
      <domain-comments/> 
     </frameworkDomainList> 
     <frameworkDomainList> 
      <domainName>Domain 4a</domainName> 
      <domainDescription>Implement Strong Access Control Measures</domainDescription> 
      <domain-requirements/> 
      <domain-comments/> 
     </frameworkDomainList> 
     <frameworkDomainList> 
      <domainName>Domain 5a</domainName> 
      <domainDescription>Regularly Monitor and Test Networks</domainDescription> 
      <domain-requirements/> 
      <domain-comments/> 
     </frameworkDomainList> 
     <frameworkDomainList> 
      <domainName>Domain 6a</domainName> 
      <domainDescription>Maintain an Information Security Policy</domainDescription> 
      <domain-requirements/> 
      <domain-comments/> 
     </frameworkDomainList> 
    </framework-domains> 
    <framework-comments/> 
</framework> 

...这正是我期待。

但是,当我尝试将XML转换回对象时,只有一个域被包含在Set中 - 即导入(unmarshalling)过程在第一个节点后忽略XML节点。

有没有人有一个想法,为什么?或者,我做错了什么?

UPDATE 我已经改变了一些进展:

private Set<FrameworkDomain> frameworkDomainList = new HashSet<>(); 

到:

private List<FrameworkDomain> frameworkDomainList = new LinkedList<>(); 

现在进口的所有子元素预期。不过,我真的更喜欢使用Set。

JAXB是否将Set(s)与List(s)不同?

+0

您是否正确设置了对象中的hashCode()方法? –

+0

不知道你的意思是“正确”...这里是代码: @Override public int hashCode(){ int hash = 0; hash + =(id!= null?id.hashCode():0); 返回散列; } – JohnMarkh

回答

0

根据您的回答我的问题:

我的意思是什么,通过适当的是,你保证每一个对象,它是不一样的将返回不同的散列。

你的问题来自于你解组的每个对象都具有相同的hashCode,因此你的组认为每个元素都是等号,并且只保留一个(最后一个JAXB进程,顺便说一下)。

您应该可以通过将HashSet添加到没有ID的对象中来确认此行为,只应保留最后一个对象。

它也解释了为什么当您切换到链接列表时填充您的列表。

可以使用不同的hashCode方法或编组id来解决您的问题。请记住,您应始终重写equals()方法以及hashCode()方法,并确保a.equals(b)和a.hashCode == b.hashCode始终产生相同的结果。

+0

你,我的朋友,是一位学者和先生们!你已经指出了问题和建议的解决方案! – JohnMarkh