목차는 다음과 같다.
1. 다국어 처리
1) 메세지 파일 생성
2) messageSource클래스 생성
3) LocaleResolver클래스 생성
4) LocaleChangeInterceptor클래스 생성
5) view에서 메세지 파일 불러오기
1. 다국어 처리
: 하나의 페이지를 여러 언어로 서비스 하는 것
1) 메세지 파일 생성
각각의 언어로 메세지 파일을 사전에 만들어두고, 어떤 파일을 불러올 것인지에 따라 표시될 메세지를 어떤 언어로 설정할 것인지 미리 설정할 수 있다.
각각의 언어로 저장된 메세지 파일에 "메세지키=메세지값"을 지정하여 view에서 호출하는 메세지 키를 통해 원하는 파일의 메세지값(번역된 언어)로 표시할 수 있게 된다.
① 파일 생성
메세지 파일은 언어별로 필요하기 때문에 패키지를 별도 생성하여 관리해주는 것이 좋은데, 이때 이 패키지는 src/main/resoutces폴더에 저장되어야한다. 파일 형식은 file이며, 확장자를 properties로 지정하여 메세지 파일임을 명시할 수 있다.
파일명에 대한 의미는 다음과 같다. "파일명_국가.확장자"
② 파일 내용 추가
파일은 언어별로 필요하게 된다. 각 파일에서 동일하게 사용할 메세지 키(후에 view에서 호출 예정)에 메세지 값(언어)을 담는다. 이때 사용되는 메세지 키는 지정된 형식이 아니며, 모든 text에 대한 내용을 메세지 키로 설정하여 값을 지정할 수 있다. 이때 한개의 파일에서 모든 페이지에 대한 언어를 다루는게 일반적이므로, 페이지별로 구분하여 작업을 진행하는 것이 효율적이다.
선정한 페이지에 어떤 text들이 사용되는지를 확인하고, 각 text를 명시할 메세지키를 설정한다. 이후에 각각의 언어로 그에 대한 값을 담는 식으로 작업을 진행할 수 있다.
2) messageSource클래스 생성
스프링 프레임워크에서 지원하는 클래스로, 위에서 작성한 메세지 파일을 읽어오는 역할을 하는 클래스이다. 클래스 사용을 위해 객체화를 진행하고, 어떤 파일을 읽을 것인지를 xml에 설정한다.
이때 프로그램 동작시(서블릿 컨테이너가 동작시) 생성되는 클래스이므로, DispatcherServlet-servlet.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:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.2.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd">
<!-- 기존에 사용되던 어노테이션 관련 설정 -->
<context:component-scan base-package="com.ham.app.controller"/>
<!-- 메세지 파일을 읽어오는 클래스 -->
<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basenames">
<list>
<value>message.a</value>
<!-- 메시지 패키지에 있는, a라는 이름의 파일들을 불러들이겠다. 이때 message.a_ko.properties라고 등록하지 않는다. 패키지와 확장자의 구분이 어려워지므로, 오류 발생 확률이 높아진다. 프로그램 자체에서 확장자는 자동으로 붙여서 알아서 읽는다. ko나 en은 나중에 어떤 국가에서 페이지를 켰는지 읽어들이는 코드에서 자동으로 붙여준다. -->
</list>
</property>
</bean>
</beans>
주석을 통해서도 설명을 하고 있지만, 지금 생성된 클래스가 value태그를 통해 어떤 메세지 파일을 읽을 것인지를 설정할 수 있는데 message패키지에 존재하는 a파일을 읽겠다는 의미가 된다.
(1)정확히 이야기 하면
<value>message.a_ko.properties</value>
<value>message.a_en.properties</value>
이 코드와 같겠지만, messageSource라는 클래스 자체가 본인이 참조해야할 확장자(.properties)에 대한 정보를 이미 알고 있기 때문에 생략해도 무관한데다가 구분점으로 인해 프로그램이 패키지명과 확장자를 혼동하여 오류가 발생할 가능성이 높아지므로 오류를 방지할 목적으로 .properties를 생략하였다.
(2) _다음으로 존재하는 ko나 en의 경우 그저 이 파일에서 담당하는 언어에 대해 명시한 내용일 뿐이며, 다음으로 추가할 클래스(
LocaleResolver:사용자가 사이트를 구동한 지역 정보를 추출해주는 클래스)를 생성하게 되면 자동으로 참조하게 되므로 생략이 가능하다.
3) LocaleResolver클래스 생성
브라우저에서 http요청 헤더에 접속한 지역 정보가 존재한다. 이 정보를 활용하여 접속 지역에 따라 messageSource클래스가 지역에 맞는 다른 파일을 읽어올 수 있도록 설정할 수 있다. 이때, 사용자가 사이트를 구동한 이 지역 정보를 추출해서 messageSource클래스에게 전달해 줄 역할을 해주는 클래스가 바로 이 LocaleResolver이다.
<?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:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.2.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd">
<context:component-scan base-package="com.ham.app.controller"/>
<!-- 메세지 파일을 읽어오는 클래스 -->
<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basenames">
<list>
<value>message.a</value>
<!-- 메시지 패키지에 있는, a라는 이름의 파일들을 불러들이겠다. 이때 message.a_ko.properties라고 등록하지 않는다. 패키지와 확장자의 구분이 어려워지므로, 오류 발생 확률이 높아진다. 프로그램 자체에서 확장자는 자동으로 붙여서 알아서 읽는다. ko나 en은 나중에 어떤 국가에서 페이지를 켰는지 읽어들이는 코드에서 자동으로 붙여준다. -->
</list>
</property>
</bean>
<!-- 헤더에 존재하는 접속지역 정보를 추출해줄 클래스 -->
<bean id="localeResolver" class="org.springframework.web.servlet.i18n.SessionLocaleResolver" />
</beans>
별도의 설정 없이 그저 초기화만 진행해주면 된다.
4) LocaleChangeInterceptor클래스 생성
테스트를 위해 여러 언어 파일을 돌려보고 싶더라도, 현실적으로 한국에서만 프로그램을 동작시킬 예정이기 때문에 다른 파일들에 대한 내용을 확인할 수 없게 된다. 이때 지역정보를 변경해줄 수 있는 LocaleChangeInterceptor클래스를 통해 버튼을 눌러 다른 언어파일의 내용도 확인할 수 있는 페이지를 구현할 수 있게 된다.
우선 코드 작성 전 nameSpace에서 mvc를 설정해주어야한다.
이후 아래와 같은 코드를 작성한다.
<?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:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.2.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd">
<context:component-scan base-package="com.ham.app.controller"/>
<!-- 메세지 파일을 읽어오는 클래스 -->
<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basenames">
<list>
<value>message.a</value>
<!-- 메시지 패키지에 있는, a라는 이름의 파일들을 불러들이겠다. 이때 message.a_ko.properties라고 등록하지 않는다. 패키지와 확장자의 구분이 어려워지므로, 오류 발생 확률이 높아진다. 프로그램 자체에서 확장자는 자동으로 붙여서 알아서 읽는다. ko나 en은 나중에 어떤 국가에서 페이지를 켰는지 읽어들이는 코드에서 자동으로 붙여준다. -->
</list>
</property>
</bean>
<!-- 헤더에 존재하는 접속지역 정보를 추출해줄 클래스 -->
<bean id="localeResolver" class="org.springframework.web.servlet.i18n.SessionLocaleResolver" />
<!-- 위치 정보를 변경해줄 클래스 -->
<mvc:interceptors>
<bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor">
<property name="paramName" value="lang" /><!-- lang이라는 이름으로 된 파라미터를 전달받으면, 접속 지역정보를 전달해주면 바뀌게 해준다는 의미임 -->
</bean>
</mvc:interceptors>
</beans>
해당 코드를 통해 lang이라는 이름으로 된 파라미터를 전달 받게 되면 접속 지역 정보를 변경해줄 수 있게 된다.
5) view에서 메세지 파일 불러오기
① 지시어 설정
메세지 파일에 대한 키와 값을 불러오기 위해서는 최상단에 별도 지시어 설정이 필요하다. 코드는 아래와 같다.
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags"%>
② 알맞은 위치에 메세지키 불러오기
사용하고자 하는 메세지값이 필요한 위치에 메세지 키를 불러오면 된다. 예시 코드는 아래와 같다.
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags"%>
<!DOCTYPE html>
<html
lang="ko"
class="light-style customizer-hide"
dir="ltr"
data-theme="theme-default"
data-assets-path="assets/"
data-template="vertical-menu-template-free"
>
<head>
<meta charset="utf-8" />
<meta
name="viewport"
content="width=device-width, initial-scale=1.0, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0"
/>
<title>Login</title>
<meta name="description" content="" />
</head>
<body>
<!-- Content -->
<!-- /Logo -->
<h4 class="mb-2"><spring:message code="message.login.welcom" /> 👋</h4>
<p class="mb-4"><spring:message code="message.login.infomsg" /></p>
<a href="login.do?lang=ko">한국어</a> | <a href="login.do?lang=en">English</a>
<form id="formAuthentication" class="mb-3" action="login.do" method="POST">
<div class="mb-3">
<label for="email" class="form-label"><spring:message code="message.login.id" /></label>
<input
type="text"
class="form-control"
id="email"
name="uid"
placeholder="<spring:message code="message.login.idinfo"/>"
autofocus
/>
</div>
<div class="mb-3 form-password-toggle">
<div class="d-flex justify-content-between">
<label class="form-label" for="password"><spring:message code="message.login.pw"/></label>
<a href="notyet.jsp">
<small><spring:message code="message.login.pwinfo"/></small>
</a>
</div>
<div class="input-group input-group-merge">
<input
type="password"
id="password"
class="form-control"
name="pw"
placeholder="············"
aria-describedby="password"
/>
<span class="input-group-text cursor-pointer"><i class="bx bx-hide"></i></span>
</div>
</div>
<div class="mb-3">
<button class="btn btn-primary d-grid w-100" type="submit"><spring:message code="message.login.login" /></button>
</div>
</form>
<p class="text-center">
<span><spring:message code="message.login.hoxy" /></span>
<a href="signup.jsp">
<span><spring:message code="message.login.signup" /></span>
</a>
</body>
</html>
위 코드와 마찬가지로 아래 코드 형식을 통해 메세지키를 삽입하면 위치정보가 반영되어 메세지값을 반환받을 수 있게 된다.
<spring:message code="메세지키" />
아래의 코드와 같이 a태그로 lang이라는 이름의 파라미터를 전달하여 원하는 언어에 해당되는 메세지파일 또한 확인할 수 있다.
<a href="login.do?lang=ko">한국어</a> | <a href="login.do?lang=en">English</a>
이때, 메세지 파일과 관련된 클래스들은 session단에 존재하는 클래스들이기 때문에 서블릿 컨테이너 관할하에 존재하여야만 한다.
즉, jsp의 요청으로 즉시 확인되는 페이지라면 반드시 controller를 경유하는 요청으로 변경하여야만 한다는 의미이다.
본인의 경우, login페이지는 메인페이지에서 <a href="login.jsp">를 통해 진입이 가능하므로, 별도의 요청 처리를 추가하여 페이지에 보여줄 데이터가 없음에도 controller를 경유할 수 있도록 구현하였다.
@RequestMapping(value = "/login.do", method = RequestMethod.GET)
public String login_get() {
System.out.println("다국어 처리 적용하여 로그인 페이지로 이동");
return "login.jsp";
}
@RequestMapping(value = "/login.do", method = RequestMethod.POST)
public String login_users (UsersVO vo, HttpSession session) {
int flag=usersService.login_users(vo);
if(flag==1) { //로그인 성공시 정보 session에 저장
vo=usersService.get_users(vo);
session.setAttribute("uid", vo.getUid());
session.setAttribute("uname", vo.getUname());
session.setAttribute("ubirth", vo.getUbirth());
session.setAttribute("uauth", vo.getUauth());
return "redirect: main.do";
}else {
return "error.jsp"; // 알럿 미구현
}
}
컨트롤러를 경유하여 로그인페이지로 돌아가는 요청과 로그인 로직을 수행해주는 요청으로 method의 요청 방식 구분을 통해 다른 처리를 할 수 있도록 하였다.
이때, session을 비우면 안되므로, 다국어 처리가 필요하다면 페이지 이동은 redirect를 통해 내장객체가 초기화되어서는 안된다.
결과는 다음과 같다.
'Spring' 카테고리의 다른 글
[JPA] JPA를 활용한 DAO버전관리_4 (0) | 2022.04.21 |
---|---|
[Mybatis] Mybatis설치 및 개요_DAO3 (0) | 2022.04.18 |
이미지 업로드 + 예외처리 (0) | 2022.04.12 |
[레이어] 비즈니스 컴포넌트 (0) | 2022.04.11 |
[AOP] 트랜잭션 관리자 (2) | 2022.04.08 |