안녕하세요, 코린이의 코딩 학습기 채니 입니다.
개인 포스팅용으로 내용에 오류 및 잘못된 정보가 있을 수 있습니다.
Model
- mvc의 model이 아닌, view단에 데이터를 전달하기 위한 임시 저장소
- Map 객체
① ModelAndView
- model 기능 : addObject
- view 기능 : setView(view) | setViewName(String)
② ModelMap
- model : addAttribute
- view 없음 : handler(Controller의 메소드)에서 view정보를 문자열로 반환해야 함
③ Model
- model : addAttribute
- view 없음 : handler(Controller의 메소드)에서 view정보를 문자열로 반환해야 함
관련 어노테이션
@ModelAttribute
- 메소드 레벨 : 해당 controller의 전역 모델 속성 등록
- 메소드 매개변수에 작성 : 모델 속성에 대한 getter
@SessionAttribute
- 메소드 매개변수에 작성
- session scope에 저장된 속성에 대한 getter
@SessionAttributes
- 클래스 레벨 작성
- session scope에 저장될 속성명 관리
@ModelAttribute
메소드 레벨 작성 : 해당 controller의 전역 모델 속성 등록
@ModelAttribute("common")
public Model common(Model model) {
log.debug("@ModelAttribute - common 호출!");
model.addAttribute("email", "honggd@abc.com");
model.addAttribute("tel", "010-1234-1234");
return model;
}
@콘솔출력값
DEBUG: com.ce.spring2.demo.controller.DemoController - @ModelAttribute - common 호출!
INFO : com.ce.spring2.demo.controller.DemoController - /demo/devForm.do 요청!
devForm.jsp
<div id="demo-container"
class="border border-secondary mx-auto p-3 rounded">
<!-- https://getbootstrap.com/docs/4.1/components/forms/#readonly-plain-text -->
${common.email}
${common.tel}
<form name="devFrm">
.. 이하 생략
전역 모델 속성으로 등록된 common의 속성들을 잘 가져오는 것을 확인할 수 있습니다.
@SessionAttributes
- 클래스 레벨 작성 : session scope에 저장될 속성명 관리
@SessionAttributes({"loginMember"})
public class MemberController {
@Autowired
private MemberService memberService;
@Autowired
private BCryptPasswordEncoder bcryptPasswordEncoder;
@PostMapping("/memberLogin.do")
public String memberLogin(@RequestParam String memberId, @RequestParam String password, Model model, RedirectAttributes redirectAttr) {
// 1. memberId로 조회
Member member = memberService.selectOneMember(memberId);
String location = "/";
// 2. member가 null이 아니면서, 비밀번호가 일치하면 로그인 성공
if(member != null && bcryptPasswordEncoder.matches(password, member.getPassword())) {
// model을 통해 session scope에 속성 저장 : 클래스레벨에 @SessionAttributes로 등록
model.addAttribute("loginMember", member);
}
// 로그인실패
else {
redirectAttr.addFlashAttribute("msg", "아이디 또는 비밀번호가 일치하지 않습니다.");
location += "member/memberLogin.do";
}
return "redirect:" + location;
}
}
Model은 기본적으로 request scope에 저장됩니다.
하지만 경우에 따라 session scope에 저장되어야 할 때가 있는데, 이 때! model을 통해 session scope에 지정하기 위해 클래스레벨에 @SessionAttributes로 등록해줍니다.
@SessionAttributes(속성명)으로 등록해주면 session scope로 사용됩니다.
세션 만료 처리
SessionStatus#setComplete() - 세션 만료처리 (세션 객체 유지, 안에 내용만 제거)
/**
* @SessionAttributes로 세션 관리를 한다면, SessionStatus#setComplete으로 만료처리!
*/
@GetMapping("/memberLogout.do")
public String memberLogout(SessionStatus sessionStatus) {
if(!sessionStatus.isComplete()) {
// 세션을 다 사용했다는 의미 - 만료 처리(세션 객체는 유지하되, 안에 내용만 제거)
sessionStatus.setComplete();
}
return "redirect:/";
}
@SessionAttributes로 세션 관리를 한다면 SessionStatus#setComplete으로 만료처리해줍니다.
세션을 다 사용했다는 의미로 세션 객체는 유지하되, 안에 내용만 제거하여 세션 객체의 효율성을 높입니다.
@SessionAttribute
- 메소드 매개변수에 작성 : session scope에 저장된 속성에 대한 getter
@GetMapping("/memberDetail.do")
public ModelAndView memberDetail(ModelAndView mav, @SessionAttribute Member loginMember) {
log.debug("loginMember = {}", loginMember);
mav.setViewName("member/memberDetail");
return mav;
}
@콘솔출력값
DEBUG: com.ce.spring2.member.controller.MemberController - loginMember = Member(memberId=honggd, password=$2a$10$G7F3EfcXE8wJWUAsCznaoOqttim4MwJBNlWey5yuL5ZRMwRSdPvEi, name=홍길동, gender=M, birthday=1999-01-19, email=honggd@abc.com, phone=01012341234, address=경기 성남시 분당구 대왕판교로 477, hobby=[운동, 독서, 여행], createdAt=2022-08-22T12:23:43, updatedAt=null, enabled=true)
@SessionAttribute를 이용해 session scope에 저장된 속성(loginMember)을 가져온 것을 확인할 수 있습니다.
ModelAndView로 view단에 전달 하였습니다.
memberDetail.jsp
<%@page import="java.util.List"%>
<%@page import="java.util.Arrays"%>
<%@page import="com.ce.spring2.member.model.dto.Member"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions"%>
<jsp:include page="/WEB-INF/views/common/header.jsp">
<jsp:param value="회원정보" name="title"/>
</jsp:include>
<style>
div#update-container{width:400px; margin:0 auto; text-align:center;}
div#update-container input, div#update-container select {margin-bottom:10px;}
</style>
<div id="update-container">
<form name="memberUpdateFrm" action="${pageContext.request.contextPath}/member/memberUpdate.do" method="post">
<input type="text" class="form-control" placeholder="아이디 (4글자이상)" name="memberId" id="memberId" value="${loginMember.memberId}" readonly required/>
<input type="text" class="form-control" placeholder="이름" name="name" id="name" value="${loginMember.name}" required/>
<input type="date" class="form-control" placeholder="생일" name="birthday" id="birthday" value="${loginMember.birthday}" />
<input type="email" class="form-control" placeholder="이메일" name="email" id="email" value="${loginMember.email}"/>
<input type="tel" class="form-control" placeholder="전화번호 (예:01012345678)" name="phone" id="phone" maxlength="11" value="${loginMember.phone}" required/>
<input type="text" class="form-control" placeholder="주소" name="address" id="address" value="${loginMember.address}"/>
<select class="form-control" name="gender" required>
<option value="" disabled selected>성별</option>
<option value="M" ${loginMember.gender eq 'M' ? 'selected' : ''}>남</option>
<option value="F" ${loginMember.gender eq 'F' ? 'selected' : ''}>여</option>
</select>
<%
Member loginMember = (Member) session.getAttribute("loginMember");
String[] hobbies = loginMember.getHobby();
List<String> hobbyList = hobbies != null ? Arrays.asList(hobbies) : null;
pageContext.setAttribute("hobbyList", hobbyList);
%>
<div class="form-check-inline form-check">
취미 :
<input type="checkbox" class="form-check-input" name="hobby" id="hobby0" value="운동" ${hobbyList.contains('운동') ? 'checked' : ''}>
<label for="hobby0" class="form-check-label" >운동</label>
<input type="checkbox" class="form-check-input" name="hobby" id="hobby1" value="등산" ${hobbyList.contains('등산') ? 'checked' : ''}>
<label for="hobby1" class="form-check-label" >등산</label>
<input type="checkbox" class="form-check-input" name="hobby" id="hobby2" value="독서" ${hobbyList.contains('독서') ? 'checked' : ''}>
<label for="hobby2" class="form-check-label" >독서</label>
<input type="checkbox" class="form-check-input" name="hobby" id="hobby3" value="게임" ${hobbyList.contains('게임') ? 'checked' : ''}>
<label for="hobby3" class="form-check-label" >게임</label>
<input type="checkbox" class="form-check-input" name="hobby" id="hobby4" value="여행" ${hobbyList.contains('여행') ? 'checked' : ''}>
<label for="hobby4" class="form-check-label" >여행</label>
</div>
<br />
<input type="submit" class="btn btn-outline-success" value="수정" >
<input type="reset" class="btn btn-outline-success" value="취소">
</form>
</div>
<jsp:include page="/WEB-INF/views/common/footer.jsp"></jsp:include>
'Java > Spring' 카테고리의 다른 글
Spring) Slf4j - 파일로 로그 출력하기 (0) | 2022.08.24 |
---|---|
Spring) 회원 정보 수정 (0) | 2022.08.23 |
Spring) 로그인 / 로그아웃 처리 (Model 세션 저장, 만료 처리) (0) | 2022.08.22 |
Spring) 암호화 처리 - BCryptPasswordEncoder (0) | 2022.08.22 |
Spring) 회원 가입 처리하기 (index페이지에서 alert 작동 안되는 원인 파악) (0) | 2022.08.19 |