로그인,기본객체 -22.06.16~06.17
복습
Line :
1.protocol
2.url
3.method
response Line : protocol , status
500 :세분화하지않아 서버에대한것을 알리지 않기 위해
404: Not found
405: request method와 연관
302/307 : redirect와 연관
header 안에
1.mime 설정 content type
2. cache 남길지말지 cache control
3. Expires :시간을 결정함
---------------------------------------------------------------------------------------------------------
<web.xml>
<?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_3_1.xsd" version="3.1">
<display-name>WebStudy02_MVN</display-name>
<welcome-file-list>
<welcome-file>index.do</welcome-file>
</welcome-file-list>
<servlet>
<servlet-name>DescServlet</servlet-name>
<servlet-class>kr.or.ddit.servlet01.DescServlet</servlet-class>
<init-param>
<param-name>param1</param-name>
<param-value>value1</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>DescServlet</servlet-name>
<url-pattern>/desc.do</url-pattern>
</servlet-mapping>
</web-app>
<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>
<form action="${ pageContext.request.contextPath}/login/loginProcess.do" method="post">
<ul>
<li><input type="text" name="memId" placeholder="아이디" /></li>
<li><input type="text" name="memPass" placeholder="비밀번호"/></li>
<li><input type="submit" value="로그인" /></li>
</ul>
</form>
</body>
</html>
=> 이거 왜하지?
데이터를 직렬화 할 수있는지 확인 하는 인터페이스
아무리 객체가 직렬화되더라도 직렬화데이터에서 빠져나옴
private transient String memPass;
getSession() : 1.무조건 강제로 만들어줘서 null 안되도록 함
if(session.isNew() : 처음들어온게 이상한것임 왜냐 폼에서부터 오기 때문 ??
<index.jsp>
<%@page import="kr.or.ddit.vo.MemberVO"%>
<%@page import="org.apache.commons.lang3.StringUtils"%>
<%@ 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>
<script type="text/javascript" src="<%=request.getContextPath()%>/resources/js/jquery-3.6.0.min.js"></script>
<%
request.setCharacterEncoding("utf-8");
String message = request.getParameter("message");
if(StringUtils.isBlank(message)){
message = (String) session.getAttribute("message");
}
if(StringUtils.isNoneBlank(message)){
%>
<script type="text/javascript">
alert("<%=message%>");
</script>
<%
session.removeAttribute("message"); // Flash Attribute
}
%>
</head>
<body>
<h4>웰컴 페이지 </h4>
<%
MemberVO authMember =(MemberVO)session.getAttribute("authMember");
if(authMember==null){
%>
<a href="<%=request.getContextPath() %>/login/loginForm.jsp">로그인</a>
<%
}else{
%>
<%=authMember.getMemId() %>님
<form id="LogoutForm" method="post" action="${pageContext.request.contextPath}/login/logout.do"></form>
<a id="LogoutBtn" href="${pageContext.request.contextPath}/login/logout.do">로그아웃</a>
<script type="text/javascript">
$('#LogoutBtn').on("click",function(event){
event.preventDefault();
$(this).prev("form:first").submit();
return false;
});
</script>
<%
}
%>
</body>
</html>
<loginForm.jsp>
<%@page import="org.apache.commons.lang3.StringUtils"%>
<%@ 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>
<%
String message =(String)session.getAttribute("message");
if(StringUtils.isNoneBlank(message)){
%>
<%-- ${message} --> JSTL --%>
<script>
alert("<%=message%>");
</script>
<%
}
%>
</head>
<body>
<form action="${ pageContext.request.contextPath}/login/loginProcess.do" method="post">
<ul>
<li><input type="text" name="memId" placeholder="아이디" /></li>
<li><input type="text" name="memPass" placeholder="비밀번호"/></li>
<li><input type="submit" value="로그인" /></li>
</ul>
</form>
</body>
</html>
<LoginProcessServlet.java>
package kr.or.ddit.login;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.Validate;
import kr.or.ddit.vo.MemberVO;
@WebServlet("/login/loginProcess.do")
public class LoginProcessServlet extends HttpServlet{
private boolean authenticate(MemberVO member) {
return member.getMemId().equals(member.getMemPass());
}
private boolean Validate(MemberVO member) {
return StringUtils.isNoneBlank(member.getMemId())
&&
StringUtils.isNoneBlank(member.getMemPass());
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
HttpSession session =req.getSession();
if(session.isNew()) {
resp.sendError(HttpServletResponse.SC_BAD_REQUEST);
return;
}
req.setCharacterEncoding("UTF-8"); //모든 컨트롤러의 첫번째
MemberVO member = new MemberVO();
member.setMemId(req.getParameter("memId"));
member.setMemPass(req.getParameter("memPass"));
//1.검증
boolean valid =Validate(member);
boolean redirect =false;
String view =null;
if(valid) {
// -통과
// 2. 처리(로그인 여부 판단)
if(authenticate(member)) {
// Post-Redirect-Get 패턴
// -로그인 성공 : welcome 페이지로 이동(redirect)
session.setAttribute("message", "로그인 성공");
session.setAttribute("authMember", member);
redirect=true;
view="/";
}else {
// -실패 : loginForm 으로 이동(forward)
session.setAttribute("message", "로그인 실패");
redirect=true;
view ="/login/loginForm.jsp";
}
}else {
// -불통 :loginForm 으로 이동(forward / include(UI책임 나눠가짐)) 서블릿이 UI책임 나눠가질 필요 없으므로 forward
session.setAttribute("message", "검증실패");
redirect=true;
view ="/login/loginForm.jsp";
}
if(redirect) {
resp.sendRedirect(req.getContextPath() +view);
}else {
req.getRequestDispatcher(view).forward(req, resp);
}
}
}
<IndexServlet .java>
package kr.or.ddit;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet("/index.do")
public class IndexServlet extends HttpServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String view ="/WEB-INF/views/index.jsp";
req.getRequestDispatcher(view).forward(req, resp);
//resp.sendRedirect(req.getContextPath()+view); 안됨 WEB-INF 안에 있으므로 도착지 위치가 외부에서 접근 가능한지 여부 확인
}
}
<LogoutServlet.java>
package kr.or.ddit.login;
import java.io.IOException;
import java.net.URLEncoder;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
@WebServlet("/login/logout.do")
public class LogoutServlet extends HttpServlet{
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
HttpSession session =req.getSession(false); //없으면 만들지말고 null값 반환해라
if(session==null || session.isNew()) {
resp.sendError(400);
return;
}
session.invalidate();
String message = URLEncoder.encode("로그아웃","UTF-8");
resp.sendRedirect(String.format("%s%s%s",req.getContextPath(),"/?message=",message));
}
}
<MemberVO.java>
package kr.or.ddit.vo;
import java.io.Serializable;
//DTO, marker interface : Serializable - marker annotation
public class MemberVO implements Serializable {
private String memId;
private transient String memPass;
public String getMemId() {
return memId;
}
public void setMemId(String memId) {
this.memId = memId;
}
public String getMemPass() {
return memPass;
}
public void setMemPass(String memPass) {
this.memPass = memPass;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((memId == null) ? 0 : memId.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
MemberVO other = (MemberVO) obj;
if (memId == null) {
if (other.memId != null)
return false;
} else if (!memId.equals(other.memId))
return false;
return true;
}
@Override
public String toString() {
return "MemberVO [memId=" + memId + "]";
}
}
기본객체
-개발자가 직접 선언하거나 생성하지 않고, 서블릿 소스가 파싱되는 단계에서 자동 생성되는 객체
1. request(HttpServletRequest) : 요청에 대한 모든 정보를 가진 객체
2. response(HrrpServletResponse): 응답에 대한 모든 정보를 가진 객체
3. out(JSPWriter, PrintWriter) : 응답데이터를 버퍼에 기록(response Body)
버퍼를 제어하거나 버퍼의정보를 확인할 때 사용.
4. session(HttpSession) : 한 클라이언트가 사용하는 하나의 브라우저를 대상으로 생성된 세션에 대한 모든 정보를 가진 객체.
5. application(ServletContext) : 서블릿 컨테이너와 커뮤니케이션 하기 위해 사용되는 객체.
서버와 현재 실행중인 어플리케이션에 대한 정보를 가진 객체.
6. config(ServletConfig): 서블릿에 대한 메타 정보를 가진 객체.
(서블릿 만들었다해서 바로 사용 못함, 컨테이너에 등록하고 매핑, 등록한 이름 ,매핑 주소 서블릿의 부가정보를 갖고 있는것)
7. page(Object) : 현재 JSP 페이지에 대한 인스턴스의 참조 (this), 커스텀태그에서 사용
8. exception(Throwable) : 발생한 예외 정보를 가진 객체(isErrorPage가 설정된 에러처리 페이지에서 사용) 에러 처리 목적
9. pageContext(PageContext,****) : 현재 JSP 페이지에 대한 모든 객체를 소유한 객체.
${ 자바 객체를 가져올 수는 없지만 pageContext는 여기 안에서 사용가능}
<톰켓이 하는일>
1.jsp 클라이언트 요청
2. 톰켓이 소스 만듦(파싱단계)
3.컴파일함
4. 클래스 나오면 싱글턴 인스턴스 생성
5. 특정 메소드 호출하기위해 메소드 만듦(스레드만듦)
6. 서비스 호출
+request, response 해서 총 8개
_ :개발자가 사용 못함
pageContext가 먼저 생성되고 나머지 기본객체들은 pageContext에서 꺼내오는 방식
exception은 이럴때만 사용할 수 있다.
응답 버퍼 , out 기본객체를 통해 관리함
3. out(JSPWriter, PrintWriter) : 응답데이터를 버퍼에 기록(response Body)
버퍼를 제어하거나 버퍼의정보를 확인할 때 사용.
JSPWriter 를 통해 버퍼 설정/상태확인/상태 변경 작업을 함.
버퍼크기 : <%=out.getBufferSize() %>
잔여크기 : <%=out.getRemaining() %>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"% buffer="1kb" autoFlush="false"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>09/bufferDesc.jsp</title>
</head>
<body>
<h4> 응답 버퍼 , out 기본객체를 통해 관리함</h4>
<pre>
JSPWriter 를 통해 버퍼 설정/상태확인/상태 변경 작업을 함.
버퍼크기 : <%=out.getBufferSize() %>
잔여크기 : <%=out.getRemaining() %>
<%
for(int i=1; i<=100; i++){
out.println(i+"번째 반복");
}
%>
</pre>
</body>
</html>
autoFlush="true" : 버퍼에서 오버플로우가 발생할거같으면 이미 버퍼에 있는 데이터를 방출해라
10X100 =1000 ,1024
에러 해결하기
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" buffer="1kb" autoFlush="false"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>09/bufferDesc.jsp</title>
</head>
<body>
<h4> 응답 버퍼, out를 통해 관리함 </h4>
<pre>
JSPWriter를 통해 버퍼 설정/상태확인/상태 변경 작업을 함.
버퍼 크기 : <%=out.getBufferSize() %>
잔여 크기 : <%=out.getRemaining() %>
<%
for(int i=1; i<=100; i++){
out.println(i+"번째 반복");
if(out.getRemaining()<20){
1. 오버플로우 이전의 데이터 방출
out.flush();
2. 이전의 데이터 삭제
out.clearBuffer();
}
}
%>
</pre>
</body>
</html>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" buffer="1kb" autoFlush="false"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>09/bufferDesc.jsp</title>
</head>
<body>
<h4> 응답 버퍼, out를 통해 관리함 </h4>
<pre>
JSPWriter를 통해 버퍼 설정/상태확인/상태 변경 작업을 함.
버퍼 크기 : <%=out.getBufferSize() %>
잔여 크기 : <%=out.getRemaining() %>
<%
for(int i=1; i<=100; i++){
out.println(i+"번째 반복");
if(out.getRemaining()<20){
out.flush();
// out.clearBuffer();
}
if(i==99){
throw new RuntimeException("강제 발생 예외");
}
}
%>
</pre>
</body>
</html>
flush 가 되버려서 버퍼에 남아있는것만 지울 수 있고 ...(추가공부)
버퍼제어가 필요하다 그것이 바로 JSPWriter
out.flush(); : 내보낸거 내손을 떠나버림, 데이터를 갈아치워야할때는 out.clearBuffer();
+예상으로는 500에러가 떠야하는데 에러 메세지가 뜨지 않는다.
그 이유는 예외발생 이전에 out.flush()로 데이터가 방출되어서 웹에서 더이상 에러 메세지를 받지 않는다.
HttpSession session
: 클라이언트의 한 세션과 관련된 모든 정보를 가진 객체
세션??
WEB-연관된 작업을 수행하고 있는 한 타임의 시간(!).
DB- 두 피어 사이에 데이터를 주고받기 위해 수립된 통로(!).
세션생성
: 클라이언트로부터 최초의 요청 발생시
** 세션 유지 방법 (session id)
session tracking mode
1) Cookie
2) URL
3) SSL
1) Cookie : S.L 프로토콜의 단점을 보완하기 위해서 나온게 session과 cookie 이다.
이 둘은 대화를 하기에 필요한 최소한의 상태정보를 저장한다.
차이점은 저장위치인데, 최소한의 상태정보를 서버에 저장한게 session, 클라이언트에 저장한게 cookie 이다
4. session(HttpSession) : 한 클라이언트가 사용하는 하나의 브라우저를 대상으로 생성된 세션에 대한 모든 정보를 가진 객체.
톰켓은 30분 30분안에 응답 없으면 아웃 (로그인하고나서부터가 아니라 요청들어왔을때)=> 추가 공부
=> 새로고침 하게 되면 생성시간은 그대로 마지막요청시간은 계속변경 즉 만료시간 결정
세션생성
: 클라이언트로부터 최초의 요청 발생시
생성시점 :<%=new Date(session.getCreationTime())%>
아이디 : <%=session.getId() %>
마지막 요청 시간: <%=new Date(session.getLastAccessedTime()) %>
<%=session.getMaxInactiveInterval() %>s
<%
session.setMaxInactiveInterval(2*60);
%>
<%=session.getMaxInactiveInterval() %>s
새로고침한번더!!
쿠키 : 한명의 클라이언트 하나의 브라우저
우리어플리케이션 안에서만 작동하는 거 변경
2는 분단위이다
;jsessionid=<%=session.getId() %>" :세션파라미터 매트릭스변수 ?
세션 소멸
1) 명시적 로그아웃 <% session.invalidate(); %>
2) Timeout 설정
:세션생성 후 다음 요청이 발생할때 timeout 이내 시간안에 요청이 발생하면,
세션이 유지되는 구조.
3) 브라우저 종료
4) 쿠키 삭제 --> 즉시 만료가 아닌 timeout 체킹 이후만료.