[Java] Filter + Session 로그인

JH·2023년 4월 21일

Java

목록 보기
16/21

1. TIL

jsp의 조건c:if을 이용하여 태그 구성

session을 이용하여 로그인 기능 유지, 비로그인 시 해당 기능 접근 불가

filter를 이용하여 전 처리하기 (Annotation, web.xml)

web.xml에서 2중 필터 구성 (encoding, seesion check)
web.xml에서 특정 error 코드 발생시 페이지 이동

DTO에서 데이터 베이스의 Date 타입을 사용하려면 sql.Date를 사용해야함
null이될 수 있는 숫자자료형은 Integer Wrapper 클래스로 명시해야함 (DB에서 NUMBER은 NULL이 될 수 있음)

올바른 url 표기법 : /Dept/insert/???? 이렇게 / 단위로 끊어주는게 올바르다고 함


A. Practice

1. JSP

login.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<title>Login</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="/css/layout.css" rel="stylesheet" type="text/css"> 
</head>
<body>
<%@ include file="../layout/header.jsp" %>
<form action="login.do" method="POST">
	<table align="center" cellpadding="5" cellspacing="1" width="600" border="1">
	    <tr>
	        <td width="1220" height="20" colspan="2" bgcolor="#336699">
	            <p align="center">
	            	<font color="white" size="3">
	            		<b>로그인</b>
	            	</font>
	            </p>
	        </td>
	    </tr>
	    <tr>
	        <td width="150" height="20">
	            <p align="center"><b><span style="font-size:12pt;">사원번호</span></b></p>
	        </td>
	        <td width="450" height="20" align="center">
	        	<b>
	        		<span style="font-size:12pt;">
	        			<input type="text" name="empno" size="30">
	        		</span>
	        	</b>
	        </td>
	    </tr>
	    <tr>
	        <td width="150" height="20">
	            <p align="center"><b><span style="font-size:12pt;">사  원  명</span></b></p>
	        </td>
	        <td width="450" height="20" align="center">
	        	<b>
	        		<span style="font-size:12pt;">
	        			<!-- input 박스 -->
	        			<input type="text" name="ename" size="30">
	        		</span>
	        	</b>
	        </td>
	    </tr>
	    <tr>
	        <td width="150" height="20">
	            <p><b><span style="font-size:12pt;">&nbsp;</span></b></p>
	        </td>
	        <td width="450" height="20" align="center">
	        	<b>
	        		<span style="font-size:12pt;">
						<input type="submit" value="로그인">
						&nbsp;&nbsp;&nbsp;&nbsp;
						<input type="reset" value="다시작성">
					</span>
				</b>
			</td>
	    </tr>
	</table>
</form>
<hr>
<div align=center>
	<span style="font-size:12pt;"><input type="button" value="메인으로" onclick="location.href='/getDeptList.do'"></span>
</div>
<%@ include file="../layout/footer.jsp" %>
</body>
</html>

header.jsp

c:if 를 활용하여 session 의 null 여부에 따라 태그 구성

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

<header>
  <h1>Servlet / JSP</h1>
  <p>Dept Practice Header</p>
  <div align="right">
	  <c:if test="${empty sessionScope.userId}">
		  	<span style="font-size:12pt;"><input type="button" value="로그인" onclick="location.href='/main.do'"></span>
	  </c:if>
  <c:if test="${not empty sessionScope.userId}">
	  	<span>${sessionScope.userName}님 환영합니다.</span><span style="font-size:12pt;"><input type="button" value="로그아웃" onclick="location.href='/logout.do'"></span>
  </c:if>
  </div>
</header>

2. Controller

MainController (login.jsp로 redirect)

@WebServlet("/main.do")
public class MainController extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
	protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		request.getRequestDispatcher("/login.jsp").forward(request, response);
	}
}

LoginController (로그인 여부 체크)

@WebServlet("/login.do")
public class LoginController extends HttpServlet {
	private static final long serialVersionUID = 1L;

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {		
		String url = "errors/error.jsp";	
		String empno = request.getParameter("empno");
		String ename = request.getParameter("ename");
		
		if(empno == "" || ename == "" || empno == null || ename == null) {
			request.setAttribute("error", "사원번호, 사원명 재확인");
			request.getRequestDispatcher(url).forward(request, response);
			return;
		}
		
		Emp emp = null;
		try {
			emp = EmpDAO.getEmpByEmpnoAndEname(Integer.parseInt(empno), ename);
			
			if (emp == null) {
				request.setAttribute("error", "존재하지 않는 사원 또는 사원정보 오류");
				request.getRequestDispatcher(url).forward(request, response);
				return;
				
			} else {
				HttpSession session = request.getSession();
				session.setAttribute("userId", emp.getEmpno());
				session.setAttribute("userName", emp.getEname());
				
				url = "/getDeptList.do";
				response.sendRedirect(url);
				return;
			}
			
		} catch (Exception e) {
			request.setAttribute("error", "로그인 실패");
			request.getRequestDispatcher(url).forward(request, response);
		}
		
	}
}

