Servlet

Servlet은 자바 플랫폼에서 컴포넌트 기반의 웹애플리케이션 개발기술이다.

JSP는 서블릿 기술에 기반했고, JSP 모델2가 주목받으면서 서블릿에 대한 중요성이 부각되었다.

쉽게 말해 JSP는 서블릿으로 변환되어 실행되기 때문에, 대부분 별도의 실행환경 없이 서블릿 컨테이너에 통합된다.

우리가 서버로 사용하고 있는 tomcat이 대표적인 서블릿 형태이다.

서블릿의 장점은

  • Java기반이므로 Java API를 사용할 수 있다.
  • OS나 하드웨어에 영향을 받지 않는다.
  • 컨텐츠와 비즈니스 로직을 분리할 수 있다.
  • 컨트롤러와 뷰의 역할 분담
  • 수월한 유지보수

등이 있다.

 

서블릿은

javax.servlet.GenericServlet
javax.servlet.http.HttpServlet

이 두개의 API로 제작되었다.

서블릿을 만들고 실습을 진행할 프로젝트를 만들었다. webServlet

서블릿은 Java기반이기 때문에, Java Resources 밑에 패키지를 만들어서 담을 것이다.

JSP는 html에서 Java를 가져다 쓸 수 있었다면, 서블릿에서는 반대로 Java에서 html을 쓸 수 있다. 비록 방법은 훨씬 복잡하지만...

서블릿은 새로 만들때 설정 몇 가지를 해줄 수 있다.

이렇게 생성할 메소드를 선택할 수 있는데, 우리는 init(), doGet(), doPost() 이렇게 세가지를 선택해서 IndexServlet.java를 만들자.

여기서 파일 하나를 더 가져와야한다.

우리가 설치한 tomcat서버의 web.xml을 복사해서 webServlet/WEB-INF에 넣어주자.

web.xml파일 경로

복사해온 web.xml파일을 열어보면 Welcome to Tomcat이라는 문구만 적혀있는 것을 볼 수 있다.

이제 여기에 일일이 매핑을 해줄 예정이다.

 

다시 IndexServlet.java로 돌아와서,

맨 처음 생성자는 IndexServlet이 상속받은 HttpServlet클래스를 선언해주는 것이고,

init()은 클라이언트가 요청했을때 doGet()과 doPost()실행 이전에 자동실행되는 메소드이다. JSP의 선언부와 비슷하다고 보면 된다.

doPost()와 doGet()은 클라이언트가 어떤 방식으로 접속했느냐에 따라 알맞게 실행된다.

package kr.co.campus;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

/**
 * Servlet implementation class IndexServlet
 */
@WebServlet("/IndexServlet")
public class IndexServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public IndexServlet() {
        super();
        // TODO Auto-generated constructor stub
    }

	/**
	 * @see Servlet#init(ServletConfig)
	 */
    // doGet(), doPost()가 실행되기 전 초기화하는 메소드
	public void init(ServletConfig config) throws ServletException {
		
	}

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	// 클라이언트 요청 시 get방식으로 접속하면 실행되는 메소드
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// response.getWriter().append("Served at: ").append(request.getContextPath());
		System.out.println("doGet()메소드 실행");
		// 클라이언트 측에서  보내온 데이터 서버로 가져오기
//		int num = Integer.parseInt(request.getParameter("num"));
//		String name = request.getParameter("name");
//		System.out.println("번호: " + num);
//		System.out.println("이름: " + name);
		
		// 클라이언트에게 문자열(html)을 response로 쓰기
		// 웹 브라우저가 받아서 표시
		// 1. response객체에 헤더 설정
		response.setContentType("text/html; charset=UTF-8");
		
		// 2. response객체에서 PrintWriter객체 구하기
		PrintWriter pw = response.getWriter();
		pw.println("<!DOCTYPE html>");
		pw.println("<html>");
		pw.println("<head>");
		pw.println("<title>서블릿 홈페이지</title>");
		pw.println("<style>");
		pw.println("h1{background-color:yellow;}");
		pw.println("</style>");
		pw.println("</head>");
		pw.println("<body>");
		pw.println("<h1 class='b'>Servlet Homepage</h1>");
        
		pw.println("<a href='"+request.getContextPath()+"/login.do'>로그인</a><br>");
		
//		pw.println("번호: "+num+"<br>");
//		pw.println("이름: "+name+"<br>");
		pw.println("</body>");
		pw.println("</html>");
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	// 클라이언트 요청 시 post방식으로 접속하면 실행되는 메소드
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// doGet(request, response);
	}

}

이렇게 Java안에 html을 작성해서 구현할 수 있다.

그리고 우린 web.xml에 가서 url매핑을 해줘야한다.

  <servlet>
  	<servlet-name>home</servlet-name>
  	<servlet-class>kr.co.campus.IndexServlet</servlet-class>
  </servlet>
  <servlet-mapping>
  	<servlet-name>home</servlet-name>
  	<url-pattern>/index.do</url-pattern>
  </servlet-mapping>

이렇게 매핑을 해주면, localhost:1024/webServlet/index.do를 주소창에 입력하면, IndexServlet.class를 실행한다는 뜻이다.

이제 로그인/로그아웃 페이지를 만들어보자.

LoginServlet.java

package kr.co.campus;

import java.io.IOException;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

/**
 * Servlet implementation class LoginServlet
 */
