ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • WebMvcConfigurer (스프링 MVC - 3)
    Programming/Spring MVC 2020. 3. 22. 23:01
    728x90

    1. Formatter

    문자열 <-> 객체 사이의 변환

     

    1) Controller 작성

    @RestController
    public class SampleController {
    
        @GetMapping("/hello/{name}")
        public String hello(@PathVariable("name") Person person) {
            return "hello " + person.getName();
        }
    }
    

     

    2) Person 클래스 작성

    public class Person {
    
        private String name;
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
    }
    

     

    3. Formatter 작성

    // 빈으로 등록되면 자동으로 설정됨
    @Component
    public class PersonFormatter implements Formatter<Person> {
    
        @Override
        public Person parse(String s, Locale locale) throws ParseException {
            Person person = new Person();
            person.setName(s);
            return person;
        }
    
        @Override
        public String print(Person person, Locale locale) {
            return person.getName();
        }
    
    }
    

     

     

    2. 도메인 클래스 Converter 자동 등록

    데이터 JPA와 관련된 내용

     

    1) Controller 작성

    @RestController
    public class SampleController {
    
        @GetMapping("/hello")
        public String hello(@RequestParam("id") Person person) {
            return "hello " + person.getName();
        }
    }
    

     

    2) Entity 클래스 작성

    @Entity
    public class Person {
    
        @Id @GeneratedValue
        private Long id;
    
        private String name;
    
        public Long getId() {
            return id;
        }
    
        public void setId(Long id) {
            this.id = id;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
    }
    

     

    3) Repository 작성

    @Repository
    public interface PersonRepository extends JpaRepository<Person, Long> {
    }
    

     

    4) 테스트 코드 작성

    @RunWith(SpringRunner.class)
    @SpringBootTest
    @AutoConfigureMockMvc
    public class SampleControllerTest {
    
        @Autowired
        MockMvc mockMvc;
    
        @Autowired
        PersonRepository personRepository;
    
        @Test
        public void hello() throws Exception {
            Person person = new Person();
            person.setName("hongchan");
            personRepository.save(person);
    
            mockMvc.perform(get("/hello")
                    .param("id", "1"))
                .andDo(print())
                .andExpect(content().string("hello hongchan"));
        }
    }

     

     

    3. 핸들러 인터셉터

    - 사이사이에 부가적인 작업을 수행할 수 있음

    - 여러 핸들러에게 반복적으로 사용하는 코드를 줄이고 싶을 때 사용할 수 있음 (로깅, 인증 체크, Locale 변경 등...)

    - 일반적인 구현은 서블릿 필터를 사용해도 됨. 그러나 스프링 MVC에 특화되어 있는 로직을 작성해야 한다면 이를 사용해야 함

    - 참고 : xss attack 을 차단하는 기능을 구현할 때는 서블릿 필터 사용 가능!

     

    (preHandle (handler 인자로 들어옴)) -> 요청 처리 -> (postHandle (modelAndView 인자로 들어옴)) -> 뷰 렌더링 -> (afterCompletion)    

    postHandle & afterCompletion은 preHandle 과 역순으로 실행됨

     

     

    1) Interceptor 1, 2를 작성

    public class GreetingInterceptor implements HandlerInterceptor {
    
        @Override
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
            System.out.println("preHandle 1");
    
            // 실제 요청이 처리되도록 true를 return
            return true;
        }
    
        @Override
        public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
            System.out.println("postHandle 1");
        }
    
        @Override
        public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
            System.out.println("afterCompletion 1");
        }
    
    }
    

     

    2) 웹 설정 추가 (WebMvcConfigurer)

    @Configuration
    public class WebConfig implements WebMvcConfigurer {
    
        @Override
        public void addInterceptors(InterceptorRegistry registry) {
            registry.addInterceptor(new GreetingInterceptor());
            
            // "/hi"라는 path로 올 때만 인터셉터 실행됨
            registry.addInterceptor(new AnotherInterceptor())
                    .addPathPatterns(("/hi"));
        }
    }
    

     

    실행 결과 (두 번째부터 역순)

     

     

    4. 리소스 핸들러

    이미지, 자바스크립트, css, html 파일과 같은 정적인 리소스를 처리하는 핸들러 등록하는 방법 

     

    디폴트 서블릿

    - 서블릿 컨테이너가 기본으로 제공하는 서블릿으로 정적인 리소스를 처리할 때 사용한다.

     

    스프링 MVC 리소스 핸들러 맵핑 등록

    - 가장 낮은 우선 순위로 등록 (다른 핸들러 맵핑이 먼저 요청을 처리하고 최종적으로 리소스 핸들러가 처리하도록)

     

    리소스 핸들러 설정

    - 어떤 요청 패턴을 지원할 것인가?

    - 어디서 리소스를 찾을 것인가

    - 캐싱

    - ResourceResolver, ResourceTransformer

     

    1. 웹 설정 작성

    @Configuration
    public class WebConfig implements WebMvcConfigurer {
    
        @Override
        public void addResourceHandlers(ResourceHandlerRegistry registry) {
        // java, resources 가 classpath의 root
            registry.addResourceHandler("/mobile/**")
                    .addResourceLocations("classpath:/mobile/")
                    .setCacheControl(CacheControl.maxAge(10, TimeUnit.MINUTES));
        }
    
    }
    

     

     

    5. HTTP 메시지 컨버터

    - 요청 본문에서 메시지를 읽어들이거나(@RequestBody), 응답 본문에 메시지를 작성할 때(@ResponseBody) 사용한다.

    - 기본 HTTP 메시지 컨버터는 매우 다양함. 바이트 배열 컨버터, 문자열 컨버터, Form 컨버터, Resource 컨버터, xml, json...

    - 어떤 컨버터인지 선택하는 기준은, content (content type - 이 형식으로 요청을 보낸다)요청 헤더 본문 (accept - 이걸 응답으로 원한다)

     

    다음의 경우에 메시지 컨버터를 사용

    @Controller
    public class SampleController {
    
        @GetMapping("/message")
        public @ResponseBody String message(@RequestBody String str) {
            return str;
        }
    }
    

     

    설정 방법

    configureMessageConverters : 기본 메시지 컨버터를 대체

    extendMessageConverters : 기본 메시지 컨버터에 추가

    위의 방법들은 잘 안쓰고 의존성 추가로 컨버터 등록하기(추천)

      - 메이븐 또는 그레들 설정에 의존성을 추가하면 그에 따른 컨버터가 자동으로 등록됨

     

     

    JSON 컨버터

    스프링 부트를 사용하는 경우 Jackson2가 의존성에 들어있음.

    따라서, JSON용 HTTP용 메시지 컨버터가 기본으로 등록되어 있다.

     

    1) 컨트롤러 작성

    @RestController
    public class SampleController {
    
        @GetMapping("/jsonmessage")
        public Person jsonMessage(@RequestBody Person person) {
            return person;
        }
    }
    

     

    2) 테스트 코드 작성 또는 postman으로 테스트

    @RunWith(SpringRunner.class)
    @SpringBootTest
    @AutoConfigureMockMvc
    public class SampleControllerTest {
    
        @Autowired
        MockMvc mockMvc;
    
        @Autowired
        ObjectMapper objectMapper;
    
        @Test
        public void json() throws Exception {
            Person person = new Person();
            person.setName("hongchan");
            person.setId(25l);
    
            String jsonString = objectMapper.writeValueAsString(person);
    
            this.mockMvc.perform(get("/jsonmessage")
                        .contentType(MediaType.APPLICATION_JSON)
                        .accept(MediaType.APPLICATION_JSON)
                        .content(jsonString))
                    .andDo(print())
                    .andExpect(status().isOk());
        }
    }

     

     

    스프링 MVC 설정 방법은 다음과 같은 순서대로 진행

    - application.properties

    - WebMvcConfigurer

    - @Bean 으로 MVC 구성 요소 직접 등록

     

     

    인프런 백기선님 '스프링 MVC’ 강의를 듣고 정리한 내용입니다.
    728x90

    댓글

Designed by Tistory.