서블릿 리스너

 

 

 

 


서블릿 리스너 동작 구조


 

 

 

 

 

 

 

 

 

서블릿 리스너

 

 

 

 


서블릿 리스너란?


서블릿 리스너란, 웹 컨테이너가 관리하는 라이프 사이클 사이에 발생하는 이벤트를 감지하여 해당 이벤트가 발생 시 해당 이벤트에 대한 일련의 로직을 처리하는 인터페이스를 말한다.

 


서블릿 이벤트 사용 용도


  • 1. 웹 컨텍스트가 초기화되는 경우
  • 2. 세션이 생기거나 소멸되는 경우
  • 3. 요청 정보의 속성이 바뀌는 경우

 

 

 

 


서블릿 이벤트 리스너 종류


1. ServletContextListener

- 웹 애플리케이션의 시작과 종료 시 자동으로 발생하는 이벤트

 

2. ServletContextAttributeListener

- 웹 컨테이너에 저장된 속성의 값이 변경될 경우 발생하는 이벤트

 

3. HttpSessionListener

- HTTP 세션이 생성되거나 종료되는 시점에 발생하는 이벤트

 

4. HttpSessionAttributeListener

- HTTP 세션에 대한 속성의 값이 변경될 경우 발생하는 이벤트

 

5. HttpSessionActivationListener

- HTTP 세션이 활성화 또는 비활성화가 발생하려 할 때 감지

 

6. HttpSessionBindingListener

- 현재 세션에 객체가 추가되거나 해제될 때 발생하는 이벤트

 

 

 

 

 

 

 

 

 


ServletContextListener


 

 

 

 

 

 

 

 

ServletContextAttributeListener


 

 

 

 

 

HttpSessionListener


 

 

 

 

 

HttpSessionAttributeListener


 

 

 

 

HttpSessionActivationListener


 

 

 

 

 

HttpSessionBindingListener


 

 

 

 

 

 

 

 

 

 

'Programming > Servlet&JSP' 카테고리의 다른 글

8. JSP(Java Server Page) (2)  (0) 2022.03.07
8. JSP(Java Server Page) (1)  (0) 2022.03.07
6. 서블릿 필터와 래퍼  (0) 2022.03.03
5. Session과 Cookie  (0) 2022.03.03
4. 서블릿 메소드  (0) 2022.02.28

 

 

 

 

 

 

서블릿 필터 동작 구조

 

 

 

 

 

 

 

서블릿 필터 동작 구조


 

 

 

 

 

서블릿 필터 내부동작


 

 

 

 

 

 

 

 

 

서블릿 필터

 

 


서블릿 필터란?


  • javax.servlet.Filter 인터페이스를 상속 받아 구현하는 클래스
  • HTTP 요청과 응답 사이에서 전달되는 데이터를 가로채어 서비스에 맞게 변경하고 걸러내는 필터링 작업을 수행할 수 있는 클래스이다.
-> Servlet과 비슷한 모습을 보임 (init, destroy, doFilter)

 

 

 

 

 

처리내용


  • Request : 보안관련사항, 요청헤더와 바디 형식지정, 요청에 대한 log기록 유지
  • Response : 응답 스트림압축, 응답스트림 내용 추가 및 수정, 새로운 응답 작성
  • 여러 가지 필터를 연결(chain / 서로 호출)하여 사용가능

 

 

 

 

 

 

 

 

 

 

 

서블릿 필터

 

 

 

 


DD설정(web.xml)


 

  • Filter등록
    <filter>
        <filter-name>필터설정이름</filter-name>
        <filter-class>필터를 구현한 클래스</filter-class>
        <init-param> // filter에서 사용할 값 설정
            <param-name>초기값설정이름</param-name>
            <param-value>설정값</param-value>
        </init-param>
    </filter>

 

 

  • Filter-Mapping(url패턴과 매핑)
    <filter-mapping>
        <filter-name>등록된 필터이름</filter-name>
        <url-pattern>요청한 페이지 형식</url-pattern>
    </filter-mapping>



  • 서블릿과 필터 맵핑(필터 적용 서블릿지정)
    <filter-mapping>
        <filter-name>등록된 필터이름</filter-name>
        <servlet-name>적용할 서블릿명</servlet-name>
    </filter-mapping>

 

   * * 매핑하는방법이 두가지 / url-pattern이 우선적용

 

 

 

 

 

클래스 설정(java코드)


    public class 클래스명 implements Filter {
        @Override
        public void init(FilterConfig config) throws ServletException
        { Filter호출시 작업 설정 }

        @Override
        public void doFilter(ServletRequest req, ServletResponse resp,
                 FilterChain chain) throws ServletException, IOException
        { 필터링 작업할 내용 }

        @Override
        public void destroy()
        { 삭제시 작업 설정 }

    }



 

 

 

 

Filter Interface


 

init(FilterConfig config);

  • 웹 컨테이너가 필터를 호출할 경우 해당 메소드가 호출되어 필터 객체를 생성하며 초기화한다.
  • 매개변수 FilterConfig는 web.xml에 있는 <filter>정보를 가지고 있음.


doFilter(ServletRequest req, ServletResponse res, FilterChain chain)

  • 필터가 수행될 때 구동하는 메소드로
  • 요청 객체와 응답 객체를 사용해 일련의 작업을 수행한 뒤, chain을 통해 가공된 값을 목적지로 전송한다.


destroy();

  • 역할이 끝난 필터는 웹 컨테이너에 의해 해당 메소드를 호출하고 소멸된다.

 

 

 

 

 

 

예제


 

CharsetEncodingFilter Class

 

 

 

 

 

 

 

예제


 

작성한 Filter를 web.xml 에 등록한다.

 

 

 

 

 

 

 

 

 

 

 

서블릿 필터 참고

 

 

 

FilterChain (interface)


  • 필터는 chain처럼 서로 연결되어 있는데 연결 되어있는 필터를 순차별로 doFilter() 매소드를 이용하여 실행시키는 인터페이스
  • 마지막 필터가 실행 된 후에는 service() 매소드를 실행시켜 서블릿의 매소드 (doGet(), doPost())를 실행

 


doFilter(ServletRequest req, ServletResponse)

  • chain으로 연결되어있는 다음 필터를 실행하는 매소드

 

 

 

 

 

 

dispatcher처리


2.4버전부터 dispatcher의 요청도 필터를 적용할 수 있음.

 


Filter-Mapping(url패턴과 매핑)

    <filter-mapping>
    
        <filter-name>등록된 필터이름</filter-name>
        <url-pattern>요청한 페이지 형식</url-pattern>
        
    <dispatcher>
        REQUEST || INCLUDE || FORWARD || ERROR
    </dispatcher>

    </filter-mapping>



 

 

 

 

 

 

 

 

 

 

 

서블릿 필터와 래퍼

 

 

 


서블릿 래퍼란?


  • 관련 클래스(ServletRequest, ServletResponse, HttpServletRequest, HttpServletResponse)를 내부에 보관하며 그 인터페이스들을 구현하고 있는 객체를 참조하여 구현 매소드를 위임(구현이 되어있다는 의미)
  • 랩퍼 클래스를 상속하면 필요한 매소드만 재정의하여 사용가능
  • 즉, java Event처리의 Adapter클래스와 비슷한 기능
  • 사용자가 별도의 request나 response 객체를 생성하여 활용할 때 랩퍼 클래스를 상속하여 활용하면 편하게 원하는 클래스만 재정의하여 사용 가능

 

 

 

 

 

 

서블릿 필터와 래퍼

 

 


Wrapper Class


 

HttpServletRequestWrapper

  • 요청한 정보를 변경하는 Wrapper 클래스
  • HttpServletRequest 객체를 매개로 하는 생성자를 가진다.
    public SampleWrapper(HttpServletRequest wrapper) {
         super(wrapper);
    }

 

 

 

 


HttpServletResponseWrapper

  • 응답할 정보를 변경하는 Wrapper 클래스
  • HttpServletResponse 객체를 매개로 하는 생성자를 가진다.
    public SampleWrapper(HttpServletResponse wrapper) {
        super(wrapper);
    }



 

 

 

 

▼ 코드 예시 보기 ▼

 

 

filter

 

