개발새발

JAXBContext를 사용한 XML 데이터 파싱 본문

Programming/[Java]

JAXBContext를 사용한 XML 데이터 파싱

재래김유진 2023. 8. 30. 18:01
728x90
반응형

넘어온 XML데이터를 파싱해서 DB에 INSERT 하는 ERP를 개발하는데 DocumentBuilder를 사용해라는 팁을 듣고 코딩하다가 파싱한 데이터를 하나씩 VO에 넣어주는게 번거로워 VO에 한 번에 넣어주는게 없을까 검색하다가 JAXBContext를 발견했다..!! 

 

JAXB(Java Architecture for XML Binding) 

: Java Object를 XML로 직렬화하고, XML을 Java Object로 역직렬화해주는 자바 Class

 

XML을 읽어서 Java Object로 만드는 언마샬(Unmarshal)과 Java Object를 XML로 변환하는 마샬(Marshal)이 있다.

 

난 XML 파일을 파싱해서 Java Object로 만들어야 했기 때문에 언마샬(Unmarshal)을 사용했다.

 

 


 

| XML 스키마

JAXB Unmarshalling은 이 XML스키마 모양대로 Java Class를 생성하면 Class의 각 필드에

해당하는 XML의 데이터가 바인딩 된다.

그러므로 XML 스키마의 구조를 파악한 후에 Java Class를 생성해야 한다.

 

아래는 학교정보를 가지고 있는 예시데이터이다.

최상위 노드인 <schoolData> 노드 하위에 학교정보가 존재하고

<studentInfo> 노드 하위에 <student> 노드로 묶인 학생정보가 존재하는 구조이다.

<schoolData>
	<schoolCd>01</schoolCd>
	<schoolNm>testSchool</schoolNm>
	<schoolLoc>Busan</schoolLoc>
	<studentInfo>
		<student>
			<studentNo>1</studentNo>
			<studentNm>KIMGILDONG</studentNm>
			<studentAge>10</studentAge>
			<studentSex>F</studentSex>
			<studentBirth>19940719</studentBirth>
		</student>
		<student>
			<studentNo>2</studentNo>
			<studentNm>LEEGILDONG</studentNm>
			<studentAge>13</studentAge>
			<studentSex>M</studentSex>
			<studentBirth>19910311</studentBirth>
		</student>
	</studentInfo>
</schoolData>

 

| Java Class 생성

 

XML 스키마의 최상위 노드인 <schoolData>를 SchoolVO의 @XmlRootElement 어노테이션으로 지정해주고 하위 학교정보 노드를 @XmlElement 어노테이션으로 지정한 필드를 만들어준다.

그러면 @XmlElement 어노테이션 name으로 지정된 명으로 된 XML 노드의 데이터를 가져와 필드에 넣어준다.

 

<studentInfo> 노드는 <schoolData>의 하위 노드이기도 하지만 <student>의 상위 노드이다.

그렇기때문에 최상위노드가 <studentInfo>인 학생정보를 담을 studentInfoVO를 내부클래스로 만들어주고 그 클래스는 

SchoolVO 내에 @XmlElement 어노테이션으로 지정한 VO형식의 필드를 생성한다.

 

studentInfoVO도 schoolVO 구조와 같이 @XmlRootElement와 @XmlElement를 생성해준다.

하지만 SchoolVO와 조금 다른 점은

실질적으로 학생정보를 가지고 있는 노드의 위치가 <studentInfo> 노드의 손자노드들이기 때문에 

studentInfoVO에 @XmlRootElement 추가,

(학생은 여러명)리스트형식의 studentVO 필드에 @XmlElement 추가

그리고 StudentVO에 학생정보를 가지고 있는 손자노드를 담을 필드에 @XmlElement를 추가한다.

@XmlAccessorType(XmlAccessType.NONE)
@XmlRootElement(name = "schoolData")
@Getter
@Setter
public class SchoolVO{

    @XmlElement(name = "studentInfo")
    private studentInfoVO studentInfo;

    /* ================================================ */

    @Getter
    @XmlRootElement(name = "studentInfo")
    public static class studentInfoVO {

        @XmlElement(name = "student")
        private List<studentVO> student;

    }


    /* ====================== 학교정보 ========================== */

    @XmlElement(name = "schoolCd")
    private String schoolCd = "";

    @XmlElement(name = "schoolNm")
    private String schoolNm  = "";

    @XmlElement(name = "schoolLoc")
    private String schoolLoc = "";


    /* ====================== 학생정보 ========================== */
    @Getter
    @Setter
    @XmlAccessorType(XmlAccessType.NONE)
    public static class studentVO {

        @XmlElement(name = "studentNo")
        private String studentNo;

        @XmlElement(name = "studentNm")
        private String studentNm;

        @XmlElement(name = "studentAge")
        private String studentAge = "";

        @XmlElement(name = "studentSex")
        private String studentSex = "";

        @XmlElement(name = "studentBirth")
        private String studentBirth = "";

    }

}

 

| Unmarshalling 실행

import javax.xml.bind.JAXBContext;
import javax.xml.bind.Unmarshaller;

public void schoolData (HttpServletRequest req, String xmlData) throws Exception{
	
    JAXBContext jaxbContext = JAXBContext.newInstance(schoolVO.class); // JAXB Context 생성
	Unmarshaller unmarshaller = jaxbContext.createUnmarshaller(); // Unmarshaller Object 생성
	SchoolVO parseVO = (SchoolVO) unmarshaller.unmarshal(new StringReader(xmlData)); // unmarshall 메소드 호출

	/* =========== SchoolInfo 학교정보 START =========== */
	SchoolVO schoolVO = new SchoolVO();
    BeanUtils.copyProperties(parseVO, schoolVO, StringUtil.getNullPropertyNames(parseVO));

	schoolMapper.insertSchoolInfo(schoolVO)	// 학교정보 insert
    /* =========== SchoolInfo 학교정보 END =========== */


	/* =========== StudentInfo 학생정보 START=========== */
	List<SchoolVO.studentVO> studentListVO = new ArrayList<SchoolVO.studentVO>();

	//JAXBContext로 파싱한 XML 데이터를 VO에 넣어준다.
	for(var i=0; i<parseVO.getStudentInfo().getStudent().size(); i++) {
    	SchoolVO.studentVO studentVO = new SchoolVO.studentVO();
        studentVO = parseVO.getStudentInfo().getStudent().get(i);
        
        //하나씩 가지고온 데이터들을 bulk Insert(mybatis)로 db에 insert 하기 위해 리스트로 담는다.
        studentListVO.add(studentVO);
	}
    
    schoolMapper.insertStudentInfo(studentListVO)	// bulk Insert(mybatis) 구현
    /* =========== StudentInfo 학생정보 END=========== */
    
    
}

 

 

728x90
반응형
Comments