본문 바로가기

책 읽기/스프링 책 읽기

스프링 책 읽기(Spring in action) - 5. 스프링 MVC 시작하기(2)

요청입력받기

스프링 MVC는 클라이언트가 데이터를 전달해줄 몇 가지 방법을 제공함

* 쿼리파라미터, 폼 파라미터, 패스 변수

 

쿼리파라미터 입력받기

* 이전 글에서 사용한 방식은, 코드 내에 1000이나 5000이 직접 적혀있었고, 클라이언트는 이를 바꾸지 못하는 구조였다. 만약 4천원~ 5천원 사이인 커피의 목록을 알고싶은 사용자는 어떻게 해야할까? => 클라이언트의 GET 요청에서, min과 max의 파라미터값을 받으면 됨

@RequestMapping(method = RequestMethod.GET)
    public List<Coffee> coffees( @RequestParam(value="min", defaultValue = "1000") int min
                              ,  @RequestParam(value="max", defaultValue = "5000") int max
                            ){
        return coffeeRepository.findCoffees(min, max);
}

=> @RequestParam 애너테이션을 통해, value 값, 기본값을 지정할  수 있다. 아무것도 입력하지 않으면 1000~5000원 사이의 커피

=> 가장 일반적인 방식 => [url]/coffees?min=4000&max=5000 ==> 4~5천원 커피 찾기

테스트

// mock 저장소
        CoffeeRepository mockRepository =
                mock(CoffeeRepository.class);
        when(mockRepository.findCoffees(4000, 5000)).thenReturn(expectedCoffees);
		// 파라미터 4000, 5000으로 예상
... 생략

mockMvc.perform(get("/coffees?min=4000&max=5000"))
                .andExpect(view().name("coffees"))
                .andExpect(model().attributeExists("coffeeList"))
                .andExpect(model().attribute("coffeeList",
                        hasItems(expectedCoffees.toArray())));

=>  [url]/coffees?min=4000&max=5000 요청 부분을 수정한다

 

패스파라미터 입력받기

커피를 찾는데, 주어진 '이름' 하나만 가지고 찾는다고 가정한다. 이를 위한 방법은 @RequestParam을 이용해 name을 쿼리 파라미터로 받는 것 일수 있다

 @RequestMapping(value = "/{coffeeName}", method = RequestMethod.GET)
    public String showCoffee(@PathVariable("coffeeName") String name, Model model)
    {
        model.addAttribute(coffeeRepository.findOne(name));
        return "coffee";
    }

=> @PathVariable 애너테이션을 이용하여, /{coffeeName}에 관한 요청을 수행할 수 있다,

간단하지만.. 플레이스 홀더의 이름과 pathVarable의 이름이 꼭 일치해야하므로, 주의해주어야함

=> [url]/coffees/amerciano => 아메리카노 찾기.

테스트

mockMvc.perform(get("/coffees/americano"))
                .andExpect(view().name("coffees"))
                .andExpect(model().attributeExists("coffee"))
                .andExpect(model().attribute("coffee", expectedCoffee));

=> => [url]/americano => 요청 부분 및, list가 아니므로, 일치하는 부분 수정

 

폼 처리하기

폼으로 처리하기 앞서서, 폼을 입력할 수 있는 컨트롤러와, 폼을 만든다

@RequestMapping(value = "/register", method = RequestMethod.GET)
    public String showRegistrationForm() {
        return "registerForm";
    }

 

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <h1>Register</h1>

    <form method="POST">
        Coffee name : <input type="text" name="name" /> <br/>
        Coffee price : <input type="text" name="price"/> <br/>
    </form>
</body>
</html>

=> 등록 컨트롤러, 및 커피 등록 jsp

간단히 만든 regiser폼

폼 처리 컨트롤러 작성

* 폼처리 관련하여, POST로 받는 컨트롤러를 구현한다.

  @RequestMapping(value = "/register", method = RequestMethod.POST)
    public String processionRegist(Coffee coffee) {
        coffeeRepository.save(coffee);

        return "redirect:/coffees/" + coffee.getName() ;
    }

=> Register에서, name, price를 가져와 Coffee 클래스를 만든후 => save로 등록 => redirect로 등록된 커피를 볼 수 있는 메소드

=> redirect를 하면 -> [url]/coffees/커피이름 으로 연결되므로 => 위에서 만든 패스 파라미터로 처리 가능

테스트

mockMvc.perform(post("/coffees/register")
                        .param("name", "americano")
                        .param("price", "2500"))
                .andExpect(redirectedUrl("/coffees/americano"));

 

폼 검증하기

* 폼을 사용할때, 이름이 없거나 가격이 없는 경우에도, 값이 넘어갈 수 있는 점을 미연에 방지하기 위함

@NotNull 애너테이션 등이 주로 사용된다.

    @NotNull
    @Size(min=3, max=20)
    private final String name;

폼을 사용 할 때, name의 값을 null이 되지 못하며 5~20 길이의 String임을 명시

@Valid 애너테이션을 통해, 검증한다

    @RequestMapping(value = "/register", method = RequestMethod.POST)
    public String processionRegist(@Valid Coffee coffee, Errors errors) {
        if (errors.hasErrors()){
            return "registerForm";
        }
        
        coffeeRepository.save(coffee);

        return "redirect:/coffees/" + coffee.getName() ;
    }

=> 만약 검증되지 않았다면, error가 생기고 바로 registerForm에 그대로 남게 됨