index.html

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>filter</title>
</head>
<body>
	<h1 align="center">Filter</h1>
	<h3>필터의 라이프 사이클</h3>
	<ul>
		<li><a href="first/filter">Filter 사용하기</a></li>
	</ul>
	
	<hr>
	
	<h3>필터의 활용</h3>
	<form action="member/regist" method="post">
		<label>아이디 : </label>
		<input type="text" name="userId">
		<br>
		<label>비밀번호 : </label>
		<input type="password" name="password">
		<br>
		<label>이름 : </label>
		<input type="text" name="name">
		<br>
		<button type="submit">가입하기</button>
	</form>
	
	
	
	
	
	
	
	
	
</body>
</html>

 

 

FirstFilter implements Filter 


import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;

@WebFilter("/first/*")
public class FirstFilter implements Filter {

    public FirstFilter() {
        /* 기본 생성자 */
    	System.out.println("FirstFilter 인스턴스 생성!");
    }

	public void destroy() {
		/* 필터 인스턴스가 소멸될 때 호출 되는 메소드 (톰캣 종료 시) */
		System.out.println("filter destory 호출");
	}

	public void doFilter(ServletRequest request, ServletResponse response, 
    FilterChain chain) throws IOException, ServletException {
		/* Servlet으로 request가 전달 되기 전에 요청을 가로채는 역할을 하는 메소드 */
		System.out.println("filter doFilter 호출");
		
		/* request, response의 가공을 처리하기 위해서는 여기에 코드를 작성한다. */
		
		/* 위에서 뭔가 처리를 한 뒤 다음 필터 혹은 서블릿의 
        service(doGet/doPost)를 호출한다. */
		chain.doFilter(request, response);
		
		/* 서블릿에서 처리 후에 다시 수행할 내용이 있으면 작성한다 */
		System.out.println("서블릿 요청 처리 완료!");
	}


	public void init(FilterConfig fConfig) throws ServletException {
		/* 필터 인스턴스가 최초 생성 될 때 호출되는 메소드 */
		System.out.println("filter init 호출");
	}

}

 

 

FirstFilterTestServlet extends HttpServlet 


import java.io.IOException;
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("/first/filter")
public class FirstFilterTestServlet extends HttpServlet {
	
	protected void doGet(HttpServletRequest request, HttpServletResponse response) 
    throws ServletException, IOException {
		System.out.println("서블릿 요청 확인");
	}

	

}

 

 

 EncodingFilter implements Filter


import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;

/* 필터 등록은 xml에서 설정 */
public class EncodingFilter implements Filter {
	
	private String encodingType;
   
	public void doFilter(ServletRequest request, ServletResponse response, 
    FilterChain chain) throws IOException, ServletException {
		
		HttpServletRequest hrequest = (HttpServletRequest) request;
		if("POST".equals(hrequest.getMethod())) {
			request.setCharacterEncoding(encodingType);
		}
		
		chain.doFilter(request, response);
	}

	public void init(FilterConfig fConfig) throws ServletException {
		/* xml에서 설정한 init-param의 key를 이용하여 fConfig에서 값을 꺼내올 수 있다. */
		encodingType = fConfig.getInitParameter("encoding-type");
	}

}

 

 

PasswordEncryptFilter implements Filter


import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;

/* member 서비스인 경우에만 암호화 처리 할 수 있도록 한다. */
@WebFilter("/member/*")
public class PasswordEncryptFilter implements Filter {

	public void doFilter(ServletRequest request, ServletResponse response,
    FilterChain chain) throws IOException, ServletException {
		
		HttpServletRequest hrequest = (HttpServletRequest) request;
		RequestWrapper wrapper = new RequestWrapper(hrequest);
		
		chain.doFilter(wrapper, response);
	}

}

 

 

RegistMemberServlet extends HttpServlet


import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;

@WebServlet("/member/regist")
public class RegistMemberServlet extends HttpServlet {
	
	protected void doPost(HttpServletRequest request, HttpServletResponse response) 
    throws ServletException, IOException {
		/* 1. 인코딩 필터
		 * 2. 암호화 필터
		 * */
		
		String userId = request.getParameter("userId");
		String password = request.getParameter("password");
		String name = request.getParameter("name");
		
		System.out.println("userId : " + userId);
		System.out.println("password : " + password);
		System.out.println("name : " + name);
		
		/* 암호화 처리된 패스워드는 동일한 값이 입력되더라도 매번 실행시마다
        다른 값을 가지게 된다.
		 * 그럼 나중에 DB에 이 상태로 기록하게 되면 가입 된 회원정보로 로그인
         할 때 비밀번호가 같은지 어떻게 비교할까?
		 * 암호화 된 문자열은 일반 문자열 비교가 불가능하고 matches()라는 
         메소드를 이용해야 한다.
		 * */
		BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
		System.out.println("비밀번호가 pass01인지 확인 : "
        + passwordEncoder.matches("pass01", password));
		System.out.println("비밀번호가 pass02인지 확인 : "
        + passwordEncoder.matches("pass02", password));

	}

}

 

 

RequestWrapper extends HttpServletRequestWrapper

package com.greedy.section02.uses;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;

import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;

public class RequestWrapper extends HttpServletRequestWrapper{

	/* 부모 쪽에 기본 생성자가 존재하지 않기 때문에 request를 
    전달해주는 생성자가 필요하다. */
	public RequestWrapper(HttpServletRequest request) {
		super(request);
	}

	@Override
	public String getParameter(String key) {
		String value = "";
		
		if("password".equals(key)) {
			/* 랜덤 솔팅 기법을 적용한 다이제스트 생성을 지연시킨
            단방향 해시 암호화 알고리즘 */
			BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
			value = passwordEncoder.encode(super.getParameter(key));
		} else {
			value = super.getParameter(key);
		}
		
		return value;
	}
}

 

 

 

 

 

 

 

 

'Programming > Servlet&JSP' 카테고리의 다른 글

8. JSP(Java Server Page) (1)  (0) 2022.03.07
7. 서블릿 리스너  (0) 2022.03.04
5. Session과 Cookie  (0) 2022.03.03
4. 서블릿 메소드  (0) 2022.02.28
3. 서블릿(Servlet)  (0) 2022.02.28

 

 

 

 

 

개요

 

 


HTTP통신방법


HTTP는 서버와 client간의 요청과 응답으로 데이터를 주고 받는 형식으로 서버는 client의 요청에
응답을 하고 나면 그 연결을 끊어버림(stateless) client는 다시 서버에 요청하려면 새로 연결하여
응답을 받아야 한다.

 


문제점


연결이 끊어지기 때문에 유지되어야 하는 정보들이 사라지는 문제가 발생을 한다.
(예: 로그인된 후 로그인 정보, 장바구니에 넣은 데이터 등)

 

 

 

 

 

Session과 Cookie


  • 연결이 끊어진 이후에도 client에 대한 정보를 유기하기 위해 Server에서 데이터를 보관하는 방법과 client에 데이터를 보관하는 방법 두가지가 있다. 
  • 이때 서버측에 데이터를 보관하는 방법을 Session이라고 하고, client측에서 데이터를 보관하는 방법이 Cookie다.
  • ** HTTP Request / Response 프로토콜 헤더에 관련 정보를 전송하여 공유함

 

 

 

 

 

 

 

 

 

 

 

Cookie

 

 

 

 

Cookie란(패키지 : javax.servlet.http.Cookie)


  • 클라이언트 즉 사용자 컴퓨터에 데이터를 저장하는 기술, 필요시에 해당하는 정보를 서버와 공유하여 정보를 유지하는 것이다.
  • Map형식으로 저장이 되고, 데이터의 크기, 개수에 제한이 있음
  • 쿠키유지시간, 유효디렉터리, 유효도메인 등을 설정할 수 있다

 


속성설정


  • name=value : ASCII문자만 사용 / 한번 설정된 쿠키의 name은 수정 못함.
  • expire=‘날짜’ : 쿠키의 유지시간 설정 없으면 브라우저 동작 동안 유지
  • path=‘경로’ : 쿠키가 전달되는 서버의 유효디렉터리를 지정하는 속성
  • domain=‘서버정보’ : 쿠키가 전달되는 유효 서버설정
  • secure : https나 ssl보안프로토콜로 요청할때만 서버전송

 

 

 

 

 

 

 

 

 

 

 

