XML변환처리기 개발

This commit is contained in:
KNKIM 2021-07-21 17:57:42 +09:00
parent 6c64f0b3a9
commit 036cb5ddf1
2 changed files with 474 additions and 321 deletions

View File

@ -1,242 +1,235 @@
package nlib.restful.service; package nlib.restful.service;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.http.HttpMethod; import org.springframework.http.HttpMethod;
import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap; import org.springframework.util.MultiValueMap;
import com.thoughtworks.xstream.XStream; import nlib.util.StringUtil;
import nlib.cmm.util.MapEntryConverter; /**
import nlib.util.StringUtil; * <pre>
* @Class Name : DataApiInterface.java
/** *
* <pre> * @Description : DAO에서 상속할 DataApi의 부모 클래스들을 위한 인터페이스
* @Class Name : DataApiInterface.java *
* *
* @Description : DAO에서 상속할 DataApi의 부모 클래스들을 위한 인터페이스 * @프로젝트명: 지방문화원 통합자료관리시스템 구축사업 (2021)
* *
* * </pre>
* @프로젝트명: 지방문화원 통합자료관리시스템 구축사업 (2021) *
* * @ ------------ -------- ---------------------------
* </pre> * @ 수정일 수정자 수정내용
* * @ ------------ -------- ---------------------------
* @ ------------ -------- --------------------------- * @ 2021. 7. 9. KNKIM 최초 생성
* @ 수정일 수정자 수정내용 *
* @ ------------ -------- --------------------------- *
* @ 2021. 7. 9. KNKIM 최초 생성 * @author 이씨플라자 * DIGITALSHIP KNKIM
* * @since 2021. 7. 9.
* * @version 1.0
* @author 이씨플라자 * DIGITALSHIP KNKIM *
* @since 2021. 7. 9. */
* @version 1.0 public interface DataApiInterface {
*
*/ static final Logger log = LoggerFactory.getLogger(DataApiInterface.class);
public interface DataApiInterface {
/**
static final Logger log = LoggerFactory.getLogger(DataApiInterface.class); * 조회
*
/** * @param reqVO
* 조회 * @return
* */
* @param reqVO public DataApiResVO get(DataApiReqVO reqVO);
* @return
*/ /**
public DataApiResVO get(DataApiReqVO reqVO); * 등록
*
/** * @param reqVO
* 등록 * @return
* */
* @param reqVO public DataApiResVO put(DataApiReqVO reqVO);
* @return
*/ /**
public DataApiResVO put(DataApiReqVO reqVO); * 수정
*
/** * @param reqVO
* 수정 * @return
* */
* @param reqVO public DataApiResVO post(DataApiReqVO reqVO);
* @return
*/ /**
public DataApiResVO post(DataApiReqVO reqVO); * 삭제
*
/** * @param reqVO
* 삭제 * @return
* */
* @param reqVO public DataApiResVO delete (DataApiReqVO reqVO);
* @return
*/ /**
public DataApiResVO delete (DataApiReqVO reqVO); * 실제 RESTful API 서버로 요청을 전송하고, 응답받은 자료를 응답VO에 담아서 리턴한다.
*
/** * @param reqVO
* 실제 RESTful API 서버로 요청을 전송하고, 응답받은 자료를 응답VO에 담아서 리턴한다. * @param method
* * @return
* @param reqVO */
* @param method public DataApiResVO send(DataApiReqVO reqVO, HttpMethod method);
* @return
*/
public DataApiResVO send(DataApiReqVO reqVO, HttpMethod method); /**
* 요청 VO를 Map 형태로 변환한다.
*
/** * @param reqVO
* 요청 VO를 Map 형태로 변환한다. * @return
* */
* @param reqVO public static MultiValueMap<String, String> makeParamMap(DataApiReqVO reqVO) {
* @return
*/ MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
public static MultiValueMap<String, String> makeParamMap(DataApiReqVO reqVO) {
// 공통
MultiValueMap<String, String> map = new LinkedMultiValueMap<>(); map.add("authKey", reqVO.getAuthKey());
map.add("rows", "" + reqVO.getPageRows());
// 공통 map.add("page", "" + reqVO.getPageNo());
map.add("authKey", reqVO.getAuthKey());
map.add("rows", "" + reqVO.getPageRows()); // 추가 정보
map.add("page", "" + reqVO.getPageNo()); if(reqVO.hasInfo()) {
HashMap<String, Object> info = reqVO.getInfo();
// 추가 정보 for(String key : info.keySet()) {
if(reqVO.hasInfo()) { Object val = info.get(key);
HashMap<String, Object> info = reqVO.getInfo(); if(val instanceof HashMap) {
for(String key : info.keySet()) { HashMap<String, String> subInfo = (HashMap)val;
Object val = info.get(key); for(String subKey : subInfo.keySet()) {
if(val instanceof HashMap) { String subVal = subInfo.get(subKey);
HashMap<String, String> subInfo = (HashMap)val; map.add(subKey, subVal);
for(String subKey : subInfo.keySet()) { }
String subVal = subInfo.get(subKey); } else {
map.add(subKey, subVal); map.add(key, (String)val);
} }
} else { }
map.add(key, (String)val); }
}
} // 요청 파라메타 확인
} for(String key : map.keySet()) {
log.debug("MultiValueMap > " + key + "=" + map.get(key));
// 요청 파라메타 확인 }
for(String key : map.keySet()) {
log.debug("MultiValueMap > " + key + "=" + map.get(key)); return map;
} }
return map;
} /**
* 요청전 공통 입력 파라메터를 확인한다.
*
/** * @param reqVO
* 요청전 공통 입력 파라메터를 확인한다. * @return
* * @throws Exception
* @param reqVO */
* @return public static DataApiResVO checkReqCommonParams(DataApiReqVO reqVO) throws Exception {
* @throws Exception
*/ if(reqVO == null) {
public static DataApiResVO checkReqCommonParams(DataApiReqVO reqVO) throws Exception { return new DataApiResVO("ERR_NO_REQ", "데이터송수신 요청객체가 존재하지 않습니다.");
}
if(reqVO == null) {
return new DataApiResVO("ERR_NO_REQ", "데이터송수신 요청객체가 존재하지 않습니다."); if(StringUtil.isEmpty(reqVO.getReqUrl())) {
} return new DataApiResVO("ERR_NO_RURL", "데이터 요청 업무ID에 대한 URL/RUI 정보가 존재하지 않습니다.");
}
if(StringUtil.isEmpty(reqVO.getReqUrl())) { if(StringUtil.isEmpty(reqVO.getAuthKey())) {
return new DataApiResVO("ERR_NO_RURL", "데이터 요청 업무ID에 대한 URL/RUI 정보가 존재하지 않습니다."); return new DataApiResVO("ERR_NO_AUTHKEY", "데이터 요청에 대한 권한키 정보가 존재하지 않습니다.");
} }
if(StringUtil.isEmpty(reqVO.getAuthKey())) {
return new DataApiResVO("ERR_NO_AUTHKEY", "데이터 요청에 대한 권한키 정보가 존재하지 않습니다."); return null;
} }
return null; /**
} * 처리결과 정보를 입력받아 DataApiResVO를 생성한다.
*
/** * @param resultCode
* 처리결과 정보를 입력받아 DataApiResVO를 생성한다. * @param resultMessage
* * @return
* @param resultCode */
* @param resultMessage public static DataApiResVO makeErrorRes(String resultCode, String resultMessage) {
* @return return new DataApiResVO(resultCode, resultMessage);
*/ }
public static DataApiResVO makeErrorRes(String resultCode, String resultMessage) {
return new DataApiResVO(resultCode, resultMessage); /**
} * 응답받은 XML 문자열을 DataApiResVO (내부 Map객체 포함) 객체로 변환하여 리턴한다.
*
/** * @param xmlStr
* 응답받은 XML 문자열을 DataApiResVO (내부 Map객체 포함) 객체로 변환하여 리턴한다. * @return
* */
* @param xmlStr public static DataApiResVO convertXmlToResVO(String xmlStr) {
* @return
*/ DataApiResVO resVO = new DataApiResVO();
public static DataApiResVO convertXmlToResVO(String xmlStr) { Map<String, Object> map = null;
DataApiResVO resVO = new DataApiResVO(); try {
map = XmlConverter.convert(xmlStr);
XStream magicApi = new XStream(); } catch(Exception e) {
magicApi.registerConverter(new MapEntryConverter()); e.printStackTrace();
magicApi.alias("result", Map.class);
resVO.setResultCode("ERR_RES_XML_FORMAT");
Map<String, Object> map = null; resVO.setResultMessage(String.format("올바르지 않은 XML 형식의 응답입니다. : [%s]", xmlStr));
try {
map = (Map<String, Object>) magicApi.fromXML(xmlStr); return resVO;
} catch(Exception e) { }
e.printStackTrace();
// 처리결과 확인
resVO.setResultCode("ERR_RES_XML_FORMAT"); String commonKeyList = "|resulttype|code|message|page|totpages|records|".toLowerCase();
resVO.setResultMessage(String.format("올바르지 않은 XML 형식의 응답입니다. : [%s]", xmlStr)); String lowerKey = null;
for( String key : map.keySet()) {
return resVO;
} lowerKey = key.toLowerCase();
if(commonKeyList.contains("|" + lowerKey + "|")) {
// 처리결과 확인
String commonKeyList = "|resulttype|code|message|page|totpages|records|".toLowerCase(); if(lowerKey.equals("resulttype")) {
String lowerKey = null; String resultType = (String)map.get(key);
for( String key : map.keySet()) { if(!StringUtil.isEmpty(resultType) && resultType.toLowerCase().compareTo("success") == 0) {
resVO.setResultCode("S0000");
lowerKey = key.toLowerCase(); }
if(commonKeyList.contains("|" + lowerKey + "|")) { }
if(lowerKey.equals("resulttype")) { if(lowerKey.equals("code")) {
String resultType = (String)map.get(key); String code = (String)map.get(key);
if(!StringUtil.isEmpty(resultType) && resultType.toLowerCase().compareTo("success") == 0) { int codeInt = 0;
resVO.setResultCode("S0000"); try {
} codeInt = Integer.parseInt(code);
} } catch(Exception e) {
log.error("회신 code 정보를 정수로 변환처리 중 오류가 발생하였습니다." + e.toString());
if(lowerKey.equals("code")) { codeInt = -1;
String code = (String)map.get(key); }
int codeInt = 0;
try { if(codeInt != 0) {
codeInt = Integer.parseInt(code); resVO.setResultCode(String.format("ERR_BIZERR(%s)", code));
} catch(Exception e) { } else {
log.error("회신 code 정보를 정수로 변환처리 중 오류가 발생하였습니다." + e.toString()); resVO.setResultCode("S0000");
codeInt = -1; }
} }
if(codeInt != 0) { if(lowerKey.equals("message")) {
resVO.setResultCode(String.format("ERR_BIZERR(%s)", code)); resVO.setResultMessage((String)map.get(key));
} else { }
resVO.setResultCode("S0000");
} if(lowerKey.equals("page")) {
} resVO.setPageNo(StringUtil.toNumber((String)map.get(key)));
}
if(lowerKey.equals("message")) {
resVO.setResultMessage((String)map.get(key)); if(lowerKey.equals("totpages")) {
} resVO.setPageTotCount(StringUtil.toNumber((String)map.get(key)));
}
if(lowerKey.equals("page")) {
resVO.setPageNo(StringUtil.toNumber((String)map.get(key))); if(lowerKey.equals("records")) {
} resVO.setRecordTotCount(StringUtil.toNumber((String)map.get(key), 0));
}
if(lowerKey.equals("totpages")) { } else {
resVO.setPageTotCount(StringUtil.toNumber((String)map.get(key))); if(resVO.getInfo() == null) resVO.setInfo(new HashMap<String,Object>());
} HashMap<String,Object> info = resVO.getInfo();
info.put(key, map.get(key));
if(lowerKey.equals("records")) { }
resVO.setRecordTotCount(StringUtil.toNumber((String)map.get(key), 0)); }
}
} else { return resVO;
if(resVO.getInfo() == null) resVO.setInfo(new HashMap<String,Object>()); }
HashMap<String,Object> info = resVO.getInfo(); }
info.put(key, map.get(key));
}
}
return resVO;
}
}

View File

@ -1,79 +1,239 @@
package nlib.restful.service; package nlib.restful.service;
import java.io.FileInputStream; import java.io.ByteArrayInputStream;
import java.io.FileNotFoundException; import java.io.FileInputStream;
import java.io.InputStream; import java.io.FileNotFoundException;
import java.util.HashMap; import java.io.InputStream;
import java.util.ArrayList;
import javax.xml.stream.XMLEventReader; import java.util.HashMap;
import javax.xml.stream.XMLInputFactory; import java.util.List;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.events.StartElement; import javax.xml.stream.XMLEventReader;
import javax.xml.stream.events.XMLEvent; import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamException;
public class XmlConverter { import javax.xml.stream.events.StartElement;
import javax.xml.stream.events.XMLEvent;
@SuppressWarnings("restriction")
public static void main(String argv[]) { import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
String inputFile = "C:/iams/workspace/nlib/data/dataxml/uac.service.board.qna.list_GET.xml";
HashMap<String, String> resMap = new HashMap<String, String>(); import nlib.sample.web.SampleEncoderController;
import nlib.util.StringUtil;
try {
// First create a new XMLInputFactory public class XmlConverter {
XMLInputFactory inputFactory = XMLInputFactory.newInstance();
// Setup a new eventReader private static final Logger log = LoggerFactory.getLogger(XmlConverter.class);
InputStream in = new FileInputStream(inputFile);
XMLEventReader eventReader = inputFactory.createXMLEventReader(in); public static HashMap<String, Object> convert(String xmlStr) throws Exception {
// Read the XML document
if(xmlStr == null) return null;
int depth = 0;
StartElement startElement = null; ByteArrayInputStream bIn = new ByteArrayInputStream(xmlStr.getBytes());
HashMap<String, Object> resMap = new HashMap<String, Object>();
while (eventReader.hasNext()) {
XMLEvent event = eventReader.nextEvent(); try {
System.out.println(" -> " + event); XMLInputFactory inputFactory = XMLInputFactory.newInstance();
String elementName = null; XMLEventReader eventReader = inputFactory.createXMLEventReader(bIn);
String elementValue = null;
HashMap<String, String> elementValues = null; resMap = getElementValue("result", eventReader, null);
log.debug("Converting XML to HashMap : Done >> " + resMap);
if (event.isStartElement()) { } catch (XMLStreamException e) {
e.printStackTrace();
startElement = event.asStartElement(); } catch (Exception e) {
e.printStackTrace();
if (startElement.getName().getLocalPart().equals("result")) { }
depth++;
return resMap;
event = eventReader.nextEvent(); }
System.out.println(" > " + event);
/**
// result의 하위 엘리먼트 시작 찾기 * @param rootElementName
while (!event.isStartElement()) { * @param eventReader
event = eventReader.nextEvent(); * @param alreadyRootOpened : 부모 요소 찾기 없이 작업 진행할지 여부. false인 경우, rootElementName 요소를 찾아서 이후 추출 수행
System.out.println(" 하위엘리먼트 시작전: " + event); * @param startElement
} * @return
* @throws Exception
while (!event.isEndElement()) { */
if (event.isCharacters()) { public static HashMap<String, Object> getElementValue(
String content = event.asCharacters().getData(); String rootElementName
System.out.println("content: -" + content + "_"); , XMLEventReader eventReader
} , XMLEvent firstChildElement) throws Exception {
event = eventReader.nextEvent();
System.out.println(" >> " + event); HashMap<String, Object> retMap = new HashMap<String, Object>();
}
try {
event = eventReader.nextEvent();
System.out.println(" >>> " + event); int depth = (firstChildElement == null ? 0 : 1);
StartElement startElement = null;
continue;
} XMLEvent event = firstChildElement;
} String upperElementName = null;
} String elementName = null; //(firstChildElement == null ? null : firstChildElement.asStartElement().getName().getLocalPart());
} catch (FileNotFoundException e) { String content = null;
System.out.println("File not Found: " + inputFile); String elementValue = "";
} catch (XMLStreamException e) { HashMap<String, String> elementValues = null;
e.printStackTrace(); boolean hasSubElements = false;
} boolean isFirst = true;
}
} while (eventReader.hasNext()) {
// 이벤트가 함께 매개변수로 넘어온 경우, 처음 읽기 생략
if(!isFirst || event == null) {
event = eventReader.nextEvent();
}
if(isFirst) isFirst = false;
// 1 레벨 엘리먼트 찾기
if (depth == 0 && event.isStartElement() && event.asStartElement().getName().getLocalPart().equals(rootElementName)) {
depth++;
continue;
}
// 1 레벨 엘리먼트내의 2 레벨 엘리먼트 찾기
if(depth == 1 && elementName == null && event.isStartElement()) {
elementName = event.asStartElement().getName().getLocalPart();
elementValue = "";
elementValues = null;
hasSubElements = false;
depth++;
continue;
}
// 2 레벨 엘리먼트 내용 찾기
if(depth == 2 && elementName != null && event.isCharacters()) {
content = event.asCharacters().getData();
if(StringUtil.isNotEmpty(content)) {
elementValue += content;
}
continue;
}
// 2 레벨 엘리먼트 종료
if(depth == 2 && elementName != null && event.isEndElement()) {
if(!elementName.equals(event.asEndElement().getName().getLocalPart())) {
throw new Exception("XML문의 요소 시작/종료 태그가 일치하지 않습니다. : " + elementName + " 요소가 " + event.asEndElement().getName().getLocalPart() + "로 종료되었습니다.");
}
addValue(retMap, elementName, elementValue);
System.out.println(elementName + " : -" + elementValue + "_");
elementName = null;
elementValue = "";
depth--;
}
// 2 레벨 엘리먼트 > 하위 엘리먼트 존재하는 경우
if(depth == 2 && elementName != null && event.isStartElement()) {
HashMap<String, Object> subMap = getElementValue(elementName, eventReader, event);
addValue(retMap, elementName, subMap);
depth--;
elementName = null;
}
// 1 레벨 엘리먼트 종료된 경우, 돌아가기
if(depth == 1 && elementName == null && event.isEndElement() && rootElementName.equals(event.asEndElement().getName().getLocalPart())) {
depth--;
return retMap;
}
} // while
} catch (XMLStreamException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("END");
return retMap;
}
public static void addValue(HashMap<String, Object> map, String key, Object value) throws Exception {
if(map == null) throw new Exception("값을 넣을 Map 변수가 초기화되지 않았습니다.");
if(key == null) return;
if(value == null) return;
Object curValObj = map.get(key);
if(curValObj == null) {
map.put(key, value);
return;
}
if(curValObj instanceof String || curValObj instanceof HashMap) {
List<Object> values = new ArrayList<Object>();
values.add(curValObj);
values.add(value);
map.put(key, values);
} else if(curValObj instanceof List) {
((ArrayList<Object>)curValObj).add(value);
}
return;
}
/*
public static void main(String argv[]) throws Exception {
XmlConverter xmlConverter = new XmlConverter();
String xmlStr = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\r\n" +
"<!-- uac.service.board.qna_GET.xml -->\r\n" +
"<result>\r\n" +
" <code>S</code>\r\n" +
" <message>성공적으로 조회되었습니다.</message>\r\n" +
" <records>10</records>\r\n" +
" <page>1</page>\r\n" +
" <totPages>15</totPages>\r\n" +
" <record>\r\n" +
" <noticeNo>1</noticeNo>\r\n" +
" <noticeType>101</noticeType>\r\n" +
" <title>공지사항 테스트</title>\r\n" +
" <readCount>15</readCount>\r\n" +
" <regDate>2021-07-19</regDate>\r\n" +
" </record>\r\n" +
" <record>\r\n" +
" <noticeNo>2</noticeNo>\r\n" +
" <noticeType>101</noticeType>\r\n" +
" <title>공지사항 테스트</title>\r\n" +
" <readCount>55</readCount>\r\n" +
" <regDate>2021-07-19</regDate>\r\n" +
" </record>\r\n" +
" <record>\r\n" +
" <noticeNo>3</noticeNo>\r\n" +
" <noticeType>101</noticeType>\r\n" +
" <title>공지사항 테스트</title>\r\n" +
" <readCount>55</readCount>\r\n" +
" <regDate>2021-07-19</regDate>\r\n" +
" </record>\r\n" +
" <record>\r\n" +
" <noticeNo>4</noticeNo>\r\n" +
" <noticeType>101</noticeType>\r\n" +
" <title>공지사항 테스트</title>\r\n" +
" <readCount>55</readCount>\r\n" +
" <regDate>2021-07-19</regDate>\r\n" +
" </record>\r\n" +
" <record>\r\n" +
" <noticeNo>5</noticeNo>\r\n" +
" <noticeType>101</noticeType>\r\n" +
" <title>공지사항 테스트</title>\r\n" +
" <readCount>55</readCount>\r\n" +
" <regDate>2021-07-19</regDate>\r\n" +
" </record>\r\n" +
" <record>\r\n" +
" <noticeNo>6</noticeNo>\r\n" +
" <noticeType>101</noticeType>\r\n" +
" <title>공지사항 테스트</title>\r\n" +
" <readCount>55</readCount>\r\n" +
" <regDate>2021-07-19</regDate>\r\n" +
" </record>\r\n" +
" <end>3333</end>\r\n" +
"</result>";
HashMap<String, Object> resMap = xmlConverter.convert(xmlStr);
}
*/
}