레이블이 Struts2인 게시물을 표시합니다. 모든 게시물 표시
레이블이 Struts2인 게시물을 표시합니다. 모든 게시물 표시

2015년 1월 14일 수요일

[Struts 2] Web Application - Getting Started

#과거 2004년도에 초기 Struts 1.3 버전 때 개발을 주로 하다가 프로그래밍 안한지 6년 7년 만에 필요한 것이 있어서 다시 시작하려니 이미 많은 부분이 바뀌어서 간단하게 만드는 부분이니 Struts 을 찾아 보다 또 버전이 업그레이드 되었다.

# 간략하게 정리 하면서 샘플을 만들어 봤다. 혹 나와 같은 사람이거나 새롭게 접근하는 친구들이 있다면 도움이 될지 모르겠다.

# 그러나, 개략적인 설명의 대부분은 기존 Struts 1을 경험한 사람을 위주로 하였음을 미안하게 생각한다. 또는 기존에 Web 관련 개발을 해본 친구들이라면 함께 이해하고 넘어가는데 큰 어려움이 없을것으로 생각된다.


[이미지출처 - 스프링3입문]

위 사진은 전반적인 구성을 보여주고 있다. 브라우저에서 요청이 들어 오면 일단 프론트 컨트롤러가 받아서 공통된 처리를 시행하면서 개별 처리와 뷰를 호출하는 구조로 되어 있다. 개별처리 부분에선 데이터에 대한 모델이 필요한 경우 참조하게 된다. 이구성은 기존의 Struts1 과도 동일하다는 것을 알 수 있다.

단지 차이가 좀 있다면 기존의 Struts1 에서는 로그인이나 입력되는 Form 관련 페이지에서 Form 값을 받아 주는 ActionForm 클래스를 상속받아서 처리 해줘야 하는 번거로움이 있었다. 그런데 버전 2.0 대에 오면서 이 부분이 없어졌다.



[이미지출처 - 스프링3입문]




# 실행을 위한 사전 준비사항

1) web.xml파일 설정
<?xml version="1.0" encoding="UTF-8"?>
<web-app
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
id="WebApp_ID"
version="2.5">
    <display-name>inv</display-name>

    <filter>
        <filter-name>struts2</filter-name>
        <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
    </filter>

    <filter-mapping>
        <filter-name>struts2</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
 
    <resource-ref>
        <res-ref-name>jdbc/myoracle</res-ref-name>
        <res-type>javax.sql.DataSource</res-type>
        <res-auth>Container</res-auth>
    </resource-ref>

    <welcome-file-list>
        <welcome-file>index.html</welcome-file>
        <welcome-file>index.jsp</welcome-file>
    </welcome-file-list>
</web-app>

2) Action 설정
import org.apache.struts2.dispatcher.SessionMap;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.Preparable;
import Resource;
import User;
import HrInfoService;
import HrInfoServiceImpl;
public class LoginAction extends ActionSupport  implements Preparable {
private static final long serialVersionUID = 9149826260758390091L;
private User user;
private Resource resource;
private HrInfoService hrInfoService;
private String id;
private String password;
private String companyName;

public void prepare() {
resource = new Resource();
resource.setDriver(getText("driver"));
resource.setUrl(getText("url"));
resource.setUsername(getText("username"));
resource.setPassword(getText("password"));

hrInfoService = new HrInfoServiceImpl();
}
public String loginForm() {
return SUCCESS;
}

public String login() throws Exception {
User user = new User();
user.setId(this.id);
user.setPassword(this.password);
User isValidLogon = hrInfoService.authenticateLogin(resource, user);

if (isValidLogon != null) {
String id = isValidLogon.getId();

@SuppressWarnings({ "rawtypes", "unchecked" })
SessionMap<String, String> session = (SessionMap) ActionContext.getContext().getSession();
session.put("userId", id);
session.put("companyName", companyName);
return SUCCESS;
} else {
addActionError("Incorrect ID or password");
return INPUT;
}
}

// ---------------------------- Log Out register user
public String logOut() {
@SuppressWarnings("rawtypes")
SessionMap session = (SessionMap) ActionContext.getContext().getSession();
session.remove("userId");
addActionMessage("You Have Been Successfully Logged Out");
return SUCCESS;
}
public void setuser(User user) {
this.user = user;
}
public User getUser() {
return user;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}

3) JSP 페이지 설정
<%@ page contentType="text/html; charset=UTF-8"%>
<!doctype html>
<html lang="ko">
<head>
<title>SUNATFOOD - Purchase</title>
<link rel="stylesheet" href="css/baseStyle.css" />
<!--[if IE]>
<script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
</head>
<body >
<header>
<hgroup>
<h1>Example</h1>
</hgroup>
</header>
<nav>
<ul>
<li><a href="index.jsp">Home</a></li>
<li><a href="#">About Us</a></li>
</ul>
</nav>

