Spring framework에서 Restful을 이용한 web service를 작성 시 어떤 서비스들이 Publishing 되어 있는지 확인이 필요한 경우가 있다.
Spring framework는 RequestMappingHandlerMapping을 통해서 Controller에 Request mapping 정보를 찾을 수 있다.
RequestMappingHandlerMapping을 이용하여 Mehtod Name, media type, parameter 등을 이용하여 XML로 생성하여 브라우저에 출력한다.
■ 소스코드
import java.io.ByteArrayOutputStream; import java.io.OutputStream; import java.lang.reflect.Method; import java.util.HashMap; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.Map; import java.util.Set; import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.xml.stream.XMLStreamWriter; import org.springframework.http.MediaType; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.method.HandlerMethod; import org.springframework.web.servlet.mvc.condition.MediaTypeExpression; import org.springframework.web.servlet.mvc.condition.PatternsRequestCondition; import org.springframework.web.servlet.mvc.method.RequestMappingInfo; import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping; @Controller public class WadlCrt extends BaseController {
@Resource(name = "requestMappingHandler") private RequestMappingHandlerMapping requestMappingHandler;
@RequestMapping(value="wadl", produces = MediaType.APPLICATION_JSON_VALUE) public @ResponseBody Map<String, Object> generateWsdl(HttpServletRequest request, HttpServletResponse response) throws Exception {
Map<String, Object> resultMap = new HashMap<String, Object>(); Map<RequestMappingInfo, HandlerMethod> mappings = requestMappingHandler.getHandlerMethods(); Set<RequestMappingInfo> keys = mappings.keySet(); Iterator<RequestMappingInfo> iterator = keys.iterator(); ByteArrayOutputStream bos = new ByteArrayOutputStream(); XMLStreamWriter writer = XmlUtil.getWriter(bos); XmlUtil.startDocument(writer, "UTF-8", "1.0"); String namespace = PropertiesUtil.getString("wadl.namespace"); // XmlUtil.startElement(writer, "application", PropertiesUtil.getString("wadl.namespace")); XmlUtil.startElement(writer, "application"); XmlUtil.addNamespace(writer, "xmlns", "http://wadl.dev.java.net/2009/02"); XmlUtil.addNamespace(writer, "xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance"); XmlUtil.addNamespace(writer, "xmlns:xsd", "http://www.w3.org/2001/XMLSchema"); XmlUtil.addNamespace(writer, "xmlns:apigee", "http://api.apigee.com/wadl/2010/07/"); XmlUtil.addNamespace(writer, "xsi:schemaLocation", "http://wadl.dev.java.net/2009/02 http://apigee.com/schemas/wadl-schema.xsd http://api.apigee.com/wadl/2010/07/ http://apigee.com/schemas/apigee-wadl-extensions.xsd");
XmlUtil.startElement(writer, "resources"); XmlUtil.writeAttribute(writer,"base", "http://localhost:8080");
while(iterator.hasNext()) {
RequestMappingInfo key = iterator.next(); HandlerMethod value = mappings.get(key); XmlUtil.startElement(writer, "resource"); PatternsRequestCondition condition = key.getPatternsCondition(); Set<String> patterns = condition.getPatterns(); if (patterns != null) { for (String pattern : patterns) { XmlUtil.writeAttribute(writer, "path", pattern); } }
Map<String, Object> list = new LinkedHashMap<String, Object>();
/** Get parameter type **/ Method method = value.getMethod(); XmlUtil.writeAttribute(writer, "id", method.getName()); /** Get request method **/ Iterator<RequestMethod> itr = key.getMethodsCondition().getMethods().iterator(); while(itr.hasNext()) { RequestMethod mkey = itr.next(); XmlUtil.writeAttribute(writer, "name", mkey.toString()); list.put("method", mkey.toString()); }
Class<?>[] paramTypes = method.getParameterTypes(); int idx = 0; if (paramTypes.length > 0) { XmlUtil.startElement(writer, "request"); for (Class<?> paramType : paramTypes) { XmlUtil.startElement(writer, "param"); String paramClass = paramType.getName(); list.put("input" + idx, paramClass); XmlUtil.writeAttribute(writer, "type", paramClass); XmlUtil.endElement(writer); } XmlUtil.endElement(writer); }
/** Get return type **/ String returnType = method.getReturnType().getName(); if (returnType != null) { XmlUtil.startElement(writer, "response"); list.put("output", returnType); XmlUtil.startElement(writer, "param"); XmlUtil.writeAttribute(writer, "type", returnType); /** Get media type **/ Iterator<MediaTypeExpression> itr1 = key.getProducesCondition().getExpressions().iterator(); String mediaType = null; while(itr1.hasNext()) { MediaTypeExpression exp = itr1.next(); mediaType = exp.getMediaType().toString(); list.put("mediaType", mediaType); XmlUtil.writeAttribute(writer, "mediaType", mediaType); } /** param **/ XmlUtil.endElement(writer); /** response **/ XmlUtil.endElement(writer); }
/** Resource **/ XmlUtil.endElement(writer); } /** resources **/ XmlUtil.endElement(writer); /** application **/ XmlUtil.endElement(writer);
XmlUtil.endDocument(writer); LOGGER.debug("Created xml :: {}", bos.toString());
String xml = XmlUtil.prettyPrint(bos.toString()); OutputStream os = response.getOutputStream(); os.write(xml.getBytes()); LOGGER.info(xml); return resultMap; } |
XML을 생성하기 위해 XMLStreamWriter를 이용하여 XML을 생성한다.
■ XML 생성 모듈
import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.StringReader; import java.io.StringWriter; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import javax.xml.stream.XMLOutputFactory; import javax.xml.stream.XMLStreamException; import javax.xml.stream.XMLStreamWriter; import javax.xml.transform.OutputKeys; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerException; import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; import org.w3c.dom.Document; import org.xml.sax.InputSource; import org.xml.sax.SAXException; public class XmlUtil { public static XMLStreamWriter getWriter(ByteArrayOutputStream bos) throws XMLStreamException {
XMLStreamWriter writer = XMLOutputFactory.newInstance().createXMLStreamWriter(bos);
return writer; }
public static void startDocument(XMLStreamWriter writer) throws XMLStreamException { writer.writeStartDocument(); }
public static void startDocument(XMLStreamWriter writer, String encoding, String version) throws XMLStreamException { writer.writeStartDocument(); }
public static void endDocument(XMLStreamWriter writer) throws XMLStreamException { writer.writeEndDocument(); }
public static void addNamespace(XMLStreamWriter writer, String namespace, String value) throws XMLStreamException { writer.writeNamespace(namespace, value); }
public static void startElement(XMLStreamWriter writer, String element) throws XMLStreamException { writer.writeStartElement(element); } public static void startElement(XMLStreamWriter writer, String element, String value) throws XMLStreamException { writer.writeStartElement(element, value); }
public static void endElement(XMLStreamWriter writer) throws XMLStreamException { writer.writeEndElement(); }
public static void writeAttribute(XMLStreamWriter writer, String name, String value) throws XMLStreamException { writer.writeAttribute(name, value); }
public static String prettyPrint(String xml) throws ParserConfigurationException, SAXException, TransformerException, IOException {
StringBuilder sb = new StringBuilder(); sb.append("<?xml version=\"1.0\" ?>"); if (xml == null) { return sb.toString(); }
Document document = toXmlDocument(xml);
TransformerFactory transformerFactory = TransformerFactory.newInstance(); Transformer transformer = transformerFactory.newTransformer(); transformer.setOutputProperty(OutputKeys.INDENT, "yes"); transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2"); transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
DOMSource source = new DOMSource(document); StringWriter strWriter = new StringWriter(); StreamResult result = new StreamResult(strWriter); transformer.transform(source, result); sb.append("\n"); sb.append(strWriter.getBuffer().toString()); return sb.toString(); } public static Document toXmlDocument(String str) throws ParserConfigurationException, SAXException, IOException { DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance(); DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder(); Document document = docBuilder.parse(new InputSource(new StringReader(str))); return document; } |
■ 출력 결과
<?xml version="1.0" ?> <application xmlns="http://wadl.dev.java.net/2009/02" xmlns:xsi:schemaLocation="http://wadl.dev.java.net/2009/02 http://apigee.com/schemas/wadl-schema.xsd http://api.apigee.com/wadl/2010/07/ http://apigee.com/schemas/apigee-wadl-extensions.xsd" xmlns:xmlns:apigee="http://api.apigee.com/wadl/2010/07/" xmlns:xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <resources base="http://localhost:8080"> <resource id="searchCodeList" path="/deploy/searchCodeList"> <response> <param type="java.util.Map"/> </response> </resource> <resource id="mainPageView" path="/deploy/mainpage.do"> <response> <param type="java.lang.String"/> </response> </resource> <resource id="selectDeployList" path="/deploy/selectDeployList"> <request> <param type="java.util.Map"/> </request> <response> <param type="java.util.Map"/> </response> </resource> <resource id="deploySource" path="/deploy/deployTarget"> <request> <param type="java.util.Map"/> </request> <response> <param type="java.util.Map"/> </response> </resource> <resource id="hudsonJobBuild" path="/deploy/jobBuild"> <request> <param type="java.util.Map"/> </request> <response> <param type="java.util.Map"/> </response> </resource> <resource id="sourceBuild" path="/deploy/uploadFile"> <request> <param type="java.util.Map"/> </request> <response> <param type="java.util.Map"/> </response> </resource> <resource id="showPage" name="GET" path="/system/showPerfPage.do"> <response> <param mediaType="application/json" type="java.lang.String"/> </response> </resource> <resource id="processPerfData" name="POST" path="/system/perf"> <request> <param type="javax.servlet.http.HttpServletRequest"/> <param type="java.util.Map"/> </request> <response> <param mediaType="application/json" type="java.util.Map"/> </response> </resource> <resource id="chartPerf" name="POST" path="/system/chartPerf"> <request> <param type="java.util.Map"/> </request> <response> <param mediaType="application/json" type="java.util.Map"/> </response> </resource> <resource id="searchPerfCpu" name="POST" path="/system/searchPerfCpu"> <request> <param type="java.util.Map"/> </request> <response> <param mediaType="application/json" type="java.util.Map"/> </response> </resource> <resource id="searchPerfMem" name="POST" path="/system/searchPerfMem"> <request> <param type="java.util.Map"/> </request> <response> <param mediaType="application/json" type="java.util.Map"/> </response> </resource> <resource id="generateWsdl" path="/wadl"> <request> <param type="javax.servlet.http.HttpServletRequest"/> <param type="javax.servlet.http.HttpServletResponse"/> </request> <response> <param mediaType="application/json" type="java.util.Map"/> </response> </resource> </resources> </application> |
'Spring Framrwork' 카테고리의 다른 글
[Spring Boot] Schedule Task (0) | 2018.08.13 |
---|---|
Spring Framework + Redis를 이용한 Session Clustering (0) | 2018.07.19 |
Spring framewok Redis session 관리 (0) | 2018.06.08 |
Spring framework Future와 AsyncResult 를 이용한 Async 서비스 호출 (0) | 2018.04.23 |
Mybatis ResultHandler를 이용한 ExcelDownload (3) | 2018.04.19 |