[230927] 요청 파라미터, model, 세션 저장-삭제-확인(가져오기)

MJ·2023년 10월 12일

수업 TIL🐣💚

목록 보기
55/68

1교시 MyController03

어제 복습하는 건 생략

요청 파라미터

서버로 데이터를 보내는 방법

/board/list.do 로 파라미터를 보내고 싶으면 3가지(?) 방법 중 선택하면 된다.

1. a태그로 보내기
<a href="/board/list.do>age=20">

2. form으로 보내기(form으로 보낼때는 action 사용)
<form action="/board/list.do">
  <input name="age" value="20"> name과 value로 설정
  <button type="submit">전송</button>
</form>

3. location으로 보내기
location.href='/board/list.do?age=20';

정해진 값을 보낼때는 1번,3번
사용자로부터 입력을 받아서 보낼때는 2번

데이터 받기

@Controller에서 받을건데 뭘로 받을 건지
1. HttpServletRequest
2. @RequestParam
3. Command -> 객체로 받기

요청 파라미터 -HpptServletRequest

MyController03

@RequestMapping("/blog") // /blog로 시작하는 요청을 처리하는 컨트롤러, 모든 메소드의 요청에 "/blog"가 자동삽입
@Controller                               
public class MyController03 {

  /*
   * 1. HttpServletRequest request를 이용한 요청 파라미터 처리
   *  1) Java EE 표준 방식
   *  2) 파라미터뿐만 아니라 HTTPSession session, String contextPath와 같은 정보도 꺼낼 수 있으므로 여전히 강력한 도구
   */
  
  @RequestMapping("/detail.do") // GET 방식의 method는 생략 가능. value만 작성할 땐 value= 부분도 생략 가능
  public String blogDetail(HttpServletRequest request, Model model) {
    String blogNo = request.getParameter("blogNo"); // 모든 parameter는 string이다. string 타입으로 받아줌
    request.setAttribute("blogNo", blogNo);
    return "blog/detail"; // /WEB-INF/views//blog/detail.jsp로 forward한다 (스프링에서는 따로 말 없으면 forward)
  } //request로 blogNo받아서 blog/detail.jsp로 전달하는 과정
  
}
  • HttpServletRequest request에서 얻어낼 수 있는건 파라미터 뿐만이 아니다. 세션, contextPath 등 request로부터 얻을 수 있어서 request로부터 얻는건 파라미터가 전부가 아님. 반면에 @RequestParam과 커맨드 객체는 파라미터 전용
    (그래서 하나만 선택한다면 HttpServletRequest 쓴다고 한것 같은데 잘못들었나)
  • request.setAttribute("blogNo", blogNo);는 model 배운 후에 model.addAttribute("blogNo",blogNo); 로 바뀔 예정
  • request.setAttribute("blogNo", blogNo); --> forward는 request(와 response)를 전달. setAttribute = request로 정보 전달하는 것.

blog/detail.jsp에서 전달받은 파라미터 사용해보기
request에 저장된 blogNo를 꺼내는 방법: -> jsp에서 파라미터는 ${ } EL로 불러온다.

blog.jsp

<body>
  ${blogNo}
  <br>
  ${requestScope.blogNo} <!-- 리퀘스트에 저장된 blogNo, ${blogNo}랑 같음 -->
</body>

톰캣 서버 실행 결과

주소에 파라미터로 넣어줫떤 100 잘 나왔다


2교시

  • forward는 request와 response를 모두 전달하는데 response는 정보 저장 능력이 없다.
  • request는 전달용으로 정보를 저장할 수 있어서 request에 정보를 저장하고 그 정보를 jsp에 값으로 내어준다.
  • 요청은 request에 그대로 유지하고 => HttpServletRequest request 매개변수로 넣어줬던건 그대로 두라는 소리
  • forward할 정보는 request에 저장하지 말자 => 모델에 저장하자는 소리
    ==> 요청은 request에 받고 forward할 정보는 model에 저장

Model

key, value로 저장하는 map 기반 forwading 할 정보를 저장하는 곳

  @RequestMapping("/detail.do")
  public String blogDetail(HttpServletRequest request, Model model) {
    String blogNo = request.getParameter("blogNo");
    model.addAttribute("blogNo",blogNo); 
    //request.setAttribute("blogNo", blogNo) 모델로 바꿔준 것
    return "blog/detail";
  }

