JSP & 서블릿

ChoRong0824·2023년 3월 23일
1

Web

목록 보기
21/25
post-thumbnail

서블릿에 대해 자세히 파헤쳐 보도록 하겠습니다.
제가 매일 공부한 곳까지 수시로 업데이트 할 예정입니다.
그래서 내용이 체계적이지 않을 수 있다는점 양해바랍니다.


웹 프로그래밍이란 ?

  • 웹 상에서 사용자와 기업 또는 사용자들 간의 연결을 가능하게 하는 프로그래밍 언어
  • (사용자에 의해 동적 변화)데이터는 사용자에 의해 계속적으로 변화된다.
  • 클라이언트(client)와 서버(server)로 구축되어있음.
    즉, 클라이언트(사용자)가 요청(request, 결과 보여달라고)을 웹 서버에 보내면 응답(response) 형태로 구성됨. (자세한 내용은 http 참고)

동적 데이터 처리 (CGI, ASP, PHP,JSP 등)

CGI

  • 응용 프로그램과 웹 서버 사이의 정보를 주고받는 방식이나 규약들을 정해 놓은 것이며,
    웹 서버에서 동적인 데이터를 처리해 클라이언트에 HTML 문서로 전송하기 위해
    (크게, ASP, PHP,JSP 등)

ASP

  • Active Server Page, 스크립트 언어를 사용해서 구성된 기술 (jsp에 비해 안좋음)

PHP

  • c를 기반으로 만들어진 스크립트언어 (보안상 약점있음)

JSP

  • 스크립트 기반으로 개발되어 서버 페이지를 훨씬 쉽게 작성 가능.
    서블릿과 함께 구동함으로써 서블릿의 기능을 그대로 사용할 수 있고 강력한 객체지향적 지원이 가능

서블릿

은 자바를 기반으로 만들어졌기에, 객체지향적이며 플랫폼 독립적인 자바의 장점을 그대로 웹에서 구현할 수 있었으며 스레드(Thread) 기반의 요청 처리 방식을 채택해서, 사용자가 많을수록 효율적으로 동작하는 강력한 기술입니다.


프로세스

  • 실행중인 프로그램을 나타내는 말
    실행중인 상태의 프로그램을 우리는 프로세서 또는 태스크라 부른다.

쓰레드

  • 하나의 프로세스 내에서 해당 프로세스가 할당받은 자원을 공유하며 실행되는 독립적인 작업단위, 프로세스의 자원을 참조할 뿐 새로 할당받을 필요 없어서 프로세스 생성보다 생성속도 빠름.

틈날때마다 자주 읽기

HTTP



인터페이스 (Interface)

  • 서버와 응용프로그램 간의 원활한 통신이 가능하도록 만들어진 규약

스크립트 언어

  • C 나 일반적인 프로그래밍 언어는 컴파일러에 의해 컴파일 되어 2진수로 되어있는 기계어로 변환되어야지만 컴퓨터 상에서 실행될 수 있습니다. 이와달리 컴파일이 필요 없이 해석기(인터프리터)에 의해 즉시 실행될 수
    있는 프로그램 언어를 스크립트 언어라고 합니다.

(다시)

참고로, 이전에는 JSP로 웹 개발이 많이 진행되었으나 현재는 JSP를 안쓰는 추세이며 JSP 대신 Thymeleaf를 사용하는 추세입니다.
but, 어느정돈 알아야 한다고 필자는 생각합니다. JSP가 이전엔 많이 쓰였기 때문입니다.
또한, JSP와 서블릿 관계는 필수적으로 체크하고 넘어가려합니다.

JSP

  • 서버에서 동작하며, 클라이언트 페이지와 상호작용함. (웹서버를 통해서)
  • 자바를 이용하여 동적인 웹 페이지를 만들기 위해 개발한 기술
  • 클라이언트가 JSP 페이지 요청을 하면 JSP 페이지 코딩 내용이 HTML 페이지 형태로 변환되면 HTML 형태로 변환된 내용이 최종적으로 브라우저에서 해석되어 사용자에게 보여진다는 구조
  • JSP 문서는 기본적인 HTML의 형식과 자바 문법 형식이 혼합되어 있는 형태임.
    (동적인 기능 + 보안의 기능) <% 여기에 내용 들어감 %>

