본문 바로가기

STUDY/국비과정

[JAVA 웹 개발 공부] 국비지원 61일차 - 서블릿, MVC 패턴, EL, 방명록 구현

서블릿

 

자바 서블릿(Java Servlet)은 웹페이지를 동적으로 생성하는 서버 측 프로그램 혹은 그 사양을 말하며, 흔히 "서블릿"이라 불린다.
 
서블릿은 웹 서버의 성능을 향상하기 위해 사용되는 자바 클래스의 일종이다. 기존에 서버는 정적인 자료(HTML, 사진, 글 등)만을 주고받았다. 하지만 웹에 다양한 기능이 요구되면서 정적인 자료뿐만 아니라 사용자 요구에 맞춘 동적인 페이지들을 만들 필요가 생겼다. 이를 위해 만들어진 것이 바로 서블릿이다.

쉽게 말해 서블릿은 클라이언트의 요청에 맞춰 동적인 결과를 만들어 주는 자바 웹 프로그래밍 기술이라고 할 수 있다. 이러한 서블릿은 WAS(Web Application Server)의 서블릿 컨테이너 안에서 동작하게 된다. 

 

 

MVC(Model-View-Controller; 모델-뷰-컨트롤러) 패턴

 

 

MVC란 Model-View-Controller의 약자로 애플리케이션을 세 가지 역할로 구분한 개발 방법론이다.

사용자가 Controller를 조작하면 Controller는 Model을 통해 데이터를 가져오고 그 데이터를 바탕으로 View를 통해 시각적 표현을 제어하여 사용자에게 전달하게 된다.

 

구성 설명
모델 비즈니스 영역의 로직을 처리한다.
비즈니스 영역에 대한 프레젠테이션 뷰(즉, 사용자가 보게 될 결과 화면)를 담당한다.
컨트롤러 사용자의 입력 처리와 흐름 제어를 담당한다.

MVC 패턴의 핵심은 다음과 같다.

*비즈니스 로직을 처리하는 모델과 결과 화면을 보여주는 뷰를 분리한다.

*어플리케이션의 흐름 제어나 사용자의 처리 요청은 컨트롤러에 집중된다.

 

 

서블릿 구현, 매핑

 

1. 서블릿 작성(HttpServlet 클래스를 상속받은 클래스를 작성) 
2. 서블릿 등록 및 url 매핑 설정(web.xml로 매핑)
3. service 메소드 재정의 
4. 요청 객체에 임의의 attribute 설정하기
5. WEB_INF 폴더안의 viewattr2.jsp로 forward 시키기 
6. 요청 객체의 어트리뷰트 출력하기 (EL 사용)

 

*ReqForwardTest2Servlet.java

package web04;

import java.io.IOException;

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

// 서블릿 작성하기
public class ReqForwardTest2Servlet extends HttpServlet {
	// service 재정의해 WEB-INF 폴더안의 viewattr2.jsp로 forward 시키기 
	// 요청 객체에 3개의 임의의 attribute 설정하기
	// WEB_INF 폴더안의 viewattr2.jsp로 forward 시키기
	@Override
	protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		req.setAttribute("random", Math.random());
		req.setAttribute("myname", "eunjin");
		req.setAttribute("bool", true);
		
		req.getRequestDispatcher("/WEB-INF/viewattr2.jsp").forward(req, resp);
	}
}


*viewattr2.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>어트리뷰트값 확인하기2</title>
</head>
<body>
	<!-- 요청 객체의 어트리뷰트 출력하기 (el 사용도 해보세요) -->
	<p><%= request.getAttribute("random") %></p>
	<p><%= request.getAttribute("myname") %></p>
	<p><%= request.getAttribute("bool") %></p>
	<hr/>
	<p>${ random }</p>
	<p>${ myName }</p>
	<p>${ bool }</p>
</body>
</html>

 

*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_4_0.xsd" version="4.0">
  <display-name>web04</display-name>
  <welcome-file-list>
    <welcome-file>welcome.jsp</welcome-file>
  </welcome-file-list>
  
  <servlet>
  	<servlet-name>HelloServlet</servlet-name>
  	<servlet-class>web04.HelloServlet</servlet-class>
  </servlet>
  
  <servlet>
  	<servlet-name>ReqTestServlet</servlet-name>
  	<servlet-class>web04.ReqForwardTestServlet</servlet-class>
  </servlet>
  
  <!-- 서블릿 등록 및 url 매핑 설정 -->
    <servlet>
  	<servlet-name>ReqTest2</servlet-name>
  	<servlet-class>web04.ReqForwardTest2Servlet</servlet-class>
  </servlet>
  
  <servlet-mapping>
  	<servlet-name>ReqTest2</servlet-name>
  	<url-pattern>/reqtest2</url-pattern>
  </servlet-mapping>
  
  <servlet-mapping>
  	<servlet-name>ReqTestServlet</servlet-name>
  	<url-pattern>/reqtest</url-pattern>
  </servlet-mapping>
  
  <servlet-mapping>
  	<servlet-name>HelloServlet</servlet-name>
  	<url-pattern>/hello</url-pattern>
  </servlet-mapping>
</web-app>

 

 

EL

 

EL은 $와 괄호{} 그리고 표현식을 사용하여 값을 표현한다.

${expr}

EL은 JSP의 스크립트 요소(스크립트릿, 표현식, 선언부)를 제외한 나머지 부분에서 사용될 수 있으며, EL을 통해서 표현식보다 편리하게 값을 출력할 수 있다.