Cookie설정 전송

 

 


Cookie클래스 생성(패키지 import)


Cookie 쿠키명 = new Cookie(“명칭”,”값”);




생성된 쿠키설정


  • setMaxAge(int expiry) : 유효시간설정
  • setPath(String uri) : 경로설정
    ** 서버의 모든 요청 X / 특정 경로를 통한 요청시 쿠키를 사용하는 경우
  • setDomain(String domain) : 쿠키도메인 설정, 쿠키생성
    ** 도메인 외의 도메인 설정시 사용

 

 

 


생성된 쿠키 전송


  • response.addCookie(Cookie cookie) : 생성된 쿠키전송

 

 

 

 

 

 

 

 

 

 

전송 Cookie활용

 

 

client 전송한 Cookie읽어오기 (HttpServletRequest객체 이용)


request.getCookies()매소드활용 쿠키객체 배열로 리턴

예) 
	Cookie[] list=HttpRequest.getCookies();

 

 

 

쿠키값 호출


getName() / getValue()를 이용하여 이름과 값 호출

 

 

예) 
    Cookie[] list=HttpRequest.getCookies();
	    for(Cookie c : list) {
	    System.out.print(c.getName()+” ”+c.getValue());
 	   }

 

 

 

 

 

 

 

 

 

 

 

 

Cookie 확인방법

 

 


Explorer


  • 브라우저 확인
개발자도구(f12) -> 네트워크 -> 페이지 선택 -> 우측화면 쿠키

 

  • 저장경로
C:\Users\user1\AppData\Local\Microsoft\Windows\ INetCache

 

 


Chrome


  • 브라우저 확인
개발자도구(f12) -> Application -> Cookies에서 확인 가능

 

  • 저장경로
C:\Users\user1\AppData\Local\Google\Chrome\UserData\Default\Cache

 

 

 

 

 

 

 

 

 

Session 개념

 

 

Session란(패키지 : javax.servlet.http.HttpSession)


  • 서버에 데이터를 저장하는 기술
  • client에는 Session ID를 부여하고 client가 request에 SessionID를 보내면 ID를 기준으로 일치 하는 Session정보를 컨테이너가 생성하여 그 객체의 데이터를 가져와 사용
  • 만일 client가 보낸 SessionID가 없으면 새로 객체를 생성

 

 

Session 생성


Session객체를 컨테이너가 자동으로 생성하여 request객체에 넣어주기 때문에 그 객체를 불러오는것을 생성이라고 한다.

  • 1. HttpRequest.getSession();
  • 2. HttpRequest.getSession(boolean);
  ** SessionID일치 Session이 없을 경우
   - boolean값에 따라 true : 객체생성, false : null값 반환

 

 

 

 

 

 

 

 

 

 

 

Session설정 / 호출

 

 

 

Session 생성(HttpServletRequest에 있음)


** client가 보낸 SessionID값이 있으면 관련 객체 호출 SessionID나 관련객체가 없으면 새로운 객체 생성

HttpSession 세션명 = HttpServletRequest.getSession();



 


생성된 Session값 설정


세션명.setAttribute(“이름”,”값(Obj)”); //세션데이터 설정
세션명.setMaxInactiveInterval(숫자); //세션유지시간설정

 

 

 


생성된 Session 호출


HttpSession 세션명=HttpServletRequest.getSession();
세션명.getAttribute(“이름”); // 데이터불러오기

 

 

 

 

 

 

Session 메소드


 

 

 

 

 

 

 

 

 

 

▼ 코드 예시 보기 ▼

 

session

 

 

index.html

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>session</title>
</head>
<body>
	<h1 align="center">Session Object Handling</h1>
	<form action="session" method="post">
		<table>
			<tr>
				<td>firstName : </td>
				<td><input type="text" name="firstName"></td>
			</tr>
			<tr>
				<td>lastName : </td>
				<td><input type="text" name="lastName"></td>
			</tr>
			<tr>
				<td colspan="2" align="center">
					<button type="submit">전송</button>
				</td>
			</tr>
		</table>
	</form>
</body>
</html>

 

 

RedirectServlet extends HttpServlet

import java.io.IOException;
import java.io.PrintWriter;
import java.util.Enumeration;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;


@WebServlet("/redirect")
public class RedirectServlet extends HttpServlet {
	
	protected void doGet(HttpServletRequest request, HttpServletResponse response) 
    throws ServletException, IOException {
		
		/* 쿼리스트링을 통한 데이터 전달 */
		String test = request.getParameter("test");
		System.out.println("test : " + test);
		
		String firstName = request.getParameter("firstName");
		String lastName = request.getParameter("lastName");
		
		System.out.println("firstName : " + firstName);
		System.out.println("lastName : " + lastName);
		
		/* 앞서 작성한 페이지와 동일한 세션 아이디를 반환한다. */
		HttpSession session = request.getSession();
		System.out.println("redirect 페이지 session id : " + session.getId());
		
		/* 세션에 담긴 모든 Attribute 키 목록을 반환받을수도 있다. */
		Enumeration<String> sessionNames = session.getAttributeNames();
		while(sessionNames.hasMoreElements()) {
			System.out.println(sessionNames.nextElement());
		}
		
		/* 동일한 아이디를 가진 세션에서는 setAttribute한 값을 
        getAttribute로 꺼내올 수 있다. */
		firstName = (String) session.getAttribute("firstName");
		lastName = (String) session.getAttribute("lastName");
		
		/* 꺼내온 값을 이용해서 페이지에 응답용 html 전송 */
		StringBuilder responseText = new StringBuilder();
		responseText.append("<!doctype html>\n")
					.append("<html>\n")
					.append("<head>\n")
					.append("</head>\n")
					.append("<body>\n")
					.append("<h3>your first name is ")
					.append(firstName)
					.append(" and last name is ")
					.append(lastName)
					.append("</h3>")
					.append("</body>\n")
					.append("</html>\n");
		
		response.setContentType("text/html; charset=UTF-8");
		
		PrintWriter out = response.getWriter();
		out.print(responseText.toString());
		out.flush();
		out.close();
		
		
	}

	
}

 

 

SessionHandlerServlet extends HttpServlet

package com.greedy.section01.session;

import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;


@WebServlet("/session")
public class SessionHandlerServlet extends HttpServlet {
	
	protected void doPost(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
		
		request.setCharacterEncoding("UTF-8");
		
		String firstName = request.getParameter("firstName");
		String lastName = request.getParameter("lastName");
		
		System.out.println("firstName : " + firstName);
		System.out.println("lastName : " + lastName);
		
		/* 이전 챕터에서는 값을 유지하기 위한 기술로 쿠키를 이용해보았다.
		 * 하지만 쿠키의 보안적인 단점과 지원하지 않는 브라우저 문제 등으로 
         상태를 유지해야 하는 
		 * 매커니즘이 적합하지 않은 경우들이 다수 있는데 특히 회원 정보를 
         이용해서 회원의 로그인 상태를
		 * 지속적으로 유지해야 하는 경우가 그러하다. 그렇기에 서버 쪽에서 조금 
         더 안전하게 관리 되는
		 * 세션이라는 인스턴스를 이용해서 상태를 유지하는 매커니즘을 제공하고 있다.
		 * HttpSession은 직접 생성할 수는 없고, request에 있는 getSession() 
         메소드를 이용해서 리턴 받는다.
		 * */
		HttpSession session = request.getSession();
		
		/* 세션은 강제로 만료 시킬 수 있는 기능도 있지만 만료 시간을
        설정해주는 것이 좋다.
		 * 설정 된 기분 시간은 30분이며 필요에 따라 늘리거나 줄이면 된다.
		 * */
		System.out.println("session default 유지 시간 : "
        + session.getMaxInactiveInterval());
		
		session.setMaxInactiveInterval(60 * 10);  // 세션 만료 시간을 10분으로 설정
		System.out.println("변경 후 session 유지 시간 : "
        + session.getMaxInactiveInterval());

		/* 세션은 브라우저 당 한 개 씩 고유한 아이디를 가지고 하나의 인스턴스를 이용한다.
		 * 매번 반복적인 요청 시 동일한 session id를 리턴한다.
		 * */
		System.out.println("session id : " + session.getId());
		
		/* 세션은 redirect를 해도 값을 유지할 수 있는 request보다 
        더 넒은 범위의 공유 영역이라고 표현할 수 있다.
		 * 세션에 값을 담을 때 setAttribute(String key, Object value) 
         형태로 담을 수 있고,
		 * 값을 꺼낼 때에는 key를 이용해서 getAttribute(key)를 이용해 꺼내게 된다.
		 * */
		session.setAttribute("firstName", firstName);
		session.setAttribute("lastName", lastName);

		
		response.sendRedirect("redirect?test=hello");
	}

}

 

 

 

 

 

