2014년 1월 14일 화요일

[java] spring3 + tiles3 설정 하기

A free open-sourced templating framework for modern Java applications.
    Based upon the Composite pattern it is built to simplify the development of user interfaces.

For complex web sites it remains
         the easiest and most elegant way to work alongside any MVC technology.
위의 내용은 Tiles 공식 홈페이지 메인에 나오는 문구 입니다.
대충 번역을 하면 아래와 같습니다. 
tiles 는 java 어플리케이션에서 사용하는 무료 오픈 소스 templating 프레임 워크 이다. 
Composite pattern 에 기초를 두었고 개발자가 사용자 인터페이스 만드는것을 간단하게 해준다. 
복잡한 웹 사이트를 위해서 tiles는 어떤 MVC 기술과 함께 작업하기에 가장 쉽고 상당히 세련된 방법 으로 남을것이다. 

이 내용이 Tiles 의 목적과 추구하는 방향에 대해서 간명하게 설명을 해주고 있습니다. 
Tiles 는 복잡한 웹사이트 개발을 쉽게 하기 위해서 개발된  무료 오픈 소스 templating  프레임 워크 입니다. 
공통된 요소 들을 부분 적으로 모듈화 해서 페이지를 runtime 시에 조립 가능하게 만들어 소스 코드의 중복을 줄이고 재새용 가능한 templates으로 만들수 있게 해줍니다. 

설정하는 방법은 아래의 순서대로 진행하면 됩니다. 

1. maven에서 라이브러리 설정하기(추가) 
    pom.xml 에 다음을 추가 한다. 


    <properties>
        <org.apache.tiles.version>3.0.3</org.apache.tiles.version>
    </properties>

    <dependency>
        <groupId>org.apache.tiles</groupId>
        <artifactId>tiles-jsp</artifactId>
        <version>${org.apache.tiles.version}</version>
    </dependency>
    <dependency>
        <groupId>org.apache.tiles</groupId>
        <artifactId>tiles-core</artifactId>
        <version>${org.apache.tiles.version}</version>
    </dependency>



2.스프링의  context-servlet.xml 에 설정하기
Tiles의 설정 파일과 viewResolver를 설정 합니다. 

    <beans:bean id="tilesViewResolver" class="org.springframework.web.servlet.view.UrlBasedViewResolver">
        <beans:property name="viewClass" value="org.springframework.web.servlet.view.tiles3.TilesView" />
        <beans:property name="order" value="1"/>
    </beans:bean>

    <beans:bean id="tilesConfigurer" class="org.springframework.web.servlet.view.tiles3.TilesConfigurer">
        <beans:property name="definitions">
            <beans:list>
                 <beans:value>/WEB-INF/tiles/tiles-layout.xml</beans:value>
            </beans:list>
        </beans:property>
    </beans:bean>


 3. 기본 템플릿 페이지를 만듭니다. 
(default_template.jsp 이란 이름으로 파일을 생성했습니다.)


<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<tiles:insertAttribute name="header" />
</head>
<body>
<tiles:insertAttribute name="menu" />
<tiles:insertAttribute name="body" />
<tiles:insertAttribute name="footer" />
</body>
</html>


4. Tiles 설정 파일을 생성
위(2)에 Spring 에 설정된대로 WEB-INF/tiles/tiles-layout.xml 파일을 생성하고 설정을 합니다. 
각각의 jsp페이지는 해달 부분의 구현을 하면 됩니다. 
name에 * 표시한 부분은 {1} {2} 등으로 맵핑이 가능합니다.  

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE tiles-definitions PUBLIC
        "-//Apache Software Foundation//DTD Tiles Configuration 2.0//EN"
        "http://tiles.apache.org/dtds/tiles-config_2_0.dtd">
<tiles-definitions>

<!-- default : 템플릿에 설정된 페이지의 구성 요소에 대한 실제 파일을 지정합니다.  -->
<definition name="default" template="/WEB-INF/views/layouts/default_template.jsp">
<put-attribute name="header" value="/WEB-INF/views/layouts/default/header.jsp" />
<put-attribute name="menu" value="/WEB-INF/views/layouts/default/menu.jsp" />
<put-attribute name="body" value="/WEB-INF/views/layouts/default/body.jsp" />
<put-attribute name="footer" value="/WEB-INF/views/layouts/default/footer.jsp" />
</definition>