<article>
<section>
<header>
<h1>Beta Test HTML5 적용 (크롬브라우저 사용 권장 최적화) </h1>
</header>
<form action="/login.action" method="post">
<label for="id">LogIn ID:</label>
<input type="text" required name="id" id="id" placeholder="Enter your id" autofocus><br />
<label for="password">LogIn Password:</label>
<input type="password" required name="password" id="password" placeholder="Enter your password"><br />
<input type="submit" value="LOG-IN">
</form>
</section>

</article>

<footer>
<p>&copy; **** All rights reserved.</p>
</footer>
</body>
</html>


4) struts.xml 작성
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" "http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
<package name="default" extends="struts-default" namespace="/">      
<!-- Login Action -->
<action name="loginForm" class="saf.hr.action.LoginAction" method="loginForm">
<result name="success">/index.jsp</result>
</action>
<action name="login" class="saf.hr.action.LoginAction" method="login">
<result name="success" type="redirect">/getPayInfoList.action</result>
<result name="input">/index.jsp</result>
</action>
<action name="logOut" class="saf.hr.action.LoginAction" method="logOut">
<result name="success" type="redirect">/loginForm.action</result>
</action>
</package>
</struts>



[Struts 2] Web Application - Env. Configuration


# Reference URL - http://struts.apache.org/docs/tutorials.html 

아래 문서는 내부 구성원을 위한 간략한 설정 및 설치를 위한 정보 공유에 목적이 있으며 IT의 구성 환경에 따라 달라 질 수 있으므로 개인적인 활용에는 적절하지 않을 수도 있다.

1. 개발환경
- Windows 7 64Bit Pro
- Java  JDK 1.7.0_55
http://www.oracle.com/technetwork/java/javase/downloads/index.html?ssSourceSiteId=ocomen
- Struts 2.3.16.3
http://archive.apache.org/dist/struts/binaries/ 
- Spring Tool Suite (STS) R3.6.1
 : https://spring.io/tools


2. 운용환경
- CentOS 6.5 64Bit
- apache Tomcat 7.0
 : http://tomcat.apache.org/download-70.cgi


3. 설치 및 설정
 JDK와 Struts 버전에 관한 관리를 위해서 lib 폴더는 버전별로 별도로 관리 하고 향후 STS에서 버전별 그리고 기능별로 분리 관리 하여 사용할 수 있도록 한다. 예를 들면 아래와 같은 화면으로 User Library 를 추가하여 관리 한다.

개발 하고자 하는 경우에 따라 버전별로 기능별로 구성하여 Build Path 를 구성 할 수 있다. 

가장 필수가 되는 라이브러리는 데이터베이스 관련 JDBC 라이브러리 이다. 우리는 오라클 11g 를 사용하는 관계로 아래 링크의 라이브러리 파일을 추가 하여 활용 한다. 오라클의 정책이 변경되서 인지 모르겠으나 어느 시점 부터는 로그인이 필요하도록 연결되어 있으니 만일 오라클 계정이 없다면 추가 한 이후에 가능 할 것으로 생각 된다. 

Oracle Database 11g Release 2 JDBC Drivers

Help URL 

라이브러리 설정이 완료된 이후엔 기존 Web Application 을 연결 또는 신규로 프로젝트를 생성하여 구성한다. 

우리는 기본 구성을 다음과 같이 한다. 
패키지 명명 기준은 "계열사명.서브시스템.action, dao, odel, service " 로 구성한다. 또한 기본구성이 되는 properties 파일은 기준이 되는 파일을 공용 디스크에서 공유된 파일로 복사 하여 맞춘다. 











2014년 9월 24일 수요일

[Struts2] JSTL: fmt

원본문서 주소 - http://noritersand.tistory.com/256

