。゚(*´□`)゚。

코딩의 즐거움과 도전, 그리고 일상의 소소한 순간들이 어우러진 블로그

[네이버클라우드] 클라우드 기반의 개발자 과정 7기/웹프로그래밍

[NC7기-95일차(9월11일)] - 웹프로그래밍 76일차

quarrrter 2023. 9. 11. 17:23

3-1

// 세션 다루기 - HttpSession 직접 사용하기
// 세션 다루기 - HttpSession 직접 사용하기
package bitcamp.app2;

import javax.servlet.http.HttpSession;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
@RequestMapping("/c03_1")
public class Controller03_1 {

  // 테스트:
  //   http://.../app2/c03_1/h1
  @GetMapping(value="h1", produces="text/plain;charset=UTF-8")
  @ResponseBody
  public String handler1(HttpSession session) {
    // HttpSession 객체를 사용하려면 아규먼트로 받아야 한다.
    //
    session.setAttribute("name", "홍길동");
    session.setAttribute("age", "20");

    return "세션에 값을 보관했음!";
  }

  // 테스트:
  //   http://.../app2/c03_1/h2
  @GetMapping(value="h2", produces="text/plain;charset=UTF-8")
  @ResponseBody
  public String handler2(HttpSession session) {
    // HttpSession 객체를 사용하려면 아규먼트로 받아야 한다.
    //
    return String.format("name=%s, age=%s",
        session.getAttribute("name"),
        session.getAttribute("age"));
  }

  // 테스트:
  //   http://.../app2/c03_1/h3
  @GetMapping(value="h3", produces="text/plain;charset=UTF-8")
  @ResponseBody
  public String handler3(HttpSession session) {
    // HttpSession 객체를 사용하려면 아규먼트로 받아야 한다.
    //

    // 세션을 무효화시키기
    session.invalidate(); // 기존 세션 무시하고 새로운 세션 생성함

    return "세션을 무효화시켰음!";
  }

  @GetMapping(value="h4", produces="text/plain;charset=UTF-8")
  @ResponseBody
  public String handler4(
      // 현재 페이지 컨트롤러의 @SessionAttributes 에 지정된 이름이 아니라면,
      // 프론트 컨트롤러는 요청 파라미터에서 해당 이름의 값을 찾아 넘겨준다.
      // 요청 파라미터에 해당 이름의 값이 없다면,
      // 프론트 컨트롤러는 빈 문자열을 넘겨준다.
      @ModelAttribute("name") String name,
      @ModelAttribute("age") String age,
      @ModelAttribute("name2") String name2,
      @ModelAttribute("age2") String age2) {

    return String.format("name=%s, age=%s, name2=%s, age2=%s",
        name, age, name2, age2);
  }
}
// 세션 다루기 - @SessionAttributes, @ModelAttribute
package bitcamp.app2;

import javax.servlet.http.HttpSession;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.SessionAttributes;

@Controller 
@RequestMapping("/c03_2")

// request handler 가 뷰 컴포넌트(jsp)에 전달하는 값 중에서 
// 세션에 보관할 값의 이름을 지정하면 
// 프론트 컨트롤러는 그 값을 HttpSession 객체에도 보관해 둔다.
// 또한 @ModelAttribute에서 지정한 이름의 값을 세션에서 꺼낼 때도 사용한다.
// 즉 @SessionAttributes 에 이름을 지정해 두지 않으면 
// 세션에 해당 값이 들어 있어도 
// @ModelAttribute가 붙은 아규먼트에 값을 넣어주지 않는다.
@SessionAttributes({"name2", "age2"})

public class Controller03_2 {

  // 테스트:
  //   http://.../app2/c03_2/h1
  @GetMapping(value="h1", produces="text/plain;charset=UTF-8")
  @ResponseBody
  public String handler1(Model model) {

    // Model 객체에 값을 담으면 프론트 컨트롤러는 ServletRequest 보관소에 값을 옮긴다.
    // 만약 @SessionAttributes 에서 지정한 이름의 값이라면
    // HttpSession 객체에도 보관된다.
    model.addAttribute("name2", "임꺽정");
    model.addAttribute("age2", "30");

    // @SessionAttributes에 등록되지 않은 이름의 값은 세션에 보관되지 않는다.
    model.addAttribute("tel2", "1111-2222");

    return "세션에 값 보관했음!";

  }

  // 테스트:
  //   http://.../app2/c03_2/h2
  @GetMapping(value="h2", produces="text/plain;charset=UTF-8")
  @ResponseBody
  public String handler2(HttpSession session) {
    return String.format("name=%s, age=%s, name2=%s, age2=%s, tel2=%s",

        session.getAttribute("name"),
        session.getAttribute("age"),
        session.getAttribute("name2"),
        session.getAttribute("age2"),
        session.getAttribute("tel2"));    //null
  }

  // 테스트:
  //   http://.../app2/c03_2/h3
  @GetMapping(value="h3", produces="text/plain;charset=UTF-8")
  @ResponseBody
  public String handler3(
      // @ModelAttribute 에 지정된 이름이 @SessionAttributes에 있는 경우 
      // => 세션에 해당 값이 있으면 아규먼트에 넣어 준다.
      // => 세션에 해당 값이 없으면 예외가 발생한다.
      @ModelAttribute("name2") String name2,
      @ModelAttribute("age2") String age2,

      // @ModelAttribute 에 지정된 이름이 @SessionAttributes에 없는 경우 
      // => 요청 파라미터에 tel2 값이 있다면 그 값을 넣어준다.
      // => 요청 파라미터에 값이 없으면 아규먼트에 빈 문자열을 넣어 준다.
      // => @SessionAttributes에 등록한 이름이 아니기 때문에 세션에서 값을 꺼내지 않는다.
      @ModelAttribute("tel2") String tel2) {

    return String.format("name2=%s, age2=%s, tel2=%s", 
        name2, age2, tel2);
  }


  // 테스트:
  //   1) http://.../app2/c03_1/h1 을 실행하여 name과 age 값을 세션에 보관한다.
  //   2) http://.../app2/c03_2/h1 을 실행하여 name2와 age2 값을 세션에 보관한다.
  //   3) http://.../app2/c03_2/h4 을 실행하여 세션에 보관된 값을 꺼낸다.
  @GetMapping(value="h4", produces="text/plain;charset=UTF-8")
  @ResponseBody
  public String handler4(
          // 현재 페이지 컨트롤러의 @SessionAttributes에 지정되지 않은 값 꺼내기
      // => 꺼내지 못한다. name과 age에는 빈 문자열이 저장된다.

      @ModelAttribute("name") String name,
      @ModelAttribute("age") String age,

      // 세션에 보관 되어 있고,
      // 현재 컨트롤러의 @SessionAttributes에 지정된 값 꺼내기
      // => 빈 문자열
      @ModelAttribute("name2") String name2,
      @ModelAttribute("age2") String age2,

      // 세션에 보관 되어 있지 않고,
      // 현재 컨트롤러의 @SessionAttributes에 지정되지 않은 값 꺼내기
      // => 빈 문자열
      @ModelAttribute("tel2") String tel2) {

    //@ModelAttribute
    // 1. @SessionAttributes에 지정된 이름인 경우
    //   1) 무조건 HttpSession 객체에서 값을 꺼내 넘긴다.
    //        없다면 예외 발생!
    // 2. @SessionAttributes에 지정된 이름이 아닌 경우
    //   2) 요청 파라미터의 값을 꺼내 넘긴다.
    //   3) 없으면, 빈 문자열을 넘긴다.

    return String.format("name=%s, age=%s, name2=%s, age2=%s, tel2=%s",
        name, age, name2, age2, tel2);
  }
}

@SessionAttribute와 @ModelAttribute

 

SessionAttribute로  담으면 세션에 담기고

ModelAttribute로 담으면 세션에도, 모델에도 담긴다 . 

// 테스트:
// http://.../app2/c03_3/h3
@GetMapping(value = "h3", produces = "text/plain;charset=UTF-8")
@ResponseBody
public String handler3(SessionStatus status) {
  // 현재 페이지 컨트롤러의 @SessionAttributes 에 지정된 값만 무효화시키기
  status.setComplete();
  // 용도:
  // => 보통 페이지 컨트롤러는 서로 관련된 작업을 처리하는 요청 핸들러를 정의한다.
  //    예) BoardController : add(), detail(), list(), update(), delete()
  // => 또는 트랜잭션과 관련된 작업을 처리하는 요청 핸들러를 두기도 한다.
  //    예) BookOrderController: 장바구니담기(), 주문하기(), 결제하기()
  // => 이렇게 특정 작업에 관계된 요청 핸들러가 작업하는 동안
  //    공유할 데이터가 있다면 세션에 보관하면 편할 것이다.
  //    작업이 완료되면 그 작업을 처리하는 동안 세션에 보관했던 데이터는 삭제해야 한다.
  //    세션의 모든 데이터가 아니라
  //    현재 페이지 컨트롤러가 보관한 데이터만 삭제하고 싶을 때
  //    바로 이 방식으로 처리하면 된다.
  // => 즉 세션을 그대로 유지한채로 이 페이지 컨트롤러에서
  // @SessionAttributes로 지정한 값만 무효화시킬 때 사용한다.
  return "status.setComplete()";
}



    //프론트 컨트롤러에게 HttpSession을 요구하면
    // 기존에 만든게 있다면 그 객체를 넘겨 줄 것이고,
    // 없다면 새로 만들어 넘겨 줄 것이다.
    // 어찌 되었든 이 요청 핸들러를 실행하는 순간 HttpSession 객체는 존재하게 된다.
    // 보통 로그인 과정에서 HttpSession 객체가 준비될 것이고,
    // 그 전에 JSP를 실행하는 과정에서 HttpSession 객체가 생성될 것이다.
    // 따라서 이 메서드처럼 일부러 HttpSession 객체를 만들게 할 필요는 없다.
    // 다만 @SessionAttributes와 @ModelAttribute를 테스트하기 위해
    // 예제를 실행하는 과정에서 HttpSession 객체를 미리 준비할 필요가 있기 때문에
    // 예제 테스트를 위해 억지로 이 메서드를 만든 것이다.
    // 이 메서드를 먼저 실행하여 HttpSession 객체를 준비한 후에 step1,2,3,4를 테스트 하라 !

 

 

회원 가입 할 때 첫 번재 사용자 기본정보 받고 다음꺼 받고 받고 다 모아서 저장해야할때 세션에 저장해둔 값들을 데이터베이스에 집어 넣는다. 셋 어트리부트는 db에 넣고 세션 저장 값을 날린다. (일반 세션 무효화가 아님, 무효화는 invalidate임) 

로그인할때  세션어트리부트 써도 됨: