8. 서블릿 & JSP

곰주·2022년 10월 19일
0

쏘의 학교 일기

목록 보기
8/10
post-thumbnail

목차

  • Servlet(서블릿)
  • JSP

1. Servelt

서블릿이란

서블릿은 JSP 표준이 나오기 전에 만들어진 표준으로, Java에서 웹 어플리케이션을 개발할 수 있도록 하기 위해 만들어졌다. Java 클래스를 웹에서 호출 및 실행할 수 있도록 하는 표준이다.


서블릿 작성 방법

Javax.servlet.http.HttpServlet 클래스로부터 상속받아서 작성할 수 있다.Javax.servlet.http.HttpServlet 클래스는 톰캣의 servlet-api.jar에 포함되어 있다.


서블릿 작성 과정

(1) 서블릿 규칙에 따라 Java 코드 작성
(2) 자바 코드를 컴파일 하여 클래스 파일 생성
(3) 서블릿 3.0부터는 @WebServlet 어노테이션을 사용
(4) 톰캣 등의 웹 컨테이너를 실행


서블릿의 요청 처리

요청 방식에 따라 doGet 이나 doPost 메서드를 재정의하여 처리하고, Service 메서드를 재정의하여 사용할 수도 있다.

cf. 세부사항

  • 서블릿 요청처리를 위해 오버라이딩한 메서드는 request객체를 이용하여 웹 브라우저의 요청 정보를 읽어온다.
  • 요청에 대한 응답을 전송할 때는 response 객체를 이용한다.
    -response 객체의 setContentType() 메서드를 이용하여 데이터 타입과 인코딩 방식을 지정해 준다.
  • 웹 브라우저의 데이터를 전송할 경우, PrintWriter 객체의 getWriter() 메서드를 호출하여 문자열 데이터를 출력한다.

서블릿 예제

  • 새로운 프로젝트 생성하기

[week02]라는 package 생성 후 해당 package 선택 후 "HelloServlet"이라는 이름으로 서블릿 생성

Source

package week02;

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("/HelloServlet")
public class HelloServlet extends HttpServlet {  // HttpServlet 상속받아짐. ttpServlet 메서드를 재정의(override)
	private static final long serialVersionUID = 1L;
       
    public HelloServlet() {
        super();
    }

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		PrintWriter out = response.getWriter();
		out.println("<html><body>");
		out.println("<h1>Hello Servlet</h1>");
		out.println("</body></html>");
		out.close();
	}

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

}

실행 결과


서블릿 호출 방법

  • Get 방식 : 주소에 매개변수를 붙여서 호출하는 방식
    • 주소에 매개변수를 붙여서 주소 표시줄에 입력하는 방법이다. (?로 구분)
    • <a> 태그를 이용하여 페이지를 요청하는 경우,
    • 자바 스크립트를 이용하여 요청하는 경우,
    • <form> 태그에서 명시적으로 GET 방식으로 요청하는 경우에 사용된다.
    • 매개변수의 데이터는 255자 이내이며 보안이 최약하다.
  • Post 방식 : 매개변수를 본문에 포함시켜 호출하는 방식
    • <form> 태그에서 명시적으로 POST 방식으로 요청하는 경우에 사용된다.
    • Get 방식과는 달리 데이터의 크기에 제한이 없고,
    • URL에 표시가 되지 않으므로 보안성이 우수하다.

서블릿 호출 예제 (1)

(1) Get 방식을 이용하여 서블릿 호출하기 (HTMl 문서에서 서블릿을 호출)

Source
HelloWorld_get.html

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

<form action = "HelloWorld" method = "get">
	<br>
	<h1> Get 방식으로 부르는 페이지입니다. </h1> 
	<br>
	<input type = "submit" value = "확인">
</form>
</body>
</html>

HelloWorld.java

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		PrintWriter out = response.getWriter();
		out.println("<html><body>");
		out.println("<h1> Hello Wrold Servelt doGet() Page </h1>");
		out.println("</body></html>");
		out.close();
	}

실행 결과


(2) Post 방식을 이용하여 서블릿 호출하기. (매개변수를 본문에 포함시켜 호출.)

HelloWorld_post.html

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

<form action = "HelloWorld" method = "post">
	<br>
	<h1> Post 방식으로 부르는 페이지입니다. </h1> 
	<br>
	<input type = "submit" value = "확인">
</form>
</body>
</html>

HelloWrold.java

protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		PrintWriter out = response.getWriter();
		out.println("<html><body>");
		out.println("<h1> Hello Wrold Servelt doPost() Page </h1>");
		out.println("</body></html>");
		out.close();
	}

실행 결과

doGet, doPost 메서드 내에 response.setContentType("text/html;charset=utf-8"); 적어주면 한글로도 나온다...

서블릿 호출 예제(2)

(1) HTML 문서에서 서블릿으로 데이터를 전송

  • Get 방식

Source

addrGet.html

<!DOCTYPE html>
<!-- Servlet 호출 예제 3 - HTML문서에서 서블릿으로 데이터를 전송 -->
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<form action = "Address" method = "get">
이름 : <input type = "text" name = "name"><br>
주소 : <input type = "text" name = "addr"><br>
<input type = "submit" value = "확인">
</form>
</body>
</html>