FMT, I18N - 국제화(Internationalization)
기능  : 지역, 메시지 형식, 숫자 및 날짜형식
접두어(Prefix)  :  fmt
directive : <%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>

JSTL 국제화 지역화 태그로 다국어 문서를 처리할 때 유용하고, 날짜와 숫자 형식을 다룰 때 사용된다.  



목차




setLocale
다국어를 지원하는 페이지를 만들 경우 ResourceBundle로 불러오는 *.properties 파일들과 연계되어서 사용한다. 

<fmt:setLocale value="locale"  [variant="variant"] [scope="{page|request|session|application}"]/>

 value의 locale 값은 http://ftp.ics.uci.edu/pub/ietf/http/related/iso639.txt 언어코드와 http://userpage.chemie.fu-berlin.de/diverse/doc/ISO_3166.html  국가코드로  이루어진다. 생략될경우 톰캣 서버의 기본 값으로 설정이 되고, 둘 중에 하나만 사용할 수도 있다.

 <%@ page contentType = "text/html; charset=utf-8" %> 
 <%@ taglib  uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> 
 <%@ taglib  uri="http://java.sun.comjsp/jsp/jstl/fmt" prefix="fmt"%> 

 <pre> 
    default  locale  : <%=  response.getLocale() %> 
    set  locale  : ko <fmt:setLocale value="ko"  /> 
    now: <%=  response.getLocale() %> 
    set  locale  : ja  <fmt:setLocale value="ja"  /> 
    now: <%=  response.getLocale() %> 
    set  locale  : en  <fmt:setLocale value="en"  /> 
    now: <%=  response.getLocale() %> 
 </pre> 



requestEncoding
request.setCharacterEncoding() 역할을 한다. 

<fmt:requestEncoding  [value="charsetName"]/> 
 <%@ page contentType = "text/html;charset=utf-8" %> 
 <%@ taglib  uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> 

 <%@ taglib  uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %> 

 <fmt:requestEncoding value="utf-8"/> 

 파라미터:<c:out value="${param.id}"/> 
 <form  method="post"> 
       <input type="text"  name="id"/> 
       <input type="submit"/> 

 </form> 



bundle
properties 확장자를 사용하는 자원 파일을 읽어오는 역할을 한다. 

<fmt:bundle  basename="basename"  [prefix="prefix"]> 
     body content 
</fmt:bundle> 

basename 속성에  지정된 properties 파일을  찾아서 locale  에  따라 읽어들인다.  
properties 파일은 보통 WEB-INF/classes 아래에 위치하며 디렉토리의 깊이에 따라서 패키지형식의 이름을 취한다. TestBundle.properties 파일이com/itexpert/test/msg 디렉토리에 있다면 basename="com.itexpert.test.msg.TestBundle"  이라고 지정하면 된다. 

locale이 ko라면 TestBundle_ko.properties 파일을 읽어오게 되며, locale이 맞지 않는 경우에는 TestBundle.properties처럼 코드가 붙지 않은 파일을 읽어온다.

prefix 속성은 key 명칭이 공통적인 부분을 지정해서 body에서 표현되는 key를 단축시킨다. import 에서 패키지 명을 지정하면 클래스명만 쓸 수 있는 것과 같이 생각할 수  있다.


setBundle
페이지 전체에서 사용할 수 있는 번들을 지정할 수 있는데, 이에 대한 지정은 <fmt:setBundle/> 태그가 담당한다. var속성에서 정한 변수를 이후에 나오는 <fmt:message/>태그에서 basename  속성에 변수 명으로 대체할 수  있다. 

<fmt:setBundle  basename="basename" [var="varName"] [scope="{page|request|session|application}"]/> 



message
 번들 태그에서 정한  값들을 가져온다. 

Syntax 1: body  없는 경우
<fmt:message  key="messageKey"  [bundle="resourceBundle"] [var="varName"] 
        [scope="{page|request|session|application}"]/> 

Syntax 2: 메시지 파라미터를 지정하는 body가 있는 경우
<fmt:message  key="messageKey"  [bundle="resourceBundle"] [var="varName"] 
        [scope="{page|request|session|application}"]> 
        <fmt:param>  서브태그 
</fmt:message> 

Syntax 3: 키와 선택적 메시지 파라미터를 지정하는 body가 있는 경우
<fmt:message  [bundle="resourceBundle"]  [var="varName"] 
        [scope="{page|request|session|application}"]> 
        key 
        선택적 <fmt:param>  서브태그 