<!--  default를 확장하여 test 라는 URL로 시작되는 호출이 오는 경우 아래 설정에 의해서 페이지를 만들게 됩니다. -->
<definition name="test/*" extends="default">
<put-attribute name="body" value="/WEB-INF/views/test/{1}.jsp" />
</definition>
</tiles-definitions>


이렇게 설정후에 ~/test/~ 인 URL을 만들어서 호출하면 body 부분만 바뀌고  default   템플릿으로 구성된 페이지를 보게 됩니다. 

[참고 자료]

Tiles 공식 사이트에 가면 더 많은 정보를 얻을수 있습니다.
    http://tiles.apache.org


2014년 1월 13일 월요일

[java] jstl 과 scriptlet 간에 값 공유하기

jsp 에서 jstl과 스크립트릿간에 값을 전달해야 하는 경우가 생길수 있습니다. 

이런때 다음과 같이 pageContext를 사용해서 값을 전달하는게 가능합니다. 


1. jstl  -> scriptlet


<c:set var="str" value="hello scriptlet" />
<% 
    String str = (String)pageContext.getAttribute( "str" );
%>

2. scriptlet -> jstl
<%    
    String str = "hello jstl";
%>
<c:set var="strTxt2" value="${pageScope.str}" /> 


** 생각해 보니 jstl 사용시 되도록 scriptlet을 사용 하지 않는게 좋은것 같다.

2014년 1월 9일 목요일

[JSP] 접속된 클라이언트의 아이피 확인하는 방법

접속하는 클라이언트의 아이피를 확인 하려면 HttpServletRequest 객체에서 가져와서 확인하면 된다. 

request.getRemoteAddr() ;


그러나 프록시나 Load Balancer 같은것을 겨쳐 오게 되는 경우 위의 방법으로는 정확한 아이피를 가져 오지 못하게 된다. 


그래서 다음과 같이 메소드를 구현해서 사용 하는 것이 편리하다. 



public String getClientIP(HttpServletRequest request) {

    String ip = request.getHeader("X-FORWARDED-FOR"); 
   
    if (ip == null || ip.length() == 0) {
        ip = request.getHeader("Proxy-Client-IP");
    }

    if (ip == null || ip.length() == 0) {
        ip = request.getHeader("WL-Proxy-Client-IP");  // 웹로직
    }

    if (ip == null || ip.length() == 0) {
        ip = request.getRemoteAddr() ;
    }
   
    return ip;

}



** localhost에서 테스트 하는 경우 0:0:0:0:0:0:0:1 값으로 넘어 오는 경우가 있다.

이 값은 IPv6 에서 IPv4의 127.0.0.1 과 같은 값이다.
Tomcat으로  개발시 이게 문제가 되는 경우 vm arguments에  -Djava.net.preferIPv4Stack=true 값을 넣어 주면 된다.


2014년 1월 8일 수요일

[Tip] 맥에서 mysql 설치후 root 계정 패스워드 설정


Mysql 다운  : http://www.mysql.org

Mysql 설치 및 기동후에 아래의 절차에 따라 root 계정의 패스워드를 설정이 가능하다. 


da-base-069:bin myid$ cd /usr/local/mysql/bin
da-base-069:bin myid$ sudo ./mysql
Password:[엔터]
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 20
Server version: 5.6.15-log MySQL Community Server (GPL)

Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> use mysql
Database changed
mysql> update user set password=password('root') where user='root';
Query OK, 4 rows affected (0.00 sec)
Rows matched: 4  Changed: 4  Warnings: 0

mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)

mysql> quit
Bye
da-base-069:bin myid$ ./mysql -u root -p
Enter password: [패스워드]
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 96
Server version: 5.6.15-log MySQL Community Server (GPL)

Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> exit
Bye





2014년 1월 6일 월요일

[TIP] tar 로 묶을때 tar: Error exit delayed from previous errors 가 발생하는 경우

