diff --git a/src/main/java/nlib/restful/service/DataApiInterface.java b/src/main/java/nlib/restful/service/DataApiInterface.java index 5fc95db0..42d8dff7 100644 --- a/src/main/java/nlib/restful/service/DataApiInterface.java +++ b/src/main/java/nlib/restful/service/DataApiInterface.java @@ -1,242 +1,235 @@ -package nlib.restful.service; - -import java.util.HashMap; -import java.util.Map; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.http.HttpMethod; -import org.springframework.util.LinkedMultiValueMap; -import org.springframework.util.MultiValueMap; - -import com.thoughtworks.xstream.XStream; - -import nlib.cmm.util.MapEntryConverter; -import nlib.util.StringUtil; - -/** - *
- * @Class Name : DataApiInterface.java
- * 
- * @Description : DAO에서 상속할 DataApi의 부모 클래스들을 위한 인터페이스 
- * 
- * 
- * @프로젝트명: 지방문화원 통합자료관리시스템 구축사업 (2021)
- *
- * 
- * - * @ ------------ -------- --------------------------- - * @ 수정일 수정자 수정내용 - * @ ------------ -------- --------------------------- - * @ 2021. 7. 9. KNKIM 최초 생성 - * - * - * @author 이씨플라자 * DIGITALSHIP KNKIM - * @since 2021. 7. 9. - * @version 1.0 - * - */ -public interface DataApiInterface { - - static final Logger log = LoggerFactory.getLogger(DataApiInterface.class); - - /** - * 조회 - * - * @param reqVO - * @return - */ - public DataApiResVO get(DataApiReqVO reqVO); - - /** - * 등록 - * - * @param reqVO - * @return - */ - public DataApiResVO put(DataApiReqVO reqVO); - - /** - * 수정 - * - * @param reqVO - * @return - */ - public DataApiResVO post(DataApiReqVO reqVO); - - /** - * 삭제 - * - * @param reqVO - * @return - */ - public DataApiResVO delete (DataApiReqVO reqVO); - - /** - * 실제 RESTful API 서버로 요청을 전송하고, 응답받은 자료를 응답VO에 담아서 리턴한다. - * - * @param reqVO - * @param method - * @return - */ - public DataApiResVO send(DataApiReqVO reqVO, HttpMethod method); - - - /** - * 요청 VO를 Map 형태로 변환한다. - * - * @param reqVO - * @return - */ - public static MultiValueMap makeParamMap(DataApiReqVO reqVO) { - - MultiValueMap map = new LinkedMultiValueMap<>(); - - // 공통 - map.add("authKey", reqVO.getAuthKey()); - map.add("rows", "" + reqVO.getPageRows()); - map.add("page", "" + reqVO.getPageNo()); - - // 추가 정보 - if(reqVO.hasInfo()) { - HashMap info = reqVO.getInfo(); - for(String key : info.keySet()) { - Object val = info.get(key); - if(val instanceof HashMap) { - HashMap subInfo = (HashMap)val; - for(String subKey : subInfo.keySet()) { - String subVal = subInfo.get(subKey); - map.add(subKey, subVal); - } - } else { - map.add(key, (String)val); - } - } - } - - // 요청 파라메타 확인 - for(String key : map.keySet()) { - log.debug("MultiValueMap > " + key + "=" + map.get(key)); - } - - return map; - } - - - /** - * 요청전 공통 입력 파라메터를 확인한다. - * - * @param reqVO - * @return - * @throws Exception - */ - public static DataApiResVO checkReqCommonParams(DataApiReqVO reqVO) throws Exception { - - 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.getAuthKey())) { - return new DataApiResVO("ERR_NO_AUTHKEY", "데이터 요청에 대한 권한키 정보가 존재하지 않습니다."); - } - - return null; - } - - /** - * 처리결과 정보를 입력받아 DataApiResVO를 생성한다. - * - * @param resultCode - * @param resultMessage - * @return - */ - public static DataApiResVO makeErrorRes(String resultCode, String resultMessage) { - return new DataApiResVO(resultCode, resultMessage); - } - - /** - * 응답받은 XML 문자열을 DataApiResVO (내부 Map객체 포함) 객체로 변환하여 리턴한다. - * - * @param xmlStr - * @return - */ - public static DataApiResVO convertXmlToResVO(String xmlStr) { - - DataApiResVO resVO = new DataApiResVO(); - - XStream magicApi = new XStream(); - magicApi.registerConverter(new MapEntryConverter()); - magicApi.alias("result", Map.class); - - Map map = null; - try { - map = (Map) magicApi.fromXML(xmlStr); - } catch(Exception e) { - e.printStackTrace(); - - resVO.setResultCode("ERR_RES_XML_FORMAT"); - resVO.setResultMessage(String.format("올바르지 않은 XML 형식의 응답입니다. : [%s]", xmlStr)); - - return resVO; - } - - // 처리결과 확인 - String commonKeyList = "|resulttype|code|message|page|totpages|records|".toLowerCase(); - String lowerKey = null; - for( String key : map.keySet()) { - - lowerKey = key.toLowerCase(); - if(commonKeyList.contains("|" + lowerKey + "|")) { - - if(lowerKey.equals("resulttype")) { - String resultType = (String)map.get(key); - if(!StringUtil.isEmpty(resultType) && resultType.toLowerCase().compareTo("success") == 0) { - resVO.setResultCode("S0000"); - } - } - - if(lowerKey.equals("code")) { - String code = (String)map.get(key); - int codeInt = 0; - try { - codeInt = Integer.parseInt(code); - } catch(Exception e) { - log.error("회신 code 정보를 정수로 변환처리 중 오류가 발생하였습니다." + e.toString()); - codeInt = -1; - } - - if(codeInt != 0) { - resVO.setResultCode(String.format("ERR_BIZERR(%s)", code)); - } else { - resVO.setResultCode("S0000"); - } - } - - if(lowerKey.equals("message")) { - resVO.setResultMessage((String)map.get(key)); - } - - if(lowerKey.equals("page")) { - resVO.setPageNo(StringUtil.toNumber((String)map.get(key))); - } - - if(lowerKey.equals("totpages")) { - resVO.setPageTotCount(StringUtil.toNumber((String)map.get(key))); - } - - if(lowerKey.equals("records")) { - resVO.setRecordTotCount(StringUtil.toNumber((String)map.get(key), 0)); - } - } else { - if(resVO.getInfo() == null) resVO.setInfo(new HashMap()); - HashMap info = resVO.getInfo(); - info.put(key, map.get(key)); - } - } - - return resVO; - } -} +package nlib.restful.service; + +import java.util.HashMap; +import java.util.Map; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.http.HttpMethod; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; + +import nlib.util.StringUtil; + +/** + *
+ * @Class Name : DataApiInterface.java
+ * 
+ * @Description : DAO에서 상속할 DataApi의 부모 클래스들을 위한 인터페이스 
+ * 
+ * 
+ * @프로젝트명: 지방문화원 통합자료관리시스템 구축사업 (2021)
+ *
+ * 
+ * + * @ ------------ -------- --------------------------- + * @ 수정일 수정자 수정내용 + * @ ------------ -------- --------------------------- + * @ 2021. 7. 9. KNKIM 최초 생성 + * + * + * @author 이씨플라자 * DIGITALSHIP KNKIM + * @since 2021. 7. 9. + * @version 1.0 + * + */ +public interface DataApiInterface { + + static final Logger log = LoggerFactory.getLogger(DataApiInterface.class); + + /** + * 조회 + * + * @param reqVO + * @return + */ + public DataApiResVO get(DataApiReqVO reqVO); + + /** + * 등록 + * + * @param reqVO + * @return + */ + public DataApiResVO put(DataApiReqVO reqVO); + + /** + * 수정 + * + * @param reqVO + * @return + */ + public DataApiResVO post(DataApiReqVO reqVO); + + /** + * 삭제 + * + * @param reqVO + * @return + */ + public DataApiResVO delete (DataApiReqVO reqVO); + + /** + * 실제 RESTful API 서버로 요청을 전송하고, 응답받은 자료를 응답VO에 담아서 리턴한다. + * + * @param reqVO + * @param method + * @return + */ + public DataApiResVO send(DataApiReqVO reqVO, HttpMethod method); + + + /** + * 요청 VO를 Map 형태로 변환한다. + * + * @param reqVO + * @return + */ + public static MultiValueMap makeParamMap(DataApiReqVO reqVO) { + + MultiValueMap map = new LinkedMultiValueMap<>(); + + // 공통 + map.add("authKey", reqVO.getAuthKey()); + map.add("rows", "" + reqVO.getPageRows()); + map.add("page", "" + reqVO.getPageNo()); + + // 추가 정보 + if(reqVO.hasInfo()) { + HashMap info = reqVO.getInfo(); + for(String key : info.keySet()) { + Object val = info.get(key); + if(val instanceof HashMap) { + HashMap subInfo = (HashMap)val; + for(String subKey : subInfo.keySet()) { + String subVal = subInfo.get(subKey); + map.add(subKey, subVal); + } + } else { + map.add(key, (String)val); + } + } + } + + // 요청 파라메타 확인 + for(String key : map.keySet()) { + log.debug("MultiValueMap > " + key + "=" + map.get(key)); + } + + return map; + } + + + /** + * 요청전 공통 입력 파라메터를 확인한다. + * + * @param reqVO + * @return + * @throws Exception + */ + public static DataApiResVO checkReqCommonParams(DataApiReqVO reqVO) throws Exception { + + 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.getAuthKey())) { + return new DataApiResVO("ERR_NO_AUTHKEY", "데이터 요청에 대한 권한키 정보가 존재하지 않습니다."); + } + + return null; + } + + /** + * 처리결과 정보를 입력받아 DataApiResVO를 생성한다. + * + * @param resultCode + * @param resultMessage + * @return + */ + public static DataApiResVO makeErrorRes(String resultCode, String resultMessage) { + return new DataApiResVO(resultCode, resultMessage); + } + + /** + * 응답받은 XML 문자열을 DataApiResVO (내부 Map객체 포함) 객체로 변환하여 리턴한다. + * + * @param xmlStr + * @return + */ + public static DataApiResVO convertXmlToResVO(String xmlStr) { + + DataApiResVO resVO = new DataApiResVO(); + Map map = null; + + try { + map = XmlConverter.convert(xmlStr); + } catch(Exception e) { + e.printStackTrace(); + + resVO.setResultCode("ERR_RES_XML_FORMAT"); + resVO.setResultMessage(String.format("올바르지 않은 XML 형식의 응답입니다. : [%s]", xmlStr)); + + return resVO; + } + + // 처리결과 확인 + String commonKeyList = "|resulttype|code|message|page|totpages|records|".toLowerCase(); + String lowerKey = null; + for( String key : map.keySet()) { + + lowerKey = key.toLowerCase(); + if(commonKeyList.contains("|" + lowerKey + "|")) { + + if(lowerKey.equals("resulttype")) { + String resultType = (String)map.get(key); + if(!StringUtil.isEmpty(resultType) && resultType.toLowerCase().compareTo("success") == 0) { + resVO.setResultCode("S0000"); + } + } + + if(lowerKey.equals("code")) { + String code = (String)map.get(key); + int codeInt = 0; + try { + codeInt = Integer.parseInt(code); + } catch(Exception e) { + log.error("회신 code 정보를 정수로 변환처리 중 오류가 발생하였습니다." + e.toString()); + codeInt = -1; + } + + if(codeInt != 0) { + resVO.setResultCode(String.format("ERR_BIZERR(%s)", code)); + } else { + resVO.setResultCode("S0000"); + } + } + + if(lowerKey.equals("message")) { + resVO.setResultMessage((String)map.get(key)); + } + + if(lowerKey.equals("page")) { + resVO.setPageNo(StringUtil.toNumber((String)map.get(key))); + } + + if(lowerKey.equals("totpages")) { + resVO.setPageTotCount(StringUtil.toNumber((String)map.get(key))); + } + + if(lowerKey.equals("records")) { + resVO.setRecordTotCount(StringUtil.toNumber((String)map.get(key), 0)); + } + } else { + if(resVO.getInfo() == null) resVO.setInfo(new HashMap()); + HashMap info = resVO.getInfo(); + info.put(key, map.get(key)); + } + } + + return resVO; + } +} diff --git a/src/main/java/nlib/restful/service/XmlConverter.java b/src/main/java/nlib/restful/service/XmlConverter.java index e869fe39..7c306e33 100644 --- a/src/main/java/nlib/restful/service/XmlConverter.java +++ b/src/main/java/nlib/restful/service/XmlConverter.java @@ -1,79 +1,239 @@ -package nlib.restful.service; - -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.InputStream; -import java.util.HashMap; - -import javax.xml.stream.XMLEventReader; -import javax.xml.stream.XMLInputFactory; -import javax.xml.stream.XMLStreamException; -import javax.xml.stream.events.StartElement; -import javax.xml.stream.events.XMLEvent; - -public class XmlConverter { - - @SuppressWarnings("restriction") - public static void main(String argv[]) { - - String inputFile = "C:/iams/workspace/nlib/data/dataxml/uac.service.board.qna.list_GET.xml"; - HashMap resMap = new HashMap(); - - try { - // First create a new XMLInputFactory - XMLInputFactory inputFactory = XMLInputFactory.newInstance(); - // Setup a new eventReader - InputStream in = new FileInputStream(inputFile); - XMLEventReader eventReader = inputFactory.createXMLEventReader(in); - // Read the XML document - - int depth = 0; - StartElement startElement = null; - - while (eventReader.hasNext()) { - XMLEvent event = eventReader.nextEvent(); - System.out.println(" -> " + event); - String elementName = null; - String elementValue = null; - HashMap elementValues = null; - - if (event.isStartElement()) { - - startElement = event.asStartElement(); - - if (startElement.getName().getLocalPart().equals("result")) { - depth++; - - event = eventReader.nextEvent(); - System.out.println(" > " + event); - - // result의 하위 엘리먼트 시작 찾기 - while (!event.isStartElement()) { - event = eventReader.nextEvent(); - System.out.println(" 하위엘리먼트 시작전: " + event); - } - - while (!event.isEndElement()) { - if (event.isCharacters()) { - String content = event.asCharacters().getData(); - System.out.println("content: -" + content + "_"); - } - event = eventReader.nextEvent(); - System.out.println(" >> " + event); - } - - event = eventReader.nextEvent(); - System.out.println(" >>> " + event); - - continue; - } - - } - } - } catch (FileNotFoundException e) { - System.out.println("File not Found: " + inputFile); - } catch (XMLStreamException e) { - e.printStackTrace(); - } - } -} +package nlib.restful.service; + +import java.io.ByteArrayInputStream; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +import javax.xml.stream.XMLEventReader; +import javax.xml.stream.XMLInputFactory; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.events.StartElement; +import javax.xml.stream.events.XMLEvent; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import nlib.sample.web.SampleEncoderController; +import nlib.util.StringUtil; + +public class XmlConverter { + + private static final Logger log = LoggerFactory.getLogger(XmlConverter.class); + + public static HashMap convert(String xmlStr) throws Exception { + + if(xmlStr == null) return null; + + ByteArrayInputStream bIn = new ByteArrayInputStream(xmlStr.getBytes()); + HashMap resMap = new HashMap(); + + try { + XMLInputFactory inputFactory = XMLInputFactory.newInstance(); + XMLEventReader eventReader = inputFactory.createXMLEventReader(bIn); + + resMap = getElementValue("result", eventReader, null); + log.debug("Converting XML to HashMap : Done >> " + resMap); + } catch (XMLStreamException e) { + e.printStackTrace(); + } catch (Exception e) { + e.printStackTrace(); + } + + return resMap; + } + + /** + * @param rootElementName + * @param eventReader + * @param alreadyRootOpened : 부모 요소 찾기 없이 작업 진행할지 여부. false인 경우, rootElementName 요소를 찾아서 이후 값 추출 수행 + * @param startElement + * @return + * @throws Exception + */ + public static HashMap getElementValue( + String rootElementName + , XMLEventReader eventReader + , XMLEvent firstChildElement) throws Exception { + + HashMap retMap = new HashMap(); + + try { + + int depth = (firstChildElement == null ? 0 : 1); + StartElement startElement = null; + + XMLEvent event = firstChildElement; + + String upperElementName = null; + String elementName = null; //(firstChildElement == null ? null : firstChildElement.asStartElement().getName().getLocalPart()); + String content = null; + String elementValue = ""; + HashMap elementValues = null; + 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 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 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 values = new ArrayList(); + values.add(curValObj); + values.add(value); + map.put(key, values); + } else if(curValObj instanceof List) { + ((ArrayList)curValObj).add(value); + } + + return; + } + +/* + public static void main(String argv[]) throws Exception { + + XmlConverter xmlConverter = new XmlConverter(); + String xmlStr = "\r\n" + + "\r\n" + + "\r\n" + + " S\r\n" + + " 성공적으로 조회되었습니다.\r\n" + + " 10\r\n" + + " 1\r\n" + + " 15\r\n" + + " \r\n" + + " 1\r\n" + + " 101\r\n" + + " 공지사항 테스트\r\n" + + " 15\r\n" + + " 2021-07-19\r\n" + + " \r\n" + + " \r\n" + + " 2\r\n" + + " 101\r\n" + + " 공지사항 테스트\r\n" + + " 55\r\n" + + " 2021-07-19\r\n" + + " \r\n" + + " \r\n" + + " 3\r\n" + + " 101\r\n" + + " 공지사항 테스트\r\n" + + " 55\r\n" + + " 2021-07-19\r\n" + + " \r\n" + + " \r\n" + + " 4\r\n" + + " 101\r\n" + + " 공지사항 테스트\r\n" + + " 55\r\n" + + " 2021-07-19\r\n" + + " \r\n" + + " \r\n" + + " 5\r\n" + + " 101\r\n" + + " 공지사항 테스트\r\n" + + " 55\r\n" + + " 2021-07-19\r\n" + + " \r\n" + + " \r\n" + + " 6\r\n" + + " 101\r\n" + + " 공지사항 테스트\r\n" + + " 55\r\n" + + " 2021-07-19\r\n" + + " \r\n" + + " 3333\r\n" + + ""; + + HashMap resMap = xmlConverter.convert(xmlStr); + } + */ +}