</fmt:message> 

 번들에 있는 key값을 불러온다. bundle 속성으로 번들을 직접 설정할 수도 있고, <fmt:bundle/> 태그 사이에 중첩되어서 키 값만 받아서 출력할 수 있다. 

● 예제 
1) 웹  루트\WEB-INF\classes\bundle  경로에  다음의 properties 파일  두  개를  작성  한다. 
- testBundle_ko.properties 
  name=\ud558\ud558\ud558. 
  message=JSTL \uc7ac\ubbf8\uc788\ub2e4. 

- testBundle.properties 
  name=Han. 
  message=JSTL is fun. 

※ 참고 :  properties 파일은 한글은 입력할 수 없기 때문에 유니코드로 입력해야 하며 j2sdk의 /bin/native2ascii.exe 파일을 이용하여 한글을 유니코드 값을 확인 할 수 있다.  먼저 한글을 입력하고 엔터를 누르면 유니코드로 변환되어 출력한다. 

 properties  파일을  두  개  작성하는  이유는 로케일에  따라 영어 또는  한글로 출력할  수  있다.  영어로 출력하기 위해서는 익스플로러의 "인터넷 옵션-일반-언어"에서 한국어를 지우고 영어를 선택하면 영어로 출력 된다. 

2) JSP  파일  작성 
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<%@ page contentType = "text/html; charset=utf-8" %>
<%@ taglib  prefix="c"  uri="http://java.sun.comjsp/jsp/jstl/core" %>
<%@ taglib  prefix="fmt"  uri="http://java.sun.com/jsp/jstl/fmt"  %>
 
<html>
<head><title>JSTL fmt  예제 -  bundle  , message</title></head>
<body>
 
<fmt:bundle  basename="bundle.testBundle">
    <fmt:message  key="name"/>
    <p/>
    <fmt:message  key="message" var="msg"/>
    <c:out value="${msg}"/>
</fmt:bundle>
 
</body>
</html>


formatNumber
숫자  형식을 표현할  때 사용된다. 

Syntax 1: body 없는 경우
<fmt:formatNumber value="numericValue" 
        [type="{number|currency|percent}"]  [pattern="customPattern"] 
        [currencyCode="currencyCode"] [currencySymbol="currencySymbol"] 
        [groupingUsed="{true|false}"]  [maxIntegerDigits="maxIntegerDigits"] 
        [minIntegerDigits="minIntegerDigits"] [maxFractionDigits="maxFractionDigits"] 
        [minFractionDigits="minFractionDigits"]  [var="varName"] 
        [scope="{page|request|session|application}"]/> 

Syntax 2: 형식에 맞출 수치가 body에 있는 경우
<fmt:formatNumber  [type="{number|currency|percent}"] 
        [pattern="customPattern"]  [currencyCode="currencyCode"] 
        [currencySymbol="currencySymbol"]  [groupingUsed="{true|false}"] 
        [maxIntegerDigits="maxIntegerDigits"]  [minIntegerDigits="minIntegerDigits"] 
        [maxFractionDigits="maxFractionDigits"] [minFractionDigits="minFractionDigits"] 
        [var="varName"] [scope="{page|request|session|application}"]> 
        형식화될 수치 
</fmt:formatNumber> 
<fmt:formatNumber value="1700600"/> // 1,700,600
<fmt:formatNumber value="1700600" type="currency" groupingUsed="true"/> // ₩1,700,600
<fmt:formatNumber value="50" type="percent" groupingUsed="false"/> // 5000%
<fmt:formatNumber value="1670400" type="currency"  currencySymbol="&"/> // &1,670,400
<fmt:formatNumber value="999" minIntegerDigits="5" minFractionDigits="2"/> // 00,999.00

속성
동적
Type
설명
value
true
String 
또는 Number
  형식화될 수치
type
true
String
  숫자, 통화, 퍼센트  중  어느 것으로 표시할  지 지정
  {number|currency|percent}
pattern
true
String
  사용자가  지정한 형식 패턴.
currencyCode
true
String
  ISO 4217 통화 코드 (통화 형식일 때만 적용)
  (type="currency")
currencySymbol
true
String
  통화 기호 (통화 형식일 때만 적용)
  (type="currency")
groupingUsed
true
boolean
  형식 출력에 그룹 분리기호를 포함할지 여부
 (기본값은 true)
