아키텍처와 함께

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

'분류 전체보기'에 해당되는 글 56건

  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.08.03
    Apache와 Tomcat AJP를 이용한 설정
  5. 2018.07.26
    Java Convert Map to 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

Apache와 Tomcat의 AJP Protocol을 사용하는 경우 설정하는 방법이 다양하다.


설정 시 단순하고, 역할별 설정할 수 있도록 구성하는 것이 향후 효율적으로 유지보수가 가능하다.


먼저 httpd-conf 파일을 수정한다.


■ httpd.conf


[conf/httpd.conf]


Include conf/extra/httpd-jk.conf


 


httpd.conf 파일에 MOD JK를 위한 설정 파일 위치를 포함한다.


■httpd-jk.conf


[conf/extra/httpd-jk.conf]


<IfModule mod_jk.c>

    JkWorkersFile conf/extra/workers.properties

    JkLogFile "/logs001/apache-2.4/jk.log"

    JkLogLevel error

    JkLogStampFormat "[%a %b %d %H:%M:%S %Y]"

    JkOptions +ForwardKeySize +ForwardURICompat -ForwardDirectories

    JkMountFile conf/extra/uriworkermap/uriworkermap.properties

</IfModule>


<Location /jk-status/>

    JkMount jkstatus

    Require ip 127.0.0.1

</Location>

 


httpd-jk.conf 파일에는 Works File 위치와 JK Mount File 위치를 설정한다.


■ workers.properties


worker.list=jkstatus,lb_dev



worker.template.type=ajp13

worker.template.lbfactor=1

worker.template.socket_timeout=300

worker.template.socket_connect_timeout=5000

worker.template.socket_keepalive=true

worker.template.connect_timeout=30000

worker.template.connection_pool_size=128

worker.template.connection_pool_minsize=32

worker.template.connection_pool_timeout=20




#########################################

## Load Balancer

#########################################

worker.lb_dev.type=lb

worker.lb_dev.balance_workers=dev

worker.lb_dev.sticky_session=true

worker.lb_dev.sticky_session_force=false



#########################################

## Worker

#########################################


worker.dev.reference=worker.template

worker.dev.host=10.255.116.163

worker.dev.port=8009



worker.jkstatus.type=status





먼저 worker list를 설정한다.

worker에 공통으로 사용되는 설정을 template으로 생성한다.


Load Balance를 설정한다. 여러대의 WAS에 Load Balance가 필요한 경우에는 worker.lb_dev.balance_workers에 추가한다.


마지막으로 worker를 설정한다.

worker에는 Was와 연결할 IP와 Port를 설정한다


■ uriworkermap.properties


/jk-status/ = jkstatus

/*.jsp = lb_dev

/*.do = lb_dev

/*.ncd = lb_dev

/oz/*.do = lb_dev

/oz/*.ncd = lb_dev

/oz/rest/* = lb_dev 


static contents는 apache에서 처리하고, 그외의 모든 호출은 WAS에서 처리하기 위해 WAS로 보내는 URI를 매핑한다.





AND

Java 프로젝트를 진행하면서 Map을 Json으로 변경하는 Library는 많이 제공하고 있다.

Map을 XML로 변환이 필요한 경우 다음 Util을 이용하여 변환이 가능하다.


■ XML To Map Convert


import java.util.Map;


import org.json.JSONObject;

import org.json.XML;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;


public class XmlUtil {


public static final Logger LOGGER = LoggerFactory.getLogger(XmlUtil.class);


public static Map<String, Object> xml2Map(String xml) throws Exception {


JSONObject xmlJSONObj = XML.toJSONObject(xml);

Map<String, Object> result = JsonUtil.json2Map(xmlJSONObj.toString());


return result;

}

public static <K, V> String  map2Xml(Map<K, V> map) throws Exception {

String jsonData = JsonUtil.map2Json(map);

String xml = XML.toString(new JSONObject(jsonData));

return xml;

}

public static String json2Xml(String json) throws Exception {

JSONObject jsonData = new JSONObject(json);

String xml = XML.toString(jsonData);

return xml;

}

public static void main(String args[]) throws Exception {

String jsonStr = "{\"name\":\"포도\", \"code\":\"1000\"}";


String xml = json2Xml(jsonStr);

Map<String, Object> map = xml2Map(xml);

String xml1 = map2Xml(map);

System.out.println("XML =" + xml);

System.out.println("map = " + map);

System.out.println("XML1 = " + xml1);

}

}



JsonObject를 이용하여 XML을 Json으로 변환한 후 변환된 Json을 Map으로 변환하여 XML을 Map으로 변환이 가능하다.




'Java' 카테고리의 다른 글

Java에서 Shell호출 방법  (0) 2018.07.05
JVM GC 설정  (0) 2018.06.07
Java Reflection 사용법  (0) 2018.04.12
JSP의 img, script에 jsessionid가 추가되는 경우  (0) 2018.02.22
Html a tag function call  (0) 2018.02.20
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

«   2024/10   »
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 29 30 31

ARCHIVE

LINK