JSP/Servlet/13. 서블릿 기초

Day 59 : 서블릿 구현

pancakemaker 2022. 1. 7. 16:31

1. 서블릿 구현

package example;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.Date;

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

public class NowServlet extends HttpServlet {					//HttpServlet 클래스를 상속받아야 서블릿으로 동작
	@Override													//메소드 재정의 (Ctrl+space 해서 사용할 메소드 고르기)
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		response.setContentType("text/html); charset=utf-8");	//응답 전송을 위한 컨텐츠 타입 지정
		
		PrintWriter out = response.getWriter();					//문자열 데이터 출력하여 웹 브라우저에 데이터 전송
		out.println("<html>");									//PrintWriter 클래스의 메소드 println() 사용
		out.println("<head><title>현재시간</title></head>");
		out.println("<body>");
		out.println("현재 시간은");
		out.println(new Date());
		out.println("입니다.");
		out.println("</body></html>");
	}	
}

2. web.xml로 매핑 (/WEB-INF/web.xml)

<?xml version="1.0" encoding="UTF-8"?>

<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
		http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
		version="3.1">
	
	<!-- 서블릿으로 사용할 클래스  -->
	<servlet>
		<servlet-name>now</servlet-name>	<!-- 클래스 이름 -->
		<servlet-class>example.NowServlet</servlet-class> <!-- 클래스 완전한 이름(경로) -->
	</servlet>
	
	<!-- 서블릿과 URL 간의 매핑 -->
	<servlet-mapping>
		<servlet-name>now</servlet-name>
		<url-pattern>/now</url-pattern>
	</servlet-mapping>
	
</web-app>

3. @WebServlet 어노테이션으로 매핑 (서블릿 3.0 버전부터 web.xml 없이도 가능)

package example;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.Date;

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(urlPatterns = "/hello")								//어노테이션으로 매핑 ("localhost/chap17/hello"로 접근 가능)
public class HelloServlet extends HttpServlet {					//HttpServlet 클래스를 상속받아야 서블릿으로 동작
	@Override													//메소드 재정의 (Ctrl+space 해서 사용할 메소드 고르기)
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		response.setContentType("text/html); charset=utf-8");	//응답 전송을 위한 컨텐츠 타입 지정
		
		PrintWriter out = response.getWriter();					//문자열 데이터 출력하여 웹 브라우저에 데이터 전송
		out.println("<html>");									//PrintWriter 클래스의 메소드 println() 사용
		out.println("<head><title>현재시간</title></head>");
		out.println("<body>");
		out.print("Hello, ");
		out.print(request.getParameter("name"));
		out.println("!^-^");
		out.println("</body></html>");
	}	
}


4. 초기화 파라미터

- <param-name> : 초기화 파라미터의 이름 지정

- <param-value> : 초기화 파라미터의 값 지정

- getInitParameter() : 초기화 파라미터 값 호출 메소드 (존재하지 않을 시 null 리턴)

 

<예시>

- 초기화 파라미터를 설정하는 web.xml

<?xml version="1.0" encoding="UTF-8"?>

<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
		http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
		version="3.1">
	
	<!-- 서블릿으로 사용할 클래스  -->
	<servlet>
		<servlet-name>now</servlet-name>	<!-- 클래스 이름 -->
		<servlet-class>example.NowServlet</servlet-class> <!-- 클래스 완전한 이름(경로) -->
	</servlet>
	
	<!-- 서블릿과 URL 간의 매핑 -->
	<servlet-mapping>
		<servlet-name>now</servlet-name>
		<url-pattern>/now</url-pattern>
	</servlet-mapping>
	
	<servlet>	
		<servlet-name>DBCPInit2</servlet-name>
		<servlet-class>jdbc.DBCPInit2</servlet-class>
		
		<init-param>
			<param-name>jdbcdriver</param-name>
			<param-value>com.mysql.jdbc.Driver</param-value>		
		</init-param>
		
		<init-param>
			<param-name>jdbcUrl</param-name>
			<param-value>jdbc:mysql://localhost:3306/chap14?characterEncoding=utf8</param-value>
		</init-param>
		
		<init-param>
			<param-name>dbUser</param-name>
			<param-value>jspexam</param-value>
		</init-param>
		
		<init-param>
			<param-name>dbPass</param-name>
			<param-value>jsppw</param-value>
		</init-param>
		
		<init-param>
			<param-name>poolName</param-name>
			<param-value>chap14</param-value>
		</init-param>
		
		<load-on-startup>1</load-on-startup>	
	</servlet>		
