본문 바로가기

웹 개발 한걸음

[Servlet] 로그인 구현하기

 

 

** 이전에 만들었던 JSP 프로젝트를 서블릿을 통해 MVC 패턴을 구현해보는 시간을 가져보았다.

 

[JSP] 4강 - 로그인 기능 구현 // **문제해결**

본 포스팅은 정보 제공용이 아닌 유튜브 동빈나님의 JSP 게시판 만들기 강좌 4강을 바탕으로 보고 배운 것을 직접 정리해본 포스트 입니다. 개인적으로 MVC 패턴에 익숙해졌는지 view를 담당하던 JS

egu99.tistory.com

** 나중에 더 추가해야할 거 : login.jsp에서 아이디, 비밀번호 누락시 control까지 오기 전에 jsp 내의 javascript를 통해 처리하면 좋을 것 같다.

 

** (추가수정) 로그인 상태에서 로그인 요청을 했을 때 다시 로그인 화면이 떠선 안된다. 아래 doGet에서 추가해주었다.

 

 


 

 

** 간략 프로세스 

-> 로그인 버튼

-> LoginControl.java의 doGet으로 login.jsp 포워드

-> login.jsp의 form을 통해 아이디와 비밀번호를 post방식으로 LoginControl에 submit.

-> LoginControl.java의 doPost방식으로 로그인 처리

-> 로그인이 성공하면 메인페이지로, 실패하면 뒤로.

 

 


 

 

** LoginControl.java - doGet()

@WebServlet("/login")
public class LoginControl extends HttpServlet{

	@Override
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

		request.getRequestDispatcher("/WEB-INF/login.jsp").forward(request, response);
	}
	
}

 

  • 로그인 버튼을 누르면 이 서블릿의 URL 매핑명으로 와지도록 되어있다.
  • 단순 get방식으로 이동했기 때문에 doGet메서드 내에서 처리되며 login.jsp로 forwarding한다.
  • 이 때 리다이렉트를 써도 될 거 같은데.. 확인 한번 해보고 추후 수정하겠다.
  • 혹시나 서블릿 매핑을 잘 모른다하면 이전에 글쓴이가 작성해둔 여기 참고 바람.
 

[JSP] 서블릿(Servlet)의 매핑 방법

본 포스팅은 정보 제공용이 아닌 유튜브 뉴렉쳐님의 2020 Servelt & JSP 프로그래밍의 강좌와 여러 개발자 블로그들의 자료를 바탕으로 보고 배운 것을 직접 정리해본 포스트 입니다. ** 매핑을 하는

egu99.tistory.com

 


 

 

** login.jsp

<!-- 로그인 컨테이너 -->
<div class="container">
	<div class="col-lg-4">
		<!-- 점보트론 -->
		<div class="jumbotron" style="padding-top:20px;">
			<!-- form의 데이터 전송 방식과 어디로 전송할지 -->
			<form method="post" action="login"><!--URL매핑명만 써주면 된다.-->
				<h3 style="text-align: center;">로그인 화면</h3>
				<div class="form-group">
					<input type="text" class="form-control" placeholder="아이디" name="userID" maxlength="20">
				</div>
				<div class="form-group">
					<input type="password" class="form-control" placeholder="비밀번호" name="userPassword" maxlength="20">
				</div>
				<input type="submit" class="btn btn-primary form-control" value="로그인">
			</form>
		</div>
	</div>
</div>
  • 이전에 작성했던 form태그와 똑같다.
  • 다만 form을 보낼 곳을 정하는 action에 url매핑명을 적어준다.
  • 아이디와 비밀번호는 post방식으로 보내진다.

 

 


 

 

** LoginControl.java - doPost()

@WebServlet("/login")
public class LoginControl extends HttpServlet{

	
	@Override
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		
		//response.setCharacterEncoding("UTF-8"); 
		//response.setContentType("text/html; charset=UTF-8");
		
		String userID = request.getParameter("userID");
		String userPassword = request.getParameter("userPassword");
		
		UserDAO uao = new UserDAO();
		int result = uao.login(userID, userPassword);
		