Cookie

 

index.html

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>cookie</title>
</head>
<body>
	<h1 align="center">Cookie handling</h1>
	<form action="cookie" method="post">
		<table>
			<tr>
				<td>firstName : </td>
				<td><input type="text" name="firstName"></td>
			</tr>
			<tr>
				<td>lastName : </td>
				<td><input type="text" name="lastName"></td>
			</tr>
			<tr>
				<td colspan="2" align="center">
					<button type="submit">전송</button>
				</td>
			</tr>
		</table>
	</form>
	
</body>
</html>

 

 

 

CookieHandlerServlet extends HttpServlet


import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;


@WebServlet("/cookie")
public class CookieHandlerServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
    
	protected void doPost(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
		
		request.setCharacterEncoding("UTF-8");
		
		String firstName = request.getParameter("firstName");
		String lastName = request.getParameter("lastName");
		
		System.out.println("firstName : " + firstName);
		System.out.println("lastName : " + lastName);
		
		/* redirect는 url을 재작성하여 url을 이용해 요청하는 방식이기 때문에 
        get 방식의 요청이다.
		 * 따라서 redirect 되는 서블릿은 doGet 메소드 쪽에서 처리해야 한다.
		 * */
		
		/* 쿠키를 사용하는 방법은 간단하며, 쿠키를 사용하는 절차가 있다.
		 * 1. 쿠키를 생성한다.
		 * 2. 해당 쿠키의 만료 시간을 설정한다.
		 * 3. 응답 헤더에 쿠키를 담는다.
		 * 4. 응답 한다.
		 * 
		 * 하지만 쿠키는 일부 제약 항목이 있다.
		 * 쿠키의 이름은 아스키코드 문자만을 사용해야하며 한 번 설정한 쿠키의 
         이름은 변경할 수 없다.
		 * 또한 공백문자와 일부 특수문자([ ] ( ) = , " \ ? @ : ;)를 사용할 수 없다.
		 * */
		Cookie firstNameCookie = new Cookie("firstName", firstName);
		Cookie lastNameCookie = new Cookie("lastName", lastName);
		
		// 초 단위 설정으로 하루를 만료시간으로 둘 때의 예시
		firstNameCookie.setMaxAge(60 * 60 * 24);
		lastNameCookie.setMaxAge(60 * 60 * 24);
		
		response.addCookie(firstNameCookie);
		response.addCookie(lastNameCookie);
		
		
		response.sendRedirect("redirect");
	}

}

 

 

RedirectServlet extends HttpServlet


import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet("/redirect")
public class RedirectServlet extends HttpServlet {
	
	protected void doGet(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
		String firstName = request.getParameter("firstName");
		String lastName = request.getParameter("lastName");
		
		System.out.println("firstName : " + firstName);
		System.out.println("lastName : " + lastName);
		
		/* null 값이 나오는 것을 확인할 수 있다.
		 * 따라서 request는 공유되지 않는다는 것을 볼 수 있다.
		 * */
		
		/* 쿠키를 사용하는 방법
		 * 1. request에서 쿠키 목록을 쿠키 배열 형태로 꺼내온다.
		 * 2. 쿠키의 getName과 getValue를 이용해 쿠키에 담긴 값을 사용한다.
		 * */
		
		Cookie[] cookies = request.getCookies();
		
		for(int i = 0; i < cookies.length; i++) {
			System.out.println("[cookie] " + cookies[i].getName()
            + " : " + cookies[i].getValue());
			
			if("firstName".equals(cookies[i].getName())) {
				firstName = cookies[i].getValue();
			} else if("lastName".equals(cookies[i].getName())) {
				lastName = cookies[i].getValue();
			}
			
		}
		
		StringBuilder responseText = new StringBuilder();
		responseText.append("<!doctype html>\n")
					.append("<html>\n")
					.append("<head>\n")
					.append("</head>\n")
					.append("<body>\n")
					.append("<h3>your first name is ")
					.append(firstName)
					.append(" and last name is ")
					.append(lastName)
					.append("</h3>")
					.append("</body>\n")
					.append("</html>\n");
		
		response.setContentType("text/html; charset=UTF-8");
		
		PrintWriter out = response.getWriter();
		out.print(responseText.toString());
		out.flush();
		out.close();
		
		/* 쿠키는 텍스트 파일 형태로 클라이언트 컴퓨터에 저장 된다.
		 * 다른 사용자와 함께 사용하는 컴퓨터인 경우 쿠키에 민감한 
         개인 정보를 담기에는 보안에 취약해지는 문제가 있다.
		 * 따라서 민감한 개인 정보를 취급하는 경우에는 쿠키보다는 
         세션을 이용하게 된다.
		 * 세션은 쿠키와 유사한 형태로 key=value 쌍으로 저장 되지만
         서버(톰캣)에서 관리 되기 때문에 보안에 더 우수하다.
		 * */
	}

}

 

 

 

 

 

 

 

 

'Programming > Servlet&JSP' 카테고리의 다른 글

7. 서블릿 리스너  (0) 2022.03.04
6. 서블릿 필터와 래퍼  (0) 2022.03.03
4. 서블릿 메소드  (0) 2022.02.28
3. 서블릿(Servlet)  (0) 2022.02.28
02. 웹 애플리케이션 개발환경 구축  (0) 2022.02.28

 

 

 

 

 

 

 

사용자 데이터 전송방식

 

 

get방식


  • URL창에 “ ? “ 뒤에 데이터를 입력하는 방법(쿼리스트링)으로 보낸다.
  • 데이터가 여러 개일 경우 &로 묶어서 보낸다.
  • 데이터 검색에 많이 사용, 데이터 크기 한계가 있으며, 보안에 취약하다

 


post방식


HTTP헤더의 내용으로 보내는 방식으로 데이터 크기에 제한이 없고, 헤더에 포함되어 보안이 뛰어남

 

☞ Servlet이 두 방식 중 하나로 전달받으면 해당하는 매소드를 호출함
html <form>에서 method속성을 이용해서 방식결정, default : get

 

 

 

 

 

 

 

 

서블릿 메소드

 

 


doGet


client에서 데이터를 전송 방식을 get방식으로 전송하게 되면 호출되는 메소드

 


doPost


client에서 데이터를 전송 방식을 Post방식으로 전송하게 되면 호출되는 메소드

 

 

☞ 반드시 ServletException 처리해야 함.

 

 

 

 

 

 

 

 

 

서블릿 매개변수 객체

 

 


HttpServletRequest (interface)


  • HTTP Servlets을 위한 요청정보(request information)를 제공 메소드 지정
  • ** 인터페이스 구현은 컨테이너가 알아서 설정 / 메소드만 이용 **
  • 상속 : javax.servlet.ServletRequest (interface)

 

 

 

 

 

 

HttpServletRequest (interface)


 

 

 

 


HttpServletResponse (interface)


  • 요청에 대한 처리결과를 작성하기 위해 사용하는 객체
  • ** 인터페이스 구현은 컨테이너가 알아서 설정 / 메소드만 이용 **
  • 상속 : javax.servlet.ServletResponse (interface)

 

 

 

 

 

 

 

 

 

 

 

sendRedirect VS RequestDispatcher

 

 


sendRedirect / encodeRedirectURL


  • client의 브라우저에게 매개변수로 등록한 페이지를 재요청하라고 응답해주는 것(301/302코드 전송)
  • encodeRedirectURL은 매개변수(URL)에 세션ID정보를 추가 재요청 처리
  • client가 별도로 다른 페이지 요청을 안해도 url주소(페이지)가 변경됨.
  • ** 브라우저가 알아서 서버에 해당 페이지를 요청 / 쿼리스트링으로 별도의
  • 데이터를 전송하지 않으면 요청데이터가 없음

 

 

 

 

 

 

 

 

 

