무작정 개발.Vlog

[Servlet] 서블릿 구조, EL, JSTl

by 무작정 개발
반응형
2022.02.18(40일 차)

 

오전 11시까지가 jsp방명록 끝 - 이제 끝남

오늘부터 Servlet을 배운다. JSP + 보안이 Servlet이다.

 

 

오늘의 수업 내용

 

Web의 데이터 전송 방식 4가지

  • form 양식 - getParameter 메서드 사용
  • input 타입 hidden
  • Session
  • setAttribute / getAttribute

 

1,2,3번 방식은 JSP에서 에서 사용하는 방식이고 4번째 setAttribute/getAttribute는 Servlet에서 사용하는 데이터 전송방식입니다.

 

 

JSP방식
JSP방식

list.jsp파일을 예시로 들면 기존 jsp파일은 상단에 jsp코딩 하단에는 html 코딩으로 이루어져 있었습니다. 그리고 위에서 만든 데이터(jsp부분)를 html부분에서 가져다 쓰는 식으로 했습니다.

 

 

Servlet 구조
Servlet 구조

하지만 Servlet은  Class파일을 따로 만들어서 사용합니다.

 


Servlet(서블릿) 장점

 

  • Class 파일을 만들어서 여러 jsp파일의 코드들을 하나의 클래스로 통일
  • JSP는 사용자한테 디렉토리 구조를 주소에 다 보여줘서 보안성이 안 좋았지만 서블릿은 구조가 보이지 않아서 보안성이 좋다.
  • 기존에 JSP에서 데이터를 만들면 HTML에서 가져가서 사용했는데 이렇게 할 경우 의존성 문제가 발생한다.           -> (의존성 문제 : 1개의 파일을 여러 사용자가 나눠서 사용할 때 발생하는 문제)
  • 사용자가 접근하는 주소에 따라 특정 jsp파일을 접근하도록 매핑해주는 내용이 web.xml에 담겨 있다.
  • Class로 JSP내용을 담게되면서 HTML이 있는 파일을 만들어야 하지만 JSP만 존재하는 경우 별도로 만들어줄 필요가 없다.

 

Web.xml

톰캣 서버가 시작될 때 web.xml파일을 찾아서 읽는데, web.xml에 오류가 있을 경우 서버가 시작되지 않는다.
서버가 시작될 때 단 1번만 xml을 읽고 그 이후에는 읽지 않기 때문에 파일을 수정할 때 서버를 재시작해줘야 한다.

Servlet(서블릿) 처리 순서

 

  1. HttpServletRequest 및 HttpServletResponse 객체 생성
  2. 서블릿 class 로딩 및 객체 생성
  3. 요청에 따라 Servlet class의 doGet() or doPost() 메서드 호출

 

Servlet(서블릿) 상속(계층) 구조

 

서블릿 클래스 계층 구조
서블릿 클래스 계층 구조

 

 

 

Servlet(서블릿)을 구현할 때 반드시 상속해야 되는 클래스가 있습니다 - (HttpServlet)

HttpServlet은 GenericServlet을 상속받고, Seralizable, Servlet, ServletConfig 클래스를 상속 받음

 

 

 

Servlet 인터페이스

 

 - 서블릿 프로그램을 개발할 때 반드시 구현해야 하는 메서드를 선언하고 있는 인터페이스

 - 메서드

  • init()
  • service()
  • destroy()
  • getServletConfig()
  • getServletInfo()

 

GenericServlet 클래스

 

 - 일반적인 네트워크 프로토콜을 위한 추상 서블릿

 - Servlet 인터페이스를 상속받아 클라이언트 - 서버 환경에서 서버단의 애플리케이션으로써 필요한 기능을 

   구현한 추상 클래스 ( ServletConfig, Servlet, Serializable 인터페이스를 구현하는 추상 클래스)

 - 프로토콜이 독립적이고 모든 유형의 프로토콜을 처리 가능

 - Service() 메서드만 지원

 

 

