포스코DX X 비트교육센터 6기 - JSP


Default servlet

Default servlet은 정적 웹 리소스(HTML, CSS, 이미지 등)를 제공하기 위한 특수 서블릿으로, 컨텍스트 경로를 기반으로 클라이 언트 요청에 응답합니다. MIME 타입 설정과 디렉토리 리스트 생성을 지원하며, 웹 애플리케이션의 정적 리소스 처리에 사용됩니다. 설정 가능하며, 대부분의 Java 웹 애플리케이션 서버에 내장되어 있습니다.

생명주기

  • servlet-practices > helloweb > servlets > LifeCycleServlet.jsp 추가

image

package servlets;

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 LifeCycleServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;

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

	@Override
	protected void service(HttpServletRequest arg0, HttpServletResponse arg1) throws ServletException, IOException {
		System.out.println("service(...) called");
		super.service(arg0, arg1);
	}

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
	System.out.println("doGet(...) called");
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		System.out.println("doPost(...) called");
		doGet(request, response);
	}

	@Override
	public void destroy() {
		System.out.println("destory() called");
		super.destroy();
	}
}

  • 결과

image

image

이미지 출처: rlo0

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns="http://java.sun.com/xml/ns/javaee"
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
	version="2.5">
	<display-name>mysite02</display-name>

	<!-- MainController servlet -->
	<servlet>
		<servlet-name>MainController</servlet-name>
		<servlet-class>com.poscodx.mysite.controller.MainController</servlet-class>
		<init-param>
			<param-name>config</param-name>
			<param-value>/WEB-INF/servlet-context.xml</param-value>
		</init-param>
	</servlet>

	<servlet-mapping>
		<servlet-name>MainController</servlet-name>
		<url-pattern></url-pattern>
	</servlet-mapping>

	<servlet-mapping>
		<servlet-name>MainController</servlet-name>
		<url-pattern>/main</url-pattern>
	</servlet-mapping>

	<!-- UserController servlet -->
	<servlet>
		<description></description>
		<display-name>UserController</display-name>
		<servlet-name>UserController</servlet-name>
		<servlet-class>com.poscodx.mysite.controller.UserController</servlet-class>
	</servlet>

	<servlet-mapping>
		<servlet-name>UserController</servlet-name>
		<url-pattern>/user</url-pattern>
	</servlet-mapping>

	<!-- default files -->
	<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>
		<description></description>
		<display-name>GuestbookController</display-name>
		<servlet-name>GuestbookController</servlet-name>
		<servlet-class>com.poscodx.mysite.controller.GuestbookController</servlet-class>
	</servlet>

	<servlet-mapping>
		<servlet-name>GuestbookController</servlet-name>
		<url-pattern>/guestbook</url-pattern>
	</servlet-mapping>
</web-app>

mainController

package com.poscodx.mysite.controller;

import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.poscodx.mysite.web.mvc.main.MainActionFactory;
import com.poscodx.web.mvc.Action;
import com.poscodx.web.mvc.user.UserActionFactory;

public class MainController extends HttpServlet {
	private static final long serialVersionUID = 1L;

	@Override
	public void init() throws ServletException {
		String configPath = getServletConfig().getInitParameter("config");
		System.out.println(configPath);
		super.init();
	}

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

		String actionName = request.getParameter("a");
		Action action = new MainActionFactory().getAction(actionName);
		action.execute(request, response);
	}

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

}

결과

image


관심: concern / 관점: aspect

객체지향이 추구하는 것. 내가 무엇을 할 것인지 금방 알 수 있는 것.

  • 핵심 관심 : MainController의 mainActionFactory… / UserController의 userActionFactory…

  • 횡단 관심 : 핵심 관심 앞뒤의 것. 이것이 객체지향을 깬다고 이야기함.

AOP의 도움을 받아서 더 완벽한 OOP를 만든다. => spring