maxIntegerDigits
true
int
  형식 출력에서 integer 최대 자리 수
minIntegerDigits
true
int
  형식 출력에서 integer 최소 자리 수
maxFractionDigits
true
int
  형식 출력에서 소수점 이하 최대 자리 수
minFractionDigits
true
int
  형식 출력에서 소수점 이하 최소 자리 수
var
false
String
  형식 출력 결과 문자열을 담는 scope에 해당하는 변수명
scope
false
String
  var의 scope
  


parseNumber
반대로 정해진 패턴을 문자열에서 수치를 파싱해내는 태그

Syntax 1: body가  없는 경우
<fmt:parseNumber value="numericValue" 
        [type="{number|currency|percent}"]  [pattern="customPattern"] 
        [parseLocale="parseLocale"] [integerOnly="{true|false}"] 
        [var="varName"] [scope="{page|request|session|application}"]/> 

Syntax 2: 파싱할 수치를 body에 갖고 있는 경우
<fmt:parseNumber  [type="{number|currency|percent}"] 
        [pattern="customPattern"]  [parseLocale="parseLocale"] 
        [integerOnly="{true|false}"]  [var="varName"] 
        [scope="{page|request|session|application}"]> 
        파싱할 수치 
</fmt:parseNumber>

속성
동적
Type
설명
value
true
String 또는 Number
  파싱할 수치
 type
true
String
  숫자, 통화, 퍼센트 중 어느 것으로 표시할 지 지정
  {number|currency|percent}
pattern
true
String
  사용자가 지정한 형식 패턴
parseLocale
true
String 또는 java.util.Locale
  파싱 작업의 기본 형식 패턴(숫자, 통화, 퍼센트 각각)을 제공하는 Locale
integerOnly
true
boolean
  true일 경우 주어진 값에서 Integer 부분만 파싱
var
false
String
  파싱 결과(java.lang.Number)를 담는 scope에 해당하는 변수명
scope
false
String
  var의 scope


formatDate
날짜 형식을 표현하는 태그

<fmt:formatDate value="date" 
        [type="{time|date|both}"] [dateStyle="{default|short|medium|long|full}"] 
        [timeStyle="{default|short|medium|long|full}"] [pattern="customPattern"] 
        [timeZone="timeZone"] 
        [var="varName"] [scope="{page|request|session|application}"]/> 

속성
동적
Type
설명
value
true
java.util.Date
  형식화 될 Date와 Time 
type
true
String
  형식화 할 데이터가 시간, 날짜, 혹은 시간과 날짜인지 지정
dateStyle
true
String
  미리 정의된 날짜 형식. java.text.DateFormat 클래스에 정의된 문법을 따른다. 
  type 속성이 생략되었거나 date 혹은 body일 때 사용
timeStyle
true
String
  미리 정의된 시간 형식.
  type 속성이 time 혹은 body일 때 사용
pattern
true
String
  사용자 지정 형식 스타일
timeZone
true
String 또는 java.util.TimeZone
  형식화 시간에 나타날 타임 존
var
false
String
  형식 출력 결과 문자열을 담는 scope에 해당하는 변수명
scope
false
String
  var의 scope


parseDate
정해진 패턴의 문자열에서  날짜를 파싱해내는  태그 

Syntax 1: body 없는 경우
<fmt:parseDate value="dateString"
        [type="{time|date|both}"] [dateStyle="{default|short|medium|long|full}"] 
        [timeStyle="{default|short|medium|long|full}"] [pattern="customPattern"] 
        [timeZone="timeZone"] [parseLocale="parseLocale"] 
        [var="varName"] [scope="{page|request|session|application}"]/> 

Syntax 2: 파싱한 값이 body에 있는 경우
<fmt:parseDate  [type="{time|date|both}"] 
        [dateStyle="{default|short|medium|long|full}"]  
        [timeStyle="{default|short|medium|long|full}"] [pattern="customPattern"] 
        [timeZone="timeZone"] [parseLocale="parseLocale"] [var="varName"] 
        [scope="{page|request|session|application}"]> 
        파싱할 Date  와 time 
</fmt:parseDate> 

속성
동적
Type
설명
value
true
java.util.Date
  파싱할 Date와 Time 
type
true
String
  파싱할 데이터가 시간, 날짜, 혹은 시간과 날짜인지 지정
