# EL(Expression Language)
콤마(,)와 대괄호([])를 사용하여
자바 빈의 프로퍼티나 맵, 리스트, 배열의 값을 보다 쉽게 꺼내게 해주는 기술
# JSP에서 표현 언어 사용 설정
JSP 페이지에서 표현 언어(EL)를 사용하기 위해서는 page 디렉티브의 isELIgnored 속성을 false로 설정해야 한다.
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" isELIgnored="false" %>
그러나 이 속성은 명시하지 않는 경우 기본값이 false이므로 true로만 설정하지 않으면 된다.
- EL 표기법
멤버 값 출력
${member.no}
또는
객체이름 프로퍼티
${member["no"]} // 상단배열
객체이름 프로퍼티
- 자바 코드 표현 시
Member obj = (Member)pageContext.findAttribute("member");
int value = obj.getNo();
// view에서 자바 소스 코드를 사용하는 것은 분업화를 위해 권장하지 않는다.
PageContext의 findAttribute()는 다음 순서에 따라 보관소(Scope Objects)를 뒤져서 객체를 찾는다.
마지막까지 뒤졌는데 없다면 null을 반환한다. // null 반환 시 아무 것도 출력하지 않는다.
JspContext - ServletRequest - HttpSession - ServletContext - null (찾는 순서)
# EL에서 검색 범위 지정
EL도 <jsp:useBean>처럼 네 군데 보관소에서 값을 꺼낼 수 있다.
다만 <jsp:useBean>과 다른 점은 EL로는 객체를 생성할 수 없다는 것이다.
EL에서 보관소를 참조할 때 사용하는 이름 |
pageScope -> JspContext |
- ServletRequest 보관소에서 값을 꺼내는 EL 코드이다.
${requestScope.member.no}
- 자바 코드 표현 시
Member obj = (Member)request.getAttribute("member");
int value = obj.getNo();
객체를 찾는 범위를 지정하지 않으면 JspContext부터 ServletContext까지 순차적으로 찾지만,
앞의 코드와 같이 범위를 지정하게 되면 해당 보관소에서만 객체를 찾는다.
못 찾으면 null을 반환한다.
// 저장영역 미설정 시 낮은 - 높은 순으로 영역에서 값을 찾아 가져온다.
# JSP에서 제공하는 EL 기본 객체
객체 | 설명 | 코드 |
pageContext | JSP의 PageContext 객체 | |
servletContext | ServletContext 객체 | ${pageContext.servletContext.객체명} |
session | HttpSession 객체 | ${pageContext.session.객체명} |
request | ServletRequest 객체 | ${pageContext.request.객체명} |
response | ServletResponse 객체 | |
param | 요청 매개변수의 값 조회 | ${param.매개변수명} |
paramValues | 요청 매개변수의 값 배열 조회 | ${paramValues.매개변수명} |
header | Http 헤더의 값 조회 | ${header.헤더명} |
headerValues | Http 헤더의 값 배열 조회 | ${headerValues.헤더명} |
cookie | 쿠키 값 조회 | ${cookie.쿠키명} |
initParam | 컨텍스트 초기화 매개변수의 값 조회 | ${initParam.매개변수명} |
pageScope | page 보관소의 값 조회 | ${pageScope.객체명} |
requestScope | request 보관소의 값 조회 | ${requestScope.객체명} |
sessionScope | session 보관소의 값 조회 | ${sessionScope.객체명} |
applicationScope | application 보관소의 값 조회 | ${applicationScope.객체명} |
# EL 기본 문법
- 리터럴 표현식
EL 블록("${})에서 사용할 수 있는 값은 문자열, 정수, 부동소수점, 참거짓(Boolean), 널(Null)이 가능하다.
// EL 표현식 + 실행결과
블록 값 | 내용 | 블록 값 | 실행결과 |
문자열 | ${"test"} | 문자열 | test |
문자열 | ${'test'} | 문자열 | test |
정수 | ${20} | 정수 | 20 |
부동소수점 | ${3.14} | 부동소수점 | 3.14 |
참거짓 | ${true} | 참거짓 | true |
null | ${null} | null | 빈 문자열 |
- 값 표현식
자바 객체, 배열, List, Map으로 부터 값을 꺼낼 때 사용하는 EL 표현식을 알아보면
① 배열에서 값 꺼내기
ex) EL 표현식
<% // 값 준비
pageContext.setAttribute("scores", new int[] {90, 80, 70, 100}); // 배열 생성 하면서 초기화 한 것
%>
<%-- 배열에서 인덱스 2의 값 꺼내기 --%>
${scores[2]} // 실행결과 : 70
② List 객체에서 값 꺼내기
ex) EL 표현식
<% // 값 준비
List<String> nameList = new LinkedList<String>();
nameList.add("홍길동");
nameList.add("임꺽정");
nameList.add("일지매");
pageContext.setAttribute("nameList", nameList);
%>
<%-- 리스트 객체에서 인덱스 1의 값 꺼내기 --%>
${nameList[1]} // 실행결과 : 임꺽정
③ Map 객체에서 값 꺼내기
ex) EL 표현식
<% // 값 준비
Map<String, String> map = new HashMap<String, String>();
map.put("s01", "홍길동"); // key, value
map.put("s02", "임꺽정");
map.put("s03", "일지매");
pageContext.setAttribute("map", map);
%>
<%-- 맵 객체에서 키 s02로 저장된 값 꺼내기 --%>
${map.s02} // 실행결과 : 임꺽정
# 연산자
연산부호 | 연산자 | 기능 |
+ | + | 숫자 덧셈 |
- | - | 숫자 뺄셈 |
* | * | 숫자 곱셈 |
/ | / | 숫자 나눗셈 |
&& | and | 논리연산자 AND |
|| | or | 논리연산자 OR |
== | eq | 동일 |
!= | ne | 다름 |
< | gt(Greater than) | 큼 |
> | lt(Less than) | 작음 |
<= | ge(Greater or equal) | 이상 |
>= | le(Less or equal) | 이하 |
empty | 객체가 값이 없는지 구분 | |
func(파라미터) | 함수 호출 | |
! | not | 값을 반대로 만듬 ture → false false → true |
% | mod | 나머지 값을 구함 |
.(온점) | bin의 property나 Map의 entry 접근 |
|
[ ] | 배열이나 리스트 엘리먼트 접근 | |
( ) | 괄호, 표현식의 연산순서를 바꿔서 연산하게 할 때 |
EL 블록에서도 간단한 연산을 수행할 수 있다.
EL에서 제공하는 연산자 중 몇몇은 기호뿐만 아니라 동일한 기능의 영문으로 된 연산자도 있다.
다음은 EL에서 지원하는 주요 연산자에 대한 설명이다.
① 산술 연산자 : 더하기(+), 빼기(-), 곱하기(*), 나누기(/, div), 나머지(%, mod)
// div, mod는 소스 가독성을 위해 있는 것
ex) EL 표현식
// Tip : ${' 앞에 '\'가 붙으면 '${'은 EL 문법이 아닌 일반 텍스트로 취급한다.
\${10 + 20} = ${10 + 20} <br/>
\${10 - 20} = ${10 - 20} <br/>
\${10 * 20} = ${10 * 20} <br/>
\${10 / 20} = ${10 / 20} <br/>
\${10 div 20} = ${10 div 20} <br/>
\${10 % 20} = ${10 % 20} <br/>
\${10 mod 20} = ${10 mod 20} <br/>
실행결과
${10 + 20} = 30
${10 - 20} = -10
${10 * 20} = 200
${10 / 20} = 0.5
${10 div 20} = 0.5
${10 % 20} = 10
${10 mod 20} = 10
② 논리 연산자 : AND(&&, and), OR(||, or) NOT(!, not)
ex) EL 표현식
\${true && false} = ${true && false}<br/>
\${true and false} = ${true and false}<br/>
\${true || false} = ${true || false}<br/>
\${true or false} = ${true or false}<br/>
\${not true} = ${not true}<br/>
\${!true} = ${!true}<br/>
실행결과
${true && false} = false
${true and false} = false
${true || false} = true
${true or false} = true
${not true} = false
${!true} = false
③ 관계 연산자 : 같다(==, eq), 같지 않다(!=, ne), 크다(>, gt), 작다(<, lt), 크거나 같다(>=, ge), 작거나 같다(<=, le)
ex) EL 표현식
\${10 == 11} = ${10 == 11} <br/>
\${10 eq 11} = ${10 eq 11} <br/>
\${10 != 11} = ${10 != 11} <br/>
\${10 ne 11} = ${10 ne 11} <br/>
\${10 < 11} = ${10 < 11} <br/>
\${10 lt 11} = ${10 lt 11} <br/>
\${10 > 11} = ${10 > 11} <br/>
\${10 gt 11} = ${10 gt 11} <br/>
\${10 <= 11} = ${10 <= 11} <br/>
\${10 le 11} = ${10 le 11} <br/>
\${10 >= 11} = ${10 >= 11} <br/>
\${10 ge 11} = ${10 ge 11} <br/>
실행결과
${10 == 11} = false
${10 eq 11} = false
${10 != 11} = true
${10 ne 11} = true
${10 < 11} = true
${10 lt 11} = true
${10 > 11} = false
${10 gt 11} = false
${10 <= 11} = true
${10 le 11} = true
${10 >= 11} = false
${10 ge 11} = false
④ empty : 값이 비어 있거나 null인지를 조사할 때 사용하는 연산자
값이 null이면 true를 반환한다.
또한, 문자열과 배열, Map, Collection 객체의 크기가 0인 경우에도 true를 반환한다.
그 밖에는 false를 반환한다.
ex) EL 표현식
<% // 값 준비
pageContext.setAttribute("title" "EL 연산자!");
%>
<%-- 자바빈에서 프로퍼티 email의 값 꺼내기 --%>
\${empty title} = ${empty title}<br/>
\${empty title2} = ${empty title2}<br/>
실행결과
${empty title} = false
${empty title2} = true
⑤ 조건 : 자바의 조건 연산자(삼항연산자)와 쓰임이 같다.
'A ? B : C'에서 A 조건이 참이면 B를 실행하고, A 조건이 거짓이면 C 조건을 실행합니다.
ex) EL 표현식
\${10 > 20 ? "크다" : "작다"} = ${10 > 20 ? "크다" : "작다"}
실행결과
${10 > 20 ? "크다" : "작다"} = 작다
# 예약 키워드
다음은 EL에서 사용하거나 사용하기로 예약한 키워드이다.
and, or, not, eq, ne, lt, ge, true, false, null, instanceof, empty, div, mod
JspContext나 SevletRequest, HttpSession, ServletContext 보관소에 객체를 저장할 때,
그 식별자(키)는 EL의 예약 키워드 이름과 같아서는 안 된다.
EL을 사용하지 않는다면 문제가 되지 않겠지만, EL을 사용한다면 오류가 발생할 것이다.
다음 예제는 객체 식별자의 이름이 예약 키워드의 이름과 같을 때, 오류가 발생하는 것을 보여준다.
ex) EL 표현식
<% // 값 준비
pageContext.setAttributte("ne", "오호라!");
%>
<%-- pageContext에서 값 꺼내기 --%>
${ne}
<%-- 예약어를 써서 오류남 --%>
# 서블릿 초기값 : 특정 서블릿에 초기값을 주는 것
- web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
<display-name>InitTest</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
<servlet>
<servlet-name>InitTest</servlet-name>
<servlet-class>com.superman.ex.InitTest</servlet-class>
<init-param>
<param-name>startNum</param-name>
<param-value>1</param-value>
</init-param>
<init-param>
<param-name>endNum</param-name>
<param-value>100</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>InitTest</servlet-name>
<url-pattern>/InitTest</url-pattern>
</servlet-mapping>
</web-app>
ex) 1부터 100까지의 합 구하기
package com.superman.ex;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
//@WebServlet("/InitTest")
public class InitTest extends HttpServlet {
private static final long serialVersionUID = 1L;
public InitTest() {
super();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String startNumStr = getInitParameter("startNum"); // 1
String endNumStr = getInitParameter("endNum"); // 100
int startNum = Integer.parseInt(startNumStr); // 문자열을 숫자로 형변환하는 것
int endNum = Integer.parseInt(endNumStr);
int sum = 0;
for(int i=startNum;i<=endNum;i++){
sum += i;
}
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
out.println("<!DOCTYPE html>");
out.println("<html>");
out.println("<body>");
out.println("합은 : " + sum);
out.println("</body>");
out.println("</html>");
}
}
- web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
<display-name>InitTest2</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
<servlet>
<servlet-name>Test3Servlet</servlet-name>
<servlet-class>com.superman.ex.Test3Servlet</servlet-class>
<init-param>
<param-name>start</param-name>
<param-value>1</param-value>
</init-param>
<init-param>
<param-name>end</param-name>
<param-value>10</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>Test3Servlet</servlet-name>
<url-pattern>/Test3Servlet</url-pattern>
</servlet-mapping>
</web-app>
ex)
package com.superman.ex;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
//@WebServlet("/Test3Servlet")
public class Test3Servlet extends HttpServlet {
private static final long serialVersionUID = 1L;
public Test3Servlet() {
super();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
ServletConfig config = this.getServletConfig();
//ServletConfig 객체를 획득한다.
//실제로는 HttpServlet이 ServletConfig를 구현했기 때문에
//이렇게 객체를 획득할 필요 없이 this를 사용해도 무방하다.
String start = config.getInitParameter("start");
String end = this.getInitParameter("end");
//config 객체를 통해서도 this를 통해서도 초기화 매개변수를 획득할 수 있다.
int startNumber = Integer.parseInt(start);
int endNumber = Integer.parseInt(end);
//초기화 매개변수로 전달된 값은 문자열이므로 숫자로 변환한다.
int sum = 0;
for(int i = startNumber; i <= endNumber; ++i)
sum += i;
//시작 수에서 끝 수까지의 총합을 구한다.
response.setContentType("text/html;charset=UTF-8");
//응답에 대한 MIME과 Encode를 설정한다.
PrintWriter out = response.getWriter();
//출력 객체를 생성한다.
out.println("<html><body><center>");
out.println(startNumber + " ~ " + endNumber + "사이의 합은 ");
out.println(sum + "입니다.");
out.println("</center></body></html>"); // HTML5는 <center> 태그 사라짐
//결과를 출력한다.
out.close();
//출력 객체를 종료한다.
}
}
- web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" id="WebApp_ID" version="4.0">
<display-name>InitTest3</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
</web-app>
ex)
package com.superman.www;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebInitParam;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet(
urlPatterns = { "/InitTest3" },
initParams = {
@WebInitParam(name = "start", value = "1"), // 초기값 설정
@WebInitParam(name = "end", value = "10")
})
public class InitTest3 extends HttpServlet {
private static final long serialVersionUID = 1L;
public InitTest3() {
super();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
ServletConfig config = this.getServletConfig();
//ServletConfig 객체를 획득한다.
//실제로는 HttpServlet이 ServletConfig를 구현했기 때문에
//이렇게 객체를 획득할 필요 없이 this를 사용해도 무방하다.
String start = config.getInitParameter("start");
String end = this.getInitParameter("end");
//config 객체를 통해서도 this를 통해서도 초기화 매개변수를 획득할 수 있다.
int startNumber = Integer.parseInt(start);
int endNumber = Integer.parseInt(end);
//초기화 매개변수로 전달된 값은 문자열이므로 숫자로 변환한다.
int sum = 0;
for(int i = startNumber; i <= endNumber; ++i)
sum += i;
//시작 수에서 끝 수까지의 총합을 구한다.
response.setContentType("text/html;charset=UTF-8");
//응답에 대한 MIME과 Encode를 설정한다.
PrintWriter out = response.getWriter();
//출력 객체를 생성한다.
out.println("<html><body><center>");
out.println(startNumber + " ~ " + endNumber + "사이의 합은 ");
out.println(sum + "입니다.");
out.println("</center></body></html>");
//결과를 출력한다.
out.close();
//출력 객체를 종료한다.
}
}
// Tip : eclipse에서 servlet 생성 시 Initialization parameters 추가하는 법
# ContextParam : 모든 서블릿이 공유하는 초기값을 주는 것
Q.
① ErrorTest.htm 파일을 만든다.
② 그 안에 input text를 두 개를 만들고 각각 숫자 두 개를 입력 받도록 하자.
③ 그리고 나누기라는 버튼을 누르면 ErrorServlet 으로 이동을 해서 결과 값을 출력하도록 하자.
④ 숫자 대신 글자가 입력이 되었을 때 에러코드를 510, “정수를 입력하지 않은 오류!”라고 출력하도록 하고,
제수가 0일때 에러코드 511, “부적합 연산 관련 오류!”라고 출력하도록 하자.
A.
- web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
<display-name>ContextParamTest</display-name>
<context-param> // context 내 요소
<param-name>companyName</param-name>
<param-value>좋은회사</param-value>
</context-param>
<context-param>
<param-name>companyTel</param-name>
<param-value>012-3456-7890</param-value>
</context-param>
<context-param>
<param-name>companyEmail</param-name>
<param-value>goodCompany@good.com</param-value>
</context-param>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
</web-app>
- ContextParamTest.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="description" content="HTML Study">
<meta name="keywords" content="HTML,CSS,XML,JavaScript">
<meta name="author" content="Bruce">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Insert title here</title>
</head>
<body>
<%
String companyName = application.getInitParameter("companyName"); // getInitParameter는 application 클래스 내 존재하기 때문
%>
<%= companyName %>
</body>
</html>
- ContextParamTest2.java
package com.superman.ex;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet("/ContextParamTest2")
public class ContextParamTest2 extends HttpServlet {
private static final long serialVersionUID = 1L;
public ContextParamTest2() {
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
response.setCharacterEncoding("UTF-8");
ServletContext context = getServletContext(); // 해당 메소드 내 context-param 존재함
String companyName = context.getInitParameter("companyName");
String companyTel = context.getInitParameter("companyTel");
String companyEmail = context.getInitParameter("companyEmail");
PrintWriter out = response.getWriter();
out.println("<!DOCTYPE html>");
out.println("<html>");
out.println("<head>");
out.println("<meta charset='UTF-8'>");
out.println("</head>");
out.println("<body>");
out.println("<h2>" + companyName + "</h2>");
out.println("<h2>" + companyTel + "</h2>");
out.println("<h2>" + companyEmail + "</h2>");
out.println("</body>");
out.println("</html>");
}
}
# 테이블 정보 보기 // 데이터베이스 정보 - 보안성을 위함
- web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
id="WebApp_ID" version="3.1">
<display-name>TableInfo</display-name>
<servlet>
<servlet-name>TableInfoForm</servlet-name>
<jsp-file>/TableInfoForm.jsp</jsp-file>
<init-param>
<param-name>driver</param-name>
<param-value>com.mysql.cj.jdbc.Driver</param-value>
</init-param>
<init-param>
<param-name>url</param-name>
<param-value>jdbc:mysql://localhost:3306/testdb?serverTimezone=UTC</param-value>
</init-param>
<init-param>
<param-name>user_id</param-name>
<param-value>root</param-value>
</init-param>
<init-param>
<param-name>user_pw</param-name>
<param-value>1234</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>TableInfoForm</servlet-name>
<url-pattern>/TableInfoForm</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
</web-app>
- TableInfoForm.jsp
<%@page import="java.sql.*"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<script>
//테이블 명은 반드시 입력해야 하기 때문에 공백 체크를 한다.
function check_form() { // 에러 체크 함수
var table_name = myform.table_name.value;
if(table_name == '') {
alert('테이블 명은 반드시 입력해야 합니다.');
myform.table_name.focus();
return false;
}
}
</script>
<meta charset="UTF-8">
<meta name="description" content="HTML Study">
<meta name="keywords" content="HTML,CSS,XML,JavaScript">
<meta name="author" content="Bruce">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Insert title here</title>
</head>
<body>
<h2>테이블 정보 출력!</h2>
<%
//GET 방식으로 호출 될 때에는 테이블을 검색할 수 있는 화면만 표시한다.
if(request.getMethod().equalsIgnoreCase("GET")) { // 대소문자를 무시하고 같은지 같지 않은지 판단하는 것
%>
<form name='myform' method='post' onSubmit='return check_form()'>
<table>
<tr>
<th width='100' align='right'>테이블명</th>
<td><input type='text' name='table_name' size='30'/></td>
</tr>
<tr>
<th width='100' align='right'>조건절</th>
<td><input type='text' name='table_where' size='30'/></td>
</tr>
<tr>
<td colspan='2' align='right'>
<input type='submit' value='테이블 정보 획득'/>
</td>
</tr>
</table>
</form>
<%
//POST 방식으로 호출이 되면
} else if(request.getMethod().equalsIgnoreCase("POST")) {
//요청한 테이블 이름과 조건절의 값을 가져온다.
String table_name = request.getParameter("table_name");
String table_where = request.getParameter("table_where");
if(table_where == null) table_where = "";
%>
<form name='myform' method='post' onSubmit='return check_form()'>
<table>
<tr>
<th width='100' align='right'>테이블명</th>
<td><input type='text' name='table_name' size='30' value='<%= table_name %>'/></td>
</tr>
<tr>
<th width='100' align='right'>조건절</th>
<td><input type='text' name='table_where' size='30' value='<%= table_where %>'/></td>
</tr>
<tr>
<td colspan='2' align='right'>
<input type='submit' value='테이블 정보 획득'/>
</td>
</tr>
</table>
</form>
<%
//config 디폴트 객체를 통해 web.xml에 지정된 초기화 매개변수의
//값들을 읽어온다.
String driver = config.getInitParameter("driver");
String url = config.getInitParameter("url");
String user_id = config.getInitParameter("user_id");
String user_pw = config.getInitParameter("user_pw");
Connection conn = null;
try {
//DB를 연동할 때 해당 변수의 값들로 설정한다.
Class.forName(driver);
conn = DriverManager.getConnection(url, user_id, user_pw);
String query = "SELECT * FROM " + table_name;
//조건절이 있다면 query에 추가한다.
if(table_where != null && table_where.trim().length() != 0)
query += " " + table_where;
Statement stmt = conn.createStatement();
//쿼리 수행 결과 셋을 가져온다.
ResultSet rs = stmt.executeQuery(query);
//결과 셋으로 가져온 내용의 Header를 획득한다.
//헤더의 메타 정보는 Column_Name, Column_Type 등이 있다.
ResultSetMetaData rsmd = rs.getMetaData();
%>
<table border='1'>
<tr>
<%
//메타 정보를 통해 Column_Name을 먼저 출력한다.
for(int i = 1; i <= rsmd.getColumnCount(); ++i) {
out.println("<td>" + rsmd.getColumnName(i) + "</td>");
}
%>
</tr>
<%
//결과 셋을 통해 각 Column별 데이터들을 추출한다.
//여기서 나머지 자료형들은 전부 getString() 으로 추출할 수 있지만
//Date 관련 값은 반드시 getDate() 라고 추출해야 오류가 없다.
while(rs.next()) {
out.println("<tr>");
for(int i = 1; i <= rsmd.getColumnCount(); ++i) {
//해당 Column의 Type이 Date Type 인지의 여부를 확인한다.
if(rsmd.getColumnTypeName(i).equalsIgnoreCase("Date"))
out.println("<td>" + rs.getDate(i) + "</td>");
else
out.println("<td>" + rs.getString(i) + "</td>");
}
out.println("</tr>");
}
%>
</table>
<%
}catch(Exception ex) {
out.println("ERROR : " + ex.getMessage() + "<br/><br/>");
}finally{
if(conn != null) conn.close();
conn = null;
}
}
%>
</body>
</html>
# Header
- HeaderForm.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<form method="POST" action="HeaderForm">
★ 이름 : <input type="text" name="name"/><br/>
★ 보유 SKIL을 모두 선택하세요!<br/>
<input type="checkbox" name="skil" value="c"/>C<br/>
<input type="checkbox" name="skil" value="c++"/>C++<br/>
<input type="checkbox" name="skil" value="java"/>JAVA<br/>
<input type="checkbox" name="skil" value="jsp"/>JSP<br/>
<input type="submit" value="전송"/>
</form>
</body>
</html>
- HeaderForm.java
package com.superman.ex;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Enumeration;
import java.util.Vector;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet("/HeaderForm")
public class HeaderForm extends HttpServlet {
private static final long serialVersionUID = 1L;
public HeaderForm() {
super();
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("UTF-8");
//한글 인코드 설정
String name = request.getParameter("name");
//name 이라는 객체명으로 전송된 데이터를 획득
String[] skils = request.getParameterValues("skil");
//skil 이라는 객체명으로 전송된 데이터를 획득
//단, 여러 개의 데이터가 같은 이름으로 전송될 수 있기 때문에
//getParameterValues()를 이용해 배열로 획득
Enumeration enu = request.getHeaderNames();
//헤더 정보의 이름 값들을 모두 획득
Vector names = new Vector();
//헤더 정보의 이름을 모두 담기 위한 객체 선언
Vector values = new Vector();
//헤더 정보의 이름에 대한 값들을 모두 담기 위한 객체 선언
while(enu.hasMoreElements()) { // hasNext()와 동일한 의미
String header_name = (String)enu.nextElement();
//헤더 이름들 중 하나를 추출해서
String header_value = request.getHeader(header_name);
//헤더 이름에 담겨있는 값을 추출.
names.add(header_name);
values.add(header_value);
//헤더의 이름과 값을 각각의 Vector 영역에 보관
}
response.setContentType("text/html;charset=euc-kr");
//응답에 대한 MIME과 Encode를 설정
PrintWriter out = response.getWriter();
out.println("<html><body>");
out.println("★ 전달받은 데이터들 ★<br/>");
out.println("name : " + name + "<br/>");
out.println("skil : ");
for(int i = 0; i < skils.length; ++i) {
out.println(skils[i] + " ");
}
out.println("<br/><br/><br/><br/>");
out.println("★ 전달받은 헤더 정보들 ★<br/>");
for(int i = 0; i < names.size(); ++i) { // 전체 헤더 네임 갯수만큼 반복
String header_name = (String)(names.elementAt(i));
String header_value = (String)(values.elementAt(i));
out.println(header_name + " : ");
out.println(header_value + "<br/>");
}
//헤더의 정보를 출력하는 코드
out.println("</body></html>");
out.close();
}
}
- HeaderRe.java
package com.superman.ex;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet("/HeaderRe")
public class HeaderRe extends HttpServlet {
private static final long serialVersionUID = 1L;
private int cnt = 0;
public HeaderRe() {
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html;charset=euc-kr");
response.setHeader("refresh", "3");
//헤더 속성 중 페이지를 갱신하는 refresh라는 속성을
//3초 라는 시간값을 주어 설정해 두면
//3초에 한번씩 페이지를 갱신한다.
PrintWriter out = response.getWriter();
out.println("<html><body>");
out.println("cnt = " + cnt++);
//cnt의 값 변화를 통해 페이지가 reload되는 것을 확인한다.
out.println("</body></html>");
out.close();
}
}
// HTTP 헤더
① 일반 헤더(서버 ↔ 클라이언트) : 클라이언트, 서버 양쪽 모두 사용
헤더 | 설명 |
Connection | 클라이언트와 서버가 요청/ 응답 연결에 대한 옵션을 정할 수 있게 해줌 |
Date | 메시지가 언제 만들어졌는지 날짜와 시간 제공 |
MIME-Version | 발송자가 사용한 MIME 버전 알려줌 |
Trailer chunked transfer | 인코딩된 메시지 끝부분에 위한 헤더 목록 나열해줌 |
Transfer-Encoding | 수신자에게 메시지에 어떤 인코딩이 적용되었는지 말해줌 |
Upgrade | 발송자가 업그레이드 하길 원해는 새 버전이나 프로토콜 알려줌 |
Via | 이 메시지가 어떤 중개자(프락시, 게이트웨이)를 거쳐 왔는지 보여줌 |
Cache-Control | 메시지와 함께 캐시 지시자를 전달하기 위해 사용 |
② 요청 헤더(클라이언트 → 서버) : 요청 메시지를 위한 헤더로 서버에게 클라이언트가 부가정보 제공
헤더 | 설명 |
GET | 지정된 리소스(URI) 요청 |
POST | 서버 : 클라이언트의 폼 입력 필드 데이터의 수락 요청함 클라이언트 : 서버로 HTTP body에 Data 전송 |
HEAD | 문서의 헤더 정보만 요청 body 응답 데이터를 받지 않음 |
PUT | 서버 : 클라이언트가 전송한 데이터를 지정한 URI로 대체 클라이언트 : 서버로 HTTP body에 Data 전송 |
DELETE | 클라이언트가 지정한 URI를 서버에서 삭제 |
TRACE | 클라이언트가 요청한 자원에 도달하기까지의 경로 기록하는 루프백의 검사용 클라이언트가 요청 자원에 도달하기까지 거쳐가는 프록시나 게이트웨이의 중간 경로부터 최종 수진 서버까지의 경로를 알아낼 때 사용 |
Accept | 클라이언트가 허용할 수 있는 파일 형식 */* : 모든 파일 형식 지원 의미 |
User-Agent | 요청을 보낸 어플리케이션의 이름을 서버에 알려줌 |
Host | 요청의 대상이 되는 서버의 호스트명과 포트 줌 |
If-Modified-Since | 주어진 날짜 이후에 리소스가 변경되지 않은 경우 요청 제한 |
Refer | 현재의 요청 URI가 들어있던 문서의 URL 제공 |
Cookie | 클라이언트가 서버에게 토큰을 전달할 때 사용 (쿠키 헤더는 RFC 2616에 정의되어 있지 않음) |
Accept-Language | 클라이언트가 인식할 수 있는 언어 우선 순위 지정 가능 |
Accept-Encoding | 클라이언트가 인식할 수 있는 인코딩 방법 서버에서 gzip, deflate로 압축한 리소스를 클라이언트가 해석할 수 있다는 뜻 서버에서 압축한 경우 응답헤더에 Content-Encoding 헤더에 해당 압축 방법 명시됨 |
③ 응답 헤더 (서버 → 클라이언트) : 클라이언트에 부가 정보 보내줌
헤더 | 설명 |
GET | 지정된 리소스(URI) 요청 |
Server | 서버 어플리케이션의 이름, 버전 나타냄 |
Date | 메시지가 언제 만들어졌는지 날짜, 시간 제공 |
Content-Type | 이 본문이 어떤 종류의 객체인지 정보 제공 |
Last-Modified | 요청한 파일의 최종 수정일 나타냄 |
Content-Length | 헤더 이후 이어지는 데이터 길이 (바이트 단위) |
ETag | 캐시 업데이트 정보를 위한 임의의 식별 숫자 |
④ 엔터티 헤더 : 엔터티 본문에 대한 헤더
요청과 응답 양쪽 모두 엔터티를 포함할 수 있기 때문에 양 타입의 메시지에 모두 나타날 수 있음
헤더 | 설명 |
Allow | 이 엔터티에 대해 수행될 수 있는 요청 메소드 나열 |
Location | 클라이언트에게 엔터티가 실제로 어디에 위치하고 있는 말해줌 수신자에게 리소스에 대한 위치(URL) 알려줄 때 사용 |
Content-Length | 헤더 이후 이어지는 데이터 길이 (바이트 단위) |
ETag | 캐시 업데이트 정보를 위한 임의의 식별 숫자 |
⑤ 확장 헤더 : 어플리케이션 개발자들이 만들었지만 승인된 HTTP 명세에 추가되지 않은 비표준 헤더
+ URL의 RFC 명세
www.w3.org/Protocols/rfc2616/rfc2616-sec14.html
// MIME
// MediaType
// 엔터티의 미디어타입
// content-type, pageEncoding을 사용한 인코딩
// https://stickyny.tistory.com/90
'Web > JSP' 카테고리의 다른 글
[실습문제] Day85 - varStatus, enctype, MIME, LOG, 파일업로드(cos) 등 (0) | 2020.10.27 |
---|---|
[필기정리] Day84-2 - EL 문제, JSTL 등 (0) | 2020.10.26 |
[필기정리] Day83 - MIME, Proxy server, http 응답코드 등 (0) | 2020.10.26 |
[실습문제] Day81 - MVC Model2 문제 및 해답 (0) | 2020.10.22 |
[필기정리]Day79-2 - MVC(Model, View, Controller) (0) | 2020.10.22 |