		if(result ==1){ //로그인 성공
			//세션 부여
			HttpSession session = request.getSession();
			session.setAttribute("userID", userID);
			
			PrintWriter script = response.getWriter();
			script.println("<script>");
			script.println("alert('로그인 성공');");
			script.println("location.href='main'");			
			script.println("</script>");
			//성공했으니 메인으로
			//request.getRequestDispatcher("/main").forward(request, response);
			
		}else if (result == 0){ //비밀번호 불일치
			PrintWriter out = response.getWriter();
			out.println("<script>");
			out.println("alert('비밀번호가 틀렸습니다.');"); 
			out.println("history.back();");
			out.print("</script>");
			
		}else if (result == -1){ //아이디 존재x
			PrintWriter script = response.getWriter();
			script.println("<script>");
			script.println("alert('존재하지 않는 아이디입니다.');"); 
			script.println("history.back();");
			script.print("</script>");
				
		}else if (result == -2){	//데이터베이스 오류
			PrintWriter script = response.getWriter();
			script.println("<script>");
			script.println("alert('데이터베이스 오류가 발생했습니다.')");
			script.println("histroy.back()");
			script.println("</script>");
			
		}
		
	}

 

  • request로 보내진 아이디와 패스워드를 getParameter해주고 이를 인자로 UserDAO의 login메서드를 호출한다.
  • 반환값에 따라 자바스크립트로 alert와 이동을 해준다.
  • 로그인에 성공했다면 세션을 부여해주고 Main.jsp로 가기 위해 MainControl의 URL매핑명을 이용해 forwarding한다.
  • 다만 자바스크립트 처리를 여기서 하는 것은 올바르지 않다고 생각한다. 자바스크립트를 좀더 공부해서 추후에 수정할 계획이다.
  • (수정) UTF-8의 필터 추가와 페이지이동과 스크립트 사이의 우선순위 때문에 location.href로 바꿔주었다. 여기 참고.
 

[Servlet] 로그아웃 + UTF-8 WebFilter 구현하기

** 이전에 JSP로 만들었던 코드를 이용해 서블릿으로 아주 쉽게 구현해보았다. 다만 두가지 이슈가 발견되었다. 하나는 자바스크립트의 한글화, 나머지 하나는 forward, redirect시 이동이 우선시 되

egu99.tistory.com


 

** UserDAO.login()

public class UserDAO {

	//데이터베이스를 접근하게 해주는 객체.
	private Connection conn;
	//쿼리문을 미리 준비해두는 객체.
	private PreparedStatement pst;
	//쿼리를 실행시키고 결과값을 내는 객체.
	private ResultSet rs;
	
	public UserDAO() {
		try {
			String dbURL = "jdbc:mysql://localhost:3306/DONG_BBS";
			String dbID = "root";
			String dbPassword = "1111";
			Class.forName("com.mysql.jdbc.Driver");
			conn = DriverManager.getConnection(dbURL, dbID, dbPassword);
			
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	public int login(String userID, String userPassword) {
		String sql = "SELECT userPassword FROM USER WHERE userID=?";
		
		try {
			pst = conn.prepareStatement(sql);
			pst.setString(1, userID);
			rs = pst.executeQuery();
			if(rs.next()) {
				if(rs.getString(1).equals(userPassword))
					return 1;	//로그인 성공
				else
					return 0; //비밀번호 불일치
				
			} 
			return -1; //아아디가 없을 경우 (rs.next()가 존재하지 않을 경우)
				
		} catch (Exception e) {
			e.printStackTrace();
		}
		return -2; //데이터베이스 오류
		
	}
	
}
  • 로그인 기능이다. 이전에 구현해둔 것과 완전히 동일하다.

 

 

 


 

** MainControl.java

@WebServlet("/main")
public class MainControl extends HttpServlet {

	@Override
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		System.out.println("앗뇽");
		request.getRequestDispatcher("/WEB-INF/main.jsp").forward(request, response);
		
	}
	
	@Override
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		

	}
	
	
}
  • 처음에는 doGet에서 구현했는데 405 오류가 나기 때문에 doPost에서 구현해야한다. 
  • 자세한 오류수정 과정은 이곳에서.
  • 메인으로 forwarding 된다.
 

[해결]HTTP 상태 405 – 허용되지 않는 메소드

** JSP 로그인 기능을 서블릿으로 이식하는 중에 처음 보는 오류가 발생했다. ** LoginControl 서블릿에서 login.jsp로 이동. -> login.jsp에서 로그인 아이디와 비밀번호 작성 후 post방식으로 loginControl로 s..

egu99.tistory.com

 

 


 

** (추가) LoginControl.java - doGet()

@Override
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		
		HttpSession session = request.getSession();
		
		if(session.getAttribute("userID") != null) {
			PrintWriter script = response.getWriter();
			script.println("<script>");
			script.println("alert('이미 로그인 되었습니다.');");
			script.println("location.href='main'");			
			script.println("</script>");
		}else {
			request.getRequestDispatcher("/WEB-INF/login.jsp").forward(request, response);
		}
	}

 

  • 기존 코드는 get으로 요청시 바로 login.jsp로 forward를 해주었었다.
  • 하지만 로그인이 이미 되어있는 상태라면 다시 로그인창을 띄워선 안된다. 
  • 세션을 가져와서 세션에 userID가 있는지 확인해보고 있다면 이미 로그인되었다는 창과 함께 메인으로 가주도록 하였다.