공부의 기록/자바 풀 스택 : 수업내용정리

자바 풀 스택 1/9 오후 기록 034-2

파티피플지선 2025. 1. 9. 17:47

<14:30 5교시>

로그아웃 기능

 

 

Step04Filter

모든 동작에 대해서 필터가 진행된다. "/*"의 의미는 select *(all) 이나 git add . 같은 역할인거다.

 

 

 

LogFilter

package test.filter;

import java.io.IOException;
import java.time.LocalDateTime;

import jakarta.servlet.Filter;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.ServletRequest;
import jakarta.servlet.ServletResponse;
import jakarta.servlet.annotation.WebFilter;
import jakarta.servlet.http.HttpServletRequest;

/*
 * [ 필터 만드는 방법 ]
 * 1. 필터 인터페이스를 구현
 * 2. 추상매소드 재정의(override)
 * 3. @WebFilter 어노테이션을 이용해서 요청 맵핑하기
 */
@WebFilter("/*") //  "/*"이 프로젝트(컨텍스트)에 오는 모든 요청에 대해서 필터가 동작되게 된다.
public class LogFilter implements Filter{

	@Override
	public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain)
			throws IOException, ServletException {
			System.out.println("Log 필터 수행됨!");
			//부모 타입 객체를 원래 타입(자식타입)으로 캐스팅
			HttpServletRequest request=(HttpServletRequest)req;
			String uri=request.getRequestURI();
			System.out.println("요청 uri:"+uri);		
			
			//
			String clientIp=request.getRemoteAddr();
			System.out.println("client ip:"+clientIp);
			
			System.out.println("시간:"+LocalDateTime.now());
			
			//요청의 흐름 계속 이어가기
			chain.doFilter(req, resp);
	}
	
}

필터에서 할 수 있어야 하는거

1. 필터 만들기

2. 필터 매핑할 수 있기

 

package test.filter;

import java.io.IOException;

import jakarta.servlet.Filter;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.ServletRequest;
import jakarta.servlet.ServletResponse;
import jakarta.servlet.annotation.WebFilter;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;
@WebFilter("/admin/*")
public class AdminFilter implements Filter{

	@Override
	public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain)
			throws IOException, ServletException {
		//HttpServletRequest 객체의 참조값
		HttpServletRequest request=(HttpServletRequest)req;
		//HttpSession 객체의 참조값
		HttpSession session=request.getSession();
		//세션 스코프에 저장된 아이디 값 읽어오기
		String id=(String)session.getAttribute("id");
		
		if(id!=null) {
			//DB에서 해당 아이디의 권한이 관리자인지 읽어와 본다.
			if(id.equals("admin")||id.equals("2ndadmin")) {
				//관리자가 맞다면 요청의 흐름을 이어간다.
				chain.doFilter(req, resp);
				return;
			}
		}
		//session에 저장된 아이디가 없거나 관리자가 아니라면 에러를 응답한다.
		HttpServletResponse response=(HttpServletResponse)resp;
		//403 에러 응답
		response.sendError(HttpServletResponse.SC_FORBIDDEN);
	}
}

<15:30 6교시>

인덱스에 로그인 기능 만들기

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
    
  <%
  	//세션에 저장된 아이디가 있는지 읽어보기
  	String id=(String)session.getAttribute("id");
  %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	<div class="container">
		<%if(id==null){ %>
			<a href="user/loginform.jsp">로그인 하러 가기</a>
		<%}else{ %>
			<strong><%=id %></strong>님 로그인중...
			<a href="user/logout.jsp">로그아웃</a>
		<%} %>
		<h1>홈페이지</h1>
		
		<ul>
			<li><a href="test/study.jsp">공부하러 가기</a></li>
			<li><a href="test/game.jsp">게임하러 가기</a></li>
			<li><a href="admin/manage.jsp">관리자 페이지</a></li>
		
		</ul>
	</div>
</body>
</html>

loginform.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	<div class="container">
		<h1>login form</h1>
		<form action="login.jsp" method="post">
			<div>
				<label for="">id</label>
				<input type="text" name="id" id="id" />
			</div>
			<div>
				<label for="pwd">pw</label>
				<input type="password" name="pwd" id="pwd" />
			</div>
			<button type="submit">로그인</button>
		</form>
	</div>
</body>
</html>

login.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%
	//폼에서 전송되는 아이디, 비밀번호를 읽어온다.
	String id=request.getParameter("id");
	String pwd=request.getParameter("pwd");
	//DB에 사용자 정보를 읽어와서 맞는 정보인지 비교한다
	boolean isValid=false;
	if(pwd.equals("1234")){
		//세션에 "id"라는 키값으로 로그인도니 아이디를 저장한다
		session.setAttribute("id", id);
		isValid=true;
		
	}
	
	
%>

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	<div class="container">
		<%if(isValid){ %>
		<p>
			<strong><%=id %></strong>님, 로그인되었습니다.
			<a href="${pageContext.request.contextPath}/">인덱스로</a>
		</p>
		<%}else{ %>
		<p>
			아이디 혹은 비밀번호가 틀립니다.
			<a href="loginform.jsp">다시 로그인하러 가기</a>
		</p>
		<%} %>
	</div>
</body>
</html>

 

 

logout.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%
	session.removeAttribute("id");
%>
    
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	<script>
		alert("로그아웃되었습니다");
		location.href="${pageContext.request.contextPath}/"
	
	</script>
