framework/spring mvc

[springMVC] 12. HttpSession객체 | @SessionAttributes

jeri 2024. 8. 4. 15:04
반응형

01. Seesion Scope의 이용방법 2가지

  • HttpSession 객체에 저장하면?
    • 같은 Session을 이용하는 모든 요청 처리 메소드의 뷰에서 사용 가능
  • HttpSession 객체에 저장 + @SessionAttributes 이용하면?
    • SessionController 클래스 내에서만 시용하는 요청 처리 메소드의 뷰에서만 사용 가능
[🖤DTO] - Hewon.java
package xyz.itwill10.dto;

import lombok.Data;

@Data
public class Hewon {
	private String id;
	private String name;
	private String email;
}
[🖤Model] SessionController.java
package xyz.itwill10.controller;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.SessionAttributes;
import org.springframework.web.bind.support.SessionStatus;

import xyz.itwill10.dto.Hewon;

@Controller
//@SessionAttributes : Model 객체를 사용하여 저장되는 속성값을 현재 요청 처리 클래스(Controller 클래스)의 모든 요청 처리 메소드와 뷰에게 제공하는 어노테이션
// => Model 객체를 사용하여 저장되는 속성값을 Request Scope 속성값이 아닌 제한적인 Session Scope 속성값으로 변환하여 제공하는 어노테이션
// => 변경 처리시 호출되는 요청 처리 메소드에서 변경할 객체를 검색하지 않고 뷰에서는 값을 전달하지 않도록 제한적인 Session Scope 속성값 사용
//value 속성 : 제한적인 Session Scope 속성값으로 변환하기 위한 속성명을 속성값으로 설정 - 다른 속성이 없는 경우 속성값만 설정 가능

// => 바인딩 된 세션 스코프를 사용하기 때문에, Session은 맞지만 SessionController 클래스 내에서 사용 가능하다는 것
@SessionAttributes(value = "hewon") //Model객체의 hewon 이름을 가진 속성값만 제한적인 Session Scope 이용해주세요~
public class SessionController {

 

Service 클래스의 메소드 - 요청 처리 메소드 아님

  • 원래 Service 클래스의 메소드에 만들어야 하는 필드이지만, DB 연동을 하지 않았으므로 우선 Model 클래스에 만들어 사용하겠음 → 아이디 가지고 이러한 회원정보를 검색했다고 가정하기 위해 만듦
	//아이디를 전달받아 회원정보를 검색하여 반환하는 메소드 - Service 클래스의 메소드
	private Hewon getHewon(String id) {
		Hewon hewon=new Hewon();
		hewon.setId(id);
		hewon.setName("홍길동");
		hewon.setEmail("abc@itwill.xyz");
		return hewon;
	}
  • /hewon_view
	///hewon_view 요청	
	//아이디를 전달받아 회원정보를 뷰에게 제공하기 위한 요청 처리 메소드
	// => 요청 처리 메소드에 의해 제공된 회원정보가 출력되도록 뷰 작성
	@RequestMapping("/hewon_view")
	public String view(@RequestParam(defaultValue = "abc123") String id, Model model) {
		//Service 클래스의 메소드를 호출하여 아이디를 전달해 해당 아이디의 회원정보를 검색하여 반환받아 저장
		Hewon hewon=getHewon(id);

		//Model 객체를 사용하여 검색된 회원정보를 속성값으로 저장하여 뷰에게 제공
		// => 요청 처리 메소드의 뷰에게만 속성값을 제공하여 출력 처리 - Request Scope
		//model.addAttribute("hewon", hewon);
		//속성값으로 저장된 객체의 자료형(클래스의 이름 - 첫문자는 소문자로 변환)이 자동으로 속성명으로 설정
		// => @SessionAttributes 어노테이션에 의해 Model 객체로 저장된 속성값은 
		// => 제한적인 Session Scope 속성값으로 변환되어 현재 요청 처리 클래스의 모든 요청 처리 메소드와 뷰에게 속성값 제공
		model.addAttribute(hewon);//속성명 생략 가능

		return "hewon_view";
	}
  • [GET] /hewon_update
	//hewon_update [GET] 방식으로 요청
	/*
	//아이디를 전달받아 회원정보를 뷰에게 제공하기 위한 요청 처리 메소드
	// => 요청 처리 메소드에 의해 제공된 회원정보를 입력태그의 초기값으로 사용되도록 뷰 작성
	@RequestMapping(value="/hewon_update", method = RequestMethod.GET)
	public String update(@RequestParam(defaultValue = "abc123") String id, Model model) {
		Hewon hewon=getHewon(id);
		model.addAttribute(hewon);
		return "hewon_update";
	}
	*/