@WebServlet("/LoginServlet")
public class LoginServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    public LoginServlet() {
        super();
        // TODO Auto-generated constructor stub
    }

    // 로그인 form
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		response.setContentType("text/html; charset=UTF-8");
		
		PrintWriter pw = response.getWriter();
		pw.println("<!DOCTYPE: html>");
		pw.println("<html>");
		pw.println("<head>");
		pw.println("<title>로그인 form</title>");
		pw.println("<style>");
		pw.println("h1{background-color:#ddd;}");
		pw.println("</style>");
		pw.println("</head>");
		pw.println("<body>");
		pw.println("<h1>Login Page</h1>");
		pw.println("<form method='post' action='"+request.getContextPath()+"/login.do'>");
		pw.println("아이디 : <input type='text' name='username'/><br>");
		pw.println("비밀번호 : <input type='password' name='password'/><br>");
		pw.println("<input type='submit' value='LOGIN'/>");
		pw.println("</form>");
		pw.println("</body>");
		pw.println("</html>");
	}

	// 로그인 DB조회
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		String username = request.getParameter("username");
		String password = request.getParameter("password");
		
		Connection conn = null;
		PreparedStatement pstmt = null;
		ResultSet rs = null;
		
		try {
			// 1. 드라이버 로딩
			Class.forName("oracle.jdbc.driver.OracleDriver");
			
			// 2. DB연
			conn = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:xe", "poby", "981024");
			
			// 3. pstmt 생성
			String sql = "SELECT username, name FROM member_tbl WHERE username=? AND password=?";
			pstmt = conn.prepareStatement(sql);
			pstmt.setString(1, username);
			pstmt.setString(2, password);
			
			// 3. 실행
			rs = pstmt.executeQuery();
			
			// 4. 결과 처리
			response.setContentType("text/html; charset=UTF-8");
			PrintWriter pw = response.getWriter();
			if(rs.next()) {	// 로그인 성공 -> 홈페이지로 이동
				// Session에 로그인 정보(아이디, 이름)을 기록한다.
				// Session에 저장된 데이터가 소멸될때까지 현재 서버에서 사용할 수 있다.
				HttpSession session = request.getSession();
				session.setAttribute("logUsername", rs.getString(1));
				session.setAttribute("logName", rs.getString(2));
				
				// 홈페이지 이동
				pw.println("<script>");
				pw.println("alert('로그인 성공했습니다. 홈페이지로 이동 중...');");
				pw.println("location.href='"+request.getContextPath()+"/index.do';");
				pw.println("</script>");
			}else {	// 로그인 실패 -> 로그인 form으로 이동
				pw.println("<script>");
				pw.println("alert('로그인 실패했습니다. 다시 로그인해주세요.');");
				pw.println("history.back();");
				pw.println("</script>");
			}
		}catch(Exception e) {
			e.printStackTrace();
		}finally {
			// 5. DB닫기
			try {
				if(rs!=null) rs.close();
				if(pstmt!=null) pstmt.close();
				if(conn!=null) conn.close();
			}catch(Exception e) {
				e.printStackTrace();
			}
		}
	}

}

index.do에서 로그인버튼을 누르면 get방식으로 요청하기 때문에 LoginServlet.java의 doGet()이 실행된다.

이때 아이디와 비밀번호 입력창을 form태그로 만들어서 LoginServlet.java에게 post방식으로 요청하면 doPost()가 실행된다.

DBConn을 상속하지 못 하기 때문에 직접 DB를 붙여줘야한다.

그렇게 post방식으로 전달받은 아이디와 비밀번호가 DB의 member_tbl에 있는지 확인 후,

일치하면 홈페이지로, 아니면 뒤로가기 시켜준다.

로그인 성공했을때, 아이디와 이름을 세션에 저장시켜서 로그인 정보를 기록한다.

이 기록을 이용해서 로그아웃을 시켜보자.

LogoutServlet.java

package kr.co.campus;

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

/**
 * Servlet implementation class LogoutServlet
 */
@WebServlet("/LogoutServlet")
public class LogoutServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    public LogoutServlet() {
        super();
    }

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// 로그아웃
		// 세션 지우기 - 새로운 세션 할당
		HttpSession session = request.getSession();
		session.invalidate();
		response.sendRedirect(request.getContextPath()+"/index.do");
	}

}

간단하게 session.invalidate()만 해주고 다시 index.do를 요청한다.

방금 만든 두 서블릿을 web.xml에 매핑해주자.

  <servlet>
  	<servlet-name>login</servlet-name>
  	<servlet-class>kr.co.campus.LoginServlet</servlet-class>
  </servlet>
  <servlet-mapping>
  	<servlet-name>login</servlet-name>
  	<url-pattern>/login.do</url-pattern>
  </servlet-mapping>
  
  <servlet>
  	<servlet-name>logout</servlet-name>
  	<servlet-class>kr.co.campus.LogoutServlet</servlet-class>
  </servlet>
  <servlet-mapping>
  	<servlet-name>logout</servlet-name>
  	<url-pattern>/logout.do</url-pattern>
  </servlet-mapping>

다음엔 IndexServlet에 로그인 정보에 따라서 로그인 버튼을 표시할지, 로그아웃 버튼을 표시할지 코드를 짜보자.

'JSP' 카테고리의 다른 글

12.05.(월) JSP(15): Servlet(2)  (0) 2022.12.06
12.02.(금) JSP(13): 게시판 만들기(2)  (0) 2022.12.05
12.01.(목) JSP(12): 게시판 만들기(1)  (0) 2022.12.05
11.30.(수) JSP(11): JSTL(5)  (0) 2022.12.05
11.30.(수) JSP(10): JSTL(4)  (0) 2022.12.05

+ Recent posts