LogoutController (로그아웃)

세션은 null로 넘어올 수 있다는 걸 항상 고려 해야함
세션을 무효화 시키고 null로 재할당

@WebServlet("/logout.do")
public class LogoutController extends HttpServlet {
	private static final long serialVersionUID = 1L;

	protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		String url = "errors/error.jsp";

		// getSession(false) : 기존의 세션이 존재하지 않으면 -> null return		
		HttpSession session = request.getSession(false);
		
		if(session == null) {
			response.sendRedirect("/main.do");
			return;
		}
		
		session.invalidate();
		session = null;
		url = "/main.do";
		response.sendRedirect(url);
		return;
	}

}

3. Filter

encoding

//@WebFilter("/EncodingFilter") // xml 사용
public class EncodingFilter implements Filter {
	String encoding = null;
		
	public void init(FilterConfig fConfig) throws ServletException {
		encoding = fConfig.getInitParameter("charset");
	}

	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
		System.out.println("encoding - pre - loading");
		request.setCharacterEncoding(encoding);
		
		chain.doFilter(request, response);
	}
}

Authentication

HttpServlet****** 으로 형변환을 해줘야함

//@WebFilter(urlPatterns = { // xml 사용
//						"/getDept.do",
//						"/insertDeptForm.do",
//						"/logout.do"
//						})
public class AuthenticationFilter implements Filter {
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
		
		HttpServletRequest req = (HttpServletRequest)request;
		HttpServletResponse res = (HttpServletResponse)response;
		
		HttpSession session = req.getSession(false);
		
		if(session == null || session.getAttribute("userId") == null) {
			res.sendRedirect("/main.do");
			return;
		} 
		chain.doFilter(request, response);		
	}
}

4. web.xml

error코드에 대한 페이지 이동
초기화시 사용할 파라미터, url-pattern / 유의

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" id="WebApp_ID" version="4.0">
  <display-name>step07_ConnectionPool_t11</display-name>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>default.html</welcome-file>
    <welcome-file>default.jsp</welcome-file>
    <welcome-file>default.htm</welcome-file>
  </welcome-file-list>
  
  <error-page>
  	<error-code>405</error-code>
  	<location>/errors/error.jsp</location>
  </error-page>

  <filter>
  	<filter-name>encoding</filter-name>
  	<filter-class>common.filter.EncodingFilter</filter-class>
  	<init-param>
  		<param-name>charset</param-name>
  		<param-value>UTF-8</param-value>
  	</init-param>
  </filter>
  
  <filter-mapping>
  	<filter-name>encoding</filter-name>
  	<url-pattern>*.do</url-pattern>
  </filter-mapping>

  <filter>
  	<filter-name>auth</filter-name>
  	<filter-class>common.filter.AuthenticationFilter</filter-class>
  </filter>
  
  <filter-mapping>
  	<filter-name>auth</filter-name>
  	<url-pattern>/getDept.do</url-pattern>
  	<url-pattern>/insertDeptForm.do</url-pattern>
  	<url-pattern>/update*</url-pattern>
  	<url-pattern>/delete*</url-pattern>
  	<url-pattern>/logout.do</url-pattern>
  </filter-mapping>
  
</web-app>


2. 에러

xml에서 url-pattern / 표기 예외

filter로 모든 페이지의 전처리에 session을 확인하도록 설계 (null → main.do)
로그아웃 상태이면 main.doredirect 시킴

로그아웃 버튼을 누르면 로그아웃이 되고 main.do로 이동하는 과정에서
main.do도 필터에 의해 다시 main.do로 이동해서 무한루프가 만들어짐

해결 방법 : *.do 를 각각의 url로 표기함 *는 사용 시 고려할 것이 많음


3. 보완 해야 할 것

Servlet을 생성할 때 Service 메소드로 받으면 requestresponse를 둘 다 받을 수 있으므로 좋을 줄 알았지만 doGet, doPost로 나눠 받아야 Post만 할 수 있는 url에 사용자가 Get요청을 하는 상황 등을 고려하지 못함

xml 파일에서 작업할 때 자동완성이 안되는 부분이 있으므로 코드에 대한 문법, 오타를 주의해야함
url-pattern/ 의 유무 때문에 서버가 열리지도 않는 상황이 발생함

JSP의 조건, 반복, 출력을 잘 사용하면 상황에 따른 페이지를 구현할 수 있음


4. 느낀점

오늘 무한루프 때문에 정말 서버를 다운시킬 뻔했다 (순간 콘솔창이 수직 낙하함)

막상 코딩을 하다가 나중에 실행시켜보면 정말 고쳐야할 부분 개선해야할 부분이 많다. java에서 이유없는 사용은 나중에 꼭 돌아오는 것 같다.

java의 기본적인 부분이 끝나고 다음 주부터 Spring을 한다고 하는데 기대반 걱정반이다.

주말에 여태 배운 것을 한바퀴 쭉 돌아봐야겠다.

profile
잘해볼게요

0개의 댓글