	//@SessionAttributes 어노테이션에 의해 제공된 회원정보를 요청 처리 메소드와 뷰에서 사용 가능
	// => 아이디를 전달받아 회원정보를 검색하는 명령과 뷰에게 제공하기 위한 속성값 저장 불필요
	@RequestMapping(value="/hewon_update", method = RequestMethod.GET)
	public String update() {
		return "hewon_update";
	}
  • [POST] /hewon_update
	//hewon_update [POST] 방식으로 요청
	//회원정보를 전달받아 변경된 회원정보를 뷰에게 제공하는 요청 처리 메소드
	// => 요청 처리 메소드의 매개변수에는 Command 객체로 @SessionAttributes 어노테이션에 의해 제공된 회원정보를 전달받아 저장하고 변경값으로 필드값만 변경해 사용
	// => 요청 처리 메소드에 SessionStatus 인터페이스로 매개변수를 선언하면 SessionStatus 객체를 제공받아 사용 가능
	// => SessionStatus 객체 : @SessionAttributes 어노테이션에 의해 제공된 제한적인 Session Scope 속성값의 상태정보를 저장하기 위한 객체
	@RequestMapping(value="/hewon_update", method = RequestMethod.POST)
	public String update(@ModelAttribute Hewon hewon, SessionStatus status) {
		//SessionStatus.setComplete() : @SessionAttributes 어노테이션에 의해 제공된 제한적인 Session Scope 속성값을 제거하는 메소드
        
    	//status.isComplete(); //상태 변경이 완료니? [true or false]
        
		status.setComplete(); //상태를 완료로 설정해라!! - 즉, 제한적인 Sessoion Scope를 없애서 클래스의 요청 처리 메소드들이 더 이상 쓰지 못하게해라!!
        
		//=> 만약 setComplete()를 사용하지 않으면?
		//=> 제한적인 Session Scope를 계속 사용하므로 [/hewon_update]를 재요청하면
    	//=> hewon.name, hewon.id, hewon.email 이 출력됨
        
		//=> 하지만 setComplete()를 사용하면 ?
    	//=> 제한적인 Session Scope가 없어졌으므로 [/hewon_update]를 재요청하면 hewon.name, hewon.id, hewon.email의 값들을 전달하지 않으므로 뷰에서 출력되지 않음
    	//=> hewon 객체에 저장은 되어있으나 출력이 안될뿐임, System.out.println으로 직접 확인해봄
		//System.out.println(hewon.getId()); //abc123
		//System.out.println(hewon.getName()); //임꺽정
        
		return "hewon_result";
	}
}
[🖤View] hewon_view.jsp - 출력페이지
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>SPRING</title>
</head>
<body>
	<h1>회원정보</h1>
	<hr>
	<ul>
		<li>아이디 = ${hewon.id }</li>
		<li>이름 = ${hewon.name }</li>
		<li>이메일 = ${hewon.email }</li>
	</ul>

	<!-- 회원정보 변경페이지를 요청할 수 있는 링크 제공 - 아이디 전달 -->
	<!-- <button type="button" onclick="location.href='hewon_update?id=${hewon.id}';">회원정보변경</button>  -->

	<!-- @SessionAttributes 어노테이션을 사용한 경우 아이디를 전달하지 않아도 회원정보 변경
	페이지의 요청 처리 메소드에서 회원정보를 제공받아 사용 가능 -->
	<button type="button" onclick="location.href='hewon_update';">회원정보변경</button>
</body>
</html>

 

[🖤View] hewon_update.jsp - 변경페이지
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>SPRING</title>
</head>
<body>
	<h1>회원정보변경</h1>
	<hr>
	<form action="hewon_update" method="post">
	<!-- 회원정보를 변경하기 위해 hidden 타입의 입력태그로 아이디 전달 -->
	<!-- => 아이디를 입력태그의 초기값으로 설정하여 read-only 속성을 사용해 전달 가능 -->
	<!-- @SessionAttributes 어노테이션을 사용한 경우 아이디를 전달하지 않아도 회원정보 변경
	페이지의 요청 처리 메소드에서 회원정보를 제공받아 사용 가능 -->
	<!-- <input type="hidden" name="id" value="${hewon.id }"> -->
      
	<table>
		<tr>
			<td>아이디</td>
			<td>${hewon.id }</td>
		</tr>
		<tr>
			<td>이름</td>
			<td><input type="text" name="name" value="${hewon.name }"></td>
		</tr>
		<tr>
			<td>이메일</td>
			<td><input type="text" name="email" value="${hewon.email }"></td>
		</tr>
		<tr>
			<td colspan="2"><button type="submit">회원변경</button></td>
		</tr>
	</table>
	</form>
</body>
</html>

 

@SessionAttributes 사용 후 hewon_update 재요청 시 status.setComplete(); 안한 경우

 

@SessionAttributes 사용 후 hewon_update 재요청 시 status.setComplete(); 한 경우

 

[🖤View] hewon_result.jsp - 결과페이지
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>SPRING</title>
</head>
<body>
	<h1>회원정보 변경 확인</h1>
	<hr>
	<ul>
		<li>아이디 = ${hewon.id }</li>
		<li>이름 = ${hewon.name }</li>
		<li>이메일 = ${hewon.email }</li>
	</ul>
</body>
</html>

 

반응형