본문 바로가기
Programming/JSP

JSP - 2일차

by yoon9i 2024. 5. 21.

######################################################################
#####################################################################
2일차

1. 서블릿(Servlet)
   - servlet-api.jar 안의 패키지 이용
     javax.servlet.http 패키지의 HttpServlet 클래스 이용.
   - Java EE API 문서 참고.
     https://javaee.github.io/javaee-spec/javadocs/

   - HttpServlet 의 계층구조


       Servlet(인터페이스): init(),destory(),getServletConfig(),service(,) 
                      , ServletConfig(인터페이스):getInitParameter(String name),getServletContext() 
             |
             |  
       GenericServlet (추상클래스)
             |   :  service(,)
   init(),destroy()
   getServletConfig()
   getServletContext()
   getInitParameter(String name)
             |
       HttpServlet (추상클래스)
                 : doGet(HttpServletRequest request, HttpServletResponse response)
                   doPost(HttpServletRequest request, HttpServletResponse response)
                   doPut(,),doDelete(,)
                  service(,)
                  init(),destroy()
                  getServletConfig()
                 getServletContext()
                 getInitParameter(String name)
             |
             |
 MyServlet (우리가 만들 서블릿 )
     ==> extends HttpServlet 코드를 작업을 하면
         웹브라우저의 요청을 처리할 수 있는 클래스가 된다.


     - 서블릿을 작성하는 순서
       1> extends HttpServlet
       2> doGet(HttpServletRequest request, HttpServletResponse response)
          또는 
          doPost(HttpServletRequest request, HttpServletResponse response)
  메서드를 재정의.
  기본 서비스 메서드는 doGet().
                 
    요청(url입력,링크클릭,새로고침,버튼클릭...
 submit )
  웹브라우저 ------------------------------------> 서버
                        get요청 ------------------------> 서블릿의 doGet 요청처리
                        post요청 ------------------------> 서블릿의 doPost 요청처리

       요청의 대부분은 GET 방식으로 요청됨.
       POST로 요청하는 단 하나의 경우는?
       <form method="post">

3> doGet/doPost 메서드에서 비즈니스로 로직 처리하고 html 작성해서 응답처리.
   - 요청처리(비즈니스 로직 처리)
             ==> 사용자의 요청처리( 폼데이터 처리 예> id/pw 얻기)
     ==> 유효성 체크 ( DB 연동 )
     ==> HttpServletRequest request 담당 ( 메서드가 처리 )

           - 응답처리
     ==> 비즈니스 로직 처리에 대한 결과(id/pw 맞다/틀리다)를
         사용자에게 알려주는 작업의미.
             ==> HttpServletResponse response 담당 ( 메서드가 처리 )

4> 서블릿 맵핑
  
   - web.xml
   - @WebServlet("/서블릿맵핑값")

package com.servlet;

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;

// 요청url: http://localhost:8090/app/xxx
@WebServlet("/xxx")
public class MainServlet extends HttpServlet {

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

		System.out.println("MainServlet.doGet"); // tomcat의 console 에 출력되.
		//요청처리
		
		//응답처리
	
	
	}
}
package com.servlet;

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;

// 요청url: http://localhost:8090/app/xxx2
@WebServlet("/xxx2")
public class HelloServlet extends HttpServlet {

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

		System.out.println("HelloServlet.doGet"); // tomcat의 console 에 출력되.
		//요청처리
		
		//응답처리
	
	
	}
}




2. 서블릿 맵핑 

    - web.xml
    <servlet>
<servlet-name>TestServlet</servlet-name>
<servlet-class>com.servlet.TestServlet</servlet-class>
    </servlet>
    <servlet-mapping>
<servlet-name>TestServlet</servlet-name>
<url-pattern>/xxx3</url-pattern>
    </servlet-mapping>

    - @WebServlet("/서블릿맵핑값") <== eclipse가 자동으로 지원 맵핑 방법

package com.servlet;

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;

// 요청url: http://localhost:8090/app/xxx3
// web.xml로 맵핑
public class TestServlet extends HttpServlet {

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

		System.out.println("TestServlet.doGet"); // tomcat의 console 에 출력되.
		//요청처리
		
		//응답처리
	
	
	}
}
<?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">
 
    <!--  서블릿 맵핑  -->
    <servlet>
        <servlet-name>TestServlet</servlet-name>
        <servlet-class>com.servlet.TestServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>TestServlet</servlet-name>
        <url-pattern>/xxx3</url-pattern>
    </servlet-mapping>
    
</web-app>




3. 서블릿 특징
 
   - main 메서드가 없다.( 시작점이 따로 없다는 의미)
    즉 사용자가 맨 처음 요청하는 서블릿이 시작점 역할을 담당한다.
   - 서블릿을 명시적으로 new(객체생성) 안함.
     Tomcat이 서블릿/JSP의 LifeCycle(생성~소멸)을 관리한다.
   - 서블릿은 단 한번만 생성됨. 
     thread-unsafe: 인스턴스변수
     thread-safe: doGet의 로컬변수 (*****)