Filter도 관심을 위함. (완벽한 OOP) => 컨트롤러 상단의 공통 필터 ex. encoding filter

****** 관심의 분리 = separation of concern *********

횡단 관심을 분리해서, 핵심관심만 남게 한다.

image

이미지 출처: rlo0


관심 분리를 위한 filter 실습

image

image

모든 경로

  • EncodingFilter.java
package com.poscodx.mysite.web;

import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpFilter;

public class EncodingFilter extends HttpFilter implements Filter {
    private static final long serialVersonUID = 1L;
	
    public EncodingFilter() {
        super();
    }

	public void destroy() {
	}

	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
		/* request 처리 */
		request.setCharacterEncoding("utf-8");
		
		chain.doFilter(request, response);
		/* response 처리 */
	}

	public void init(FilterConfig fConfig) throws ServletException {
	}

}

  • web.xml

image

만약에 web.xml에 init을 이용한다면,

image

  • EncodingFilter.java
package com.poscodx.mysite.web;

import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpFilter;

public class EncodingFilter extends HttpFilter implements Filter {
    private static final long serialVersonUID = 1L;
	private String encoding;
	
	public void init(FilterConfig fConfig) throws ServletException {
		encoding = fConfig.getInitParameter("encoding");
		
		if(encoding == null) {
			encoding = "utf-8";
		}
	}

	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
		/* request 처리 */
		request.setCharacterEncoding(encoding);
		
		chain.doFilter(request, response);
		/* response 처리 */
	}

	public EncodingFilter() {
        super();
    }

	public void destroy() {
	}



}


WAS = Servlet Container, Application Context, Servlet Context

  • Listener : 로딩될 때, 실행 (서버 시작했을 때…)

ex. 전역에 사용되는 객체가 필요할 때!

image

image

package com.poscodx.mysite.web;

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

public class ContextLoadListner implements ServletContextListener {

	public void contextInitialized(ServletContextEvent sce)  { 
		System.out.println("Application starts.....");
	}

    public void contextDestroyed(ServletContextEvent sce)  { 
    }

	
}

  • 이러면, web.xml에 자동 추가가 됨.

  • 서버 재 실행시,

image


<!-- Context Parameter : 어디서나 접근 가능한 . 전역. -->
	<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>/WEB-INF/applicationContext.xml</param-value>
	</context-param>

스크립트 태그

image

  • 액션 태그
    • <jsp:action> </jsp:action>
    • 페이지 삽입, 공유, 자바빈 사용 등 + 이 코드는 자바코드는 아니다. 여기서 제공하는 함수를 이용하는 것.

    사용 이유: JSP에 자바 코드를 쓰지 않기 위해서. 내부에서 따로 자바코드를 불러준다.

package servlet;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

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

public class _01Servlet extends HttpServlet {
	private static final long serialVersionUID = 1L;

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		//값
		int iVal = 10;
		long lVal = 10L;
		float fVal = 3.14f;
		double dVal = 3.14;
		boolean bVal = true;
		String sVal = "가나다라마바사";
		
		request.setAttribute("ival", iVal);
		request.setAttribute("lval", lVal);
		request.setAttribute("fval", fVal);
		request.setAttribute("dval", dVal);
		request.setAttribute("bval", bVal);
		request.setAttribute("sval", sVal);
		
		//객체
		UserVo userVo = new UserVo();
		userVo.setNo(10L);
		userVo.setName("둘리");
		
		request.setAttribute("vo", userVo);
		
		//Map객체
		Map<String, Object> m = new HashMap<>();
		m.put("ival", iVal);
		m.put("fval", fVal);
		m.put("sval", sVal);
		
		request.setAttribute("map", m);
		
		
		
		
		
		
		
		request.getRequestDispatcher("/WEB-INF/views/01.jsp").forward(request, response);
		
	}

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

}


image

