최신 게시글(JAVA)
2019.01.13 / 22:17

[BINDING] Excel과 VO객체 바인딩

hanulbit
추천 수 18

델페이랑 통신하면서 multipart로 xml을 넘겨주는데 이 xml을 multipart 형태로 받아

xml building -> parsing -> VO Biding -> batch Insert하는 과정이다.

 

이 과정을 진행하는데 있어서 ~ 아래와 같은 라이브러리와 패키지를 사용했다.

multipartrequesr : con.jar

xml parsing : jdom.2.0.4.jar

VO biding : java reflection

 

HttpServletRequest를 받아서 MultipartRequest file로 받아준다.

 

MultipartRequest file = new MultipartRequest(request, savePath, 1000*1024*1024, "utf-8");

 

여기서 MultipartRequest가 가지는 생성자는 request, 그리고 파일의 저장 위치, 크기, 인코딩이 있다.

여기서 크기는 지정된 크기를 초과하게 되면 exception을 던지게 된다~

 

SAXBuilder sber = new SAXBuilder();

//DOM 파서랑 삭스(어감이 좀 이상;;)파서가 있지만 xml이 커봤자

10메가 안될거라서 SAX를 선택했다.


String xmlFileNm = savePath+"/"+fileName;

//xml파일이 저장된 위치로 가서 받아놓은 파일을 가져온다.


Document doc = sber.build(xmlFileNm);

//Document 형태로 xml을 build하고


Element root = doc.getRootElement();

//Document에서 root Element를 가져온다.


List<Element> info = root.getChildren();

//Root Element 아래에 속한 Node들을 List 형태로 받아온다.

내가 파싱한 xml 문서는 4레벨 짜리다.

xml을 전문적으로 다루는 분들ㅇ디야 뭐 훨씬 많은 양을 핸들링하겠지만 ㅋㅋㅋ

나는 한 drwng가 커봤자 고작 5000건 ?

음.. 얘기를 계속하면

 

저런 형식의 xml 데이터를 아래와 같이 파싱했다.

for(int i=0; i<info.size(); i++){

if(hasChildren(info.get(i))) {

List<Element> drwng = info.get(i).getChildren();

HashMap<String, String> infoMap = new HashMap<String, String>();

for(int j=0; j<drwng.size(); j++){

if(hasChildren(drwng.get(j))) {

List<Element> docInfo = drwng.get(j).getChildren();

for(int l=0; l<docInfo.size(); l++) { //하위 노드들을 반복함
infoMap.put(docInfo.get(l).getName().replace("-", "").toUpperCase(), docInfo.get(l).getText()); }
} else {
infoMap.put(drwng.get(j).getName().replace("-", "").toUpperCase(), drwng.get(j).getText }
}
infoList.add(infoMap);

} else {
object[i] = info.get(i).getText();

}
}

 

이 코드가 복잡해 보이신다면 맞습니다. XD 사실 Jdom 처음써봐요. 아니 써봤을지도 모르겠네요 ㅋㅋ

Node List를 받아서 if(hasChildren(info.get(i))) 를 통해서 자식노드가 있으면 ~ 계속 4Lvl까지 내려가는 형태입니다. 각 단계별로 자식이 없는 Node라면 그냥 해당 Node의 Text 정보(info.get(i).getText();)만 가져오는 형태를 하고 있어용~

 

Lvl2에서 필요한 정보만 Object[0][1]에 담고 Object[2]에는 레벨에 상관없이 3레벨 이하에 있는 모든 text 정보를 Map형태로 add한 List를 담습니다. 그리고 return ~

 

자 이제 ~ Xml을 parsing 했어요

일단 모듈화는 제껴두고 내가 담고 싶은 VO객체에 지정해서 빈에 Mapping 하는 작업을 하겠습니다.

사실 이것도 처음해봐요 XD

 

Class<?> c = Class.forName("com.ese.domain.DrwngAllInfo");

//DrwngAllInfo라는 VO의 객체 정보를 가져옵니다.


Method[] methods = c.getMethods();

//c라는 객체의 모든 메서드 리스트를 가져와요


ArrayList<DrwngAllInfo> drwngList = new ArrayList<DrwngAllInfo>();

try {
for(HashMap<String, String> list : mapList) {
DrwngAllInfo target = (DrwngAllInfo) c.newInstance();

//아까 말씀드린대오 xml의 drwng는 여러개가 있을 수 있어요 즉, VO 객체를 생성해줘야해요.

c 객체를 통해서 객체를 생성합니다.


Iterator iter = list.keySet().iterator();

//아까 xml 정보에서 담았던 map에서 key 정보를 가지고 오죠


while(iter.hasNext()) {

String key = (String) iter.next();

for(int i=0; i<methods.length; i++) {

//Methods 길이만큼 반복


if(methods[i].getName().startsWith("set")) {

//메서드가 "set"으로 시작할때 즉, setter를 찾습니다.

if(methods[i].getName().replace("set", "").toUpperCase().equals(key.replace("_", "").toUppe

rCase())){

//setter중에 set을 제외한 나머지 이름이 map의 key이름과 비교를 합니다.


String colunm = methods[i].getName().replace("set", "").toUpperCase();

//해당 setter 메서드의 set을 제외하고 String 객체에 담아요.


Class<?>[] types = methods[i].getParameterTypes();

//메서드를 실행시키는데 있어서 parameter형이 필요해서 해당 메서드의 type을 가져와요.


Method m = c.getMethod(methods[i].getName(), types[0]);

//실행되어야 할 메서드명과 그 메서드가 가진 paramater 형식을 줍니다.


if(types[0].toString().equals("int"))
m.invoke(target, Integer.parseInt(list.get(key)));
else
m.invoke(target, list.get(key));

//invoke를 통해 target 클래스에 지정된 메서드를 실행시킵니다.


}
}
}
}
drwngList.add(target);
}

} catch(Exception e) {
throw e;
}
return drwngList;
}

 

객체 바인딩까지 끝났어요 ~

ArrayList<DrwngAllInfo> 형태로 Return 됩니다.

이렇게 한 이유는 기존에 사용하던 메서드를 쓰기 위해서 이렇게 작업한거죠(후후.. 사실 새로 짜기 그래서 그냥 ........ ) 많은 데이터를 루프를 돌면서 처리해야 하기 때문에 정확하지 효율성을 따지자면

좋진 않아요 저도 압니다 (__)(--) 그래도 나름 parsing하는 부분이랑 VO Biding하는 부분은 분리해서

구현하니 모.. 모듀 ㄹ 호 .... ㅈㅅ

 

보너스로 node가 자식 node를 가지고 있는지 체크하는 메서드~

public boolean hasChildren(Element el) {
boolean hasChild = false;
List<Element> list = el.getChildren();
if(list.size() > 0) {
hasChild = true;
}
return hasChild;
}