</web-app>

- 초기화된 파라미터를 사용하는 클래스

package jdbc;

import java.sql.DriverManager;

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

import org.apache.tomcat.dbcp.dbcp2.ConnectionFactory;
import org.apache.tomcat.dbcp.dbcp2.DriverManagerConnectionFactory;
import org.apache.tomcat.dbcp.dbcp2.PoolableConnection;
import org.apache.tomcat.dbcp.dbcp2.PoolableConnectionFactory;
import org.apache.tomcat.dbcp.dbcp2.PoolingDriver;
import org.apache.tomcat.dbcp.pool2.impl.GenericObjectPool;
import org.apache.tomcat.dbcp.pool2.impl.GenericObjectPoolConfig;


public class DBCPInit2 extends HttpServlet {
	@Override
	public void init() throws ServletException {
		loadJDBCDriver();
		initConnectionPool();
	}	

	public void loadJDBCDriver() {
		String driverClass = getInitParameter("jdbcdriver");	//초기화 파라미터 사용
		try {
			Class.forName("driverClass");
		} catch(ClassNotFoundException ex) {
			throw new RuntimeException("fail to load JDBC Dirver", ex);
		}
	}
	
	private void initConnectionPool() {
		try {
			String jdbcUrl= getInitParameter("jdbcUrl");		//초기화 파라미터 사용
			String username = getInitParameter("dbUser");		//초기화 파라미터 사용
			String pw = getInitParameter("dbPass");				//초기화 파라미터 사용
			
			//커넥션 풀이 새로운 커넥션을 생성할 때 사용할 커넥션 팩토리 생성
			ConnectionFactory connFactory = 
						new DriverManagerConnectionFactory(jdbcUrl, username, pw);
			
			//PoolableConnection(풀에 커넥션 보관)을 생성하는 팩토리 생성
			PoolableConnectionFactory poolableConnFactory = 
						new PoolableConnectionFactory(connFactory, null);
			
			//커넥션이 유효한지 검사할 때 사용할 쿼리 지정
			poolableConnFactory.setValidationQuery("select 1");
			
			//커넥션 풀의 설정 정보 생성
			GenericObjectPoolConfig poolConfig = new GenericObjectPoolConfig();
			poolConfig.setTimeBetweenEvictionRunsMillis(1000L * 60L * 5L);		//유휴 커넥션 검사 주기
			poolConfig.setTestWhileIdle(true); 									//풀에 보관중인 커넥션이 유효한지 검사할지 여부
			poolConfig.setMinIdle(4); 											//커넥션 최소 개수
			poolConfig.setMaxTotal(50);											//커넥션 최대 개수
			
			//커넥션 풀 생성 : 사용할 팩토리와 커넥션 풀 설정 인자값으로 생성
			GenericObjectPool<PoolableConnection> connectionPool =
						new GenericObjectPool<>(poolableConnFactory, poolConfig);
			poolableConnFactory.setPool(connectionPool);
			
			//커넥션 풀 제공하는 jdbc 드라이버
			Class.forName("org.apache.commons.dbcp2.PoolingDriver");
			PoolingDriver driver = 
						(PoolingDriver) DriverManager.getDriver("jdbc:apache:commons:dbcp:");
			String poolName = getInitParameter("poolName");		//초기화 파라미터 사용
			//생성한 커넥션 풀 등록 (JDBC URL = jdbc:apache:commons:dbcp:chap14)
			driver.registerPool(poolName, connectionPool);
	
		} catch(Exception e) {
			throw new RuntimeException(e);
		}
	}
}