아키텍처와 함께

블로그 이미지
by gregorio
  • Total hit
  • Today hit
  • Yesterday hit

'Spring Framrwork'에 해당되는 글 33건

  1. 2018.08.13
    [Spring Boot] welcome-file-list 적용
  2. 2018.08.13
    [Spring Boot] ReloadableResourceBundleMessageSource를 이용한 다국어 처리
  3. 2018.08.13
    [Spring Boot] Schedule Task
  4. 2018.07.19
    Spring Framework + Redis를 이용한 Session Clustering
  5. 2018.07.17
    Spring framework RequestMapping을 XML 파일로 생성하기

Spring Boot에서 webcome-file-list를 등록하는 방법이다.


먼저 Spring MVC에서는 web.xml 파일에 다음과 같이 등록한다.


■ web.xml


     <welcome-file-list>

        <welcome-file>index.jsp</welcome-file>

    </welcome-file-list>

 

index.jsp 파일을 welcome-file로 등록한다.


Spring Boot에서는 web.xml을 사용하지 않을 경우 index.jsp를 welcome-file로 다음과 같이 등록한다.


■WebConfig.java


 import java.util.ArrayList;

import java.util.List;

import java.util.Locale;


import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.boot.web.servlet.FilterRegistrationBean;

import org.springframework.context.annotation.Bean;

import org.springframework.context.annotation.Configuration;

import org.springframework.context.support.ReloadableResourceBundleMessageSource;

import org.springframework.core.Ordered;

import org.springframework.web.servlet.LocaleResolver;

import org.springframework.web.servlet.config.annotation.InterceptorRegistry;

import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;

import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import org.springframework.web.servlet.i18n.LocaleChangeInterceptor;

import org.springframework.web.servlet.i18n.SessionLocaleResolver;

import org.springframework.web.servlet.view.json.MappingJackson2JsonView;


import dymn.demo.filter.ABCFilter;

import dymn.demo.interceptor.SessionInterceptor;

import dymn.demo.util.PropertiesUtil;


@Configuration

public class WebConfig implements WebMvcConfigurer {


/** 

* Add Index Page

*/

@Override

public void addViewControllers(ViewControllerRegistry registry) {

registry.addViewController("/").setViewName("forward:/index.jsp");

}


}



WebMvcConfigurer addViewControllers를 재정의하여 index.jsp로 forward한다.


즉 http://localhost:8080을 입력하면 http://localhost:8080/index.jsp를 호출하도록 한다.


AND

이번에는 Spring MVC와 Spring Boot의 다국어를 처리하기 위한 방법에 대해 비교한다.


먼저 Spring MVC를 사용하여 다국어 처리하는 경우는 다음과 같이 XML 설정이 필요하다.


■ mvc-context-servlet.xml


     <bean id="localeResolver" class="org.springframework.web.servlet.i18n.SessionLocaleResolver" />

    

    <!-- 쿠키를 이용한 Locale 이용시 

<bean id="localeResolver" class="org.springframework.web.servlet.i18n.CookieLocaleResolver"/> -->


    <bean id="localeChangeInterceptor" class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor">

        <property name="paramName" value="locale" />

    </bean>


다국어를 처리하기 위해 localeResolver와 localeChangeInterceptor를 bean으로 설정한다.

그리고 다국어 메세지를 정의한다.


■context-message.xml


 <?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xmlns:context="http://www.springframework.org/schema/context"

xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd

http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd">


<bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">

<property name="basenames">

<list>

<value>classpath:/message/message</value>

</list>

</property>

<property name="defaultEncoding" value="UTF-8" />

<property name="cacheSeconds" value="60" />

</bean>

    

</beans>


Spring에서 사용하느 메세지를 정의하기 위해 ReloadableResourceBundleMessageSource에 basenames에 메세지 파일이 정의되어 있는 위치를 등록한다.



Spring boot에서는 Annotation을 이용하여 localeResolver와 localeChangeInterceport를 정의한 후 localeChangeInterceptor를 등록해야한다.



■WebConfig.java


import java.util.ArrayList;