요청 파라미터 - @RequestParam

  /*
   * 2. @RequestParam을 이용한 요청 파라미터 처리
   *  1) 파라미터 개수가 적은 경우에 유용 (2~3개여도 가독성 별로됨)
   *  2) 주요 메소드
   *    (1) value : 요청 파라미터의 이름
   *    (2) required : 요청 파라미터의 필수 여부(디폴트 true - 요청 파라미터 없으면 오류 발생, false - 꼭 와야하는건 아니다.)
   *    (3) defaultValue : 요청 파라미터가 없는 경우(required=false 써야 함) 사용할 값
   *  3) @RequestParam을 생략할 수 있다  
   */
  
  // @RequestMapping("/detail.do")
  public String blogDetail2(@RequestParam(value = "blogNo", required = false, defaultValue = "1") int blogNo, Model model) { 
    //@RequestParam(value = "blogNo") int blogNo은 int blogNo로만 써도 됨 (@RequestParam은 생략가능하니까)
    model.addAttribute("blogNo",blogNo);
    return "blog/detail";
  }
  • 출력 결과 required true로 100 전달해줐더니 100 잘 나오고
    false로 하고 index.jsp에 가서 blogNo 요청부(?blogNo=100) 통째로 지우고 실행했더니 defaultValue인 1 잘 나옴
  • @RequestParam을 생략할 수 있으므로 아래처럼만 적어줘도 같은 코드로 실행됨
	 public String blogDetail2(int blogNo, Model model)

3교시

요청 파라미터 - 커맨드 객체

  /*
   * 3. 커맨드 객체를 이용한 요청 파라미터 처리
   *  1) 요청 파라미터를 필드로 가지고 있는 객체를 커맨드 객체라고 한다
   *  2) 요청 파라미터를 필드에 저장할 때 Setter가 사용됨
   *  3) 요청 파라미터가 많은 경우 유용
   *  4) 커맨드 객체는 자동으로 Model에 저장 (model.addAttribute 할 필요없음), 객체명(dto)이 아닌 클래스명(BlogDto)으로 저장됨 (클래스명을 LowerCamelCase(blogDto)로 바꿔서 저장)
   *  
   */
  1. 커맨드 객체가 될 BlogDto를 만든다

MyController03

  // @RequestMapping("/detail.do")
  public String blogDetail3(BlogDto dto) { // Model에 저장된 이름은 dto가 아니라 blogDto
  // model.addAttribute("blogDto",dto) 커맨드객체는 모델 자동이라 안적어도 된다.
    return "blog/detail";
  }
  • 여기서 BlogDto dto로 객체를 선언했는데 BlogDto 안에는 blogNo라는 필드가 있어. 그러면 dto에 blogNo도 잘 저장이 된거임.

  • 커맨드 객체 좋은 이유: DB로 보내려면 입력된 걸 받아서 서비스에서 Dto를 만들어서 (다오를 한다는거야머야)
    아무튼 이게 하나의 패턴인데 이게 BlogDto dto 하나로 해결되는거라고 한다

잘 이동되는지 blog.jsp에 소환해주고 확인해보기

blog.jsp 소환

  ${blogDto.blogNo}
  <br>
  ${blogDto.getBlogNo()}

결과는 100 100 잘 나왔다

  // @ModelAttribute를 이용해서 Model에 저장되는 커맨드 객체의 이름을 지정할 수 있다.
  // @RequestMapping("/detail.do")
  public String blogDetail4(@ModelAttribute("dto") BlogDto blogDto) {  // Model에 저장되는 이름은 dto 이다. 
    return "blog/detail";
  }

이름 지정 가능한거 특이한 특징인데 벼로 안중요한다고 함. 이유는 확인할 수 있다고 함.

웹개발에서 각종 페이지 저장할 때 사용할 수 있는 저장소
-HttpServletRequest 요청과 응답 한 싸이클에서 사용할 수 있는 값 저장
-HttpSession 라이프 싸이클, 브라우저가 실행되어서 닫히기 전까지 값 저장 ex 로그인 (4교시에 하겠따)


4교시 MyController04

index.jsp로 MyController04에 요청

  <%-- MyController04으로 요청 --%>
  <div>
    <a href="${contextPath}/article/add.do?title=이럴수가">기사 등록하기</a>
  </div>

세션에 저장하기

1. HttrServletRequest에서 HttpSession 얻기

오리지널 방식임
MyController04

  @GetMapping("/article/add.do")
  public String articleAdd(HttpServletRequest request) {

    // ViewResolver의 prefix : /WEB-INF/views/
    // ViewResolver의 suffix : .jsp
    
    HttpSession session = request.getSession(); // 1
    session.setAttribute("title", request.getParameter("title")); //2
    
    return "article/result";
  }
  1. request로부터 얻어낸 세션을 HttpSession session에 저장
  2. session에 정보 저장할 때 사용하는 방법 (request와 동일)
  • 세션에 저장되는 값은 모든 jsp에서 확인 가능하다. 어디로 전달할 지 얘기 안해도 확인 어디서도 가능. (브라우저도 마찬가지(?))

article.result

  <%-- model에 저장된 title --%>
  ${requestScope.title}
  <br>
  <%-- session에 저장된 title --%>
  ${sessionScope.title}
  <br>

실행 결과

세션에 저장된 정보는 브라우저 닫기 전엔 안지워짐

2. HttpSession 선언하기

스프링에서 지원하는 방식임
MyController04

@GetMapping("/article/add.do")
  public String add2(HttpSession session, HttpServletRequest request) {
    session.setAttribute("title", request.getParameter("title"));
    return "article/result";
  }

3. @SessionAttributes

스프링에서 지원하는 방식임
1) 클래스 레벨의 annotation이다. (@Controller처럼 클래스 위에 적어야함.)
2) Model에 값을 저장하면 HttpSession에 함께 저장된다.

