일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
- jsp
- Ajax
- jQuery
- css3
- 서블릿
- 비밀번호찾기
- 제이쿼리
- 오라클
- javascript
- 마이바티스
- 미로 생성 알고리즘
- 웹페이지
- html5
- Binding
- 풀스택
- 로그인
- dbms
- 네비게이터
- 웹개발
- MVC
- 백엔드
- 회원가입
- c programming
- 웹서비스
- 프론트엔드
- mybatis
- 스프링
- 프레임워크
- Linked List
- spring
- Today
- Total
Programmer's Progress
ServletContext, ServletConfig 를 활용하여 DB 데이터 요청하기 본문
ServletContext, ServletConfig 를 활용하여 DB 데이터 요청하기
Blanc et Noir 2021. 7. 2. 21:32ServletContext 클래스는 톰캣 컨테이너 실행 시에 각 콘텍스트마다 하나의 객체가 생성된다.
톰캣 컨테이너가 종료되면 이 객체가 소멸되는데, 이 객체를 통해 웹 애플리케이션의 모든 서블릿들이
자원이나 정보를 미리 바인딩해서 공유하여 사용할 수 있도록 한다.
쉽게 말해서 전역변수를 선언하는 것과 비슷한 효과를 얻을 수 있다.
반면 ServletConfig 클래스는 각 서블릿 객체들마다 생성되는 클래스다. 즉, 각 서블릿은 고유한 ServletConfig
객체를 가지며, 지역변수처럼 데이터를 읽어 들일 수 있게끔 한다. 이 클래스는 데이터를 초기화할 때 주로 사용한다.
이렇게 글로만 나열해둔 정보로는 도대체 어떻게 동작하는지 잘 알수가 없었다. 직접 사용해 필요성을 느끼기로 했다.
LoginServlet 클래스
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
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({ "/LoginServlet", "/login" })
public class LoginServlet extends HttpServlet {
ServletConfig config;
ServletContext context;
UserDAO dao = new UserDAO();
public void init(ServletConfig config) throws ServletException {
super.init(config);
this.config = config;
context = config.getServletContext();
}
public void destroy() {
// TODO Auto-generated method stub
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doHandle(request, response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doHandle(request, response);
}
protected void doHandle(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
ArrayList<UserVO> list = dao.getList(context.getInitParameter("col1"), context.getInitParameter("col2"));
for(int i=0; i<list.size(); i++) {
System.out.println(list.get(i).user_id+" : "+list.get(i).getUser_pw());
}
out.close();
}
}
LoginServlet 클래스는 UserDAO클래스를 통해 DB에 기록된 로그인 정보들을 얻어온다.
이때 중요한 것은, 초기화를 위해서 web.xml 파일에는 아래와 같이 구성되어 있는데
<param-name>태그의 내용에 유의하도록 하자. key값은 col1, col2이며 각각 value값이 user_id, user_pw이다.
이는 DB의 컬럼이름과 동일하다.
<?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_3_0.xsd" id="WebApp_ID" version="3.0">
<context-param>
<param-name>col1</param-name>
<param-value>user_id</param-value>
</context-param>
<context-param>
<param-name>col2</param-name>
<param-value>user_pw</param-value>
</context-param>
</web-app>
저런 식으로 web.xml파일에 초기화와 관련된 선언을 하거나, 어노테이션을 이용하는 경우에는
getInitParameter(String string) 메소드를 통해 그 value값을 얻을 수 있다.
앞서 LoginServlet에서는 col1, col2라는 key값을 통해 user_id, user_pw라는 문자열 값을 얻었으며
이를 UserDAO의 getList( ) 메서드의 인자로 전달하였다.
UserDAO 클래스
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.sql.DataSource;
public class UserDAO {
ArrayList<UserVO> list = new ArrayList<>();
DataSource ds;
UserDAO(){
try {
Context con = new InitialContext();
Context env = (Context) con.lookup("java:/comp/env");
ds = (DataSource) env.lookup("jdbc/oracle");
} catch (NamingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public ArrayList<UserVO> getList(String col1, String col2){
try {
Connection con = ds.getConnection();
PreparedStatement pstmt = con.prepareStatement("select "+col1+", "+col2+" from t_user");
ResultSet rs = pstmt.executeQuery();
while(rs.next()) {
UserVO user = new UserVO(rs.getString(col1),rs.getString(col2));
list.add(user);
}
con.close();
pstmt.close();
rs.close();
return list;
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return list;
}
}
DataSource, ConnectionPool 등을 이용해 DB와 연동한 후에, 로그인 정보를 요청하고 있다.
이때 수행하고자 하는 쿼리문을 보면 다음과 같다.
PreparedStatement pstmt = con.prepareStatement("select "+col1+", "+col2+" from t_user");
얻어오고자 하는 칼럼의 값이 col1, col2 String참조 변수로 지정되어 있다.
이렇게 복잡하게 구성하면 도대체 어떤 이점이 있는 걸까?
바로 DB에서 칼럼명이 바뀌더라도, web.xml 파일에서 그 칼럼명만 수정하면 전체 소스코드를 수정할 필요가
줄어들게 된다. 즉, 유지보수 면에서 뛰어나다는 것이다.
생각해보자, 만약 지금과 같이 구현하지 않고, 일일이 "user_id", "user_pw"같이 getList( ) 메서드의 내용을
채워 넣었더라면, 지금이야 간단한 소스코드지만, 소스코드가 복잡하거나, 수십 개의 칼럼명이 바뀌고
수백 개의 서블릿이 존재한다면... 이 소스코드를 일일이 수정하는 것은 고된 노동일 것이다...
어노테이션이나 web.xml파일에 미리 선언하지 않고, 동적으로 설정하는 경우도 존재한다.
이때는 서블릿 간 데이터를 포워딩할 때 사용하던 바인딩 방식처럼 setAttribute( ) 메서드와 getAttribute( ) 메서드를
활용하면 된다.
'Servlet + JSP > Self Learning' 카테고리의 다른 글
스프링 프레임워크 트랜잭션 기능 (0) | 2021.12.31 |
---|---|
세션을 활용하여 로그인 정보 유지하기 (0) | 2021.07.04 |