2017-09-13 9 views
0
내가 마샬링을 테스트하고 다음과 같은 자바 객체를 비 정렬 화하고

: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<>(); 

(만 게터, 세터 및 추가 주석없이 기능의 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<>(); 

요구 사항 CIA 요원 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<>(); 

마샬링 및 비 정렬 화 코드 :

<?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> 

... 정확히입니다 : 내가 만든 개체 마샬링 할 때

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을 개체로 다시 변환하려고 시도하면 도메인 중 하나만 집합에 포함됩니다. 즉, 가져 오기 (비 정렬 화) 프로세스는 첫 번째 노드 이후에 XML 노드를 무시합니다.

누구나 이유가 있습니까? 아니면 내가 뭘 잘못하고 있니?

UPDATE 나는 변경하여 일부 진전을 만들었습니다 :

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

에 예상대로 이제 모든 어린이 요소를 가져

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

. 그러나 Set을 사용하는 것이 좋습니다.

JAXB는 목록과 다른 세트를 취급합니까?

+0

개체에 hashCode() 메서드를 올바르게 설정 했습니까? –

+0

"적절하게"의미하는 것이 확실하지 않습니다. 코드는 다음과 같습니다. @Override public int hashCode (int hash = 0; 해시 + = (id! = null? id.hashCode() : 0); 리턴 해시; } – JohnMarkh

답변

0

내 질문에 대한 답을 바탕으로 : 내가 제대로 무슨 뜻인지

는 동일하지 않은 모든 객체가 다른 해시를 반환 할 것을 보장한다는 것이다.

당신이 비 정렬 화하는 모든 객체가 동일한 hashCode를 갖는다는 사실 때문에 문제가 발생합니다. 따라서 모든 요소가 동일하다고 생각하고 하나만 유지하십시오 (마지막 하나의 JAXB 프로세스, 우연히 첫 번째 프로세스).

개체를 ID없이 HashSet에 추가하면이 동작을 확인할 수 있습니다. 마지막 개체 만 유지해야합니다.

또한 연결된 목록으로 전환 할 때 목록이 채워지는 이유에 대해서도 설명합니다.

다른 hashCode 메서드를 사용하거나 ID를 마샬링하여 문제를 해결하십시오.

hashCode() 메서드와 함께 항상 equals() 메서드를 재정의하고 a.equals (b) 및 a.hashCode == b.hashCode가 항상 동일한 결과를 반환해야합니다.

+0

당신, 내 친구, 학자 여러분입니다! 문제와 제안 된 해결책을 정확하게 지적했습니다! – JohnMarkh