import java.util.List;

import java.util.Locale;


import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.boot.web.servlet.FilterRegistrationBean;

import org.springframework.context.annotation.Bean;

import org.springframework.context.annotation.Configuration;

import org.springframework.context.support.ReloadableResourceBundleMessageSource;

import org.springframework.core.Ordered;

import org.springframework.web.servlet.LocaleResolver;

import org.springframework.web.servlet.config.annotation.InterceptorRegistry;

import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;

import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import org.springframework.web.servlet.i18n.LocaleChangeInterceptor;

import org.springframework.web.servlet.i18n.SessionLocaleResolver;

import org.springframework.web.servlet.view.json.MappingJackson2JsonView;


import dymn.demo.filter.ABCFilter;

import dymn.demo.interceptor.SessionInterceptor;

import dymn.demo.util.PropertiesUtil;


@Configuration

// @EnableWebMvc

// public class WebConfig extends WebMvcConfigurerAdapter {

// public class WebConfig extends WebMvcConfigurationSupport {

public class WebConfig implements WebMvcConfigurer {


/** Register intercepter **/

@Override

public void addInterceptors(InterceptorRegistry registry) {

registry.addInterceptor(localeChangeInterceptor());

}


@Bean

public ReloadableResourceBundleMessageSource messageSource() {

ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();

messageSource.setBasename("classpath:message/message");

messageSource.setCacheSeconds(10);

messageSource.setDefaultEncoding("UTF-8");


return messageSource;

}


@Bean(name = "localeResolver")

public LocaleResolver sessionlocaleResolver() {

SessionLocaleResolver localeResolver = new SessionLocaleResolver();

localeResolver.setDefaultLocale(new Locale("en_US"));

return localeResolver;

}


@Bean

public LocaleChangeInterceptor localeChangeInterceptor() {

LocaleChangeInterceptor localeChangeInterceptor = new LocaleChangeInterceptor();

localeChangeInterceptor.setParamName("locale");


return localeChangeInterceptor;

}

}



WebMvcConfigurer를 구현하는 Class를 생성한다.


먼저 ReloadableResourceBundleMessageSource를 이용하여 messageSource Bean을 생성한다.


messageSource bean에 메세지 파일의 위치 등 필요한 정보를 등록하여 messageSource를 생성한다.


SessionLocaleResolver를 이용하여 localeResolver bean을 생성 시 bean이름을 localeResolver를 정의한다.


LocaleChangeInterceptor를 이용하여 localeChangeInterceptor bean을 생성할 때 parameterName을 locale로 정의한다.


파라미터가 locale로 입력되는 경우 localeChangeInterceptoer에 의해 Local이 변경된다.


마지막으로  WebMvcConfigurer에 정의되어 있는 addInterceptors 메소드를 재정의하여 localeChangeInterceptor를 Interceptor로 등록한다.




AND

주기적으로 특정 Schedule Task를 수행하는 방법을 Spring MVC와 Spring Boot를 이용하는 방법에 대해 비교한다.


먼저 Spring MVC를 사용하는 경우 XML 파일을 이용하여 Task를 정의하는 방법이다.


■ schedule-context.xml


<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

        xmlns:p="http://www.springframework.org/schema/p"

        xmlns:context="http://www.springframework.org/schema/context"

        xmlns:task="http://www.springframework.org/schema/task"

        xmlns:mvc="http://www.springframework.org/schema/mvc"

        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd

                http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd

                http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd

                http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-4.0.xsd">


<task:annotation-driven  executor="taskExecutor" scheduler="scheduler"/>

<bean id="taskExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">

    <property name="corePoolSize" value="100"/>

    <property name="maxPoolSize" value="100"/>

    <property name="queueCapacity" value="2000000000"/>

    <property name="keepAliveSeconds" value="120"/>

</bean> 

<task:scheduler id="scheduler" pool-size="10"/>

    <!-- job bean -->

    <bean id="jobScheduler" class="batch.web.service.impl.CronScheduleSvc" />


<!-- Collect JVM Information -->

