웹프로그래밍

로그인,기본객체 -22.06.16~06.17

AIN99 2022. 6. 17. 20:19
728x90

복습

 

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 체킹 이후만료.

      

728x90