특징

  1. 강력한 이식성

  2. 서버 자원의 효율적인 사용

    • 쓰레드 기반의 아키텍처를 사용하여 개선. 즉, 최초 요청이 웹서버에 오면 서버는 그 요청에 맞는 JSP 페이지에 대한 서블릿 인스턴스를 단 한 번만 생성, 이후 같은 페이지를 요청하는 사용자가 있을 경우 이미 생성되어 있는 인스턴스에 쓰레드 단위로 요청을 전송하여 처리 - > 효율적
  3. 간편한 MVC 패턴 적용
    - 사용자에게 보이는 View, 실제 비즈니스 로직이 들어가는 Model,
    View 와 Model을 연결시켜주는 Controller 부분으로 구성됨(MVC)
    이러한 MVC 패턴을 JSP(View), 자바빈즈(Model), 서블릿(Controller)을 이용해 쉽게 구현가능.

인스턴스

  • 클래스로부터 만들어진 객체를 뜻하며, 어떤 클래스를 객체로 만드는 과정을 인스턴스화라고 합니다.

디자인 패턴

  • 지침서, 프로젝트 개발함에 있어서 특정한 문제가 주어졌을 때 그 문제를 해결하기 위한 방법을 설명해놓음

서블릿과 비교되는 장점

  • 서블릿 페이지는 전체 코드가 자바코드로 이루어졌고, HTML코드를 자바 코드안에 생성해야해서 화면 내용을 구성하기 불편
  • JSP는 HTML 태그로 구성. JSP 필요한 부분은 <% %> 안에 삽입하면 되서 화면 내용 구성이 편함.

서블릿

  • 자바 코드를 써서 웹페이지를 만드는 것.

  • 브라우저는 기본적으로 HTML 형식의 문서만을 표시할 수 있고, 사용자의 요구에 따라 HTML 페이지를 전송해줄 기술이 필요해서 개발된 기술중 하나

  • 자바의 모든 API를 그대로 사용할 수 있어서 강력한 객체지향성등 자바 장점도 갖춤

  • 중요 !
    서블릿은 반드시 javax.servlet.Servlet 인터페이스를 구현해서 작성해야만 하며 입력과 출력을 HTTP 프로토콜의 요청(Request), 응답(Response)의 형대로 다룸.
    즉. 서버 사이드의 자바 응용 프로그램임.


파싱

코드를 해석해서 그에 맞는 변화 코드로 바꾸는 작업

프로토콜

컴퓨터 상호간의 대화에 필요한 통신 규약

파라미터

HTML 코드의 form 태그 안에 정의된 인자들을 파라미터
폼 전송이 일어날 때 HTTP 요청 메시지에 담겨서 폼 태그 내의 action에 정의된 URL로 전송된다.
폼 태그의 method가 GET으로 명시되는가, POST로 명시되는가에 따라 전송되는 방식이 달라진다.


결론, JSP 와 서블릿 차이

사실 기능의 차이는 거의 없다고 봐도 무방합니다.
둘 다 java를 이용하여 웹 페이지(html의 정적으로 한정되었던)를 동적으로 생성 하기 때문입니다.
but, 역할의 차이는 있습니다.

서블릿

은 사용자가 입력한 값을 바탕으로 멤버 객체를 생성하고, 그 객체를 db에 저장 합니다.
그리고 html 코드에 동적으로 생성한 멤버의 정보를 중간에 껴넣음으로써 동적인 웹 페이지를 제공할 수 있게 됩니다.
여기까지 내용은 좋습니다. 하지만 서블릿에는 크나큰 단점이 있습니다.
단점,
자바 코드 안에 html 코드를 일일이 기입해야한다는 것입니다. 오타가 발생할 가능성이 상당히 높으며, 유지보수는 생각만해도 어우.. 끔찍합니다.