<bean id="systemScheduler" class="batch.web.service.impl.SystemInfoSvc" />

    <task:scheduled-tasks> <!-- scheduled job list -->

        <!-- task:scheduled ref="jobSchedule" method="executeJobCheck" cron="0/30 * * * * ?"/-->

        <task:scheduled ref="jobScheduler" method="cronJobCheck" cron="#{system['batch.cron.expression']}"/>

        <!-- Collect JVM Information -->

        <task:scheduled ref="systemScheduler" method="saveJvmInfo" cron="#{system['jvm.cron.expression']}"/>

        <!-- add more job here -->

    </task:scheduled-tasks>

</beans>


Spring MVC에서는 먼저 task:annotation-driven을 이용하여 executor를 설정한다.


executor는 ThreadPoolTaskExecutor를 이용하여 Bean을 설젛하고, task:scheduler를 이용하여 pool-size를 설정한다.


이제는 주기적으로 실행할 Task를 bean으로 설정한 후 실행 주기와 함께 실행할 Method를 설정한다..



Spring Boot는 XML을 이용하여 Configuration을 할 수 있으나, Annotation 설정을 통해 Task Schedule을 정의한다.


■ ScheuleConfig.java


import org.springframework.beans.factory.DisposableBean;

import org.springframework.context.annotation.Bean;

import org.springframework.context.annotation.Configuration;

import org.springframework.scheduling.annotation.EnableScheduling;

import org.springframework.scheduling.annotation.SchedulingConfigurer;

import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;

import org.springframework.scheduling.config.ScheduledTaskRegistrar;


@Configuration

@EnableScheduling

public class ScheduleConfig implements SchedulingConfigurer {


private final int POOL_SIZE = 10;


@Override

public void configureTasks(ScheduledTaskRegistrar taskRegister) {

ThreadPoolTaskScheduler taskScheduler = threadPoolTaskScheduler();

taskRegister.setTaskScheduler(taskScheduler);

}

@Bean 

public ThreadPoolTaskScheduler threadPoolTaskScheduler() { 

ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler(); 

taskScheduler.setThreadNamePrefix("schduler-task-pool-");

taskScheduler.initialize();

taskScheduler.setPoolSize(POOL_SIZE);

return taskScheduler; 

}


}

@Configuration과 @EnableScheduling Annotation을 통해 TaskScheduler Bean을 생성한다.



ThreadPoolTaskScheduler 가 Bean으로 등록한 후 주기적으로 수행할 서비스를 생성한다.


■ScheduleSvc.java


import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.scheduling.annotation.Scheduled;

import org.springframework.stereotype.Component;


@Component

public class SchdulerSvc{


private static final Logger LOGGER = LoggerFactory.getLogger(SchdulerSvc.class);


@Autowired

private AsyncTask asyncTask;

@Scheduled(cron = "0/30 * * * * ?")

public void sampleTask() throws Exception {

LOGGER.info("SchdulerSvc is started");

}

@Scheduled(fixedDelay = 2000)

public void scheduleTaskWithFixedDelay() {

asyncTask.scheduleTaskWithFixedDelay();

}


}


@Component Annotation을 이용하여 해당 서비스를 Bean으로 등록한다.

각각의 Method에 @Schedule Annotation을 이용하여 수행할 주기를 정의한다.


XML로 설정할 때와 Annotation으로 Task Schedule를 설정하는 방법을 비교하였으며, 개인적인 생각으로는 XML을 이용하는 방식이 가독성이 좋아 보인다.





AND

Tomcat 서버 다중화 시 Session Clustering을 통해 한 서버의 장애 시에도 지속적인 서비스가 가능하도록 구성한다.


Tomcat의 Session Clustering은 Multicast를 이용하여 서버간에 Session을 동기화 하는데

AWS와 같은 Cloud platform에서는 Muticast가 지원되지 않는다.


이 때 사용할 수 있는 방법이 Redis를 이용하여 Session 동기화가 필요한다.


Spring Framework에서는 Redis를 통해 Session Clustering을 지원하고 있다.


■ Dependency