Address.java

package week02;

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("/Address")
public class Address extends HttpServlet { 
/* Address는 서블릿 클래스명.
접근지정자는 반드시 public이어야 함.
HttpSevlet을 상속받아야 함.
*/

	private static final long serialVersionUID = 1L;
       
    public Address() {
        super();
    }

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		response.setContentType("text/html;charset=utf-8");
        // 클라이언트에 응답할 페이지에 대한 환경설정.
		
		String name = request.getParameter("name");
        // name 변수명에 값이 저장되어 넘어온다.
        
		String addr = request.getParameter("addr");
		// addr 변수명에 값이 저장되어 넘어온다. text 타입으로 넘어오므로 String 타입으로 받음.
        
		PrintWriter out = response.getWriter();
		out.println("<html><body>");
		out.println(name + " 님은 " + addr + "에 사시는군요.");
		out.println("</body></html>");
		
		}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		request.setCharacterEncoding("utf-8");
		doGet(request, response);
	}

}

실행 결과


  • Post 방식

Source

addrPost.html

<!DOCTYPE html>
<!-- Servlet 호출 예제 3 - HTML문서에서 서블릿으로 데이터를 전송 -->
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<form action = "Address" method = "post">
이름 : <input type = "text" name = "name"><br>
주소 : <input type = "text" name = "addr"><br>
<input type = "submit" value = "확인">
</form>
</body>
</html>

Address.java는 위 소스코드와 동일함!

실행 결과



<form action = "Address" method = "get"> 에서 "Address"는 @WebServlet 어노테이션으로 URL mpping 즉, 요청할 서블릿이다.

<input type = "submit" vlaue = "확인"에서 "submit"은 해당 버튼을 클릭하면 서블릿이 요청되는 것이다.

<input type = "text" name = "name"> 에서 "text"는 전송되는 값의 데이터 타입으로, 보기와 같이 text인 경우에는 String 타입으로 전송된다. "name"은 해당 변수명에 값이 저장되어 서블릿으로 데이터가 전송되는 것이다.

잠깐!! 여기서 어노테이션...?

@WebServlet

서블릿 클래스의 요청을 위한 URL 매핑을 보다 쉽게 자바 클래스에서 설정할 수 있도록 제공되는 어노테이션인데, 어노테이션이란 문장이나 문서에 추가적인 정보를 기입하는 것이다. 자바 프로그램에 영향을 주는 것이 아니라, 컴파일 할 때 환경 설정을 변경해 줄 것을 알려 주는 주석 형태이다.

그렇다면 URL Mapping은 왜 필요한 걸까?

실제 서블릿 클래스명을 공개하지 않기 위함이다. 프로그램 개발자는 자신이 만든 서블릿 클래스의 위치를 알아야 하지만, 클라이언트는 URL을 입력하여 원하는 서비스만 얻으면 된다. 내부 경로나 파일명이 바뀌면 일일이 사용자에게 알려 주어야 하는데, URL 매핑을 이용하면, 내부 구조가 바뀌더라도 매핑 이름만 동일하면 URL 요청이 가능하다. 사용자에게 서블릿 구조와 파일명을 공개하는 것은 보안에 문제가 생길 수 있다.


서블릿 연습 문제 - 구구단 출력

  • HTML 문서에서 출력할 구구단 숫자를 선택한다.
  • 선택한 숫자를 서블릿으로 넘겨서 해당 숫자의 구구단을 출력한다.

Source

gugu.html

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1> 구구단 선택 </h1>
<form action = "Gugu" method = "get">
숫자: <select name = "number">
<option> 2 </option>
<option> 3 </option> 
<option> 4 </option> 
<option> 5 </option> 
<option> 6 </option> 
<option> 7 </option> 
<option> 8 </option> 
<option> 9 </option> 
</select> <br><br>
<input type = "submit" value = "확인">
</form>
</body>
</html>

Gugu.java

package week02;

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

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		response.setContentType("text/html;charset = utf-8");
		
		int num = Integer.parseInt(request.getParameter("number"));
		
		PrintWriter out = response.getWriter();
		
		out.println("<html><body>");
		out.println("<h3> 구구단" + num + "단</h3>");
		for (int i = 1; i <= 9; i++ ) {
			out.println(num + "*" + i + "=" + num*i + "<br>");
		}
		out.println("</body></html>");
		out.close();
	}
	
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doGet(request, response);
	}

}

실행 결과



2. JSP

JSP란

앞장에서 말했듯 서블릿의 단점을 보완하기 위한 스크립트 방식의 표준으로, 서버 쪽 모듈을 개발하기 위한 기술이다.

  • JSP 기본 구조
    HTML 문서 사이에 Java 문법의 코드가 삽입되는 형태로 작성된다.
<%@ page contentType = "text/html;charset=eue-kr"%>
<html>
<head>
<title> Title </title>
<body>
<%
	int total = 0;
    for (int i = 0; i <= 100; i++) {
    	total += i;
        }
