ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Spring MVC(@ModelAttribute, @Valid, @Validated)
    웹개발/Spring 2020. 7. 28. 01:17

    이 내용은 인프런의 스프링 웹 MVC강좌를 참고하여 만들었습니다.

     

    1,@ModelAttribute

    - 파라미터로 오는 사항들을 파라미터 타입을 임의 클래스 타입으로 받아오면서 파라미터 명과 필드명이 같으면 자동으로 매핑이 되어 저장이 됨

     

    - 바인딩 오류 시에는 오류 발생, 그러나 BindingResult변수를 이용하여서 오류를 발생시키지 않고 타입이 다르면 null값을 대신 저장 후 오류 사항을 메시지 형태로 출력이 가능

     

    -해당 선언 후 자동으로 진행이 되는 작업

    1, MemberInfo클래스의 객체(받아오는 객체) info를 자동으로 생성

    2, 해당 파라미터 명으로 자동으로 매핑이 됨

    3, 자동으로 Model객체에 추가가 되고 뷰까지 전달이 됨

     

    -()안에 오는 인자는 지정한 문자열의 이름으로 MenberInfo 객체가 Model객체로 추가될 때 해당 이름으로 사용(session이름이랑 겹치면 안됨)

     

    - 생략이 가능함

     

    Event class

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

     

    @Controller
    public class SampleController {
    
        @PostMapping("/events")
        @ResponseBody
        public Event getEvent(@Valid @ModelAttribute Event event, BindingResult bindingResult) {
            System.out.println(bindingResult.hasErrors());
            if(bindingResult.hasErrors()){
                System.out.println("===============================");
                bindingResult.getAllErrors().forEach(c -> {
                    System.out.println(c.toString());
                });
    
                return null;
            }
            return event;
        }
    }

     

    테스트 코드

    1, 정상적인 바인딩이 일어난 경우

    @RunWith(SpringRunner.class)
    @WebMvcTest
    public class SampleControllerTest {
    
        @Autowired
        MockMvc mockMvc;
    
        @Test
        public void testEvent() throws Exception{
            mockMvc.perform(post("/events")
                    .param("id", "1")
                    .param("name","test")
                    .param("limit","10"))
                    .andDo(print())
                    .andExpect(status().isOk())
                    .andExpect(jsonPath("name").value("test"))
            ;
        }
    }

    2, 바인딩 오류인 경우

    @RunWith(SpringRunner.class)
    @WebMvcTest
    public class SampleControllerTest {
    
        @Autowired
        MockMvc mockMvc;
    
        @Test
        public void testEvent() throws Exception{
            mockMvc.perform(post("/events")
                    .param("id", "1")
                    .param("name","test")
                    .param("limit","abc")) 
                    .andDo(print())
                    .andExpect(status().isOk())
            ;
        }
    }

    원래는 바인딩 오류이나 테스트는 통과가 되고 컨트롤러의 프린트문에 의하여 바인딩 오류 부분 확인 가능

     

    2,@Valid, @Validated

    - 변수에 조건을 주어 @ModelAttribute을 통하여 바인딩이 일어날 때 타입 이외의 조건에 의하여도 오류가 발생이 되도록 처리를 함

     

    - validation을 하기 위하여는 다음과 같은 의존성을 추가해야 함

            <dependency>
                <groupId>org.hibernate</groupId>
                <artifactId>hibernate-validator</artifactId>
                <version>6.1.5.Final</version>
            </dependency>

     

    Event class에 validate 조건을 줌

    public class Event {
    
        private Integer id;
    
        @NotBlank
        private String name;
    
        @Min(value = 0)
        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;
        }
    }
    @Controller
    public class SampleController {
    
        @PostMapping("/events")
        @ResponseBody
        public Event getEvent(@Valid @ModelAttribute Event event, BindingResult bindingResult) {
            System.out.println(bindingResult.hasErrors());
            if(bindingResult.hasErrors()){
                System.out.println("===============================");
                bindingResult.getAllErrors().forEach(c -> {
                    System.out.println(c.toString());
                });
    
                return null;
            }
            return event;
        }
    }

    위와 같이 유효성을 추가 할 수 있다.

     

    - @Validated같은 경우에는 유효성마다 그룹화를 지어서 해당 그룹만 유효 조사를 할 수 있는 느낌이다.

    Event class

    public class Event {
    
        interface ValidateLimit{}
        interface ValidateName{}
    
        private Integer id;
    
        @NotBlank(groups = ValidateName.class)
        private String name;
    
        @Min(value = 0, groups = ValidateLimit.class)
        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;
        }
    }

     

    @Controller
    public class SampleController {
    
        @PostMapping("/events")
        @ResponseBody
        public Event getEvent(@Validated(Event.ValidateLimit.class) @ModelAttribute Event event, BindingResult bindingResult) {
            System.out.println(bindingResult.hasErrors());
            if(bindingResult.hasErrors()){
                System.out.println("===============================");
                bindingResult.getAllErrors().forEach(c -> {
                    System.out.println(c.toString());
                });
    
                return null;
            }
            return event;
        }
    }

    name의 유효성 검사는 진행하지 않고 limit에 대한 검사만 진행을 한다.

    '웹개발 > Spring' 카테고리의 다른 글

    Spring MVC(세션 관리)  (0) 2020.07.28
    Spring MVC(폼 서블릿 오류 해결)  (0) 2020.07.28
    Spring MVC(html과의 매핑)  (0) 2020.07.28
    Spring MVC(요청 매개변수)  (0) 2020.07.26
    Spring MVC(URI 패턴)  (0) 2020.07.26
Designed by Tistory.