sendRedirect VS RequestDispatcher

 


RequestDispatcher() ~ forward()


  • 컨테이너 내에서 처음 요청 받은 페이지가 요청 데이터 (HttpServletRequest,
  • HttpServletResponse)를 다른 페이지에 전송하여 처리를 요청을 하고 자신이 처리한 것처럼 하는 것.
  • url주소(페이지)가 변경되지 않음.

 

 

 

 

 

 

 

 

 

 

 

서블릿 데이터 공유

 

 

 


객체별 공유 데이터 설정


** 공유값은 Map형식으로 저장됨.

 

 

 

 

 

 

 

 

 

 

 

▼ 코드 예시 보기 ▼

 

 

Response

 

ResponseTestServlet extends HttpServlet

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;

/**
 * Servlet implementation class ResponseTestServlet
 */
 
@WebServlet("/response")
public class ResponseTestServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;

    public ResponseTestServlet() {
        super();

    }


	protected void doGet(HttpServletRequest request, HttpServletResponse response) 
    throws ServletException, IOException {


	/* 서블릿이 하는 역할은 크게 3가지라고 볼 수 있다.
	 * 1. 요청받기 (http method GET/POST 요청에 따른 parameter로 전달 받은 데이터를 
     꺼내올 수 있다.)
	 * 2. 비즈니스 로직 처리 (DB 접속과 CRUD에 대한 로직 처리 -> 서비스를 호출하는 
     쪽으로 해결 (MVC))
	 * 3. 응답하기 (문자열로 동적인 웹(html 태그)페이지를 만들어서 스트림을 
     이용하여 내보내기)
	 * 
	 *  */	
		
		
		
		/* 기본값은 text/plain 이지만 html 태그를 사용하면 요청 시 text/html도 응답으로 
        수락 가능하도록
		 * 헤더 설정이 되어 있기 때문에 text/html로 인식하게 된다.
		 * 하지만 명시적으로 text/plain 으로 설정되면 html 태그를 태그로 인식하지 
         않고 문자열로 인식하게 된다. */
		
		 //response.setContentType("text/plain");
		response.setContentType("text/html");
		
		/* 응답시에도 별도로 인코딩을 지정하지 않으면 기본적으로 설정 된 
        인코딩 방식을 따르게 된다. (iso-8859-1)
		 * 따라서 한글로 페이지를 응답하는 경우 글씨가 깨져서 나오게 된다.
		 * */
		/* 인코딩 설정 확인 */
		System.out.println("default response encoding : "
        + response.getCharacterEncoding());
		// 콘솔창 : default response encoding : ISO-8859-1 
		
		
		/* 이 때 응답할 인코딩 방식이 UTF-8임을 응답 헤더에 알려주게 되면 브라우저가 
        이를 해석할때 UTF-8로 인식한다.
		 * 즉, 한글 값이 깨지지 않게 된다. */
		/* 유의할 점은 반드시 getWriter()로 스트림을 얻어오기 전에 설정해야 한다.  : */
		response.setCharacterEncoding("UTF-8");
		System.out.println("default response encoding : " 
        + response.getCharacterEncoding());
		
        
		/* 콘솔창 출력 */
		/* default response encoding : ISO-8859-1
		   default response encoding : UTF-8 */
		

		
		/* 사용자 브라우저에 응답하기 위해 HttpServletResponse가 가지는 getWriter() 메소드로
		 * PrintWriter 인스턴스를 반환 받는다. PrintWriter는 BufferedWriter와 형제격인 
		 * 클래스이지만 더 많은 형태의 생성자를 제공하고 있어서 실제로는 범용성으로 
         인해 더 많이 사용된다. */
         
		PrintWriter out = response.getWriter();
        
        
		
		/* 문자열을 이용해 사용자에게 내보내기를 할 페이지를 작성한다. */
		StringBuilder responseBuilder = new StringBuilder();
		responseBuilder.append("<!doctype html> \n")
						.append("<html>\n")
						.append("<head>\n")
						.append("</head>\n")
						.append("<body>\n")
						.append("<h1>안녕 servlet response</h1>\n")
						.append("</body>\n")
						.append("</html>\n");
		
		
		/* 스트림을 이용해 내보내기 */
		out.print(responseBuilder.toString());
		
		/* 버퍼에 잔류한 데이터를 강제로 내보낸다. */
		out.flush();
		
		/* 스트림을 닫아준다. */
		out.close();
		
		
		
		
		
	}

}

 

 

 

HeaderPrintServlet

package com.greedy.section02.headers;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.Collection;
import java.util.Enumeration;
import java.util.Iterator;

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("/headers")
public class HeaderPrintServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
       


    
	protected void doGet(HttpServletRequest request, HttpServletResponse response) 
    throws ServletException, IOException {

		
		
		/* request header 출력 */
		Enumeration<String> headerNames = request.getHeaderNames();
		while(headerNames.hasMoreElements()) {
			System.out.println(headerNames.nextElement());
		}
	
		
		/* request.getHeader()에 name 값을 전달해서 값을 가져올 수 있다. */
		System.out.println("accept : " + request.getHeader("accept"));
		System.out.println("host : " + request.getHeader("host"));
		
		
		response.setContentType("text/html; charset=UTF-8");
		/* 1초에 한번씩 새로고침 */
		//response.setHeader("Refresh", "1");
		
		/* 출력할 스트림 */
		PrintWriter out = response.getWriter();
		
		long currentTime = System.currentTimeMillis();
		
		out.print("<h1>" + currentTime + "</h1>");
		
		out.close();
		
		
		
		
		/* response header 출력 */
		Collection<String> responseHeaders = response.getHeaderNames();
		Iterator<String> iter = responseHeaders.iterator();
		while(iter.hasNext()) {
			String headerName = iter.next();
			System.out.println(headerName + " : " + response.getHeader(headerName));
		}
		
		
	}



}

 

StatusCodeTestServlet

package com.greedy.section03.status;

import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Servlet implementation class StatusCodeTestServlet
 */
@WebServlet("/status")
public class StatusCodeTestServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
       

	protected void doGet(HttpServletRequest request, HttpServletResponse response) 
    throws ServletException, IOException {

		//response.sendError(404, "없는 페이지 입니다. 경로를 확인해주세요.");
		response.sendError(500, "서버 내부 오류입니다. 서버 오류는 개발자의 잘못이고,
        개발자는 여러분입니다.");
		
		
	}



}

 

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>chap04-response</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>

 

 

index.html

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Response</title>
</head>
<body>
<h1 align="center">Response</h1>

	<ul>
	<li><a href="response"> 응답 확인하기 </a></li>
	<li><a href="headers"> 헤더 확인하기 </a></li>
	<li><a href="status"> 응답 상태 코드 확인하기 </a></li>
	
	</ul>
</body>
</html>

 

 

 

 

 

Exception Handler

 

 

index.html

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>

	<h1 align="center">Exception Handler</h1>
	
	<ul>
		<li><a href="show404error">404 에러 확인</a></li>
		<li><a href="show500error">500 에러 확인</a></li>
	</ul>


</body>
</html>

 

 

ExceptionHandlerServlet extends HttpServlet

import java.io.IOException;
import java.io.PrintWriter;
import java.util.Enumeration;

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("/showErrorPage")
public class ExceptionHandlerServlet extends HttpServlet {
	