</body>
</html>

logout.jsp

 

 

 

 

 

로그인 한 사람들만 게임 아이템을 구매할 수 있게 로그인 상태를 확인하는 기능 추가해보기

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	<div class="container">
		<h1>게임 아이템 구매 페이지입니다</h1>
		<a href="${pageContext.request.contextPath}/">홈페이지로 들어가기</a>
		
	</div>
</body>
</html>

 

 

LoginFilter.java

package test.filter;

import java.io.IOException;

import jakarta.servlet.Filter;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.ServletRequest;
import jakarta.servlet.ServletResponse;
import jakarta.servlet.annotation.WebFilter;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;
@WebFilter({"/test/protected/*", "/xxxx/protected/*"}) //자바에서 {}안은 배열이라 여러 경로를 쓸 수 있다.
public class LoginFilter implements Filter {

	@Override
	public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain)
			throws IOException, ServletException {
		HttpServletRequest request=(HttpServletRequest)req;
		HttpSession session=request.getSession();
		//세션영역에 아이디라는 키값으로 저장된 값이 있는지 확인하기(로그인된 사용자인지 확인)
		String id=(String)session.getAttribute("id");
		//만일 로그인 하지 않았다면
		if(id==null) {
			//로그인 페이지로 리다이렉트 이동시킴
			String cPath=request.getContextPath();
			HttpServletResponse response=(HttpServletResponse)resp;
			response.sendRedirect(cPath+"/user/loginform.jsp");
		}else {
			//로그인 한 사용자라면 관여하지 않고 요청의 흐름을 이어간다
			chain.doFilter(req, resp);
		}
	}
}

<16:30 7교시>

Step05Fetch : 요청을 자바스크립트로 하고, 페이지 이동 없이 함수로 요청 내용을 받음

요청할 경로를 전달 -> html 형식으로 응답한 데이터가 최종적으로 data 로 전달.

 

res=>res.text() 의 모양은   function(res){return res.text();} 의 모양과 동일하다.

			fetch("${pageContext.request.contextPath }/index.jsp")
			.then(function(res){
				return res.text();
			})
			.then(function(data){
				console.log(data);
			});
			
			fetch("${pageContext.request.contextPath }/index.jsp")
			.then(res=>{
				return res.text();
			})
			.then(data=>{
				console.log(data);
			});
			
			fetch("${pageContext.request.contextPath }/index.jsp")
			.then(res=>res.text())
			.then(data=>{
				console.log(data);
			});

 

Fetch 함수의 구조!!!!! 암기!!!!! 페이지가 바뀌지 않으면서 요청을 응답할 수 있으므로!!!!

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	<h3>fetch 함수 테스트</h3>
	<button id="myBtn">click</button>
	<script>
		document.querySelector("#myBtn").addEventListener("click", ()=>{
			//javascript로 서버에 요청하기
			
			
			/*
			서버 (jsp or servlet) 에서 응답한 문자열이 json 형식이면 
			return res.json();
			그 외 형식이면 html, xml, plain txt 등등
			return res.text();
			*/
			fetch("${pageContext.request.contextPath}/index.jsp") //페이지 전환 없이 javascript 로 요청을 하면 응답된 문자열이
			.then(res=>res.text())
			.then(data=>{							//두번째 then()애 전달한 함수의 매개 변수에 전달된다.
				console.log(data);
				
				//위의 then() 함수에서 res.json()을 리턴하면 data는 응답된 json 문자열을 JSON.parse()과정을 이미 거친 object나 array이다.
				//위의 then() 함수에서 res.text()를 리턴하면 data는 서버가 응답한 문자열(String)이다
			});
		});
	</script>
</body>
</html>

 

 

 

fetch 함수의 구조는 꼭 파악해야 한다!!! 페이지 전환 없이 데이터를 요청해서 응답할 수 있는 구조

예를 들어 회원 가입 폼을 작성 중인데, 데이터 베이스에 내가 쓸 수 있는 아이디인지 아닌지 확인해보려고 서버에 확인을 요청하는데 페이지가 전환되면 작성중이던 폼이 다 삭제되어 버리니까, Fetch를 사용해서 페이지 전환 없이 요청에 응답

 

test02.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>/fetch/test02.jsp</title>
</head>
<body>
	<input type="text" id="msg" placeholder="메세지 입력..."/>
	<button id="sendBtn">전송</button>
	<script>
		document.querySelector("#sendBtn").addEventListener("click", ()=>{
			//입력한 문자열 읽어오기
			const msg=document.querySelector("#msg").value;
			//fetch 함수를 호출하면서 GET 방식 파라미터로 send.jsp 페이지를 요청하면서 전달한다.
			fetch("send.jsp?msg="+msg)
			.then(res=>res.text())
			.then(data=>{
				console.log(data);
			});
		});
	</script>
</body>
</html>

 

send.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<% 
	//Get 방식으로 요청 파라미터 읽어오기
	String msg=request.getParameter("msg");
	System.out.println("msg:"+msg);
%>

<!DOCTYPE html>
<html>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	메시지 문자 확인	
</body>
</html>

 

 

 

 

<17:30 8교시> 

서버는 불특정 다수를 상대해야 하기 때문에 요청에 대해 응답한 다음 잠시 연결된 것을 끊어버림. 연결을 유지하지 않음.

 

아카이브에 자바 수업 내용 정리하러 다시 갑니다.