- 0928

Yung·2022년 9월 28일
0

Java223bitcamp

목록 보기
11/26
post-thumbnail

JSP와 PageContext

JSP
JSTL 태그를 처리하는 핸들러(객체)
EL 태그를 처리하는 핸들러
커스텀 태그 핸들러 : 개발자가 임의로 태그를 만들 수 있다. JSTL은 자바에서 만든거지만 개발자가 자기만의 태그를 만들수 있다. 태그를 JSP에서 사용하기위해 핸들러도 만들어야한다.

PageContext : JSP와 핸들러 사이에 객체를 공유할때 사용하는 저장소(데이터 조회/저장)

SpringBoot는 JSP를 사용하지 않도록 권유하고있으므로, JSP 디테일한것 까지 배울필요없다

클라이언트 저장소와 서버 저장소

서버 저장소

ServletContext : 특정 클라이언트에 따라서 준비하는 보관소,사용자에 상관없이 어떤 요청을 처리하든 상관없다면 ServletContext에 저장하라.
DAO, Service, Connection객체를 저장

HttpSession 특정 클라이언트가 실행되는동안 사용할 객체를 저장할때 사용하면 적절하다,
로그인 사용자 정보, 페이지 입력값(여러 페이지에 거쳐서 입력되는 것들)

ServletRequest : 요청을 처리하는동안 요청 처리에 참여하는 서블릿들이 공유할 객체가 있다면 ServletReguest에 넣어두면 적절하다.
하나의 요청을 여러 서블릿이 협엽해서 처리할 수 있다.
요청처리하는 동안 요청처리에 참여할 여러 서블릿이있다면 ServletRequest 저장소를 사용하라.
요청처리결과(ex. 게시판 목록 저장)

PageContext
JSP내에서 공유할 객체가 있으면 사용때 사용하기 적절한 저장소
EL에서 사용할 객체

클라이언트 저장소

쿠키테이블 : 클라이언트 저장소
쿠키는 클라이언트 쪽에 저장되기 때문에 쉽게 노출된다.
따라서 보안 데이터는 외부로 노출되어선 안되므로, 쿠키로 저장하면 안된다.

  • 요청 프로토콜 : 웹 브라우저가 자동으로 처리
Get /app/auth/login HTTP/1.1
Host: localhost:8888
...
Cookie: email=user1@test.com; name=okok

Cookie : 서버로 받은 쿠키를 클라이언트에서 다시 서버로 보내는 방법
  • 응답 프로토콜 : 개발자의 코딩이 필요(Cookie)
HTTP/1.1 200 OK
Content-Type: text/html; charset=UTF-8
...
Set-Cookie: email=user1@test.com
Set-Cookie: name=okok

[응답콘텐트]

Set-Cookie : 서버에서 클라이언트 저장소에 보관할 데이터를 보내는 방법
클라이언트 저장소에 보관할 데이터 : Cookie
쿠키 테이블 : 서버로 부터 받은 쿠키를 저장
  • 쿠키 테이블
KeyValue
emailuser1@test.com
nameokok

쿠키

따로 설정하지 않으면 auth어느 서블릿으로 부터 쿠키를 받게되면 auth/ 같은 경로에 서블릿으로 요청할때는 보낸다, 만약에 다른경로일때는 안보낸다.
쿠키를 보낼때 다른경로에도 보내고 싶으면 따로 설정을 해줘야한다. -> 비추
그경로의 서블릿으로 받은 쿠키는 해당 경로의 서블릿으로만 보내라 -> 모든 경로에 보내면 쿠키테이블 관리 힘듬

066. 로그인 정보 활용하기: HttpSession 활용

로그인 사용자 정보를 활용하는 방법

  1. 0단계 - 게시글에 작성자 이름을 포함하기
  • com.bitcamp.board.domain.Board 클래스 변경
    • 필드에 직접 접근하지 못하게 private으로 접근 범위를 변경한다.
public class Board {
  private int no;
  private String title;
  private String content;
  private String password;
  private int viewCount;
  private Date createdDate;
  private Member writer;
  • com.bitcamp.board.dao.MariaDBBoardDao 클래스 변경

    • /webapp/board/list.jsp 변경
    • /webapp/board/detail.jsp 변경
    • com.bitcamp.board.controller.BoardAddController 클래스 변경
    • com.bitcamp.board.controller.BoardUpdateController 클래스 변경

    그림