<h4>산술 연산</h4>
	${3*4+6/2 } <br>
	${ival + 10 } <br>
	
	<h4>관계 연산</h4>
	${ival == 10 } <br>
	${ival < 5 } <br>
	${obj == null} <br>
	${obj != null} <br>
	${empty obj} <br>
	${not empty obj} <br>
	
	<h4>논리 연산</h4>
	${ival == 10 && lval < 1000 }<br>
	${ival == 10 || lval < 1000 }<br>

image

	<h5>요청 파라미터</h5>
	${param.a + 10  } <br>
	${param.email } <br>
	<h6>Context Path</h6>
	${pageContext.request.contextPath  }

image

scope의 지속 순서

application > session > request > page

  • 이름이 중복되게 하지 말자!

=== 실습

package servlet;

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 _02Servlet extends HttpServlet {
	private static final long serialVersionUID = 1L;

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		/**
		 * 1. 객체의 scope (객체의 존속 범위): 객체가 존재하는 범위
		 * 
		 * 2. 객체가 오래 지속되는 순서 
		 * 
		 * Applicaton(Context) Scope > Session Scope > Request Scope > Page Scope
		 * 
		 * 3. EL이 이름으로 객체를 찾는 순서
		 * 
		 * Applicaton(Context) Scope < Session Scope < Request Scope < Page Scope
		 * 
		 * [주의]
		 * 같은 이름으로 여러 범위에 객체를 저장하는 경우 주의가 필요!
		 * 
		 * 
		 */
		
		// request scope 
		UserVo vo1 = new UserVo();
		vo1.setNo(1L);
		vo1.setName("둘리1");
		
		request.setAttribute("vo", vo1);
		
		// session scope 
		UserVo vo2 = new UserVo();
		vo2.setNo(2L);
		vo2.setName("둘리2");
		
		request.getSession(true).setAttribute("vo", vo2);
		
		// application scope
		UserVo vo3 = new UserVo();
		vo3.setNo(3L);
		vo3.setName("둘리3");
		
		request.getServletContext().setAttribute("vo", vo3);
		
		
		request.getRequestDispatcher("/WEB-INF/views/02.jsp").forward(request, response);
	
	
	}

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

}

<%@page import="servlet.UserVo"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<%
UserVo vo0 = new UserVo();
vo0.setNo(0L);
vo0.setName("둘리0");

pageContext.setAttribute("vo", vo0);
%>

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	<h4>scope(객체의 존속 범위)</h4>
	${vo.no } <br>
	${vo.name } <br>
	
	
	== request scope ============ <br>
	${requestScope.vo.no } <br>
	${requestScope.vo.name } <br>
	== session scope ============ <br>
	${sessionScope.vo.no } <br>
	${sessionScope.vo.name } <br>
	== application scope ============ <br>
	${applicationScope.vo.no } <br>
	${applicationScope.vo.name } <br>
	
	
</body>
</html>

image


JSTL

https://mvnrepository.com/artifact/jstl/jstl/1.2

=> 추가

package servlet;

import java.io.IOException;
import java.util.ArrayList;
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 _03Servlet extends HttpServlet {
	private static final long serialVersionUID = 1L;

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		List<UserVo> list = new ArrayList<>();
		
		UserVo vo1 = new UserVo();
		vo1.setNo(1L);
		vo1.setName("둘리1");
		list.add(vo1);
		
		UserVo vo2 = new UserVo();
		vo2.setNo(2L);
		vo2.setName("둘리2");
		list.add(vo2);
		
		UserVo vo3 = new UserVo();
		vo3.setNo(3L);
		vo3.setName("둘리3");
		list.add(vo3);
		
		request.setAttribute("list", list);
		request.getRequestDispatcher("/WEB-INF/views/03.jsp").forward(request, response);
		
	}

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

}

if - else if - else

<c:choose>
				<c:when test="">
				</c:when>
				<c:when test="">
				</c:when>
				<c:when test="">
				</c:when>
				<c:otherwise>
				</c:otherwise>
			</c:choose>