dateStyle
true
String
  미리 정의된 날짜 형식. java.text.DateFormat 클래스에 정의된 문법을 따른다.
  type 속성이 생략되었거나 date 혹은 body일 때 사용
timeStyle
true
String
  미리 정의된 시간 형식
  type 속성이 time 혹은 body일 때 사용
pattern
true
String
  사용자 지정 형식 스타일 
timeZone
true
String 또는 java.util.TimeZone
  형식화 시간에 나타날 타임 존 
parseLocale
true
String 또는 java.util.Locale
  파싱하는 동안 적용될 미리 정의된 형식스타일의 Locale 
var
false
String
  파싱 결과(java.util.Date)를 담는 scope에 해당하는 변수명 
scope
false
String
  var의 scope

● 예제
?
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
32
33
34
<%@ page contentType = "text/html; charset=utf-8" %>
<%@ page pageEncoding="utf-8" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
 
<!DOCTYPE html>
<html>
<head><title></title></head>
<body>
    <pre>
        <fmt:setLocale value="ko_KR"/>
        number : <fmt:formatNumber value="9876543.61" type="number"/>
        currency : <fmt:formatNumber value="9876543.61" type="currency"/>
        percent : <fmt:formatNumber type="percent">9876543.61</fmt:formatNumber>
 
        pattern=".000"    :<fmt:formatNumber value="9876543.61" pattern=".000" />
        pattern="#,#00.0#":<fmt:formatNumber value="9876543.612345" pattern="#,#00.0#"/>
 
        <jsp:useBean id="now" class="java.util.Date"/>
        <c:out value="${now}"/>
        date : <fmt:formatDate value="${now}" type="date"/>
        time : <fmt:formatDate value="${now}" type="time"/>
        both : <fmt:formatDate value="${now}" type="both"/>
        default : <fmt:formatDate value="${now}" type="both"  dateStyle="default" timeStyle="default"/>
        short : <fmt:formatDate value="${now}" type="both"  dateStyle="short"   timeStyle="short"   />
        medium : <fmt:formatDate value="${now}" type="both"  dateStyle="medium"   timeStyle="medium"  />
        long : <fmt:formatDate value="${now}" type="both"  dateStyle="long"     timeStyle="long"    />
        full : <fmt:formatDate value="${now}" type="both"  dateStyle="full"     timeStyle="full"     />
 
        pattern="yyyy년MM월dd일 HH시mm분ss초"
        <fmt:formatDate value="${now}"  type="both" pattern="yyyy년MM월dd일 HH시mm분ss초"/>
    </pre>
</body>
</html>




setTimeZone, timeZone
<fmt:setTimeZone/> : 특정 스코프의 타임 존을 설정한다.
<fmt:setTimeZone value="timeZone" [var="varName"] [scope="{page|request|session|application}"]/>

<fmt:timeZone/> : 타임 존을 부분 적용한다.
<fmt:timeZone value="timeZone"> 
    body content 
</fmt:timeZone> 

● 예제
?
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
<%@ page contentType = "text/html; charset=utf-8" %>
<%@ taglib  uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@ taglib  uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt"%>
 
<!DOCTYPE html>
<html>
<head><title></title></head>
<body>
    <pre>
        <fmt:setLocale value="ko_KR"/>
        <jsp:useBean id="now" class="java.util.Date"/>
 
        default : <c:out value="${now}"/>
        Korea KST :
        <fmt:formatDate value="${now}" type="both" dateStyle="full" timeStyle="full"/>
         
        <fmt:timeZone value="GMT">
            Swiss GMT :
            <fmt:formatDate value="${now}" type="both" dateStyle="full" timeStyle="full"/>
        </fmt:timeZone>
 
        <fmt:timeZone value="GMT-8">
            NewYork GMT-8 :
            <fmt:formatDate value="${now}" type="both" dateStyle="full" timeStyle="full"/>
        </fmt:timeZone>
    </pre>
</body>
</html>

언제 부터 였던가 생각해보니 아르바이트 겸 외부 컨설팅을 의뢰 받고 맥북 프로를 처음 써봤을 때 부터 였던 것 같다. 지금은 거의 대부분의 작업을 맥으로 작업을 하다 보니 윈도우에서만 실행되는 일부 프로그램들 때문과 회사 내부 ERP프로그램이 윈도우 ...