Everything has an expiration date
[inflearn] 20240114 [스프링-프레임워크] - 19강 필기 본문
[inflearn] 20240114 [스프링-프레임워크] - 19강 필기
Jelly-fish 2024. 1. 14. 17:3719강 - Controller 객체 구현 - Ⅱ
컨트롤러의 URL 맵핑과 파라미터 처리 방법에 대해서 학습한다.
19-1 @ModelAttribute
19-2 커맨드 객체 프로퍼티 데이터 타입
19-3 Model & ModelAndView
19-1 @ModelAttribute
`@ModelAttribute` 를 이용하면 커맨드 객체의 이름을 변경할 수 있고,
이렇게 변경된 이름은 뷰에서 커맨드 객체를 참조할 때 사용된다.
Controller | View |
public String memJoin(Member member) | ID : ${member.memId} |
public String memLogin(Member member) | ID : ${member.memId} |
public String memRemove (`@ModelAttribute("mem")` Member member) |
ID: ${mem.memId} |
MemberController.java
@RequestMapping(value="/memJoin", method=RequestMethod.POST)
public String memJoin(@ModelAttribute("mem") Member member)
//  ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄★
{
service.memberRegister(member.getMemId(), member.getMemPw(), member.getMemMail()
, member.getMemPhone1(), member.getMemPhone2(), member.getMemPhone3());
return "memJoinOk";
}
memJoinOk.jsp
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ page session="false" %>
<html>
<head>
<title>Home</title>
</head>
<body>
<h1> memJoinOk </h1>
<!-- @RequestMapping 어노테이션을 통해 -->
<!-- 『mem』으로 객체에 접근한 것을 확인! -->
ID : ${mem.memId}<br />
PW : ${mem.memPw}<br />
Mail : ${mem.memMail} <br />
Phone : ${mem.memPhone1}-${mem.memPhone2}-${mem.memPhone3} <br />
<a href="/lec17/resources/html/memJoin.html"> Go MemberJoin </a>
</body>
</html>
`@ModelAttribute("serverTime")` 란?
①
`serverTime`
실제로 서버에서 컨트롤러 내부의 특정 메소드가 호출됐을 때의 서버의 시간을 나타내 주는 기능을 한다.
MemberController.java
@ModelAttribute("serverTime")
public String getServerTime(Locale locale)
{
Date date = new Date();
DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG, locale);
return dateFormat.format(date);
}
memRemoveOk.jsp
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ page session="false" %>
<html>
<head>
<title>Home</title>
</head>
<body>
<h1> memRemoveOk </h1>
ID : ${mem.memId}<br />
<P> The time on the server is ${serverTime}. </P>
<!--  ̄ ̄ ̄ ̄ ̄ ̄ ̄★ -->
<a href="/lec19/resources/html/index.html"> Go Main </a>
</body>
</html>
<P> The time on the server is ${serverTime}. </P>
위와 같이, View 페이지에서 바로 메소드`String getServerTime()` 가 실행됐던 순간의 서버 시간을 표시해 줄 수 있다.
★②
`@ModelAttribute()` 어노테이션을 특정 메소드 상단에 작성하게 되면
Controller 내부의 `memJoin()` `memLogin()` `memRemove()` 등의 메소드들 중 어떤 것을 호출하든지 간에
`@ModelAttribute()` 가 적용되어 있는 메소드는 공통적으로 무조건 실행되는 것이다.
example ) `ModelAttribute()` 어노테이션 메소드, 다른 메소드와 함께 공통 호출
1. 클라이언트 `/memRemove` URL 요청
2. MemberController.java 컨트롤러의 `memRemove()` 메소드 실행
@RequestMapping(value = "/memRemove", method = RequestMethod.POST)
public String memRemove(@ModelAttribute("mem") Member member)
{
service.memberRemove(member);
return "memRemoveOk";
}
3. `@ModelAttribute("serverTime")` 어노테이션으로 인해
`getServerTime()` 메소드도 `memRemove()` 메소드와 함께 실행
@ModelAttribute("serverTime")
public String getServerTime(Locale locale)
{
Date date = new Date();
DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG, locale);
return dateFormat.format(date);
}
※ [총정리] : `@ModelAttribute()` 어노테이션의 기능
▶ Ⅰ. View 페이지에서 특정한 닉네임으로 접근 가능
`ModelAttribute("mem") Member member` 특정 닉네임을 정해서, View 페이지에서 (`${mem.memId}`) 사용할 수 있다.
▶ Ⅱ. 공통 호출
`ModelAttribute()` 가 적용되어 있는 메소드는, 컨트롤러의 어떤 메소드가 호출되던 간에 공통적으로 같이 호출된다.
19-2 커맨드 객체 프로퍼티 데이터 타입
데이터가 기초데이터 타입인 경우
memberJoin.html
ID : <input type="text" name="memId">
PW : <input type="password" name="memPw">
MAIL : <input type="text" name="memMail">
AGE : <input type="text" name="memAge" size="4" value="0">
Member.java (회원 DTO : Data Transfer Object)
private String memId;
private String memPw;
private String memMail;
private int memAge;
★데이터가 중첩 커맨드 객체를 이용한 List 구조인 경우
memberJoin.html
PHONE1 : <input type="text" name="memPhones[0].memPhone1" size="5"> -
<input type="text" name="memPhones[0].memPhone2" size="5"> -
<input type="text" name="memPhones[0].memPhone3" size="5"><br />
PHONE2 : <input type="text" name="memPhones[1].memPhone1" size="5"> -
<input type="text" name="memPhones[1].memPhone2" size="5"> -
<input type="text" name="memPhones[1].memPhone3" size="5"><br />
Member.java (회원 DTO : Data Transfer Object)
private List<MemPhone> memPhones;
회원의 전화번호 `memPhone` 같은 경우,
전화번호를 총 3개의 입력 창으로 분리하여 처리
memJoin.html
사용자로부터 하나의 전화번호를 입력받을 때,
`PHONE1 : [ ① ] - [ ② ] - [ ③ ]`
위와같이 입력을 받도록 처리한다.
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1>Member Join</h1>
<form action="/lec19/member/memJoin" method="post">
<!-- * Phone 입력 객체를 제외한 다른 Element 생략. -->
PHONE1 : <input type="text" name="memPhones[0].memPhone1" size="5"> -
<input type="text" name="memPhones[0].memPhone2" size="5"> -
<input type="text" name="memPhones[0].memPhone3" size="5"><br />
PHONE2 : <input type="text" name="memPhones[1].memPhone1" size="5"> -
<input type="text" name="memPhones[1].memPhone2" size="5"> -
<input type="text" name="memPhones[1].memPhone3" size="5"><br />
<!-- ... -->
MemPhone.java (전화번호 DTO)
`PHONE1 : [ ① ] - [ ② ] - [ ③ ]`
으로 입력된 값들은 MemPhone.java DTO 에 setter를 통해 입력 값이 저장되게 된다.
→ ① (010) : `Memphone.memPhone1` 값
→ ② (1234) : `Memphone.memPhone2` 값
→ ③ (5678) : `Memphone.memPhone3` 값
package com.bs.lec19.member;
public class MemPhone {
private String memPhone1;
private String memPhone2;
private String memPhone3;
public String getMemPhone1() {
return memPhone1;
}
public void setMemPhone1(String memPhone1) {
this.memPhone1 = memPhone1;
}
public String getMemPhone2() {
return memPhone2;
}
public void setMemPhone2(String memPhone2) {
this.memPhone2 = memPhone2;
}
public String getMemPhone3() {
return memPhone3;
}
public void setMemPhone3(String memPhone3) {
this.memPhone3 = memPhone3;
}
}
Member.java (회원 DTO)
`MemPhone.java` (전화번호 DTO) DTO 객체는
하나의 전화번호에 해당하는 값을 갖고 있고,
`Member.java` (회원 DTO) 에서는 본인의 전화번호와 비상 전화번호(보호자 전화번호),
총 두 개의 전화번호를 저장할 수 있도록 설정해 두었다.
즉, `Member.java` (회원 DTO) 객체에는 전화번호 '들' (`MemberPhone.java`)을 저장해야 하므로
이를 `List<MemberPhone>` 자료구조 형식으로 선언하여 총 두 개의 전화번호 객체를 저장할 수 있도록 한 것이다.
package com.bs.lec19.member;
import java.util.List;
public class Member
{
// * memPhone 프로퍼티를 제외한 다른 프로퍼티 생략.
private List<MemPhone> memPhones;
public List<MemPhone> getMemPhones()
{
return memPhones;
}
public void setMemPhones(List<MemPhone> memPhones)
{
this.memPhones = memPhones;
}
}
memJoinOk.jsp (회원가입 완료 창)
회원 객체인 `Member.java`에 저장된 전화번호 `memPhones` 프로퍼티의 타입은 `List<MemPhone>` 이다.
private List<MemPhone> memPhones;
★ 즉, `memPhones[0]` 과 같이 인덱스로 하나의 요소를 선택했을 때의 타입은 `MemberPhone` (전화번호 DTO)이므로
`${member.memPhone[0].memPhone1}` → 본인 전화번호의 첫 번째 자리인 `010` 을 표시하게 되는 것이다.
① `${member.memPhone[0].memPhone1}` : 010
② `${member.memPhone[0].memPhone2}` : 1234
③ `${member.memPhone[0].memPhone3}` : 5678
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ page session="false" %>
<html>
<head>
<title>Home</title>
</head>
<body>
<h1> memJoinOk </h1>
<!-- * Phone 에 해당하는 EL을 제외한 다른 EL 구문 생략. -->
PHONE1 : ${member.memPhones[0].memPhone1} - ${member.memPhones[0].memPhone2} - ${member.memPhones[0].memPhone3} <br />
PHONE2 : ${member.memPhones[1].memPhone1} - ${member.memPhones[1].memPhone2} - ${member.memPhones[1].memPhone3} <br />
<!-- ... -->
19-3 Model & ModelAndView
컨트롤러에서 뷰에 데이터를 전달하기 위해 사용되는 객체로 Model과 ModelAndView 가 있다.
두 객체의 차이점은
◎ `Model` 은 뷰에 데이터만을 전달하기 위한 객체이고,
◎ `ModelAndView` 는 데이터와 뷰의 이름을 함께 전달하는 객체이다.
ⓐ return : `String` 일 때 - [`Model` 만 사용]
MemberController.java
@RequestMapping(value = "/memModify", method = RequestMethod.POST)
public String memModify(Model model, Member member)
{
Member[] members = service.memberModify(member);
// ① 데이터 전달
model.addAttribute("memBef", members[0]); //-- 수정 전 멤버 객체
model.addAttribute("memAft", members[1]); //-- 수정 후 멤버 객체
// ② 뷰의 이름 전달
return "memModifyOk";
}
memModifyOk.jsp
ID : ${memBef.memId}
ID : ${memAft.memId}
ⓑ return : `ModelAndView` 일 때
MemberController.java
@RequestMapping(value = "/memModify", method = RequestMethod.POST)
public ModelAndView memModify(Model model, Member member)
{
Member[] members = service.memberModify(member);
ModelAndView mav = new ModelAndView();
// ① 모델(model) 객체에 데이터 저장(추가)
mav.addObject("memBef", members[0]);
mav.addObject("memAft", members[1]);
// ② 뷰(view) 페이지 이름 전달(추가).
mav.setViewName("memModifyOk");
return mav;
}
'[Inflearn] > 자바 스프링 프레임워크(renew ver.)' 카테고리의 다른 글
[inflearn] 20240120 [스프링-프레임워크] - 21강 필기 (1) | 2024.01.20 |
---|---|
[inflearn] 20240114 [스프링-프레임워크] - 20강 필기 (1) | 2024.01.14 |
[inflearn] 20240113 [스프링-프레임워크] - 18강 필기 (2) | 2024.01.14 |
[inflearn] 20240113 [스프링-프레임워크] - 17강 필기 (2) | 2024.01.13 |
[inflearn] 20240110 [스프링-프레임워크] - 13강 필기 (1) | 2024.01.11 |