MyController04

@SessionAttributes("title")  // Model에 title이 저장되면 HttpSession에도 같은 값을 저장한다.
@Controller
public class MyController04 {
  @GetMapping("/article/add.do")
  public String add3(HttpServletRequest request, Model model) {
    model.addAttribute("title", request.getParameter("title"));
    return "article/result";
  }

result.jsp

  <%-- model에 저장된 title --%>
  ${requestScope.title}
  <br>
  
  <%-- session에 저장된 title --%>
  ${sessionScope.title}
  <br>

@SessionAttributes를 쓰지 않으면 기존에 배웠던 것처럼 request에만 저장되는 것이기 때문에 첫번째 ${requestScope.title} 에서만 title이 출력되고
@SessionAttributes("title")을 써주면 Model에 title이 저장될 시 HttpSession에도 같은 값을 저장하기 때문에 첫번째와 두번째 다 title이 출력된다


세션 정보 삭제하기

세션 초기화하고 main 화면 가기

result.jsp에 링크 추가

  <a href="${contextPath}/article/main.do">세션 초기화하고 main 화면으로 가기</a>

MyController04

  /*
   * 1. HttpSession의 invalidate() 메소드
   * 자바 웹개발 표준, 예전부터 쓰던 방식임
   */
  @GetMapping("/article/main.do")
  public String main(HttpSession session) {
    // session 정보 초기화
    session.invalidate();
    return "index";
  }
  
  /*
   * 2. SessionStatus의 setComplete() 메소드
   * 스프링에서 지원하는 방식. 코드를 스프링으로 짜면 2번을 많이 쓴다
   */
  @GetMapping("/article/main.do")
  public String main2(SessionStatus sessionStatus) {
    // session attribute의 삭제
    sessionStatus.setComplete();
    return "index";
  }

저장할 땐 setAttribute
삭제할 땐 invalidate (전체 초기화), sessionStatus.setComplete()
골라서 삭제 removeAttribute (수업에서 배우지는 않았다)

삭제됐는지 확인
MyController04에서 main1 실행시킬거니까 main2는 주석 만들어주고

index.jsp의 MyController04 요청 코드 밑에

${sessionScope.title}로 세션에 저장된 파라미터 적어줌

결과

여기 맨아랫줄에 뜨게 해줬으니까, 기사 등록하기 탭 들어가서 title 파라미터 받아오면 이제 여기 뜰거임.

들어갔음

나왔음. 나오니까 떴음. session은 브라우저만 안 닫으면 어느 창에서든 유효하니까.

이제 안나오게 해보자. invalidate 설정해준게 잘 먹는지

다시 기사 등록하기 링크 들어가서 invalidate 있는 main1 작동하도록 연결해준 '세션 초기화하고 main 화면으로 가기' 누른다.

결과: title 없애짐.

쌤 이거 하다가 오류났는데 index.jsp 앞쪽에 contextPath 안 적어줘서엿음
저거를 까먹지 말고 잘 적자


5교시

세션에 저장 @SessionAttributes -> 4교시 부분에 적었음
세션 삭제 setComplete() -> 4교시 부분에 적었음

세션 가져오기 방식

지금까지는 세션 정보 가져올 때 jsp 썼음.
그런 방식말고 세션에 올라와있는 정보를 java에서 가져오려면 어떻게 해야할까.

  • 세션은 문자열, 숫자, 객체 등 모든걸 다 저장할 수 있음 따라서 세션의 타입은 object임-> object로 저장할 때 장단점= 장: 뭐든지 저장가능, 단: 꺼낼때 캐스팅해야함. 이게 표준방식.(
  • 오늘 배울 방식
  1. session.getAttribute() - 그냥 getter임 (이게 표준방식이라는데? 위랑 아래랑 같은건가. 그런가봄 얘는 스프링 방식 아니고 원래 쓰던거래)
  2. @SessionAttribute (세션에 저장 때 배운 @SessionAttributes 아님 주의)

다음 시간에 함


6교시

세션 가져오기

result.jsp

<a href="${contextPath}/article/confirm.do">세션 확인하기</a>

MyController04

1. HttpSession의 getAttribute() 메소드

  // @GetMapping("/article/confirm.do")
  public String confirm(HttpSession session) {
    
    String title = (String)session.getAttribute("title");
    System.out.println(title);
    return "index";
  }

연결해준 링크 '세션확인하기' 눌렀더니 세션에 저장되어 있던 title이 콘솔에 찍혔음

확인성공

2. @SessionAttribute

  @GetMapping("/article/confirm.do")
  public String confirm2(@SessionAttribute("title") String title) {  // session에 저장된 "title" 속성을 String title에 저장한다.
    System.out.println(title);
    return "index";
  }

결과

잘 찍혔다.

코드 가져오다보니까 클래스 어노테이션까지는 신경을 못써서 제대로 보고 싶으면 해당 코드로 다시 확인해보기


7교시 숙제안내

jspstudy 10_mybatis_ex

0개의 댓글