[JSP] 서블릿의 개념 및 기초 예제

서블릿이란?

- JSP 표준이 나오기 전에 만들어진 표준으로 자바로 웹 어플리케이션을 개발할 수 있도록 만들어진 것 자바 클래스 종류

- 요즘은 프레임워크의 사용으로 개발자가 직접 서블릿을 개발해야하는 경우는 없지만 동작방식을 이해해야할 필요가 있는 웹 개발의 기초중의 기초이다.

 

서블릿 구현 코드

public class NowServlet extends HttpServlet{
	
	@Override
	public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		
	}
	
}

- 메소드명은 get방식이냐 post방식이냐에 따라 doGet, doPost로 변경하면 된다. 서블릿으로 이용할 클래스는 HttpServlet 클래스를 상속받아야 하고 doGet,doPost 메소드는 request객체와 response 객체를 매개변수로 받는다.

 

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>
 
 <servlet-mapping>
 	<servlet-name>now</servlet-name>
 	<url-pattern>/now</url-pattern>
 </servlet-mapping>

</web-app>

- servlet-name으로 해당 서블릿을 참조할 이름, servlet-class로 사용할 클래스의 완전한이름(패키지경로)을 적는다.

- servlet-mapping은 url을 호출할 때 어떤 서블릿을 호출할지 매핑해주는 태그이다. servlet-name 태그로 servlet 참조명을 적고 url-pattern 태그에 호출할 url을 적는다. 

 

어노테이션으로 매핑하기

@WebServlet 어노테이션을 이용하여 url-pattern을 설정할 수 있다.

@WebServlet(urlPatterns="/hello")
public class HelloServlet extends HttpServlet{
	
	@Override
	public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
	}
	
}

- @WebServlet 어노테이션을 이용하면 web.xml파일에 따로 등록하지 않아도 서블릿으로 등록된다. 

- 속성으로 urlPatterns 값을 갖는데 이것으로 호출할 서블릿의 url을 지정할 수 있다.

 

서블릿은 최초 요청시 객체를 생성하고 이후 요청에 대해서는 생성된 객체를 사용하는 방식으로 구성된다.

하지만 처음 서블릿을 사용하는 시점 보다는 웹 컨테이너를 처음 구동하는 시점에 초기화를 진행하는 방식이 좋다. 이를 위해서 web.xml 파일에 <load-on-startup> 태그에 다음과 같이 설정하면 톰캣을 구동할때 해당 서블릿이 초기화 된다.

 

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>
 
 <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/testpoll?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>testpool</param-value>
 	</init-param>
 	<load-on-startup>1</load-on-startup>
 </servlet>
 
</web-app>		 

- 위 코드는 DBCP 커넥션풀을 이용해서 jdbc 드라이버를 먼저 구동해놓아 connection 객체를 코드상에서 선언하지 않고도 커넥션풀에서 쓰고 반납할 수 있도록 mysql 드라이버를 구동하는 서블릿을 초기화하는 코드를 포함하고 있다.

아래쪽에 load-on-startup 태그 바디에 1을 쓰면 톰캣이 구동되고 제일 먼저 jdbc.DBCPInit2라는 서블릿 클래스를 실행하여 서블릿 코드로 커넥션 정보를 로드할 것이다.

 

DBCPInit2 클래스의 코드는 다음과 같다.

 

package jdbc;

public class DBCPInit2 extends HttpServlet {

	@Override
	public void init() throws ServletException{
		loadJDBCDriver();
		initConnectionPool();
	}
	
	private void loadJDBCDriver() {
		String driverClass = getInitParameter("jdbcdriver");
		try {
			Class.forName(driverClass);
		}catch(ClassNotFoundException e) {
			throw new RuntimeException("fail to load JDBC Driver", e);
		}
	}
	
	private void initConnectionPool() {
		try {
			String jdbcUrl = getInitParameter("jdbcUrl");
			String username = getInitParameter("dbUser");
			String pw = getInitParameter("dbPass");
			
			ConnectionFactory connFactory = 
					new DriverManagerConnectionFactory(jdbcUrl, username, pw);

			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);
			
			Class.forName("org.apache.commons.dbcp2.PoolingDriver");
			PoolingDriver driver = (PoolingDriver) DriverManager.getDriver("jdbc:apache:commons:dbcp:");
			String poolName = getInitParameter("poolName");
			driver.registerPool(poolName, connectionPool);

		}catch(Exception e) {
			throw new RuntimeException(e);
		}
	}
}

getInitParameter(); 메소드는 web.xml에서 init-param태그로 감싸여진 param-name과 param-value의 값을 받아오는 것이다. param-name으로 적어둔 값을 getInitParameter()의 인자값으로 넘기면 param-value 값을 얻어와 내부 코드에서 jdbc 연결정보로 활용할 수 있게 된다.

댓글

Designed by JB FACTORY