본문으로 바로가기

[Spring MVC] @ModelAttribute

category Spring/SpringMVC 2019. 8. 13. 20:50

@ModelAttribute

:여러곳에 있는 단순 타입 데이터를 복합 타입 객체로 받아오거나  해당 객체를 새로 만들때 사용할수 있다.

 또한 생략 가능하다.

 

 - 어디서 받아 올수있나?

: URI 패스, Request param , session등등

 

package com.example.demo;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
public class SampleController {

	@GetMapping("/events/form")
	public String eventForm(Model model) {
		Event event = new Event();
		event.setLimit(50);
		model.addAttribute(event);
		return "/events/form";		
	}
	
	@PostMapping("/events")
	@ResponseBody
	public Event getEvent(@ModelAttribute Event event) {
		return event;
	}

	
	
}
package com.example.demo;

public class Event {

	private Integer id;
	private String name;
	private Integer limit;
	public Integer getLimit() {
		return limit;
	}
	public void setLimit(Integer limit) {
		this.limit = limit;
	}
	public Integer getId() {
		return id;
	}
	public void setId(Integer id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
}
package com.example.demo;

import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;

@RunWith(SpringRunner.class)
@WebMvcTest
public class SampleControllerTest {

	@Autowired
	MockMvc mockMvc;
	
	@Test
	public void postEvent() throws Exception{
		
		mockMvc.perform(post("/events")
				.param("name", "sung")
				.param("limit", "10"))
		.andDo(print())
		.andExpect(status().isOk())
		.andExpect(jsonPath("name").value("sung"));
	}
	
	
}

 

 

이렇게 테스트를 해보면 정상적으로 잘 동작한다.

param("name","sung") , param("limit","10") 은 Event의 필드명인 name, limit과 동일하기 때문에 값이

Event에 객체에 들어가게 된다. 그런데 만약 limit을 Integer가 아닌 String type을 넣게 되면 어떻게 될까?

 

param("limit","10")  => param("limit","test") 로 변경후 테스트케이스를 돌려보면 error가 발생한다.

BindingException 이 나는것이다.

 

 

그러면 BindingException은 제어할수 없는것인가?

결론부터 말하자면 가능하다. 아규먼트로 BindingResult 타입의 매개변수를 추가하는 것이다.

 

 

 

테스트케이스를 실행시키면 status 200 으로 정상적으로 잘 돌아가고 

bindingResult에 있는 error를 통해 원하는 방향으로 제어가 가능하다. 보통 문구를 띄워준다고 한다.