@WebServlet으로 서블릿을 URL에 매핑할 때 사용 - 클래스 앞에
서블릿은 늦은 초기화를 사용한다
스프링은 이른 초기화를 사용한다. - 스프링은 서블릿을 발전시킨 것이다.
@WebServlet(urlPatterns={"/hello", "/hello/*"}, loadOnStartup=1)
미리 초기화를 해두고 싶은 서블릿에 붙일 수 있는 옵션임 - loadOnStartup
매핑 패턴 소개 - React Router사용하는 컨셉
아래 번호는 순번을 의미하므로 1번을 따져서 없으면 2번이 또 없으면 3번이 적용됨
exact mapping - /basic/hello.do -> http://localhost/basic/hello.do
path mapping - /basic/* ->
스프링에서는 @RequestMapping이 제공된다 - 메소드 앞에온다
@Controller - 컨트롤계층의 역할을 맡게됨 - 어노테이션(@) - annotation
:자바에서는 Reflection API를 지원하고 있음
-> 힙 영역에 로드되어 있는 클래스 타입의 객체를 통해서 필드/메소드/생성자를
접근제어자와 상관없이 사용할 수 있도록 지원하는 API
-> 컴파일 시점이 아닌 런타임 시점에 동적으로 특정 클래스의 정보를
추출해 주는 프로그래밍 기법을 지원
-> 주로 프레임워크 또는 라이브러리 개발시 사용됨
예) Spring DI(dependency Injection), Test프레임워크(JUnit), JSON 라이브러리
서블릿 경유하지 않은 상태(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);
}
}
서블릿을 경유한 경우(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이 와야한다.