%>
1부터 100까지 더한 값 : <%= total %>
</body> </html>
  • JSP 실행
    JSP에 있는 HTMl 코드는 웹 브라우저로 그대로 전송되고, JSP 문법의 코드는 웹 컨테이너 쪽에서 실행되며 그 결과만 웹 브라우저로 전송된다.

JSP 처리 과정

  • WAS는 JSP 페이지에 대한 요청이 들어오면 다음과 같이 처리한다.

(1) JSP에 해당하는 서블릿이 존재하지 않을 경우 (과정 1.1)

(a) JSP 페이지로부터 자바코드를 생성한다. (과정 1.2)
(b) 자바 코드를 컴파일하여 서블릿 클래스를 생성한다. (과정 1.3)
(c) 서블릿에 클라이언트 요청을 전달한다. (과정 2.1)
(d) 서블릿이 요청을 처리한 결과를 응답으로 생성한다. (과정 2.2)
(e) 응답을 웹 브라우저에 전송한다. (과정 3)

(2) JSP에 해당하는 서블릿이 존재하는 경우 (과정 1.1~1.3을 이미 거친 경우)

(a) 서블릿에 클라이언트 요청을 전달한다. (과정 2.1)
(b) 서블릿이 요청을 처리한 결과를 응답으로 생성한다. (과정 2.2)
(c) 응답을 웹 브라우저에 전송한다. (과정 3)


JSP 기본 구조

  • <!DOCTYPE ....> 이전
    JSP 페이지에 대한 정보를 이용하는 설정 부분으로, JSP 페이지가 생성하는 문서의 타입 및 사용할 커스텀 태그, 자바 클래스 등을 지정한다.
  • <!DOCTYPE ....> 이후
    문서를 생성하는 부분으로, <%...%> 등의 기호를 이용하여 스크립트 코드를 작성한다.

JSP 구성요소

  • 디렉티브(Directive) : 지시자
  • 스크립트
    • 스크립틀릿 (scriptlet)
    • 표현식 (expression)
    • 선언부 (declaration)
  • 표현언어 (Expression Language)
  • 기본 객체
  • 정적인 데이터
  • 표준 액션 태그
  • 커스텀 태그와 표준 태그 라이브러리 (JSTL)

1. 디렉티브(Directive) : 지시자

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>

<%@ 로 시작하여 %>로 끝난다. JSP 페이지에 대한 정보를 지정하며, JSP가 생성하는 문서의 타입, 출력 버퍼의 크기, 에러 페이지 등을 지정한다. JSP 페이지에서 필요로 하는 정보를 설정한다.


2-1. 스크립트 - 스클립틀릿

<%
	int total = 0;
    for (int i = 0; i <= 100; i++) {
    	total += i;
        }
%>

<%로 시작하여 %>로 끝난다. JSP 페이지에서 java 코드를 실행할 때 사용된다.


2-2. 스크립트 - 표현식

1부터 100까지 더한 값 : <%= total %>

// <%= total +100 %> 이런 표현식도 가능
// <%= Math.sqrt(total) %> 얘도 가능

<%=로 시작하여 %>로 끝난다. 사이에 자바식이 들어갈 수 있고, 상수나 변수 이름 하나로 구성될 수도 있다. 또, 연산자를 포함할 수 있고, return 값이 있는 메서드 호출이 가능하다.


2-3. 스크립트 - 선언부

<%!
	public int sum(int x, int y) {
    	return x + y;
    }
%>

<%!로 시작하여 %>로 끝난다. 사이에 자바 메서드 작성이 가능하다. 선언부의 함수는 자바 메서드 문법 구조와 동일하다.


JSP 예제

  • (1) 두 수(13, 19)의 곱을 선언부를 이용하여 출력하기.

Source

mul.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>
<%!
	public int mul(int x, int y) {
		return (x * y);
	}
%>

<h1> 두 수의 곱 구하기 </h1>
<h2> 13 * 18 = <%= mul(13, 19) %></h2>
</body>
</html>

실행 결과


  • (2) 입력받은 두 수를 이용하여 사칙연산 결과 출력하기.

Source

cal.html

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1> 두 수를 입력하세요. </h1>

<form action = "calResult.jsp" method = "post">

숫자 1 : <input type = "text" name = "num1"><br>
숫자 2 : <input type = "text" name = "num2"><br><br>
<input type = "submit" value = "확인">

</form>

</body>
</html>

calResult.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>
<%
 int num1 = Integer.parseInt(request.getParameter("num1"));
 int num2 = Integer.parseInt(request.getParameter("num2"));
%>

<h2> 사칙연산 결과 </h2>

<%= num1 %> + <%= num2 %> = <%= num1 + num2 %> <br>
<%= num1 %> - <%= num2 %> = <%= num1 - num2 %> <br>
<%= num1 %> * <%= num2 %> = <%= num1 * num2 %> <br>
<%= num1 %> / <%= num2 %> = <%= num1 / num2 %> <br>
</body>
</html>

실행 결과

profile
열심히 살아보려고 합니다...^^

0개의 댓글