HttpServlet 클래스

 

 - Http 프로토콜을 위한 http전용 서블릿

 - GenericServlet 클래스를 상속받아 service() 메서드를 재정의함으로써 Http 프로토콜에 알맞은 동작을 수행하도록

   구현한 클래스. ( Htpp프로토콜 기반으로 브라우저로부터 요청을 전달받아 처리하도록 하는 클래스 )

 - 프로토콜에 의존적이고, 특정 Http프로토콜만 처리 가능 

 

 - 메서드

  • doGet()
  • doPost()
  • doHead()
  • doPut()
  • doOptions()
  • doDelete()
  • doTrace()

HttpServletRequest & HttpServletResponse

 

HttpServletRequest - 요청정보 처리

  • Http 통신 기반의 요청 관련 메서드를 확정하여 제공
  • 클라이언트의 모든 요청정보를 처리하는 객체
  • 요청 Http 헤더 정보
  • InputStream 형태의 클라이언트로부터 전송된 데이터

 

 

 

 

HttpServletResponse - 응답 정보 처리

  • 일반적인 네트워크 통신에서의 응답 관련 메서드 제공
  • 클라이언트로 보내지는 응답 정보를 처리하는 객체
  • 응답 Http 헤더 정보
  • OutputStream 형태의 클라이언트로 전송되는 데이터

 

HttpServletRequest와 HttpServletResponse는 클라이언트로부터 서비스 요청이 있을 때마다 생성되며 웹서버가 응답한 후에 삭제된다.

 


서블릿 Class 생성하기

 

web.xml

 

사용자가 주소 칸에 hello를 입력하면 helloServlet을 찾아가는 사용자 정의

/study 프로젝트 이름 이후 검색어를 작성하니 <url-pattern>에 ' / '를 써줘야 한다.

<?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>study</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>helloServlet</servlet-name>
  	<servlet-class>com.svt.Test1</servlet-class>
  </servlet>
  
  <servlet-mapping>
  	<servlet-name>helloServlet</servlet-name>
  	<url-pattern>/hello</url-pattern>
  </servlet-mapping>
  
  </web-app>

web.xml 파일 위치
web.xml 파일 위치

 

GenericServlet을 상속받아 서블릿 클래스 생성

- Test 1 클래스를 생성해서 GenericServlet 상속

package com.svt;

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

import javax.servlet.GenericServlet;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

public class Test1 extends GenericServlet{

	private static final long serialVersionUID = 1L;

	@Override
	public void service(ServletRequest request, ServletResponse response) throws ServletException, IOException {
		
		//response 객체의 한글 인코딩
		//지금부터 클라이언트에게 전달하는 데이터 타입은
		//text 혹은 html 형식이고 UTF-8 인코딩 방식이다.
		response.setContentType("text/html;charset=utf-8");
		
		try {
			
			//JSP는 out.print로 작성하면 되지만
			//Servlet은 객체가 필요하면 요청해야함

			PrintWriter out = response.getWriter();
			
			out.print("<html>");
			out.print("<head>");
			out.print("<title>");
			out.print("예제프로그램</title></head>");
			out.print("<body style='font-size:10pt;'>");
			out.print("화면 디자인은 서블릿보다 JSP가 편하다");
			out.print("</body>");
			out.print("</html>");
			
			
		} catch (Exception e) {
			// TODO: handle exception
		}
			
	}
}

Test1 실행 결과
Test1 실행 결과
Test1 클래스 위치
Test1 클래스 위치

servlet 클래스는 따로 패키지를 생성해서 만들었습니다.

 


ServletConfig, ServletContext 인터페이스

 

web.xml 파일에 변하지 않고, 공통적으로 사용하는 변숫값을 써놓을 수 있습니다.

 

