[ PersonalInfoServlet.java ]
package ch08;
import java.io.IOException;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
//------------------------------------------------------------------------
// public class PersonalInfoServlet
//------------------------------------------------------------------------
public class PersonalInfoServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
PersonalInfo obj = new PersonalInfo();
obj.setName("고길동");
obj.setGender("남");
obj.setAge(55);
request.setAttribute("pinfo", obj);
RequestDispatcher dispatcher = request.getRequestDispatcher("/ch08/CustomerInfoView.jsp");
// 경로 루트를 정확히 입력
dispatcher.forward(request, response);
}
} // End - public class PersonalInfoServlet
[ Web.xml ]
<servlet>
<servlet-name>pinfo-servlet</servlet-name>
<servlet-class>ch08.PersonalInfoServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>pinfo-servlet</servlet-name>
<url-pattern>/pinfo</url-pattern>
</servlet-mapping>
[ PersonalInfo.java ]
package ch08;
//---------------------------------------------------------------
// public class PersonalInfo
//---------------------------------------------------------------
public class PersonalInfo {
private String name; // 이름
private char gender; // 성별
private int age; // 나이
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public char getGender() {
return gender;
}
public void setGender(char gender) {
this.gender = gender;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public void setGender(String string) {
// TODO Auto-generated method stub
}
} // End - public class PersonalInfo
[ CustomerInfoView ]
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>CustomerInfoView.jsp</title>
</head>
<body>
<h1>회원 정보</h1>
<jsp:useBean class="ch08.PersonalInfo" id="pinfo" scope="request" />
<h1>이름 : <jsp:getProperty name="pinfo" property="name" /></h1>
<h1>성별 : <jsp:getProperty name="pinfo" property="gender" /></h1>
<h1>나이 : <jsp:getProperty name="pinfo" property="age" /></h1>
</body>
</html>
https://tomcat.apache.org/taglibs/standard/
[ 유효성 검사(Validation) ]
○ 사용자가 폼 페이지에서 입력한 데이터 값이 서버로 전송되기 전에 특정 규칙에 맞게 입력되었는 검증
○ 사용자가 유효하지 않은 데이터 값 입력하면 부적합하다고 판단해 다시 폼 페이지로 되돌려 사용자에게 오류 전달
- 입력 데이터가 null인지 확인
- 날짜나 이메일을 입력할 때 형식에 맞는지 확인
- 나이 입력할 때 숫자인지 확인
- 입력 데이터의 제한 길이를 초과했는지 확인
- 로그인 인증 시 아이디와 비밀번호 확인
- 회원가입 시 아이디 중복 여부를 확인
<script type="text/javascript">
function 핸들러 함수() {
var str = document.폼 이름.입력항목 이름.value;
}
</script>
<form name="폼 이름">
....(생략)....
<input type="submit" onclick="핸들러 함수()">
</form>
○ 기본 유효성 검사
- 사용자가 폼 페이지의 입력 항목에 입력한 데이터 값이 있는지 없는지 확인하고 데이터 길이, 숫자 등
기본적인 것 맞는지 검사
- 폼 페이지의 입력 데이터 길이 확인해 데이터 유무 검증하는 것
- 입력 데이터의 유무를 검사하는 형식
document.폼 이름.입력양식 이름.value==""
- 데이터 길이 확인하기
document.폼 이름.입력양식 이름.value.length
- 숫자 여부 확인하기(isNotNumber의 약자)
isNaN(document.폼 이름.입력양식 이름.value)
○ 데이터 형식 유효성 검사
- 사용자가 폼 페이지의 입력 항목에 입력한 데이터 값이 특정 형태에 적합한지 검사하기 위해 정규 표현식 사용
- 정규 표현식
1) 특정한 규칙을 가진 문자열의 집합을 표현하는 데 사용하는 형식 언어
2) 문자열의 특정 형태를 찾아내기 위해 패턴으로 표현한 수식
3) 주민등록번호, 전화번호, 이메일과 같이 데이터 형식의 패턴이 일정한 데이터를 검사하는 데 이용
4) 객체 초기화(Object initalizer)를 사용하는 방법, 입력된 표현식이 거의 바뀌지 않는 상수 형태일 때 주로 사용
var 변수 이름 = /정규 표현식/[flag];
flag | 설명 |
i | Ignore Case : 문자열의 대문자와 소문자를 구별하지 않고 검출 |
g | Global : 문자열 내의 모든 패턴 검출 |
m | Multi Line : 문자열에 줄 바꿈 행이 있는지 검출 |
var 변수 이름 = new RegExp('정규 표현식', ['Flag']);
메소드 | 설명 |
test() | 매개변수 값으로 전달되는 문자열이 정규 표현식이 부합한지 판단해 true/false 반환 |
exec() | 매개변수 값으로 전달되는 문자열에서 정규 표현식에 부합된 문자열을 추출해 반환 |
[ addProduct.jsp ]
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>상품 등록</title>
<style>
.inputRow {
margin: 15px 0px;
display: flex;
align-items : center;
}
.inputRow label {
width : 150px;
}
.inputRow input, .inputRow textarea {
font-size: 1.3rem;
}
.inputRow input.btn {
font-size: 1rem;
padding : 5px 15px;
}
</style>
<script type="text/javascript" src="./resources/js/validate.js">
</script>
</head>
<body>
<jsp:include page="header.jsp" />
<div class="main">
<div class="banner">
<div class="container">
<h1>상품 등록</h1>
</div>
</div>
<div class="content">
<div class="container">
<form name="newProduct" action="./processAddProduct.jsp"
class="form-horizontal" method="post" enctype="multipart/form-data">
<div class="inputRow">
<label for="productId">상품 코드</label> <input type="text"
name="productId" id="productId">
</div>
<div class="inputRow">
<label for="name">상품 명</label> <input type="text" name="name" id ="name">
</div>
<div class="inputRow">
<label for="unitPrice">가격</label> <input type="text" name="unitPrice" id="unitPrice">
</div>
<div class="inputRow">
<label for="description">상세 정보</label>
<textarea name="description" cols="50" rows="2" id="description">
</textarea>
</div>
<div class="inputRow">
<label for="manufacturer">제조사</label> <input type="text" name="manufacturer" id="manufacturer">
</div>
<div class="inputRow">
<label for="category">분류</label> <input type="text" name="category" id="category">
</div>
<div class="inputRow">
<label for="unitStock">재고 수</label> <input type="text" name="unitInStock" id="unitStock">
</div>
<div class="inputRow">
<label>상태</label>
<label><input type="radio" name="condition" value="New"> 신규 제품</label>
<label><input type="radio" name="condition" value="Old"> 중고 제품</label>
<label><input type="radio" name="condition" value="Refurbished"> 재생 제품</label>
</div>
<div class="inputRow">
<label for="productImage">이미지</label>
<input type="file" name="productImage" id="productImage">
</div>
<div class="inputRow">
<input type="button" value="등록" class="btn btn-secondary" onclick="CheckAddProduct()">
</div>
</form>
<hr>
</div>
</div>
</div>
<jsp:include page="footer.jsp" />
</body>
</html>
[ validation.js ]
function CheckAddProduct() {
var productId = document.getElementById("productId");
var name = document.getElementById("name");
var unitPrice = document.getElementById("unitPrice");
var unitInStock = document.getElementById("unitStock");
// 상품 아이디 체크
if(!check(/^P[0-9]{4,11}$/, productId, "[상품 코드]\nP와 숫자를 조합하여 5~12자까지 입력하세요\n첫 글자는 반드시 P로 시작하세요"))
return false;
// 상품명 체크
if(name.value.length < 4 || name.value.length>12) {
alert("[상품명]\n 최소 4자에서 최대 12자까지 입력하세요");
name.select();
name.focus();
return false;
}
// 상품 가격 체크
if(unitPrice.value.length == 0 || isNaN(unitPrice.value)) {
alert("[가격]\n숫자만 입력하세요");
unitPrice.select();
unitPrice.focus();
return false;
}
if(unitPrice.value<0) {
alert("[가격]\n음수는 입력할 수 없습니다");
unitPrice.select();
unitPrice.focus();
return false;
}else if(!check(/^\d+(?:[.]?[\d]?[\d])?$/,unitPrice, "[가격]\n소수점 둘째 자리까지만 입력하세요"))
return false;
// 재고수 체크
if(isNaN(unitInStock.value)) {
alert("[재고 수]\n 숫자만 입력하세요");
unitInStock.select();
unitInStock.focus();
return false;
}
function check(regExp, e, msg) {
if(regExp.test(e.value)){
return true;
}
alert(msg);
e.select();
e.focus();
return false;
}
document.newProduct.submit();
}
[ 다국어 처리 ]
○ 웹 브라우저를 사용하는 국가에 따라 다양한 언어 및 지역을 지원하는 서비스
○ 다른 언어와 지역적 차이를 기술 변경 없이 소프트웨어에 바로 적용하는 것
○ JSP 페이지에 JSTL의 fmt태그를 이용하면 언버별로 페이지를 따로 만들 필요 없이 간단하게 다국어 지원 가능
○ 다국어는 다양한 언어와 지역에 적용될 수 있도록 하는 국제화와 언어별 구성요소를 추가해 특정 지역의 언어나
문화에 맞추는 지역화 포함
○ 지역화
- 사용 국가별 환경에서 특정 언어와 지역에 맞게 적합화하는 것
- L10n으로 표기
○ 정규화에 주로 고려되는 사항
- 숫자, 날짜 ,시간 형식
- 화폐 단위
- 키보드 지원
- 문자열의 순서와 정렬
- 심볼, 아이콘, 색상
- 문화에 따라 오해의 소지가 있거나 의미가 없는 문자, 그림
- 지역별 법률의 차이
○ 국제화
- 여러 국가에서 사용할 수 있도록 다국어 지원
- i18n으로 표기
- 어느 국가에서나 사용할 수 있게 하는 지역화 기능 포함
- 유니코드의 사용이나 기존 인코딩을 적절히 처리하고 사용자 인터페이스에 표시할 문자열에는 문자 코드가 포함되지 않도록 설계 및 개발해야 함
- 국제화 처리하는 정보에 언어 정보를 포함하거나, 세로 쓰기, 가로 쓰기, 우측에서 좌측으로의 가로 쓰기 등 언어의
특성을 반영하는 처리 등을 지원해야 함
- 날자와 시간 표시, 지역의 달력, 숫자 표시, 리스트의 정렬과 표시, 인명이나 주소의 처리 등 언어의 특성에 대한
사용자 설정 지원해야 함
- 사용자의 요청이나 설정에 다라 필요 시, 사용되도록 지역화 정보를 코드와 분리해야 함
[ Locale 클래스 ]
○ 특정 지리적 정치적.문화적 지역 나타내는 클래스
○ 사용자의 지역 환경에 따라 결정되는 지역적 문화(언어, 날짜, 시간 등)의 정보 담고 있음
○ 단순한 메시지뿐만 아니라 숫자, 날자 시간 등을 표현하는 데 사용
○ Locale 객체 생성은 request 내장 객체 이용해 현재 웹 브라우저에 미리 정의된 언어나 국가정보를 가져오는 방법
java.util.Locale request.getLocale();
메소드 | 반환 유형 | 설명 |
getDefault() | static Locale | 디폴트 로케일의 현재 값 가져옴 |
getCountry() | String | 현재 로케일의 국가/지역 코드(대문자) 가져옴 |
getDisplayCountry() | String | 현재 로케일의 국가 이름 가져옴 |
getLanguage() | String | 현재 로케일의 언어 코드(소문자) 가져옴 |
getDisplayLanguage() | String | 현재 로케일의 언어 이름 얻어옴 |
○ 로케일 표현하기
- 언어 설정 : response 내장 개체의 setHeader() 메소드 사용
- 날짜와 시간 설정 : DateFormat 클래스의 getDateTimeinstance() 메소드 사용
- 통화와 숫자 설정 : NumberFormat 클래스의 getCurrencyInstance() 메소드 사용
[ JSTL fmt 태그 ]
○ 다국어 문서 처리를 위한 국제화 및 지역화 태그
○ 날짜와 숫자 등을 형식화하는 기능 제공하는 JSTL 라이브러리인 JSTL fmt 태그는 특정 지역에 따라
다른 메시지 출력할 때 사용
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
구분 | 태그 유형 | 설명 |
Locale 설정 | setLocale | 로케일 설정 |
requestEncoding | 요청 파라미터의 문자 인코딩 설정 | |
메시지 처리 | bundle | 사용할 리소스번들을 설정 |
message | 리소스번들에서 로케일에 맞는 메시지를 가져와 출력 | |
setBundle | 리소스번들을 읽어와 특정 변수에 저장 |
구분 | 태그 유형 | 설명 |
날짜 | formatDate | 날자 형식 표현 |
parseDate | 문자열에서 원하는 패턴의 날짜 형식으로 변환 | |
숫자 | parseNumber | 문자열에서 원하는 패턴의 숫자 형식으로 변환 |
formatNumber | 숫자 형식 표현 | |
시간 | setTimeZone | 특정 범위의 시간대 설정 |
timeZone | 시간대 설정 |
○ setLocale 태그
- 국체화 태그가 사용할 로케일을 설정하는 태그
<fmt:setLocale
value="언어 코드[_국가 코드]"
[scope="{page|request|session|application}"]/> // 기본값 = page
○ requestEncoding 태그
- 요청 파라미터의 문자 인코딩을 설정하는 태그
<fmt:requestEncoding value="문자 인코딩"/>
[ 리소스 번들 ]
○ 메시지 처리 태그에서 사용하는 파일, 메시지 번들이라고도 함
○ WEB-INF/classes/폴더에 있음
○ java.util.Properties 클래스에 정의된 방법으로 메시지 읽어오기 때문에 확장자가 properties인 파일이 반드시 있어야 함
*.properties 파일 | 설명 |
파일 이름.properties | 기본 메시지일 때 사용 |
파일 이름_ko.properties | 한글 메시지일 때 사용 |
파일 이름_en.properties | 영어 메시지일 때 사용 |
○ bundle 태그 : 사용할 리소스 번들을 설정하는 태그
<fmt:bundel basename="리소스번들" [prefix="key 이름"]>
// body 내용
</fmt:bundle>
○ message 태그
- bundle 태그에 설정한 리소스 번들에서 메시지를 읽어와 출력하는 태그
<fmt:message
key="메시지 key 이름"
[bundle="setBundle 태그의 변수 이름"]
[var="메시지를 저장하는 변수 이름"]
[scope="{page|request|session|aaplication}"]/> // 기본값 = page
○ setBundle 태그
- 리소스번들을 가져와 변수로 저장한 후 JSP 페이지 어디에서나 사용, bundle 태그 대체 가능
<fmt:setBundle
basename="리소스번들"
[var="리소스번들을 저장할 변수 이름"]
[scope={page|request|session|application}"]/> // 기본값 = page
[ 숫자 태그 ]
○ formatNumber 태그
- 숫자를 형식에 맞춰 출력하는 태그
<fmt:formatNumber value="형식화할 숫자"
[type="{number|currency|percent}"] // 기본값 = number
[pattern="사용자 정의 패턴"]
[currencyCode="통화 코드"] // type="currency"일 때만 적용
[currencySymbol="통화 기호"] // type="currency"일 때만 적용
[groupingUsed="천 단위마다 구분 기호{true|false}"] // 기본값 = true
[maxIntegerDigits="최대 자릿수"]
[minIntegerDigits="최소 자릿수"]
[maxFractionDigits="소수점 이하 최대 자릿수"]
[minFractionDigits="소수점 이하 최소 자릿수"]
[var="형식화된 결과를 저장할 변수 이름"]
[scope="{page|request|session|application}"]/> // 기본값 = page
○ parseNumber 태그
- 사용자가 설정한 패턴 문자열에서 숫자 추출
<fmt:formatNumber value="파싱할 숫자"
[type="{number|currency|percent}"] // 기본값 = number
[pattern="사용자 정의 패턴"]
[parseLocale = "파싱의 기본 형식 패턴을 제공하는 로케일"]
[integerOnly="{true|false}"]
[var="형식화된 결과를 저장할 변수 이름"]
[scope="{page|request|session|application}"]/> // 기본값 = page
[ 날짜 태그 ]
○ formatDate 태그
- 날짜 정보를 담고 있는 객체를 형식화해 출력
<fmt:formatDate value="형식화할 날짜"
[type="{time|date|both}"]
[dateStyle="{default|short|medium|long|full}"]
[timeStyle="{default|short|medium|long|full}"]
[pattern="사용자 정의 패턴"]
[timeZone="타임존"]
[var="형식화된 결과를 저장할 변수 이름"]
[scope="{page|request|session|aaplication}"]/>
○ ParseDate 태그
- 문자열로 표시된 날자와 시간값을 java.util.Date로 변환
<fmt:formatDate value="파싱할 날짜"
[type="{time|date|both}"]
[dateStyle="{default|short|medium|long|full}"]
[timeStyle="{default|short|medium|long|full}"]
[pattern="사용자 정의 패턴"]
[timeZone="타임존"]
[parseLocale="파싱의 기본 형식 패턴을 제공하는 로케일"]
[var="파싱 결과를 저장할 변수 이름"]
[scope="{page|request|session|aaplication}"]/>
[ 시간 태그 ]
○ TimeZone 태그
- 시간대별로 시간을 처리하는 태그
<fmt:timeZone value="타임존">
//
</fmt:timeZone>
○ setTimeZone 태그
- 특정 영역 범위의 시간대별로 시간을 처리하는 태그
<fmt:setTimeZone value="타임존"
[var="시간대 결과를 저장할 변수 이름"]
[scope="{page|request|session|aaplication}"]/>
'프로그래밍 언어 > JSP' 카테고리의 다른 글
JSP_22-11-04 (0) | 2022.11.04 |
---|---|
JSP_22-11-02 (0) | 2022.11.02 |
JSP_22.10.31 (0) | 2022.10.31 |
JSP_22-10-28(2) (0) | 2022.10.28 |