4. 서블릿의 LifeCycle 

  - 콜백 메서드가 제공됨.

  가. 서블릿 생성될 때 호출되는 콜백 메서드
    - init()
    - 용도: 서블릿이 생성될 때 초기화 작업 처리.
    - 중요: 
       서블릿은 단 한 번만 생성됨. 따라서 init() 메서드도 단 한번만 호출됨.
       따라서 서블릿에서 인스턴스 변수를 작성하면 여러 사용자들이 공유하게 됨.(보안에 매우 취약해짐)
            인스턴스 변수 사용은 권장안함.
       thread-unsafe 하다고 함.
       thread-safe하게 작성하는 방법은 doGet의 로컬 변수로 작성해야 된다.


  나.  서블릿 요청될 때 호출되는 콜백 메서드
    - doGet/doPost
    - 용도:  요청처리 와 응답처리

  다.  서블릿 소멸될 때 호출되는 콜백 메서드
     - destory()
     - 용도: 서블릿이 소멸될 때 clean up 작업 처리.

package com.servlet;

import java.io.IOException;

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

	int num = 10; // 인스턴스 변수 thread-unsafe 함.
	
	@Override
	public void destroy() {
		System.out.println("destroy");
	}

	@Override
	public void init(ServletConfig config) throws ServletException {
		System.out.println("init");
	}

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		System.out.println("doGet");
		
		int size =20; // 로컬변수, thread-safe 함.
	}
}



5.  서블릿의 응답처리
 
  - 응답처리 개념
    ==> 웹브라우저에서 볼 수 있도록 html 작성하는 처리의미.
  - 담당
    => doGet의 두 번째 파라미터인 HttpServletResponse 가 처리함.

  - HttpServletResponse 인터페이스의 메서드 확인

     response.addCookie(Cookie cookie): 쿠키 저장할 때 사용. 300개가 가능
     response.addHeader(String name, String value) : 응답 헤더에 헤더값을 추가할 때 사용.
     response.getHeader(String name) : 응답 헤더값을 얻을 때 사용.
     response.getStatus():           응답에 대한 status 값
    
     response.sendRedirect(String location): 서블릿에서 JSP로 위임할 때 사용.
     response.setContentType(String type)   :  웹 브라우저에게 처리할 데이터의 종류를 알려주는 기능.
                                               MIME 타입이라고 부름
       Servers > web.xml 에서 종류 확인 가능.
       예> text/plain : 일반 텍스트로 전달
          text/html:   html로 전달
  application/json: JSON으로 전달

     PrintWriter out = response.getWriter();
     out.print(값);  // 이 값이 웹 브라우저에 출력됨.

     System.out.println(값);  // tomcat의 console에 출력

    


     * 헤더 정보(header)

                     요청
     (요청헤더가 전달됨)
      method:get
      Accept:text/html;~~~
      Accept-Language: ko-kr,~
      User_Agent: Mozilla~
     웹브라우저 ----------------------------> 서버
                        <----------------------------
                                   응답
                         (응답헤더가 전달됨)
                          Content-Type:text/html; charset=utf-8

 - 웹브라우저에 html 출력하는 방법

   가. MIME 설정
     response.setContentType("text/html");  // 한글처리: "text/html;charset=utf-8"

   나. html작성 출력
  
     PrintWriter out = response.getWriter();
     out.print("html코드");

  ==> 서블리에서 하는 응답처리는 쉽지않다.
     따라서 실제로는 서블릿에서 응답처리 하지 않음.
     대신 JSP에 위임해서 응답처리를 작업한다.

    예>
       1> 현재상황
                                      서버
       웹브라우저 ------------------>  서블릿
                 <------------------

      2> 변경된 구조

                                      서버
       웹브라우저 ------------------>  서블릿
                                                        |
                                                        | 위임( 2가지 방법)
                                                        |  -response.sendRedirect(String location):
                                                        |  -request.getRequestDispatcher(String path):
                      <------------------         jsp

package com.servlet;

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

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		System.out.println("doGet");
		
		// 응답처리
		response.setContentType("text/html;charset=utf-8");
		
		PrintWriter out = response.getWriter();
		out.print("<html>");
		out.print("<head>");
		out.print("<title>서블릿응답처리</title>");
		out.print("</head<");
		out.print("<body>");
		out.print("<h1>안녕하세요. Hello~~~</h1>");
		out.print("</body>");
		out.print("</html>");
	}
}



