2017-09-13 58 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