	protected void doGet(HttpServletRequest request, HttpServletResponse response) 
    throws ServletException, IOException {
		
		Enumeration<String> attrName = request.getAttributeNames();
		while(attrName.hasMoreElements()) {
			System.out.println(attrName.nextElement());
		}
		
		
		String forwardRequestURI
        = (String)request.getAttribute("javax.servlet.forward.request_uri");
        
		String contextPath
        = (String)request.getAttribute("javax.servlet.forward.context_path");
        
		String servletPath
        = (String)request.getAttribute("javax.servlet.forward.servlet_path");
        
		Integer statusCode
        = (Integer)request.getAttribute("javax.servlet.error.status_code");
        
		String errorMessage
        = (String)request.getAttribute("javax.servlet.error.message");
        
		String servletName
        = (String)request.getAttribute("javax.servlet.error.servlet_name");
        
		String errorRequestURI
        = (String)request.getAttribute("javax.servlet.error.request_uri");
        
        
        

		System.out.println("forwardRequestURI : " + forwardRequestURI);
		System.out.println("contextPath : " + contextPath);
		System.out.println("servletPath : " + servletPath);
		System.out.println("statusCode : " + statusCode);
		System.out.println("errorMessage : " + errorMessage);
		System.out.println("servletName : " + servletName);
		System.out.println("errorRequestURI : " + errorRequestURI);
		
		
		StringBuilder errorPage = new StringBuilder();
		errorPage.append("<!doctype html>\n")
				.append("<html>\n")
				.append("<head>\n")
				.append("</head>\n")
				.append("<body>\n")
				.append("<h1 align='center'>")
				.append(statusCode)
				.append(" - ")
				.append(errorMessage)
				.append("</h1>")
				.append("</body>\n")
				.append("</html>\n");
		
		response.setContentType("text/html; charset=UTF-8");
		
		PrintWriter out = response.getWriter();
		
		out.print(errorPage.toString());
		
		out.flush();
		out.close();
		
		
		
		
		
		
		
		
		
	}


}

 

 

Show404ErrorServlet extends HttpServlet


import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Servlet implementation class Show404ErrorServlet
 */
 
@WebServlet("/show404error")
public class Show404ErrorServlet extends HttpServlet {

	protected void doGet(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {

		response.sendError(404, "페이지를 찾을 수 없습니다!");
	}


}

 

 

Show500ErrorServlet extends HttpServlet


import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Servlet implementation class Show500ErrorServlet
 */
 
@WebServlet("/show500error")
public class Show500ErrorServlet extends HttpServlet {

	protected void doGet(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {

		response.sendError(500, "500번 에러는 개발자 잘못! 개발자는 바로 나...ㅠ");
	}



}

 

 

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>chap05-exception-handler</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>
  <error-page>
  	<error-code>404</error-code>
  	<location>/showErrorPage</location>
  </error-page>
  <error-page>
  	<error-code>500</error-code>
  	<location>/showErrorPage</location>
  </error-page>
</web-app>

 

 

 

 

 

 

forward

 

index.html

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>forward</title>
</head>
<body>
	<h1 align="center">forward</h1>
	
	<form action="forward" method="post">
		<table align="center">
			<tr>
				<td>아이디 : </td>
				<td><input type="text" name="userId"></td>
				<td rowspan="2"><button type="submit" style="height:50px;">
                로그인</button></td>
				
			</tr>
			<tr>
				<td>비밀번호 : </td>
				<td><input type="password" name="password"></td>
			</tr>
		</table>
	</form>
	
</body>
</html>

 

 

PrintLoginSuccessServlet extends HttpServlet

package com.greedy.section01.forward;

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("/print")
public class PrintLoginSuccessServlet extends HttpServlet {

	protected void doPost(HttpServletRequest request, HttpServletResponse response) 
    throws ServletException, IOException {
		/* forward 받은 서블릿에서도 요청 방식이 get이면 doGet 메소드를, 
        요청 방식이 post이면 doPost 메소드를 호출한다. */
		/* request에 이전 서블릿에서 전달하고자 하는 정보를 담았기 때문에 
        해당 서블릿에서는 다시 꺼내온다. */
		String userId = (String)request.getAttribute("userId");
		System.out.println("forward 확인 : " + userId);
		
		/* 응답에 필요한 데이터가 다 준비 되면 동적인 웹 페이지를 생성한다. */
		StringBuilder responseText = new StringBuilder();
		responseText.append("<!doctype html>\n")
					.append("<html>\n")
					.append("<head>\n")
					.append("</head>\n")
					.append("<body>\n")
					.append("<h3 align='center'>")
					.append(userId)
					.append("님 환영합니다.</h3>")
					.append("</body>\n")
					.append("</html>");
		
		response.setContentType("text/html; charset=UTF-8");
		
		PrintWriter out = response.getWriter();
		
		out.print(responseText.toString());
		
		out.flush();
		out.close();
		
		/* 변수의 기본 스코프는 메소드(page)이기 때문에 다른 페이지(서블릿)
        으로 데이터 공유 불가
		 * forward 방식은 request와 response를 넣어서 위임하므로 request에 
         정보를 저장하여
		 * forward 했을 경우 위임 당한 서블릿에서도 서블릿의 정보를 
         공유할 수 있게 된다.
		 * 또한 forward 방식은 해당 서블릿의 존재를 client가 알 필요가 없어 
         url 자체가 변경 되지 않는다.
		 * 단, 서버로 전송한 데이터가 남아있는 상태로 새로고침(재요청)을 
         하게되면 요청을 계속 반복하게 되어
		 * DB에 insert하는 행위가 반복 되어 중복 행이 발생하는 등의 문제가 있을 수 있다.
		 * 이러한 경우는 또 다른 페이지 전환 방식 sendRedirect를 사용해야 한다.
		 * */
					
	}

	
	
	
	
	
	
	
	
}

 

 

ReceiveInformationServlet extends HttpServlet

package com.greedy.section01.forward;

import java.io.IOException;

import javax.servlet.RequestDispatcher;
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("/forward")
public class ReceiveInformationServlet extends HttpServlet {

	protected void doPost(HttpServletRequest request, HttpServletResponse response) 
    throws ServletException, IOException {
		
		request.setCharacterEncoding("UTF-8");
		
		String userId = request.getParameter("userId");
		String password = request.getParameter("password");
		
		System.out.println("userId : " + userId);
		System.out.println("password : " + password);
		
		/* 위에서 요청 정보를 받았고
		 * 모든 비즈니스 로직은 성공이라는 가정 하에 
		 * user01을 입력 시 해당 아이디를 이용해 user01님 환영합니다 라는 메세지를 
         출력해주는 화면을 만들자
		 * 
		 * PrintLoginSuccessServlet으로 위임하기 위해서는 RequestDispatcher 
         인스턴스 생성 후
		 * forward 메소드를 이용해서 요청과 응답에 대한 정보를 전달한다.
		 * 이 때 다른 서블릿으로 요청하기 위한 데이터는 request에 setAttribute로
         전달하여 받는 쪽에서는 getAttribute를 이용해 꺼내서 사용한다.
		 * */
		
		request.setAttribute("userId", userId);
		
		RequestDispatcher rd = request.getRequestDispatcher("print");
		rd.forward(request, response);
		
	}

}

 

 

 

redirect

 

index.html

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>redirect</title>
</head>
<body>
	<h1 align="center">redirect</h1>
	<ul>
		<li><a href="othercite">다른 웹 사이트 redirect 테스트</a></li>
		<li><a href="otherservlet">다른 서블릿으로 redirect 테스트</a></li>
	</ul>
</body>
</html>

 

 

OtherCiteRedirectServlet extends HttpServlet 


import java.io.IOException;
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("/othercite")
public class OtherCiteRedirectServlet extends HttpServlet {
       
  
	protected void doGet(HttpServletRequest request, HttpServletResponse response) 
    throws ServletException, IOException {
		System.out.println("get 요청 후 naver 사이트로 redirect");
		/* 브라우저의 개발자 도구 network 탭을 보면 302번 status code와 함께 
        naver 사이트로 이동하는 것을 볼 수 있다.
		 * 사용자 url 재작성이라고 불리는 redirect 방식은 302번 응답 코드인
         경우 요청에 대한 처리를 잘 했으며
		 * 사용자의 url을 강제적으로 redirect 경로로 이동시키라는 의미이다.
		 * */
		response.sendRedirect("http://www.naver.com");
	}

	

}

 

 

OtherServletRedirectTest extends HttpServlet


import java.io.IOException;
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("/otherservlet")
public class OtherServletRedirectTest extends HttpServlet {
	
	protected void doGet(HttpServletRequest request, HttpServletResponse response) 
    throws ServletException, IOException {
		System.out.println("get 요청 정상 수락");
		response.sendRedirect("redirect");
	}

	
}

 

 

RedirectServlet extends HttpServlet



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("/redirect")
public class RedirectServlet extends HttpServlet {
	
