[Spring] @ModelAttribute 및 중첩 커맨드 객체, Model & ModelAndView

2021. 1. 14. 03:00 Spring Framework/Spring 입문 - 개념 및 핵심

| @ModelAttribute

 

@ModelAttribute는 스프링에서 JSP파일에 반환되는 Model 객체에 속성값을 주입하거나 바인딩할 때 사용되는 어노테이션이다. 컨트롤러(Controller) 객체에서 2가지 방법으로 사용된다.

 

@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를 붙이는 경우다. 이 때 serverTime 속성을 Model 객체에 아래와 같은 코드를 실행함으로서 반환되는 dateFormat.format(date) 값을 바인딩한다. 이 값은 JSP 파일에서 사용할 수 있다.

@RequestMapping(value="/memJoin", method=RequestMethod.POST)
public String memJoin(@ModelAttribute("mem") Member member) {
    service.memberRegister(member);
    return "memJoinOk";
}

 

다음은 컨트롤러 메서드의 인수에 어노테이션을 부착하는 경우다. @ModelAttribute을 써서 HTTP 요청에 들어있는 속성값들을 Member 커맨드 객체에 자동적으로 바인딩 하게 된다. 만일 @ModelAttribute([NAME]) 형태로 붙일경우 JSP파일에서 ${[NAME].property} 형태로 Model 객체의 값을 사용할 수 있게 된다.

@Controller
@RequestMapping("/member")
public class MemberController {

    @Resource(name="memService")
    MemberService service;

    @ModelAttribute("serverTime")
    public String getServerTime(Locale locale) {
        Date date = new Date();
        DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG, locale);
        return dateFormat.format(date);
    }

    @RequestMapping(value="/memJoin", method=RequestMethod.POST)
    public String memJoin(@ModelAttribute("mem") Member member) {
        service.memberRegister(member);
        return "memJoinOk";
    }
}

 

위 두 가지 방식을 동시에 써서 @ModelAttribute를 써서 JSP파일에 전달하는 Model 객체에 serverTime 속성과 mem으로 표현되는 Member 객체의 데이터를 넘겨줄 수 있다. 

 

<%@ page language="java" contentType="text/html; charset=EUC-KR"
pageEncoding="EUC-KR"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=EUC-KR">
    <title>memJoinOk</title>
</head>
<body>
<h1> memJoinOk</h1>

ID : ${mem.memId} <br/>
PW : ${mem.memPw} <br/>
Mail : ${mem.memMail} <br/>
Phone : ${mem.memPhone.memPhone1} - ${mem.memPhone.memPhone2} - ${mem.memPhone.memPhone3} <br/>
<P>  The time on the server is ${serverTime}. </P>
<a href="/mvc/resources/html/memJoin.html"> Go MemberJoin</a>
</body>
</html>

 

| 중첩 커맨드 객체

 

사용자가 HTTP로 사용자 데이터를 보내올 때 커맨드 객체를 여러 번 중첩시켜서 보낼 수 있다. 이 중첩 커맨드 객체는 VO List 형태로 데이터를 받을 수 있다. HTML 파일에서 데이터를 전송할 때 데이터의 name 속성은 아래처럼 커맨드 객체의 속성명과 인덱스 그리고 속성을 명시해야한다.

<!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">
...

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 />

...
</form>
<a href="/lec19/resources/html/login.html">LOGIN</a> &nbsp;&nbsp; <a href="/lec19/resources/html/index.html">MAIN</a>
</body>
</html>

 

 PHONE1, PHONE2의 중첩 커맨드 객체는 아래의 List형태의 MemPhone 객체 리스트로 받을 수 있다.

 

public class Member {

    private String memId;
    private String memPw;
    private String memMail;
    private List<MemPhone> memPhones;

    ...
}
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;
    }

}

| Model & ModelAndView 

 

컨트롤러에서 뷰에 데이터를 전달하기 위해 사용되는 객체로 Model ModelAndView가 있다. Model ModelAndView의 차이는 Model은 데이터만을 전달하기 위한 객체이고 ModelAndView는 데이터와 뷰의 이름을 함께 전달하는 객체다.

 

아래 코드를 보면 Model은 객체에 속성값을 넣어 JSP에 해당 속성값을 제공하는 역할을 한다. ModelAndView Model이 하는 역할 뿐만 아니라 해당 뷰의 이름을 추가하여 전달할 수 있다. 또한 메서드의 리턴값에도 차이가 있다.

@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";
}


@RequestMapping(value = "/memModify", method = RequestMethod.POST)
public ModelAndView memModify(Member member) {

        Member[] members = service.memberModify(member);

        ModelAndView mav = new ModelAndView();
        mav.addObject("memBef", members[0]);
        mav.addObject("memAft", members[1]);

        mav.setViewName("memModifyOk");

        return mav;
}



출처: https://engkimbs.tistory.com/694?category=767795 [새로비]