Jsp & Servlet : 로그인

지환·2023년 12월 4일
0

Jsp & Servlet

목록 보기
7/21

@WebServlet으로 서블릿을 URL에 매핑할 때 사용 - 클래스 앞에

서블릿은 늦은 초기화를 사용한다
스프링은 이른 초기화를 사용한다. - 스프링은 서블릿을 발전시킨 것이다.
@WebServlet(urlPatterns={"/hello", "/hello/*"}, loadOnStartup=1)
미리 초기화를 해두고 싶은 서블릿에 붙일 수 있는 옵션임 - loadOnStartup

매핑 패턴 소개 - React Router사용하는 컨셉
아래 번호는 순번을 의미하므로 1번을 따져서 없으면 2번이 또 없으면 3번이 적용됨

  1. exact mapping - /basic/hello.do -> http://localhost/basic/hello.do

  2. path mapping - /basic/* ->

  1. extension mapping - .do, .gd
    :확장자가 do로 끝나기만 한다면 내가 가로챌께
  1. default mapping
    :위에서 부터 따져보다가 어디에도 해당되지 않으면 디폴트가 적용됨
    - http://localhost/basic/hello.do
    - http://localhost/basic/hello
    - http://localhost/basic/
    - http://localhost/basic/test

스프링에서는 @RequestMapping이 제공된다 - 메소드 앞에온다

@Controller - 컨트롤계층의 역할을 맡게됨 - 어노테이션(@) - annotation
:자바에서는 Reflection API를 지원하고 있음
-> 힙 영역에 로드되어 있는 클래스 타입의 객체를 통해서 필드/메소드/생성자를
접근제어자와 상관없이 사용할 수 있도록 지원하는 API
-> 컴파일 시점이 아닌 런타임 시점에 동적으로 특정 클래스의 정보를
추출해 주는 프로그래밍 기법을 지원
-> 주로 프레임워크 또는 라이브러리 개발시 사용됨
예) Spring DI(dependency Injection), Test프레임워크(JUnit), JSON 라이브러리

유효범위

1. pageContext

  • 현재 페이지에서만 사용이 가능하다.
  • EL사용을 위해서만 사용될뿐 사용되지 않는다.
  • 주소창이 바뀐다.

2. request(요청이 유지되는 동안에)

  • 요청할 떄 마다 생기고 서로 독립적이다.
  • 요청마다 1개씩 갖는다.
  • forward시 사용이 가능하다. (forward) 주소창이 바뀌지 않는다.

3. Session

  • 사용자마다 1개씩 생기는 개별저장소이다.
  • 서버에 부하가 높다.(부담이 높다)
  • 로그인하면 생겼다가 로그아웃하면 사라진다.
  • 잠깐 저장했다가 지우는 방법도 가능하다.
  • 주소창이 바뀌어서 요청이 끊어져도 유지된다. (시간)

4. application

  • 서버에 큰 부담을 준다.
  • 공통의 저장소라는 점이 Session과 다르다.
  • context마다 1개라서 어디서나 접근이 가능하다.
  • 모든 클라이언트가 공유가 가능하다.
  • Web Application의 시작부터 종료까지 계속 유지된다.

사용방법

  • 저장할 떄 : SetAttribute(이름.값);
  • 읽어올 때 : getAttribute(이름)/값;

서블릿 경유하지 않은 상태(localhost:8000/auth/index.jsp)

logic

package com.example.demo.separator;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class Login1Logic {
	Logger logger = LoggerFactory.getLogger(Login1Logic.class);

	public String login(String mem_id, String mem_pw) {
		String mem_name = null;
		String db_id = "kiwi";
		String db_pw = "123";
		String db_name = "키위";
		if(mem_id.equals(db_id)) {
			if(mem_pw.equals(db_pw)) {
				mem_name = db_name;
			}else {
				mem_name="비밀번호가 맞지 않습니다.";
			}
		}else {
			mem_name="아이디가 존재하지 않습니다.";
		}
		return mem_name;
	}
	
}


// 

controller

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
    
  <%
  			String mem_name = (String)request.getAttribute("mem_name");
  			out.print(mem_name);
  			// 서블릿을 경유하지 않고 sendRedirect로 요청하면 무조건 null이 출력된다.
  			// auth/lndex.jsp에서 아이디와 비밀번호 입력 후 로그인 버튼을 누르면 auth/login.do를 요청하니깐
  			// 서블릿을 경유한 뒤 Login1Controller에서 sendRedirect로 index.jsp요청이 된다.
  			
  			// 테스트 케이스 localhost:8000/auth/index.jsp
  
  %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	<form id = "f_login" action = "./login.do">
		<input type = "text" name = "mem_id"/><br>
		<input type = "text" name = "mem_pw"/><br>
		<input type = "button" value = "로그인" onclick = "login()"/>
	</form>
	<script>
	login = () =>{
		console.log("login");
		document.querySelector("#f_login").submit();
	}
	</script>
</body>
</html>

<!-- 요청을 나타내는 문자열이 서블릿 매핑 이름 뒤에 붙어서 Get 방식이다. 
		내 비번이 노룿된다. ( 보안 취약)
1. URL : - req.getRequestURI()  도메인을 제외한 나머지 값만 /auth/login.do
2. req.getRequestURL() - full name 모두 다 (http://localhost:8000/auth/login.do)
요청 url을 통해서 사용자의 요청사항을 구분할 수 있다.
auth/login.do
upmu[0] = auth - 컨트롤 클래스 이름으로 사용 
upmu[1] = login - 컨트롤 클래스의 메소드 이름 사용



-->
package com.example.demo.separator;

import java.io.IOException;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

@WebServlet("/auth/login1.do")
public class Login1Controller extends HttpServlet{
	Logger logger = LoggerFactory.getLogger(Login1Controller.class);
	Login1Logic lgLogic = null;
	protected void doService(HttpServletRequest req, HttpServletResponse res) throws IOException
	{
			String mem_id = req.getParameter("mem_id");//where mem_id=?
			String mem_pw = req.getParameter("mem_pw");//and mem_pw=?
			lgLogic = new Login1Logic();
			String mem_name = lgLogic.login(mem_id,mem_pw);
			req.setAttribute("mem_name", mem_name);
			res.sendRedirect("./index.jsp");
	}
	
	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		doService(req,resp);
	
	}

	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		doService(req,resp);
	
	}

	
}

  • doService는 사용자 정의 메소드이다. 객체로 (http~,http~) 를 받아야 사용가능하다.

서블릿을 경유한 경우(sendRedirect)할 떄 null이 나온다.

http://localhost:8000/auth/index.jsp
http://localhost:8000/auth/login1.do

http://localhost:8000/auth/index.jsp 엔터를 쳐도 전부 리다이렉트 되어서 첫 화면으로 넘어간다.

만약에 값을 유지하고 싶으면 forward이다.


http://localhost:8000/auth/login1.do?mem_id=kiwi&mem_pw=12345
(테스트케이스)

package com.example.demo.separator;

import java.io.IOException;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import jakarta.servlet.RequestDispatcher;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

@WebServlet("/auth/login1.do")
public class Login1Controller extends HttpServlet{
	Logger logger = LoggerFactory.getLogger(Login1Controller.class);
	Login1Logic lgLogic = null;
	protected void doService(HttpServletRequest req, HttpServletResponse res) throws ServletException,IOException
	{
			String mem_id = req.getParameter("mem_id");//where mem_id=?
			String mem_pw = req.getParameter("mem_pw");//and mem_pw=?
			lgLogic = new Login1Logic();
			String mem_name = lgLogic.login(mem_id,mem_pw);
			req.setAttribute("mem_name", mem_name);
			RequestDispatcher view = req.getRequestDispatcher("index.jsp");
			view.forward(req, res);
	}
	
	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		doService(req,resp);
	
	}

	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		doService(req,resp);
	
	}

	
}

html

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
    
  <%
  			String mem_name = (String)request.getAttribute("mem_name");
  			out.print(mem_name);
  			// 서블릿을 경유하지 않고 sendRedirect로 요청하면 무조건 null이 출력된다.
  			// auth/lndex.jsp에서 아이디와 비밀번호 입력 후 로그인 버튼을 누르면 auth/login.do를 요청하니깐
  			// 서블릿을 경유한 뒤 Login1Controller에서 sendRedirect로 index.jsp요청이 된다.
  			
  			// 테스트 케이스 localhost:8000/auth/index.jsp
  
  %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	<form id = "f_login" action = "./login1.do">
		<input type = "text" name = "mem_id"/><br>
		<input type = "text" name = "mem_pw"/><br>
		<input type = "button" value = "로그인" onclick = "login()"/>
	</form>
	<script>
	login = () =>{
		console.log("login");
		document.querySelector("#f_login").submit();
	}
	</script>
</body>
</html>

<!-- 요청을 나타내는 문자열이 서블릿 매핑 이름 뒤에 붙어서 Get 방식이다. 
		내 비번이 노룿된다. ( 보안 취약)
1. URL : - req.getRequestURI()  도메인을 제외한 나머지 값만 /auth/login.do
2. req.getRequestURL() - full name 모두 다 (http://localhost:8000/auth/login.do)
요청 url을 통해서 사용자의 요청사항을 구분할 수 있다.
auth/login.do
upmu[0] = auth - 컨트롤 클래스 이름으로 사용 
upmu[1] = login - 컨트롤 클래스의 메소드 이름 사용



-->

logic

package com.example.demo.separator;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class Login1Logic {
	Logger logger = LoggerFactory.getLogger(Login1Logic.class);

	public String login(String mem_id, String mem_pw) {
		String mem_name = null;
		String db_id = "kiwi";
		String db_pw = "123";
		String db_name = "키위";
		if(mem_id.equals(db_id)) {
			if(mem_pw.equals(db_pw)) {
				mem_name = db_name;
			}else {
				mem_name="비밀번호가 맞지 않습니다.";
			}
		}else {
			mem_name="아이디가 존재하지 않습니다.";
		}
		return mem_name;
	}
	
}


// 

url경로로 분석해보자.

http://localhost:8000/auth/index.jsp
이렇게 클라이언트는 url 창에서 아이디와 비밀번호를 입력한다

http://localhost:8000/auth/login1.do?mem_id=kiwi&mem_pw=123
아이디와 비밀번호를 입력 받은 후에 url이 이렇게 바뀐다.

여기서 login1.do는 서블릿 @WebServlet 경로이다.

mem_id & mem_pw는

       1. 우선 서블릿에서  req.getParameter :: req는 듣고 저장한다
       2. 사용자가 입력한 값을 받는다.(form에)
       3. 그걸 logic(java)에 보낸다.
       4. logic의 결과 값은 String mem_name이다 
       5. 이것을 setAttribute로 넘긴다. 당연히 저장하니 req이다.
       6  그걸 index.jsp를 디스패쳐에 넣는다.



세션을 통한 리다이렉트

package com.example.demo.separator;

import java.io.IOException;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

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

@WebServlet("/auth/login1.do")
public class Login1Controller extends HttpServlet{
	Logger logger = LoggerFactory.getLogger(Login1Controller.class);
	Login1Logic lgLogic = null;
	protected void doService(HttpServletRequest req, HttpServletResponse res) throws ServletException,IOException
	{
			String mem_id = req.getParameter("mem_id");//where mem_id=?
			String mem_pw = req.getParameter("mem_pw");//and mem_pw=?
			lgLogic = new Login1Logic();
			String mem_name = lgLogic.login(mem_id,mem_pw);
			req.setAttribute("mem_name", mem_name);
			HttpSession session = req.getSession();
			//응답으로부터 값을 얻어온다. 즉 클라이언트로부터 요청받은 값을 req에 저장하고 그 값을 setAttribute를 통해
			// 스트리트릿으로 내보낸다. 근데 방식을 보면 sendRedirect()로 구성되어 있는데 세션값은 유지되고 있다.
			//session.setAttribute 값은 어디서 이 값을 받을까?
			// 서블릿은 jsp로 클라이언트에게 내보내기 떄문에 jsp로 해당 정보를 전달한다.
			// 해당 정보라는 얘기는 서버로부터 받은 값을 의미한다.
			// Controller 계층은 디비로부터 접근하고 그 값을 가지고 logic 메소드로 넘기는 역할을 진행한다.
			// logic 메소든느 순수 자바 역할을 의미하며,
			
			session.setAttribute("smem_name", mem_name);
			res.sendRedirect("./index.jsp");
			
	}
	
	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		doService(req,resp);
	
	}

	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		doService(req,resp);
	
	}

	
}

꺼내오는것도 Session에서 꺼내와야함

Test Case : http://localhost:8000/auth/login1.do?mem_id=kiwi&mem_pw=123

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
    
  <%
  			String smem_name = (String)session.getAttribute("smem_name");
  			String mem_name = (String)request.getAttribute("mem_name");
  			out.print("세션: +" + smem_name);
  			out.print("<br>");
  			out.print(mem_name);
  			// 서블릿을 경유하지 않고 sendRedirect로 요청하면 무조건 null이 출력된다.
  			// auth/lndex.jsp에서 아이디와 비밀번호 입력 후 로그인 버튼을 누르면 auth/login.do를 요청하니깐
  			// 서블릿을 경유한 뒤 Login1Controller에서 sendRedirect로 index.jsp요청이 된다.
  			
  			// 테스트 케이스 localhost:8000/auth/index.jsp
  
  %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	<form id = "f_login" action = "./login.do">
		<input type = "text" name = "mem_id"/><br>
		<input type = "text" name = "mem_pw"/><br>
		<input type = "button" value = "로그인" onclick = "login()"/>
	</form>
	<script>
	login = () =>{
		console.log("login");
		document.querySelector("#f_login").submit();
	}
	</script>
</body>
</html>

<!-- 요청을 나타내는 문자열이 서블릿 매핑 이름 뒤에 붙어서 Get 방식이다. 
		내 비번이 노룿된다. ( 보안 취약)
1. URL : - req.getRequestURI()  도메인을 제외한 나머지 값만 /auth/login.do
2. req.getRequestURL() - full name 모두 다 (http://localhost:8000/auth/login.do)
요청 url을 통해서 사용자의 요청사항을 구분할 수 있다.
auth/login.do
upmu[0] = auth - 컨트롤 클래스 이름으로 사용 
upmu[1] = login - 컨트롤 클래스의 메소드 이름 사용



-->

그러면

이렇게 넘어감 이 부분에 대한 처리는 Login1Logic에서 처리한다.


Test1

form태그에서 name이 아니라 , id 를 쓴다면?

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
    
  <%
  			String smem_name = (String)session.getAttribute("smem_name");
  			String mem_name = (String)request.getAttribute("mem_name");
  			out.print("세션: +" + smem_name);
  			out.print("<br>");
  			out.print(mem_name);
  			// 서블릿을 경유하지 않고 sendRedirect로 요청하면 무조건 null이 출력된다.
  			// auth/lndex.jsp에서 아이디와 비밀번호 입력 후 로그인 버튼을 누르면 auth/login.do를 요청하니깐
  			// 서블릿을 경유한 뒤 Login1Controller에서 sendRedirect로 index.jsp요청이 된다.
  			
  			// 테스트 케이스 localhost:8000/auth/index.jsp
  
  %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	<form id = "f_login" action = "./login.do">
		<input type = "text" id = "mem_id"/><br>
		<input type = "text" name = "mem_pw"/><br>
		<input type = "button" value = "로그인" onclick = "login()"/>
	</form>
	<script>
	login = () =>{
		console.log("login");
		document.querySelector("#f_login").submit();
	}
	</script>
</body>
</html>

<!-- 요청을 나타내는 문자열이 서블릿 매핑 이름 뒤에 붙어서 Get 방식이다. 
		내 비번이 노룿된다. ( 보안 취약)
1. URL : - req.getRequestURI()  도메인을 제외한 나머지 값만 /auth/login.do
2. req.getRequestURL() - full name 모두 다 (http://localhost:8000/auth/login.do)
요청 url을 통해서 사용자의 요청사항을 구분할 수 있다.
auth/login.do
upmu[0] = auth - 컨트롤 클래스 이름으로 사용 
upmu[1] = login - 컨트롤 클래스의 메소드 이름 사용



-->

  • id는 주로 정적페이지 / js에서 주로 사용하고 name은 서블릿에서 사용한다.

  • 서블릿에서는 화면에서 입력한 값을 들을 떄, name 속성으로만 읽을 수 있다.

  • getParameter의 인자로 String name이 와야한다.

profile
아는만큼보인다.

0개의 댓글