이번에는 Test 2 서블릿으로 이동하면서 2개의 변수를 같이 가져가는 예제 시작

 

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>study</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>
  
  <!-- 1. ServletConfig 인터페이스 -->
  <!-- 해당 Servlet에서만 사용가능 -->
  <servlet>
  	<servlet-name>test2Servlet</servlet-name>
  	<servlet-class>com.svt.Test2</servlet-class>
  		<init-param>
  			<param-name>name</param-name>
  			<param-value>배수지</param-value>
  		</init-param>
  		<init-param>
  			<param-name>age</param-name>
  			<param-value>27</param-value>
  		</init-param>
  </servlet>
  
  <servlet-mapping>
  	<servlet-name>test2Servlet</servlet-name>
  	<url-pattern>/itwill</url-pattern>
  </servlet-mapping>
  
  
  <!-- 2. ServletContext인터페이스 -->
  <!-- 애를 쓰면 모든 곳에 인식 가능 context라는 말이 나오면 모든 곳(글로벌)
       어떠한 클래스 명도 안적어서 범용적으로 사용 가능하다. -->
  <context-param>
  	<param-name>gender</param-name>
  	<param-value>여자</param-value>
  </context-param>

</web-app>

 

ServletConfig , ServletContext 인터페이스

 - Test2 클래스 생성 후 HttpServlet 상속

package com.svt;

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

import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class Test2 extends HttpServlet {

	private static final long serialVersionUID = 1L;

	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		
		doPost(req,resp);
		
	}

	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		
		//1. ServletConfig 인터페이스
		ServletConfig config = getServletConfig();
		String name = config.getInitParameter("name");
		String age = config.getInitParameter("age");
		
		//2. ServletContext인터페이스
		ServletContext context = getServletContext();
		String gender = context.getInitParameter("gender");
		
		//한글 인코딩
		resp.setContentType("text/html;charset=utf-8");
		
		//객체생성
		PrintWriter pw = resp.getWriter();
		
		pw.print("<html><body>");
		pw.print("name : " + name + "<br/>");
		pw.print("age : " + age + "<br/>");
		pw.print("gender : " + gender + "<br/>");
		pw.print("</body></html>");
		
		
	}
}

Test2 실행 결과
Test2 실행 결과


사용자한테 입력값 받는 웹페이지 만들기

 

web.xml

<servlet>
  	<servlet-name>test3Servlet</servlet-name>
  	<servlet-class>com.svt.Test3</servlet-class>
  </servlet>
  <servlet-mapping>
  	<servlet-name>test3Servlet</servlet-name>
  	<url-pattern>/ss1</url-pattern>
  </servlet-mapping>

 

Test 3.java

- 기존에는 html 태그를 작성했지만 소스가 길어지는 단점이 있어 포워딩 방식을 활용해서

  JSP페이지로 전달해서 사용한다.

package com.svt;

import java.io.IOException;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class Test3 extends HttpServlet {

	private static final long serialVersionUID = 1L;

	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		
		doPost(req, resp);
	}

	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		
		req.setCharacterEncoding("UTF-8");
		
		String name = req.getParameter("name");
		String age = req.getParameter("age");
		
		String str = name + "의 나이는" + age + "살 입니다!";
		
		req.setAttribute("result", str);
		
		//포워딩될 페이지 지정
		RequestDispatcher rd = req.getRequestDispatcher("/servlet/test3_ok.jsp");
		
		rd.forward(req, resp);
		
	}
	
}

 

Test 3.jsp

<%@ page contentType="text/html; charset=UTF-8"%>
<%
	request.setCharacterEncoding("UTF-8");
	String cp = request.getContextPath();
%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>

<form action="<%=cp%>/ss1" method="post">

이름: <input type="text" name="name"/><br/>
나이: <input type="text" name="age"/><br/>
<input type="submit" value="확인"/><br/> 

</form>


</body>
</html>

Test 3_ok.jsp

