1. Model을 통해 Controller에서 View에 데이터 전달


컨트롤러 -> 뷰로 데이터를 전달하면 뷰에서는 전달받은 데이터를 사용할 수 있다.

"/survey" 경로로 요청이 들어오면 "/survey/surveyForm" 뷰에서 전달받은 데이터를 이용해 폼을 작성해보자.

일단 VO 객체 하나를 만들고

public class Question {
    private String title;
    private List<String> options;
    
    public Question(String title, List<String> options) {
        this.title = title;
        this.options = options;
    }
    
    public Question(String title) {
        this(title, Collection.<String>emptyList());
    }
    
    // getter 메서드는 생략 (있다고 가정하자)
    
    public boolean isChoice() { return options != null && !options.isEmpty(); }
}

뷰에 데이터를 전달할 컨트롤러를 작성하고

@Controller
@RequestMapping("/survey")
public class SurveyController {
    
    @GetMapping
    public String form(Model model) {
        List<Question> questions = createQuestion();
        model.addAttribute("questions", questions);
        return "survey/surveyForm"; // 뷰를 반환한다.
    }
    
    private List<Question> createQuestion() {
        Question q1 = new Question("당신의 역할은?", Arrays.asList("서버", "프론트", "풀스택"));
        Question q2 = new Question("사용하는 개발도구는?", Arrays.asList("이클립스", "인텔리J", "서브라임"));
        Question q3 = new Question("하고 싶은 말은?");
        return Arrays.asList(q1, q2, q3);
    }
    
    // PostMapping 생략
}

뷰 JSP 코드에서 전달받은 데이터를 이용해서 폼을 만들어보자

<h2>설문조사</h2>
<form method="post">
<c:forEach var="q" items="${questions}" varStatus="status">
    ${status.index + 1}.${q.title} <br/>
    <c:if test="${q.choice}">
        <c:forEach var="option" items="${q.questions}">
            <input type="radio" name="res[${status.index}]" value="${option}">
        </c:forEach>
    </c:if>
    
    <c:if test="! ${q.choice}">
        <input type="text" name="res[${status.index}]">
    </c:if>
</c:forEach>

2. ModelAndView를 통한 뷰 선택과 모델 전달


위의 코드에서 컨트롤러는 2가지 역할을 한다.

  1. Model을 이용해 뷰에 전달할 데이터를 설정
  2. 결과를 보여줄 뷰 이름을 반환

ModelAndView를 사용하면 이 두 가지를 한 번에 처리할 수 있다.

@Controller
@RequestMapping("/survey")
public class SurveyController {
    
    @GetMapping
    public ModelAndView form() {
        List<Question> questions = createQuestions();
        ModelAndView mav = new ModelAndView();
        mav.addObject("questions", questions); // 뷰에 전달할 데이터를 설정한다.
        mav.setViewName("survey/surveyForm");  // 결과를 보여줄 뷰 이름을 설정한다.
        return mav;
    }
}