  1. 1단계 - 게시글 등록할 때 로그인 정보를 활용한다.
  • /webapp/board/form.jsp 변경
    • 작성자 입력 상자에 로그인 사용자 번호를 자동으로 입력한다.
    • 로그인 사용자 정보를 요청 파라미터로 보낼 때의 문제점을 이해한다.
  • com.bitcamp.board.controller.BoardAddController 클래스 변경
    • 게시글 등록할 때 로그인 사용자의 번호를 작성자 번호로 설정한다.
  1. 2단계 - 게시글을 변경, 삭제할 때 로그인 정보를 활용한다.
  • com.bitcamp.board.domain.Member 클래스 변경
    • 필드에 직접 접근하지 못하게 private으로 접근 범위를 변경한다.
  • com.bitcamp.board.controller.MemberAddController 클래스 변경
  • com.bitcamp.board.controller.MemberUpdateController 클래스 변경
Member loginMember = (Member) request.getSession().getAttribute("loginMember");
      if (boardDao.findByNo(board.no).getMemberNo() != loginMember.getNo()) {
        throw new Exception("게시글 작성자가 아닙니다.");
      }
  • com.bitcamp.board.controller.BoardDeleteController 클래스 변경

067. 로그인이 필요한 요청인 경우 로그인으로 유도하기: Filter활용

  • filter를 활용하여 로그인을 검사하는 방법
  • 로그인이 필요한 요청에 대해 로그인 화면으로 유도하는 방법.
  • 1단계 - 로그인 검사 및 유도를 수행하는 필터를 만든다.
    • com.bitcamp.board.filter.LoginCheckFilter 클래스 생성
  • 2단계 - 관리자 여부를 검사하는 필터를 만든다.
    • com.bitcamp.board.filter.AdminCheckFilter 클래스 생성
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.bitcamp.board.domain.Member;

@WebFilter("*")
public class LoginCheckFilter implements Filter {

  @Override
  public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
      throws IOException, ServletException {
    // 요청 URL을 통해 로그인 여부를 검사할 지 결정한다.
    // 요청 URL은 HTTP 프로토콜과 관련된 값이다.
    // ServletRequest 타입은 HTTP 프로토콜과 관련된 기능을 다룰 수 있는 메서드가 없다.
    // ServletRequest 타입의 객체를 HttpServletRequest 객체로 형변환 해야 하낟.
    // 필터의 파라미터로 넘어오는 객체는 원래 HttpServletRequest 객체이기 때문에 형변환 할 수 있다.
    // 필터의 파라미터로 넘어오는 객체는 원래 HttpServletRequest 객체이다.
    // 세션처럼 HTTP 프로토콜과 관련된 기능을 쓰고 싶다면,
    // 원래 타입으로 형변환 한 다음에 사용하라!
    HttpServletRequest httpRequest = (HttpServletRequest) request;

    // 응답 기능에 대해서도 HTTP 관련 메서드를 사용하고 싶다면 형변환 하라!
    HttpServletResponse httpResponse = (HttpServletResponse) response;

    // 요청 URL에서 서블릿 경로만 추출한다.
    // 예) 요청 URL: http://localhost:8888/app/board/add?title=aaa&content
    //  서블릿 경로 : /board/add <===웹 애플리케이션 경로는 뺀다.
    //    String servletPath = httpRequest.getServletPath();
    //    System.out.println(servletPath);
    //    /welcome.jsp
    //    /board/list
    //    /welcome.jsp
    //    /board/list
    //    /board/detail

    String servletPath = httpRequest.getServletPath();
    // 콘텐트를 틍록, 변경, 삭제하는 경우 로그인 여부를 확인한다.
    if (servletPath.endsWith("add") || servletPath.endsWith("update")
        || servletPath.endsWith("delete")) {

      Member loginMember = (Member) httpRequest.getSession().getAttribute("loginMember");
      if (loginMember == null) { // 로그인 하지 않았다
        httpResponse.sendRedirect(httpRequest.getContextPath() + "/auth/form.jsp");
        return;
        //getContextPath 웹애플리케이션인 경우 애플리케이션 이름이 바뀌면 자동으로 변경된다.
      }
    }

    // 현재 필터, 다음에 실행할 필터를 지정한다.
    // 다음 필터를 실행한다.
    // 다음으로 실행할 필터가 없다면 원래 목적지인 서블릿이 실행될 것이다.
    chain.doFilter(request, response);
  }
}

0개의 댓글