6.  서블릿의 요청처리

  - 요청처리 개념
    ==> 웹브라우저에서 요청했을 때 서블릿에서 처리하는 작업의미.
       예> 사용자입력 데이터 얻기.
           한글처리
   ..
  - 담당
    => doGet의 첫 번째 파라미터인 HttpServletRequest 가 처리함.

  - HttpServletRequest 인터페이스의 메서드 확인

     request.getContextPath() : 요청 URL에서 context명 얻을 때 사용.
     request.getCookies():      쿠키를 배열로 반환. Cookie[]
     request.getHeader(String name) : 요청헤더값 얻을 때 사용.
     request.getQueryString():    요청 URL에서 ?name=value&name=value
     request.getSession():      세션 얻을 때 사용. 매우중요(로그인시 사용됨)

     request.setAttribute(key,value);  // key/value쌍으로 데이터 저장할 때 사용
     request.getAttribute(key);        // key 이용해서 value 얻을 때 사용.
     
     request.setCharacterEncoding(String env):  "utf-8" 지정해서 한글처리 가능

     // 다음 4개이 메서드로 사용자 입력 데이터를 얻을 수 있다.
     request.getParameter(String name)
     ==> 무조건 String 반환됨.
     ==> 일치하지 않는 name을 지정하면 null 이 반환된다.
     ==> GET 방식으로 요청했을때 한글처리가 되서 한글이 잘 나옴.
     ==> POST 방식으로 요청했을때 한글처리가 안됨. 한글이 깨짐
          request.setCharacterEncoding("utf-8"); 사용하면 한글이 깨지지 않음. 

     request.getParameterNames():
     request.getParameterValues(String name):
     request.getParameterMap():


     request.getRequestDispatcher(String path):  서블릿에서 JSP로 위임할 때 사용.

- 요청처리 실습하기 위한 구조
                                                서버
                1> jsp 요청                               
    웹 브라우저 ------------------------------>  memberForm.jsp(회원가입화면)
                        <------------------------------
                         2> 응답
    3> html 랜더링
    id: aaa
    pw: 1234
                                         4> 요청
    로그인버튼클릭 ----------------------------> MemberServlet


7. 경로

    1> 절대경로
    - / 로 시작
    - 서블릿에서 / 는 다음 URL 에서 8090(port번호) 뒤의 / 를 의미한다
      즉, / 를 기준으로 경로를 선택하는 방법이다.

      ex>
            http://localhost:8090/app5/memberForm.html

            action="/login? <=== 8090/login 의미.
            href="/~"
            src="/~"


    2> 상대경로
    - / 로 시작안하고 . 또는 .. 사용
    - 현재 URL 에 보여지는 페이지의 경로를 기준으로 경로를 선택하는 방법이다.

8. 405 에러
- 발생되는 경우는 클라이언트의 method="get|post" 과 서블릿의 doGet|doPost 가 일치하지
  않는 경우에 발생됨.

 

package com.servlet;

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

	// ?userid=aaa&passwd=123
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		System.out.println("doGet");
		
		String userid = request.getParameter("userid");
		// String userid = request.getParameter("userid2");
		// 일치하지 않은 name 이 있으면 null 값을 return 해준다.
		String passwd = request.getParameter("passwd");
		
		System.out.println("userid: " + userid);
		// getParameter 는 String 반환되어서 password 도 String 으로 반환된다.
		System.out.println("passwd: " + passwd); 
	}
}
package com.servlet;

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

	// ?userid=aaa&passwd=123 --> POST 형식이라 보이지 않음.
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		System.out.println("doPost");
		
		// POST 방식의 한글처리
		request.setCharacterEncoding("utf-8");
		
		String userid = request.getParameter("userid");
		String passwd = request.getParameter("passwd");
		
		System.out.println("userid: " + userid);
		System.out.println("passwd: " + passwd); 
	}
}
// memberForm.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	<h1>1. getParameter 메서드 실습-GET 방식</h1>

	http://localhost:8090/app5/memberForm.jsp
	--->
	http://localhost:8090/app5/login : 404 error 발생
	<br>
	<br>
	절대경로로 사용할려면 아래의 방식을 사용한다.<br>
	form 의 action을 /login 으로 한다면 무조건 컨텍스트명을 명시해야함.
	<br>
	action="/login" --> action="/app5/login"
	<br>
	<br>
	상대경로로 사용할려면 아래의 방식을 사용한다.<br>
	form action="login"
	<br>
	<form action="login" method="get">
		아이디: <input type="text" name="userid"><br>
		비번: <input type="text" name="passwd"><br>
		<input type="submit" value="로그인">	
	</form>
	
	<h1>2. getParameter 메서드 실습-POST 방식</h1>
	http://localhost:8090/app5/memberForm.jsp<br>
	http://localhost:8090/app5/login
	
	<form action="login2" method="post">
		아이디: <input type="text" name="userid"><br>
		비번: <input type="text" name="passwd"><br>
		<input type="submit" value="로그인">	
	</form>
</body>
</html>

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

JSP 5일차 - MyBatis 연동  (0) 2024.05.24
JSP 5일차  (0) 2024.05.24
JSP 4일차  (0) 2024.05.23
JSP 3일차  (0) 2024.05.22
JSP 1일차  (0) 2024.05.20