tar 로 묶을때 다음과 같은 에러가 발생하는 경우가 있다.

tar: Error exit delayed from previous errors

일반 적으로 read 권한이 하위 폴더가 존재 하는 경우 발생을 하는데 만약 그 폴더가 필요없다면  "--ignore-failed-read" 옵션을 통해서 read 에러를 무시하고 묶는게 가능하다.

$ tar cvzf package.tar.gz ./target --ignore-failed-read

[Spring] spring + java web application 다국어 지원 설정

다국어를 사용하기 위해서는 코딩시에 여러가지 사항들을 고려 해야 한다.
spring framework 및 설정을 통해서 다국어를 사용하는 방법에 여러가지가 있다.
상황에 따라서 쿠키를 이용하거나 세션 그리고 브라우져의 언어 설정을 이용하는 방법등 다양한 방법이 있지만 세션을 이용하는게 현재 작업하는 내용과 가장 일치 하기 때문에 이 방법에 대해서 정리 하도록 한다.


[목차]

  1. 인코딩 설정 하기
  2. Spring 설정 
  3. Locale을 설정하는 Controller 클래스 작성
  4. 현재 설정된  Locale을 확인 하는 클래스 작성 
  5. 메시지를 언어 설정에 따라서 가져오는 클래스
  6. Javascript용 파일 생성하기
  7. JAVA에서 사용하는 방법
  8. JSP에서 사용 하는 방법 
  9. javascript  설정및 사용하는 방법

[설명]

1. 인코딩 설정하기 

다국어를 사용하기 위해서는 web.xml 에서 인코딩필터를 UTF-8 로 설정해 주어야 한다. 

  <filter>
    <filter-name>encodingFilter</filter-name>
    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
    <init-param>
      <param-name>encoding</param-name>
      <param-value>UTF-8</param-value>
    </init-param>
  </filter>
  <filter-mapping>
<filter-name>encodingFilter</filter-name>
  <url-pattern>/*</url-pattern>
  </filter-mapping>


2. Spring 설정하기


Spring 의 application-servlet.xml  파일에 MessageSource 를 설정한다.
아래 설정은 ReloadableResourceBundleMessageSource 을 사용하여 설정을 바꾸면 다시 읽도록 처리 하였다.

<!-- 
    MessageSource 를 선언하고 설정한다. 
    메시지는 classpath 에 선언된곳에 놓는다 .
-->
<bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
    <property name="defaultEncoding" value="UTF-8"/>
    <property name="basenames">
<list>
           <value>classpath:/com/test/mydomain/message</value>
        </list>
    </property>
    <property name="fallbackToSystemLocale" value="false"/>
    <property name="cacheSeconds" value="60"/>
</bean>
<bean id="localeResolver" class="org.springframework.web.servlet.i18n.SessionLocaleResolver">
    <property name="defaultLocale" value="ko" />
  </bean>

<!-- java 에서 사용하기 위해 만든 클래스 -->
<bean id="prop" class="com.common.util.Prop" />
  



  •  /com/test/mydomain 이 패키지 위치에  다국어 문장을 포함한 파일을 넣는다.
    message.property - 기본 언어 셋
    message_ko.property - 한국어 언어셋
    message_en.property - 영어 언어셋

  • 파일의 내용은 다음과 같은 형식이다.  ( 영어인 경우 아래 문장들이 영어로 번역되어 들어 가면된다.)

    test.message=안녕하세요.test.hello={0}님 안녕하세요. {1}
    {0}과 {1} 은 치환될 영역이다. 사용자가 해당 문구를 사용시에 치환해서 사용해야 하는 경우 이런식으로 메시지를 작성해서 치환하면 된다.
  • 기본적으로 한국어를 사용하면 굳이 message_ko.property를 만들지 않아도 된다.


3. Locale을 설정하는 Controller 클래스 작성

/**
 * 세션에 있는 로케일을 변환 하는 Controller 클래스
 */


@Controller
public class LocaleController {

