Spring Framrwork

Spring framework RequestMapping을 XML 파일로 생성하기

gregorio 2018. 7. 17. 15:10

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>