	protected void doGet(HttpServletRequest request, HttpServletResponse response) 
    throws ServletException, IOException {
		System.out.println("이 서블릿으로 redirect 성공!");
		
		StringBuilder redirectText = new StringBuilder();
		redirectText.append("<!doctype html>\n")
					.append("<head>\n")
					.append("</head>\n")
					.append("<body>\n")
					.append("<h1>이 서블릿으로 redirect 성공!</h1>")
					.append("</body>\n")
					.append("</html>");
		
		response.setContentType("text/html; charset=UTF-8");
		
		PrintWriter out = response.getWriter();
		
		out.print(redirectText.toString());
		
		out.flush();
		out.close();
			
		/* redirect를 하는 경우 url이 재작성 되어 새로 고침 해도 redirect 
        된 페이지에 대한 요청만을 반복한다.
		 * 즉, 이전 요청에 남아있던 정보는 더이상 남아있지 않게 된다. 
         또한 url도 변경 된다.
		 * http 요청은 요청 시에 잠시 connection을 맺고 응답 시에도 잠시
         connection을 맺으며
		 * 요청 단위 당 request 객체는 한 개만 생성이 된다.
		 * 따라서 첫 요청 시의 request와 redirect된 페이지의 request는 
         서로 다른 객체이다.
		 * 그렇기 때문에 redirect를 이용하게 되면 이전 서블릿의 값을 
         공유해서 사용할 수 없게 된다.
		 * 그럼 redirect시 값을 유지하는 방법은? 크게 쿠키와 세션이라는 
         것을 이용할 수 있다.
		 * */
		
	}

	
}

 

 

 

 

 

'Programming > Servlet&JSP' 카테고리의 다른 글

6. 서블릿 필터와 래퍼  (0) 2022.03.03
5. Session과 Cookie  (0) 2022.03.03
3. 서블릿(Servlet)  (0) 2022.02.28
02. 웹 애플리케이션 개발환경 구축  (0) 2022.02.28
01. 웹이란  (0) 2022.02.28

 

 

 

 

 

서블릿 개요

 

 

 


서블릿이란?


Server + Applet의 합성어, JAVA 언어를 이용하여 사용자의 요청을 받아 처리하고 그 결과를 다시 사용자에게 전송하는 역할의 Class 파일을 말한다. 즉 웹에서 동적인 페이지를 java로 구현한 서버측 프로그램이라고 보면 된다.

※ 관련 패키지와 클래스는 tomcat에서 제공하는 API문서에서 확인 가능
https://tomcat.apache.org/tomcat-8.0-doc/servletapi/

 

 

 

 

 

 

 

 

서블릿 동작구조

 

 

서블릿 컨테이너란


  • 웹 서버 또는 응용 프로그램 서버의 일부로, 웹 서버에서 온 요청을 받아 서블릿 class를 관리하는 역할(생명주기)을 한다.
  • 컨테이너의 서블릿에 대한 설정은 Deployment Descriptor(web.xml)파일을 이용

 

 

 

 

 

 

 

 

 

 

Deployment Descriptor(DD)

 

 

배포서술자(DD)


  • 어플리케이션에 대한 전체 설정정보를 가지고 있는 파일로 이정보를 가지고 웹 컨테이너가 서블릿을 구동, xml파일로 요소(태그)로 이루어져 있음.
  • 어플리케이션 폴더의 WEB-INF폴더에 web.xml이라는 파일이다.

 

 

설정정보


  • Servlet정의 / Servlet 초기화 파라미터
  • Session설정 파라미터
  • Servlet/jsp 매핑 / MIME type 매핑
  • 보안설정
  • Welcome file list설정
  • 에러 페이지 리스트, 리소스 그리고 환경변수

 

 

 

 

 

 

 

Deployment Descriptor(DD)

 

 

파일세부내용


  • <web-app> : 루트속성, 문법식별자 및 버전의 정보를 속성값으로 설정
  • <context-param> : 웹 어플리케이션에서 공유하기 위한 파라미터 설정
  • <mime-mapping> : 특정파일 다운로드시 파일이 깨지는 현상방지
  • <servlet>~<servlet-class> / <servlet-mapping> : 서블릿 맵핑
  • <servlet>~<servlet-class> : 컨테이너에 서블릿 설정
 예) default : 공유자원제공 및 디렉토리목록 제공, jsp : jsp컴파일과 실행 담당

 

  • <welcome-file-liest> : 시작페이지 설정
  • <filter> : 필터정보 등록
  • <error-page> : 에러발생시 안내페이지설정
  • <session-coinfig> : session기간 설정
  • <listener> : 이벤트 처리 설정(6가지)

 

 

 

 

 

 

 

 

 

서블릿 맵핑

 

 

서블릿 mapping


client가 servlet에 접근할 때 원본 클래스명이 아닌 다른 명칭으로 접근시 사용 설정방법은 web.xml을 이용하여 적용하는 방법과@annontation를 이용하는 방법이 있음

 


web.xml 이용

    <servlet>
        <servlet-name>mapping명칭</servlet-name>
        <servlet-class>실제 클래스명칭</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>mapping명칭</servlet-name>
        <url-pattern>사용자 접근명칭</url-pattern>
    </servlet-mapping>



 

 

 

 

 

 

서블릿 맵핑


  • @annotation 이용
    @web-Servlet(“/매핑명칭”)
        public class 서블릿명칭 extends HttpServlet {
                servlet코드……………….
                ……………………….
        }

 

 

 

 

 

 

 

 

 

서블릿 초기값 설정

 

 

ServletConfig


  • web.xml에 대한 정보를 가져오는 객체(interface)로 저장할 객체를 만들어 저장하고 getServlet 메소
    드로 정보가 저장된 객체 호출가능, getInitParam(“저장이름”)으로 초기화된 값을 가져올 수 있음
  • ** 지정된 servlet에서만 활용 가능한 초기값임 / 동적 수정이 불가하여 상수값으로 보면 됨.
  • ** servlet이 초기화된 이후에 활용가능

 

<web-app>
    <servlet>
        <servlet-name>mappin명칭</servlet-name>
        <servlet-class>설정 클래스명칭</servlet-class>
        <init-param>
            <param-name>저장 이름</param-name>
            <param-value>저장값</param-value>
        </init-param>
    </servlet>
</web-app>

 

 

 

 

 

 


ServletContext


  • ServletConfig의 초기값은 지정된 Servlet에서만 사용이 가능하나 ServletContext는 모든 어플리케이션이 공용으로 사용하는 초기값을 설정, 값은 getContext().getInitParam(“저장이름”)으로 호출
  • ** <servlet>태그안이 아니라 <web-app>내부에 설정
  • ** getContext앞에는 getConfig() / this가 생략되어 있음.

 

    <web-app>
        <context-param>
            <param-name>저장 이름</param-name>
            <param-value>설정값</param-value>
        </context-param>
    </web-app>



 

 

 

 

 

 

 

 

 

웹 애플리케이션 접근

 

 

컨텍스트 패스(Context Path)


  • 어플리케이션에 접근하는 경로를 말한다. ( * 컨테이너에서 어플리케이션 구분)
  • 즉, 어플리케이션의 root경로라고 볼 수 있다.
  • 프로젝트의 별칭은 톰캣 서버 설정의 server.xml 내  설정을 따른다.

 

    http://localhost:[PORT번호]/[ 프로젝트 별칭 ]/[ Servlet 명]
    EX ) http://localhost:8800/first/test1.do

 

 

 

 

 

 

 

 

 

서블릿 라이프사이클


  • 1. 첫 번째 요청일 경우, 객체를 생성하며 init( ) 메소드를 호출한다.
  • 2. 이 후 작업이 실행 될 때마다 service() 메소드가 요청한 HTTP Type에 따른 doGet(), doPost() 메소드 호출
  • 3. 최종적으로 서블릿이 서비스 되지 않을 때 destroy() 메소드가 호출.
  • ** destroy() 는 보통 서버가 종료되었을 때, 서블릿의 내용이 변경되어 재 컴파일 될 때 호출한다

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Servlet 구동


 

 

 

 

 

 

 

'Programming > Servlet&JSP' 카테고리의 다른 글