    @RequestMapping(value = "/changeLocale")
    public String changeLocale(HttpServletRequest request, HttpServletResponse response, @RequestParam(required = false) String locale) {
        HttpSession session = request.getSession();
        Locale lo = null;
        
        //step. 파라메터에 따라서 로케일 생성, 기본은 KOREAN 
        if (locale.matches("en")) {
                lo = Locale.ENGLISH;
        } else {
                lo = Locale.KOREAN;
        }

        // step. Locale을 새로 설정한다.          session.setAttribute(SessionLocaleResolver.LOCALE_SESSION_ATTRIBUTE_NAME, lo);
        // step. 해당 컨트롤러에게 요청을 보낸 주소로 돌아간다.
        String redirectURL = "redirect:" + request.getHeader("referer");
        return redirectURL;
    }


}


4. 현재 설정된  Locale을 확인 하는 클래스 작성


public class LocaleUtil {

    /**
    * 기본 로케일을 리턴한다. 기본은 한글이다. 
    */
    public static Locale getDefaultLocale() {
        return Locale.KOREAN;
    }

    /**
    *  HttpServletRequest 를 받아서 저장되어 있를 locale 값을 리턴한다. 없는 경우는 기본 로케일을 리턴한다. 
    */

    public static Locale getLocale(HttpServletRequest request) {
        Locale locale = null;
        HttpSession session = request.getSession(); 
        locale = (Locale)session.getAttribute(SessionLocaleResolver.LOCALE_SESSION_ATTRIBUTE_NAME);

        if (locale == null ) {
            locale = getDefaultLocale();
        }
        return locale;
    }


}

5. 메시지를 언어 설정에 따라서 가져오는 클래스

public class Prop implements MessageSourceAware {
    
    private static MessageSource msg;

    public void setMessageSource (MessageSource msg) {
        Prop.msg = msg;
    }
    
    /**
     * 시스템 속성을 얻기위한 함수
     * 호출 내용은 기존 메시지와 동일하나 기능적으로 구분하기 위해서 추가한 메소드 이다. 
     */
    public static String prop(String key) {
    return Prop.msg(key);
    }
    
    public static String prop(String key, Locale locale) {
    return Prop.msg(key, locale);
    }
    
    public static String propFormat(String key, Object...objects) {
         return MessageFormat.format(Prop.msg(key),objects);
    }
    
    public static String propFormat(String key, Locale locale, Object...objects) {
        return MessageFormat.format(Prop.msg(key, locale),objects);
    }
    
   /**
    * 메지시를 리턴한다.
    */
    public static String msg(String key){
        return msg.getMessage(key, null, Locale.getDefault());
    }
    
    public static String msg(String key, Locale locale){
        return msg.getMessage(key, null, locale);
    }
}


6. javascript용 파일 생성하기
message.i18n.js  는 사용하기 편리 하도록 만든 파일이다. 파일 내용은 아래와 같다.

function loadBundles(lang) {
        jQuery.i18n.properties({
            name:'message'
            path:'/js/message/prop/'
            mode:'both',
            language:lang, 
            callback: function() {
        }
    });
}

i18nProp = jQuery.i18n.prop;


7. JAVA에서 사용하는 방법

자바에서 controller 에서 HttpRequest 객체를 넣어서 현재 locale 를 얻어 온 다음에 Prop 클래스를 통해서 메시지를 가져 온다.


Locale locale = LocaleUtil.getLocale(request);


String message= Prop.propFormat("message.java", locale,  "[Message]","java");


8. JSP에서 사용 하는 방법
spring tag 를 통해서 값을 가져온다.



<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %>

<spring:message code="message.jsp" arguments=" 메시지, JSP"/>


9. javascript  설정및 사용하는 방법
javascrpit 는 설정 파일을 별도로 만들었다. 이 경우 javascript에서 파일(message.i18n.js)을 지정해서 하나만 사용하는 편이 편하다.



<script type="text/javascript" language="JavaScript"  src="/js/lib/jquery.i18n.properties-min-1.0.9.js"></script>
<script type="text/javascript" language="JavaScript"  src="/js/message/message.i18n.js"></script>

<script type="text/javascript">
<!--
jQuery(document).ready(function() {
loadBundles('<%=(LocaleUtil.getLocale(request)).toString()%>');
});
//-->


</script>