<%@ page contentType="text/html; charset=UTF-8"%>
<%
	request.setCharacterEncoding("UTF-8");
	String cp = request.getContextPath();
	
	//setAttribute로 보내는건 object로 보내기때문에 다운캐스팅(String)
	String str = (String)request.getAttribute("result"); 
%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<%-- <%=str %> --%>

<%-- EL(Express Language) --%>

${result }
</body>
</html>

 

test3.jsp
test3.jsp
결과
결과

포워드 방식을 통해 전달해서 사용하는데  /servlet/test 3_ok.jsp로 이동한다. 하지만 포워딩으로 처리되면서

주소는 /ss1이 보이게 된다.

 


EL (Expression Language)

 

표현 언어 EL는 표현식 ( <%=)을 대신하는 효과를 가지고 null 값을 가지는 변수에 대해 좀 더 관대하고 데이터형을 

자동으로 변환해준다.

 

test4.jsp

<%@ page contentType="text/html; charset=UTF-8"%>
<%
	request.setCharacterEncoding("UTF-8");
	String cp = request.getContextPath();
%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>

<form action="" method="post">

수1: <input type="text" name="su1"/><br/>
수2: <input type="text" name="su2"/><br/>
<input type="submit" value="결과"/><br/>

</form>

su1: ${param.su1 }<br/>
su2: ${param.su2 }<br/>

결과: ${param.su1 + param.su2 }<br/>

${param.su1 }은 ${param.su1 % 2 == 0 ? "짝수" : "홀수" }

</body>
</html>

test4.jsp 실행화면
test4.jsp 실행화면


JSTL - (JSP Standard Tag Library)

 

JSTP

JSP는 사용자 정의 태그를 만들 수 있는 기능이 있는데 apache에서 개발자들이 만든 태그들을 표준화시켜 배포한 것

 

1. 설치 링크

https://jakarta.apache.org/site/downloads/

 

The Jakarta Site - Jakarta Downloads

Binary and source releases and links into the archives may be obtained by selecting a project below. We recommend that you subscribe to the Jakarta announcements mailing list to be notified when releases are made by the Jakarta project.

jakarta.apache.org

2. archives 클릭

archives 클릭
archives 클릭

3.  Index of /dist/jakarta/taglibs/standard/source 경로로 들어가기

경로
경로

상단 화면에서  Index of /dist/jakarta/taglibs/standard/source 경로로 들어가면

jakarata 파일이 여러 개 있습니다.

노란색으로 표시된 파일 설치
노란색으로 표시된 파일 설치

상단 화면에 표시된 파일을 설치한 후에 zip 파일 안에 lib에 존재하는 파일들을 복사해서 lib에 넣어준다.

lib 경로
lib 경로

lib에 추가한 후에 JSP 페이지에 디렉티브를 작성해야 한다.

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

 

test 1.jsp

<%@ page contentType="text/html; charset=UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%
	request.setCharacterEncoding("UTF-8");
	String cp = request.getContextPath();
	
	//JSTL (JSP Standard Tag Language)
	//JSTL을 사용하기 위해서는 jstl.jar, standard.jar 2개의 파일이 필요
	//처리 영역이 4개이다. : core, format, xml, sql
	
	
%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>

<form action="" method="post">
수 : <input type="text" name="su"/><br/>
<input type="submit" value="결과"/><br/>
</form>

<br/>

<c:if test="${!empty param.su }">
	<c:if test="${param.su%2==0 }">
		${param.su } : 짝수<br/>
	</c:if>
	<c:if test="${param.su%2==1 }">
		${param.su } : 홀수<br/>
	</c:if>
	
</c:if>

<br/><br/>

<table>
<c:forEach var="i" begin="1" end="9" step="1">
<tr>
	<c:forEach var="j" begin="1" end="9" step="1">
		<td width="50">${i*j }</td>
	</c:forEach>
</tr>
</c:forEach>
</table>



</body>
</html>

 

반응형

블로그의 정보

무작정 개발

무작정 개발

활동하기