6. 서블릿 필터와 래퍼  (0) 2022.03.03
5. Session과 Cookie  (0) 2022.03.03
4. 서블릿 메소드  (0) 2022.02.28
02. 웹 애플리케이션 개발환경 구축  (0) 2022.02.28
01. 웹이란  (0) 2022.02.28

 

 

 

 

 

 

웹 애플리케이션 개발환경 구축

 

 

 


개발환경 구축 순서


  1. https://tomcat.apache.org/download-80.cgi 접속
  2. Dowload – Tomcat 8 선택 후 8.5.61 버전 다운로드
  3. D드라이브의 dev폴더 생성 후 압축 풀기
  4. 이클립스에 설치한 통캣의 경로로 런타임 등록
  5. 테스트 서버 생성 후 실행
  6. 정상 start up 확인

 

 

 

 

 

 

웹 애플리케이션 개발환경 구축


 

  • 아파치-톰캣 서버 버전 별 지원정보 확인 (1)

 

 

 

 

 

 

 

 

 

  • 아파치-톰캣 서버 버전 별 지원정보 확인 (2)

 

  • 8.5.X 버전과 8.0.X 버전의 차이는 JASPIC 1.1(자바 인증 서비스 인터페이스) Spec의 지원 유무이며
    다른 부분은 동일하다.

 

 

 

 

 

 

 

  • 아파치-톰캣 서버 설치
  •  

 

 

 

 

 

 

 

 

  • 아파치-톰캣 서버 구성하기

  1. 이클립스 상단의 [ Window ] – [ Preferences ] 선택 
  2. [Server ] – [ Runtime Environments ] – [ Add … ] 선택

 

 

 

 

 

 

 

  • 아파치-톰캣 서버 구성하기

New Server Environment 에서 Apache Tomcat v8.5 선택 후 [ Next ]

 

 

 

 

 

 

 

 

  • [ Browse… ] 선택하여 Apache-tomcat 설치 경로 등록

 

 

 

 

 

 

 

 

 

 

  • Server Runtime Environments 의 등록 정보를 확인 후 [ Apply and Close ]

 

 

 

 

 

 

 

 

 

  • Servers 설정에서 new Server 클릭 후, 이미 만들어 둔 환경을 선택하고 Finish

 

 

 

 

 

 

 

  • 생성된 서버를 더블 클릭하여 서버 설정 변경
  • Server가 정상 구동 되는지 확인

 

 

 

 

 

 

 

 

 

 

 

 

 

  • 톰캣 관련 참고사항 - Directory

 

 

 

 

 

 

 

  • 톰캣 관련 참고사항 - 환경설정

 

 

 

 

 

 

 

 

 

 

 

이클립스 환경 설정


 

 

  • 이클립스의 구동환경을 Java EE 로 변경

 

 

 

 

 

 

 

  • 웹 애플리케이션 구현 시 생성해야 할 파일의 바로가기를 생성한다.

 

 

 

 

 

 

 

 

  • 이클립스 환경 설정

 

 

 

 

 

 

  • 우클릭하여 [ New ] 메뉴 접근 시 다음과 같이 나오면 완료된 것이다.

 

 

 

 

 

 

 

 

 

 

 

 

Web Project 서버에 등록하기


 

 

  • [ New ] – [ Dynamic Web Project ] 생성

 

 

 

 

 

 

 

 

  • 1. 프로젝트 이름 설정
  • 2. Target runtime 을 이전에 생성한 서버로 설정 
  • 3. [ Next ] 클릭

 

 

 

 

 

 

 

 

 

  • Web 프로젝트가 생성된 것을 확인하고, 서버 우 클릭하여 해당 프로젝트 추가

 

 

 

 

 

 

 

 

 

  • Web Project 서버에 등록하기 
  • 서버 재 기동하여 실행 확인

 

 

 

 

 

 

 

 

 

 

 

 

 

 

'Programming > Servlet&JSP' 카테고리의 다른 글

6. 서블릿 필터와 래퍼  (0) 2022.03.03
5. Session과 Cookie  (0) 2022.03.03
4. 서블릿 메소드  (0) 2022.02.28
3. 서블릿(Servlet)  (0) 2022.02.28
01. 웹이란  (0) 2022.02.28

 

 

 

 

 

 

네트워크통신 개요

 

 

 

 

 


Server-client Model


서버는 특정한 서비스를 제공하는 컴퓨터를, 클라이언트는 이러한 서비스를 이용하는 사용자를 의미한다.

 

 

 

 

 

 

 


Server의 종류


 

 

 

 

 

 

 

 

 

 

웹통신 개요

 

 

 


Web통신구조


 

 

 

 

 

 


Web Server란?


  • 사용자에게 HTML 페이지나 jpg,png와 같은 이미지를 HTTP프로토콜을 통해 웹 브라우저에 제공하는 서버
  • 내부의 내용이 이미 만들어져 있는 정적인 요소들을 화면에 보여주는 역할을 한다.

 


Web Server의 종류


 

Apache Software Foundation 에서 만든 서버로 HTTP 통신에 대한 여러 라이브러리를 제공한다.
Window OS에서 제공하는 웹 서버로, 높은 수준의 보안성과 성능을 제공한다.
무료 오픈 소스 서버로, 사용자 요청을 스레드가 아닌 확장성이 있는 이벤트 기반설계를 통해 필요 리소스만 할당하여 사용한다.

 

 

 

 

 

 

 

 

 

WAS 란?


Web Application Server의 약자로, 사용자가 요청한 서비스의 결과를 스크립트 언어 등으로 가공하여 생성한 동적인 페이지를 사용자에게 보여주는 역할을 한다.

 

 

Apache Software Foundation에서 Servlet과 JSP를 통한 동적인 웹 문서를 처리하기 위해 만든 웹 애플리케이션 서버
Jboss라고도 불리며, 톰캣이 제공하는 servlet container뿐만 아니라 EJB container를 별도로 제공하여 폭넓은 서비스를 구현
국산 WAS, 대용량의 데이터 트랜잭션을 고성능으로 처리하며 개발 및 운영에 관한 기술 지원이 뛰어나다.

 

 

 

 

 

 

 

 

 

 

 

CGI와 WAS

 

 

 

 


CGI(Common Gateway Interface)


  • 웹서버가 직접적으로 웹 프로그램을 실행하는 것을 말한다. 동일한 프로그램에 대한 요청이 있을 때 마다 각각 프로그램을 실행, 요청과 프로그램이 1:1 매칭되어 실행
  • Perl이나 C/C++ 언어를 사용하여 웹서버가 실행할 수 있는 프로그램을 작성

 

 

 

 

 

 

 

 

WAS(Web Application Server)


웹서버가 웹 애플리케이션 서버에 요청하면 웹 애플리케이션 서버가 해당되는 프로그램을 실행하는 방식, 한 프로그램에 여러 요청이 있는 경우 한 개의 프로그램을 실행하여 그 프로그램을 다수 요청을 처리

 

 

 

 

 

 

 

 

 

 

 

 

CGI와 WAS

 

 


서블릿 컨테이너(Servlet-Container)


  • 서블릿의 생명주기를 관리(생성,초기화,소멸), HttpServletRequest, HttpResponse객체를 생성 요청에 따라 멀티스레딩 구성, 전송방식에 따라 동적으로 페이지 구성하는 작업진행
  • 정적로딩처리

 

 


JSP 컨테이너(JSP-Container)


  • JSP파일을 다시 java코드로 변경해주고 class파일로 전환하여 메모리 공간에 로드한 뒤 실행 가능하게 만드는 작업을 진행(Servlet화)
  • 처리결과를 HTML파일로 만들어주는 작업진행
  • 동적로딩처리

 

 

 

 

 

 

 

 

 

 


Web Server VS WAS


 

 

 

 

 

 

 

 

 

 

 

'Programming > Servlet&JSP' 카테고리의 다른 글

6. 서블릿 필터와 래퍼  (0) 2022.03.03
5. Session과 Cookie  (0) 2022.03.03
4. 서블릿 메소드  (0) 2022.02.28
3. 서블릿(Servlet)  (0) 2022.02.28
02. 웹 애플리케이션 개발환경 구축  (0) 2022.02.28

+ Recent posts