spring-aop-4.3.1.RELEASE.jar

spring-beans-4.3.1.RELEASE.jar

spring-context-4.1.2.RELEASE.jar

spring-context-support-4.1.2.RELEASE.jar

spring-core-4.3.1.RELEASE.jar

spring-data-commons-1.12.10.RELEASE.jar

spring-data-keyvalue-1.1.10.RELEASE.jar

spring-data-redis-1.7.10.RELEASE.jar

spring-expression-4.3.1.RELEASE.jar

spring-jdbc-4.1.2.RELEASE.jar

spring-modules-validation-0.9.jar

spring-orm-4.1.2.RELEASE.jar

spring-security-config-4.1.2.RELEASE.jar

spring-security-core-4.1.2.RELEASE.jar

spring-security-web-4.1.2.RELEASE.jar

spring-session-1.3.1.RELEASE.jar

spring-session-data-redis-1.3.1.RELEASE.jar

spring-tx-4.1.2.RELEASE.jar

spring-web-4.1.2.RELEASE.jar

spring-webmvc-4.1.2.RELEASE.jar

spring-ws-core-2.4.0.RELEASE.jar

 



먼저 Session Clustering을 이용하기 위해 XML을 이용하여 설정한다.


 ■ context-redis.xml


<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xmlns:context="http://www.springframework.org/schema/context" xmlns:util="http://www.springframework.org/schema/util"

xmlns:cache="http://www.springframework.org/schema/cache"

xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd

http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd

        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd

        http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">


<!-- This should not be removed -->

<context:annotation-config/>

<bean class="org.springframework.session.data.redis.config.annotation.web.http.RedisHttpSessionConfiguration"/>

<bean id="lettuceConnectionFactory" class="org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory" destroy-method="destroy">

<property name="hostName" value="#{project['session.redis.url']}" />

<property name="port" value="#{project['session.redis.port']}" />

</bean>

<!-- Do not remove -->

<util:constant static-field="org.springframework.session.data.redis.config.ConfigureRedisAction.NO_OP"/>

<!-- bean id="jedisConnFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">

<property name="hostName" value="int-bus-mgmt-eh-dev.hez7xm.ng.0001.euw1.cache.amazonaws.com" />

<property name="port" value="6379" />

<property name="usePool" value="true" />

</bean-->

<bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate">

<property name="connectionFactory" ref="lettuceConnectionFactory" />

</bean> 

</beans>

 


<context:annotation-config>를 통해 Context내의 Annotation을 활성화 한다.


RedisHttpSessionConfiguration을 bean으로 설정한다.


LettuceConnectionFactory에 Redis hostname과 port를 정의한다.


AWS에서 제공하는 Redis를 사용할 경우에는 ConfigureREsisAction.NO_OP를 적용해야 오류가 발생하지 않는다.


설정이 완료되었으면 web.xml에 springSessionFilter를 추가해야 한다.


■ web.xml Filter 추가


   <filter>

    <filter-name>springSessionRepositoryFilter</filter-name>

    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>

  </filter>

  <filter-mapping>

    <filter-name>springSessionRepositoryFilter</filter-name>

    <url-pattern>/*</url-pattern>

    <dispatcher>REQUEST</dispatcher>

    <dispatcher>ERROR</dispatcher>

  </filter-mapping>



이상으로 Spring Framework와 Redis의 연동은 완료되었다.


Redis에 Session이 저장되어 있는지 확인하기 위해 Redis Client를 설치하여 확인이 가능하다.


Redis client에 접속하기 위해 redis-cli -h "hostname" -p "port"로 접속이 가능하다.


keys * command를 이용하여 모든 키 정보 출력이 가능하다.

AND

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> 




AND

ARTICLE CATEGORY

분류 전체보기 (56)
Spring Framrwork (33)
Linux (1)
APM (1)
Java (8)
python (0)
ant (1)
chart (1)
OS (1)
tomcat (1)
apache (1)
database (0)

RECENT ARTICLE

RECENT COMMENT

CALENDAR

«   2025/02   »
1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28

ARCHIVE

LINK