[JSP] 서블릿의 개념 및 기초 예제
- 웹 개발/JSP
- 2019. 8. 18. 22:53
서블릿이란?
- 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 연결정보로 활용할 수 있게 된다.
'웹 개발 > JSP' 카테고리의 다른 글
[JSP] ServletContextListener 개념 및 예제, 구현해보기 (1) | 2019.08.25 |
---|---|
[JSP] 커스텀 태그 개념 및 예제 (0) | 2019.08.18 |
[JSP] 공통코드 작성하기 - <jsp:include> 액션태그 (1) | 2019.08.17 |
[JSP] flush 속성 (0) | 2019.08.17 |
[JSP] 에러페이지 지정하기 (0) | 2019.08.17 |