예시,

	printWriter.write("<html>\n"+
    "<head>\n"+
    "<meta charset =\"UTF-8\">\n+
    ...

서블릿 소스를 잘 살펴보면 <HTML>,<BODY> 등 HTML 태그를 사용자의 브라우저에 전송하기 위해 response.getWrite()를 사용해 PrintWriter 객체를 얻어와서 일일이 write()메소드를 사용해야 합니다.

JSP

이러한 서블릿의 단점을 보완하기 위해 나온 기술이 바로 JSP 입니다.
JSP는 자바 코드 안에 HTML 코드를 작성하는 것이 아니라 HTML안에 자바 코드를 껴 넣는 방식으로 동적인 웹 페이지를 제공할 수 있습니다.

예시, <% %>안에 넣어줌.

<%
final MemberRepository memberRepository = MemberRepository.getInstance();
final String username = request.getParameter("username");
%>

웹 컨테이너란?

웹 서버 내부에서 서블릿 클래스 또는 JSP 파일을 실행하기 위한 실행 환경을 제공하는 역할을 하며, 특히 서블릿 클래스에 대한 웹 컨테이너를 서블릿 컨테이너, JSP 파일에 대한 웹 컨테이너를 JSP 컨테이너라고 함.
다만 실제적으로 둘을 혼용하여 웹 컨테이너 로 통칭합니다. 대표적으로 (톰캣)


service() 메소드 호출과 서블릿 클래스 실행

스레드가 생성되면 각 스레드에서 service() 메소드가 호출됨.
HTTP 요청 방식이 GET 방식일 경우에는 서블릿 클래스의 doGet() 메소드가
POST 방식일 경우에는 doPostt()메소드가
request, response 객체를 인자로 자동으로 호출함


코드 분석

ServletTest.java

// 코드 분석할 코드만 빼내서 해석할 예정입니다.

public class SErvletTest extends HttpServlet{
	resopnse.setContentType("text/html");
	PrintWriter out = response.getWriter();
    out.write("<HTML><HEAD><TITLE>ServletTest</TITLE></HEAD>");
    out.write("<BODY><H!>");
    out.write("현재시각은"):
  1. 서블릿 클래스를 정의하는 부분이며, HttpServlet 클래스를 상속받습니다.
  2. 응답 데이터의 마임 타입을 HTML 타입의 데이터로 지정
  3. 응답(response)에 내용을 출력할 출력스트림을 생성 (화면에 출력하기 위해)
    4~6. 클라이언트로 응답할 내용을 응답에 html 타입의 데이터로 출력하는 부분

web.xml

<servlet>
<servlet-name>ServletTest</servlet-name>
<servlet-class>ServletTest</servlet-class>
</servlet>

<servlet-mapping>
<servlet-name>ServletTest</servlet-name>
<url-pattern>/test</url-pattern>
</servlet-mapping>

web.xml 파일의 서블릿 관련 부분은 웹 컨테이너에게 어떠한 (url)요청이 어떤 것인지를 알려주는 파일입니다.
1~4 : 서블릿 클래스를 지정하는 부분
5~8 : url 상의 요청명과 서블릿을 연결해 주는 부분
6 : 서블릿의 이름을 배정
7 : 서블릿 이름에 대한 클래스를 명시
<servlet> 태그로 묶인 부분과 <servlet-mapping> 태그로 묶인 부분은 1 : 1 매칭이 되어야 합니다.


톰캣 재가동

web.xml 파일을 수정하였으므로 톰캣을 재가동(서버 재시작)을 해야 합니다.
(설정 파일을 수정하였을 경우, 무조건 서버를 재시작하는 것이 안전합니다.)


서블릿의 동작 원리

(다시)
최초 요청이 이루어졌을 때에만 전부 거치게 되고, 같은 페이지에 대한 두 번째 요청부터는 이미 생성된 인스턴스에서 쓰레드만 하나씩 생성되어 service()메소드를 호출합니다.
-> JSP 파일이 서블릿으로 변환되는 과정은 오직 한 번만 일어나므로 같은 페이지에 대한 수많은 사용자의 요청이 있더라도 처리 속도는 거의 떨어지지 않게 됩니다.


서블릿 라이프 사이클

  • 클라이언트의 첫 번째 요청이 들어오면 서블릿 객체가 생성되고 init 메소드가 호출되어 서블릿에 필요한 초기화 작업을 수행함.
  • 즉, init 메소드는 첫 번째 클라이언트의 요청이 들어올 때만 서블릿 생애 주기 중 단 한 번만 호출됨.
  • 두 번째 요청부터는 요청 하나당 service 메소드가 한 번 호출됩니다.
  • 컨테이너에서는 service 메소드를 호출하기 전에 HttpServletRequest 객체와 HttpServletResponse 객체를 생성하여 service 메소드에 파라미터로 전송합니다.
  • service 메소드에서는 클라이언트의 요청이 GET 방식으로 넘어왔으면 doGet 메소드를 호출, 요청이 POST 방식으로 넘어왔으면 doPost 메소드를 자동으로 호출

Servlet의 핵심 사항들

웹 클라이언트에서 서블릿으로 요청하는 방식은 GET , POST 두 가지 방식

GET

GET 방식으로 요청이 전송되는 경우

  1. 브라우저 주소 표시줄에 주소를 직접 입력해서 요청을 전송하는 경우
  2. Html 의 a 태그를 사용해서 링크를 걸어서 전송하는 경우
    <a href="list.jsp">목록보기</a>
    참고로 하이퍼링크는 무조건 GET
  3. Html 폼 태그에서 method 속성을 GET으로 지정하는 경우
    <form action=" " name=" " method="GET">

POST

POST 방식으로 요청을 서버로 전송하려면 반드시 Html 의 form 태그를 사용하여 method 속성을 POST 로 지정해야 합니다. (생략시 GET)


어노테이션/애노테이션(Annotation)

기존에 설정파일(web.xml 등)에서 제공하는 설정 내용들을 설정 파일에서 설정하지 않아도 해당 소스 내에 설정 할 수 있는 방법을 제공함으로써 설정 파일의 크기를 줄이거나 설정 파일 자체를 없앨 수 있는 역할을 하는 기능입니다.


서블릿 페이지 코딩

@WebServlet("/boardList")
public class BoardListServlet extends HttpServlet{
  1. 서블릿이 "boardList" URL로 전송되어 오는 요청을 처리하도록 설정하는 부분
protected void doGet(HttpServletRequest request, ...)
  1. doGet : GET 방식일 때, 자동으로

주소 표시줄에 URL을 직접 입력하여 요청하는 GET 방식의 요청 방식

@WebServlet("/directURL")
public class DirectURLServlet extends HttpServlet{

POST 방식으로 요청이 전송되어 올 경우

요청 처리를 수행할 때, doGet이 아닌 doPost 메소드에서 요청이 처리됩니다.


서블릿에서 한글 처리하기

한글 처리가 제대로 되기 위해서는 클라이언트
즉, 브라우저에서 문자를 처리하는 방식과 서버에서 문자를 처리하는 방식이 같아야합니다.

즉, 브라우저에서는 문자를 euc-kr 방식으로 처리하는데 서버에서는 ISO-8859-1 방식으로 처리하게 되면 한길이 깨지는 결과가 됩니다.

따라서, 서버와 클라이언트 문자를 동일하게 처리해줘야합니다.
기본적으로 톰캣 서버에서 사용하는 캐릭터셋은 UTF-8 방식이므로 한글이 제대로 인식되려면 아래와 같은 방법 중 하나를 사용해서 캐릭터 셋을 변경해줘야합니다.

1. GET 방식 요청

  1. 한글 처리용 클라이언트 페이지를 작성하는 것이비다.
<meta charset="UTF-8">
  • 서버로 전송되는 한글 파라미터 값이 제대로 처리 되도록 하기 위해서 페이지 인코딩 방식을 지정해줌.
  1. 한글 처리용 서블릿 페이지 작성 (doGet)

2. POST 방식 요청

  1. form 태그의 method 속성을 POST 로 변경

  2. 한글 처리용 서블릿 페이지 작성 (doPost)

  3. 클라이언트 요청 방식이 GET 방식에서 POST 방식으로 변경
    POST 방식으로 요청이 전송되어 올 경우는 요청 파라미터 값이 요청 body 영역에 따로 인코딩되어 넘어 오기 때문에 URLEncoding 설정만으로는 한글이 제대로 처리 되지 않습니다. (한글이 깨지게 됨)

    이럴 경우, (클라이언트에서 POST방식으로 전송되어온)
    한글 파라미터 값을 제대로 처리하려면 request 객체의setCharacterEncoding 메소드를 사용하여 request 객체의 body 영역의 인코딩 방식을 변경 해주어야 합니다.
    request.setCharacterEncoding("UTF-8"); // body 영역에 대한 한줄 인코딩

주의 !, 인코딩은 반드시 파라미터 값을 받기 전에 처리해야 한다는 것입니다.


하나의 파라미터 이름으로 여러 개의 파라미터 값이 전송되어 올 경우 처리하기

HttpServletRequest 인터페이스에서 제공되는 String[ ] getParameterValues(StringparamName) 메소드를 사용해서 처리해야 합니다.


서블릿에서 세션 살펴보기

  • 세션이란?
    HTTP 프로토콜의 대표적인 특징 중의 하나는 상태를 유지하지 않는다는 것입니다.
    HTTP의 이런 특징 때문에 웹 서버는 동시에 여러 개의 요청을 효과적으로 처리할 수 있는 것입니다.

    여기서 질문, HTTP 프로토콜 이란?

but, HTTP 프로토콜의 상태를 유지하지 않는 특징 때문에 로그인, 장바구니 등 상태가 유지되어야 할 프로그램을 작성하기는 힘듭니다.

이러한 단점을 보완하기 위한 방법이 바로 세션(session)
세션은 서블릿에서 클라이언트와 서버의 상태를 유지하기 위해 제공되는 API 이다.

참고,

서블릿에서는 세션을 다룰 수 있는 HttpSession 인터페이스를 제공하고 있습니다.


세션

세션(session)이란 웹 사이트의 여러 페이지에 걸쳐 사용되는 사용자 정보를 저장하는 방법을 의미합니다.
사용자가 브라우저를 닫아 서버와의 연결을 끝내는 시점까지를 세션이라고 합니다.
앞서 살펴본 쿠키는 클라이언트 측의 컴퓨터에 모든 데이터를 저장합니다.
하지만 세션은 서비스가 돌아가는 서버 측에 데이터를 저장하고, 세션의 키값만을 클라이언트 측에 남겨둡니다.
브라우저는 필요할 때마다 이 키값을 이용하여 서버에 저장된 데이터를 사용하게 됩니다.
이러한 세션은 보안에 취약한 쿠키를 보완해주는 역할을 하고 있습니다


포워딩이란 ?

  • 서블릿에서 "포워딩(forwarding)"은 클라이언트 요청을 받은 서블릿이 다른 서블릿이나 JSP로 요청을 전달하는 것을 말합니다. 포워딩을 사용하면, 클라이언트는 서블릿으로부터 응답을 받는 것이 아니라, 포워드된 서블릿이나 JSP에서 생성된 응답을 받게 됩니다.

  • 예를 들어, 클라이언트가 "http://localhost:8080/myapp/myservlet" URL로 요청을 보냈다고 가정해보겠습니다. 이 요청을 받은 "myservlet" 서블릿이 "http://localhost:8080/myapp/myjsp.jsp" JSP 페이지로 포워딩을 하면, 클라이언트는 마치 "http://localhost:8080/myapp/myjsp.jsp" 페이지로 직접 요청을 보낸 것과 같은 결과를 받게 됩니다.

포워딩은 주로 다음과 같은 경우에 사용

  • 서블릿에서 처리한 데이터를 JSP에서 출력하기 위해
  • 서블릿에서 처리한 데이터를 다른 서블릿에서 사용하기 위해
  • 여러 개의 서블릿을 연결하여 작업을 분리하기 위해
  • 에러 처리를 위해 에러 페이지로 포워딩하기 위해

서블릿에서 포워딩을 하려면, HttpServletRequest 객체의 forward()메서드를 호출하면 됩니다. 이 메서드는 요청을 전달할 URL을 인자로 받습니다.


서블릿에서 특정 페이지로 포워딩하는 두 가지 방법

1. Dispatcher 방식

이 방식으로 포워딩을 하게 되면 주소 표시줄의 주소가 변경되지 않습니다.
즉, 하나의 요청이라는 의미입니다. 따라서, 같은 request 영역을 공유하게 됩니다.

DispatcherServlet.java

protected void doGet (HttpServletRequest request, 
HttpServletResponse reesponse) throws ServletException, 
IOException{
	RequestDispatcher dispatcher = 
	    request.getRequestDispatcher("dispatcher.jsp");
        request.setAttribute("request",:requestValue");
        dispatcher.forward(request, response);
        }

5 : 포워딩 할 주소. (주소 노출이 안됨)

브라우저 주소 표시줄 URL에 변경이 없었으며 서블릿과 jsp가 같은 request 영역을 공유하기 때문에 포워딩된 jsp 페이지에서 request 영역에 공유되어 있는 값에 접근이 가능합니다.

포워딩 이란? 사용자가 특정 도메인 주소를 비슷하게만 쳐도 아니, 다르게 쳐도 그 입력한 값을 사전에 대상
도메인으로 가게끔 설정해두는 것을 말한다.


2. Redirect 방식

포워딩될 때 브라우저의 주소 표시줄 URL이 변경되므로 요청이 바뀌게 됩니다.

주소가 바뀌는 것 : 새로운 요청 (Request)

RedirectServlet.java

protected void doGet (HttpServletRequest request, HttpServletResponse) 
throws ServletException, IOException{
			request.setAttribute("request", "requestValue");
            response.sendRedirect("redirect.jsp"); // 포워딩 주소
            }

포워딩주소 확인
response.sendRedirect(String url) 메소드가 리다이렉트 방식으로 해당 URL로 포워딩을 해주는 메소드입니다.


문제 (답은 댓글로 남겨주시면 감사하겠습니다.)

  1. HTTP 프로토콜이란 ?

  2. JSP와 서블릿의 차이점?

  3. 위에 보면 서블릿 컨테이너에 대해서 설명했는데, 이것이 무엇입니까 ? 그리고 어떤 역할을 하나요 ?

  4. 서블릿에서 데이터 저장은 언제쓰며, 저장하는 방법은 무엇이 있을까요?

  5. 서블릿에서 request와 response 객체에 대해 알려드렸습니다. 어떤기능을 갖고 있으며, 각각의 개념은 ?

  6. 서블릿 lifecycle에 대해 틀린 것은 ?
    a. 컨테이너는 클라이언트 요청 분석 후 서블릿을 결정한다.
    b. 서블릿에서, init 메소드는 요청마다 생성된다.
    c. service 메소드의 호출은 2 번째 요청부터 호출되며, 서블릿 생애 주기 중 단 1번만 호출된다.
    d. 클라이언트의 요청에 따라 doGet || doPost 메소드를 호출합니다.

  7. 서블릿에서 GET 방식으로 요청되지 않는 경우는 ?
    a. GET 방식으로 요청이 전송되는 경우
    b. 서블릿이 초기화되지 않은 경우
    c. PUT, DELETE, HEAD 등의 HTTP 메서드로 요청된 경우
    d. 잘못된 URL로 요청된 경우
    e. 폼 태그에서 method 속성을 GET
    f. HTTP/1.1에서 요청 메서드가 정의되지 않은 경우
    g. 주소를 직접 입력해서 요청을 전송하는 경우
    h. a 태그를 사용해서 링크를 걸어서 전송

profile
컴퓨터공학과에 재학중이며, 백엔드를 지향하고 있습니다. 많이 부족하지만 열심히 노력해서 실력을 갈고 닦겠습니다. 부족하고 틀린 부분이 있을 수도 있지만 이쁘게 봐주시면 감사하겠습니다. 틀린 부분은 댓글 남겨주시면 제가 따로 학습 및 자료를 찾아봐서 제 것으로 만들도록 하겠습니다. 귀중한 시간 방문해주셔서 감사합니다.

8개의 댓글

comment-user-thumbnail
2023년 3월 26일

정답은 답글의 답글을 펼치면 정답이 다 있습니다.
댓글 먼저 작성 후 답글 확인 부탁드립니다.

4개의 답글