EL은 불리언 타입, 정수 타입, 실수 타입, 문자열 타입 그리고 널 타입의 5가지를 제공하고 있다. 

EL은 값이 없으면 출력하지 않는다.

 

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>출력을 할 때 사용할 수 있는 el 표현들</title>
</head>
<body>
	<p>연산 : ${ 1 + 1 }</p>
	<p>문자열 결합 : ${ "문자열" += "결합" }</p>
	<p>수 + 문자열 : ${ 22 + "22" }</p>
	<hr>
	<p>관계연산 : ${ 55 == 55 }</p>
	<p>문자열 eq : ${ "문자열1" == "문자열1" }</p>
	<hr>
	<p>논리연산 : ${ true && true }</p>
	<hr>
	<p>empty : ${ empty null }</p><!-- null / 빈문자열 / 원소가없는 배열or컬렉션 -->
</body>
</html>

 

 

JSTL 활용 - 리스트 원소 나열

 

*ListServlet.java

package web04;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

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

public class ListServlet extends HttpServlet {

	@Override
	protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		List<String> list = new ArrayList<>(Arrays.asList("문자열1", "문자열2", "문자열3", "문자열4"));
		
		req.setAttribute("list", list);
		req.getRequestDispatcher("/WEB-INF/viewlist.jsp").forward(req, resp);
	}
}

 

*viewlist.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
    <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>리스트 원소 나열</title>
</head>
<body>
<c:if test="${ not empty list }">
	<c:forEach var="item" items="${ list }">
		<p>${ item }</p>
	</c:forEach>
</c:if>
</body>
</html>

 

*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_4_0.xsd" 
version="4.0">
  <display-name>web04</display-name>
  <welcome-file-list>
    <welcome-file>welcome.jsp</welcome-file>
  </welcome-file-list>
  
  <servlet>
  	<servlet-name>ListServlet</servlet-name>
  	<servlet-class>web04.ListServlet</servlet-class>
  </servlet>
  
  <servlet-mapping>
  	<servlet-name>ListServlet</servlet-name>
  	<url-pattern>/list</url-pattern>
  </servlet-mapping>
  
  <servlet>
  	<servlet-name>HelloServlet</servlet-name>
  	<servlet-class>web04.HelloServlet</servlet-class>
  </servlet>
  
  <servlet>
  	<servlet-name>ReqTestServlet</servlet-name>
  	<servlet-class>web04.ReqForwardTestServlet</servlet-class>
  </servlet>
  
  <!-- 서블릿 등록 및 url 매핑 설정 -->
  <servlet>
  	<servlet-name>ReqTest2</servlet-name>
  	<servlet-class>web04.ReqForwardTest2Servlet</servlet-class>
  </servlet>
  
  <servlet-mapping>
  	<servlet-name>ReqTest2</servlet-name>
  	<url-pattern>/reqtest2</url-pattern>
  </servlet-mapping>
  
  <servlet-mapping>
  	<servlet-name>ReqTestServlet</servlet-name>
  	<url-pattern>/reqtest</url-pattern>
  </servlet-mapping>
  
  <servlet-mapping>
  	<servlet-name>HelloServlet</servlet-name>
  	<url-pattern>/hello</url-pattern>
  </servlet-mapping>
</web-app>

 

 

웹 어플리케이션의 일반적인 구성 및 방명록 구현

 

 

*list.jsp

<%@page import="guestbook.MessageListView"%>
<%@page import="guestbook.GetMessageListService"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%
	String pageNumberStr = request.getParameter("page");
	int pageNumber = 1;
	if (pageNumberStr != null) {
		pageNumber = Integer.parseInt(pageNumberStr);
	}
	
	GetMessageListService messageListService = GetMessageListService.getInstance();
	MessageListView viewData = messageListService.getMessageList(pageNumber);
%>
<c:set var="viewData" value="<%= viewData %>"/>
<html>
<head>
<meta charset="UTF-8">
<title>방명록 메시지 목록</title>
</head>
<body>
<form action="writeMessage.jsp" method="post">
이름: <input type="text" name="guestName"><br>
암호: <input type="password" name="password"><br>
메시지: <br><textarea name="message" cols="30" rows="3"></textarea><br>
<input type="submit" value="메시지 남기기"/>
</form>
<hr>
<c:if test="${!viewData.isEmpty()}">
등록된 메시지가 없습니다.
</c:if>

<c:if test="${!viewData.isEmpty()}">
<table border="1">
	<c:forEach var="message" items="${viewData.messageList}">
	<tr>
		<td>
		메시지 번호: ${message.id} <br/>
		손님 이름: ${message.guestName} <br/>
		메시지: ${message.message} <br/>
		<a href="confirmDeletion.jsp?messageId=${message.id}">[삭제하기]</a>
		</td>
	</tr>
	</c:forEach>
</table>

<c:forEach var="pageNum" begin="1" end="${viewData.pageTotalCount}">
<a href="list.jsp?page=${pageNum}">[${pageNum}]</a>
</c:forEach>
</c:if>

</body>
</html>

 

 

라이브러리 다운

 

https://mvnrepository.com/artifact/javax.servlet/jstl/1.2
https://mvnrepository.com/artifact/org.apache.commons/commons-dbcp2/2.9.0

https://mvnrepository.com/artifact/commons-logging/commons-logging/1.2

https://mvnrepository.com/artifact/org.apache.commons/commons-pool2/2.11.1