'Spring Framrwork'에 해당되는 글 33건
- 2018.08.13
- 2018.08.13
- 2018.08.13
- 2018.07.19
- 2018.07.17
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를 호출하도록 한다.
[Spring Boot] Intercepor 적용 (0) | 2018.08.13 |
---|---|
[Spring Boot] Filter 적용 (0) | 2018.08.13 |
[Spring Boot] ReloadableResourceBundleMessageSource를 이용한 다국어 처리 (0) | 2018.08.13 |
[Spring Boot] Schedule Task (0) | 2018.08.13 |
Spring Framework + Redis를 이용한 Session Clustering (0) | 2018.07.19 |
이번에는 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로 등록한다.
[Spring Boot] Filter 적용 (0) | 2018.08.13 |
---|---|
[Spring Boot] welcome-file-list 적용 (0) | 2018.08.13 |
[Spring Boot] Schedule Task (0) | 2018.08.13 |
Spring Framework + Redis를 이용한 Session Clustering (0) | 2018.07.19 |
Spring framework RequestMapping을 XML 파일로 생성하기 (0) | 2018.07.17 |
주기적으로 특정 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을 이용하는 방식이 가독성이 좋아 보인다.
[Spring Boot] welcome-file-list 적용 (0) | 2018.08.13 |
---|---|
[Spring Boot] ReloadableResourceBundleMessageSource를 이용한 다국어 처리 (0) | 2018.08.13 |
Spring Framework + Redis를 이용한 Session Clustering (0) | 2018.07.19 |
Spring framework RequestMapping을 XML 파일로 생성하기 (0) | 2018.07.17 |
Spring framewok Redis session 관리 (0) | 2018.06.08 |
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를 이용하여 모든 키 정보 출력이 가능하다.
[Spring Boot] ReloadableResourceBundleMessageSource를 이용한 다국어 처리 (0) | 2018.08.13 |
---|---|
[Spring Boot] Schedule Task (0) | 2018.08.13 |
Spring framework RequestMapping을 XML 파일로 생성하기 (0) | 2018.07.17 |
Spring framewok Redis session 관리 (0) | 2018.06.08 |
Spring framework Future와 AsyncResult 를 이용한 Async 서비스 호출 (0) | 2018.04.23 |
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 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 |