SPRING
2017.05.22 / 18:52

Top 5 enhancements of Spring MVC 3.1

ducati
Ãßõ ¼ö 251

http://blog.goyello.com/2011/12/16/enhancements-spring-mvc31/

¿ª½Ã Ãë¹Ì »ï¾Æ ..

Spring 3.1ÀÌ °³¹ßµÈÁö ¼ö°³¿ùÀÌ Áö³­ Áö±Ý µåµð¾î ¸±¸®Áî ?ç´?. À̹ø ¹èÆ÷ ¹öÀüÀº ij½¬ Ãß»óÈ­, ºó ÇÁ·ÎÆÄÀÏ, °£´ÜÇÑ ÄÁÅ×ÀÌ³Ê ¼³Á¤ µî ¸î°¡Áö Àç¹Ì³­ ±â´ÉÀ» Æ÷ÇÔÇÏ°í ÀÖ´Ù. ¾Æ¹«Æ° ÀÌ ºí·Î±× Æ÷½ºÆÿ¡¼­ ½ºÇÁ¸µ 3.1¿¡¼­ ³»°¡ »ý°¢ÇÏ´Â TOP 5 °³¼±¿¡ ´ëÇؼ­ ¼³¸íÇÒ °ÍÀÌ´Ù.

1. Flash Attributes support
Ç÷¡½¬ ¾îÆ®¸®ºäÆ®µéÀº ¿äû »çÀÌÀÇ 

2. @Validated annotation with support for JSR-303 validation groups.

½ºÇÁ¸µ MVC bean validationÀº JSR303 ±×·ì º§¸®µ¥À̼ÇÀ» Áö¿øÇÏ´Â »õ·Î¿î @Validated annotationÀ»  Áö¿øÇÑ´Ù. ÀÌ ±×·ìÀº ÁÖ¾îÁø °´Ã¼¿¡ ´ëÇØ °ËÁõÀ» ÇÏ°í Á¦¾àÀÇ ÇÏÀ§ ÁýÇÕÀ» Á¤ÀÇ ÇÑ´Ù. °¢ Á¦¾à Á¶°Ç¿¡ ´ëÇÑ ¼±¾ðÀº ±×·ìÀ̳ª ±×°ÍÀÌ ¼ÓÇÑ ±×·ìÀÇ ¸ñ·ÏÀ» Á¤ÀÇÇÒ ¼ö ÀÖ´Ù.


public class User {
    @NotNull
    private String name;
 
    @NotNull(groups = { Simple.class })
    private String address;
 
    @NotNull(groups = { Simple.class, Extended.class })
    private String licenceType;
 
    @NotNull(groups = { Extended.class })
    private String creditCard;
}




public interface Simple {
 
}
 
public interface Extended {
 
}


»õ·Î¿î @Validated annotation¿¡ ´ëÇÑ »ç¿ëÀº ¾Æ·¡ ¿¹Á¦¿¡ ³ª¿Í ÀÖ´Ù.


@Controller
public class MyController {
 
    @RequestMapping(value = "/user/default", method = RequestMethod.GET)
    public String createDefaultUser(@Validated({ Default.class }) User user, BindingResult result) {
        if(result.hasErrors()) {
            // Validation on 'name'
        }
        return null;
    }
 
    @RequestMapping(value = "/user/simple", method = RequestMethod.GET)
    public String createSimpleUser(@Validated({ Simple.class }) User user, BindingResult result) {
        if(result.hasErrors()) {
            // Validation on 'licenceType' and 'address'
        }
        return null;
    }
 
    @RequestMapping(value = "/user/extended", method = RequestMethod.GET)
    public String createExtendedUser(@Validated({ Simple.class, Extended.class }) User user, BindingResult result) {
        if(result.hasErrors()) {
            // Validation on 'creditCard' and 'licenceType' and 'address'
        }
 
        return null;
    }
}


½ºÇÁ¸µ 3.1¿¡ Ãß°¡µÈ ÀÌ ±×·ì º§¸®µ¥À̼ÇÀº Á¤¸» Æí¸®ÇÏ´Ù. ÀÌ º§¸®µ¥ÀÌ¼Ç ±×·ì¿¡ ´ëÇؼ­ ´õ ¸¹Àº ÀÚ·á´Â download and read the JSR 303 specification

3. Support @Valid on @RequestBody method arguments

@RequestMapping Çڵ鷯 ¸Þ¼­µå´Â HTTP request body¿¡ Á¢±ÙÇÒ ¼ö ÀÖ´Â @RequestBody ¾î³ëÅ×À̼ÇÀ» Áö¿øÇÑ´Ù. º¯È¯ÀÌ °¡´ÉÇÑ ¸Þ½ÃÁö´Â ¸Þ½ÃÁö ÄÁ¹öÅ͸¦ ÅëÇØ º¯È¯ÀÌ ÀÌ·ç¾îÁø´Ù. FormHttpMessageConverter(application/x-www-form-urlencoded), MarshallingHttpMessageConverter(application/xml), MappingJacksonHttpMessageConverter(appliction/json) ±×¸®µµ ´Ù¸¥ converterµéµµ. ÇÏÁö¸¸ @RequestBody ¾î³ëÅ×À̼ÇÀÌ ºÙÀº º¯¼öµéÀº ÀÚµ¿ÀûÀ¸·Î º§¸®µ¥À̼Çüũ¸¦ ÇÏÁö ¾Ê´Â´Ù. ¼öµ¿À¸·Î üũÇØÁÖ´Â ·ÎÁ÷ÀÌ ÇÊ¿ä.


@Controller
public class MyController {
 
    @Autowired
    private Validator validator;
 
    @RequestMapping(value = "", method = RequestMethod.PUT)
    @ResponseStatus(value = HttpStatus.CREATED)
    @Secured("ROLE_ADMIN")
    @Transactional
    public void save(@RequestBody User user) {
        validate(user);
        dao.save(user);
    }
 
    private void validate(User user) {
        // perfom validation using injected validator
    }
}


½ºÇÁ¸µ 3.1¿¡¼­ @RequestBody ¸Þ¼­µå ¾î³ëÅ×À̼ÇÀº @Valid ¸Þ¼­µå¸¦ ÅëÇØ ÀÚµ¿À¸·Î º§¸®µ¥ÀÌ¼Ç Ã¼Å©¸¦ ÇÒ ¼ö ÀÖ´Ù. ÀÌ ¹æ¹ýÀº Äڵ带 ½ÉÇÃÇÏ°Ô ¸¸µé¾î ÁØ´Ù.

@Controller
public class MyController {
 
    @RequestMapping(value = "/user", method = RequestMethod.POST)
    @ResponseStatus(value = HttpStatus.CREATED)
    @Transactional
    public void save(@Valid @RequestBody User user) {
        dao.save(user);
    }
 
    @ExceptionHandler
    @ResponseStatus(value = HttpStatus.BAD_REQUEST)
    @ResponseBody
    public String handleMethodArgumentNotValidException(
            MethodArgumentNotValidException error) {
        return "Bad request: " + error.getMessage();
    }
}


À§ÀÇ ¿¹Á¦¿¡¼­ ½ºÇÁ¸µÀº ÀÚµ¿À¸·Î À¯È¿¼º°Ë»ç¸¦ ¼öÇàÇÏ°í ¿¡·¯°¡ ¹ß»ýÇÒ °æ¿ì MethodArgumentNotValidExceptionÀ» ´øÁ®ÁØ´Ù. Ãß°¡ÀûÀ¸·Î @ExceptionHandler ¸Þ¼­µå´Â ÀÌ·¯ÇÑ À¯ÇüÀÇ ¿¡·¯ 󸮿¡ ´ëÇÑ »ç¿ëÀÚ ÁöÁ¤ µ¿ÀÛÀ» Ãß°¡ÇÏ¿© ¸¸µé ¼ö ÀÖ´Ù.

4. Supporting PUT request with form encoded data

¼­ºê¸´ ±¸ÇöÀÇ ÇÑ°è´Â ÀÎÄÚµùµÈ HTTP PUT ¿äû¿¡ ´ëÇѠ󸮸¦ ÇÏÁö ¾Ê´Â ´Ù´Â °ÍÀÌ´Ù. »õ·Ó°Ô ¼Ò°³µÇ´Â  HttpPutFormContentFilter´Â ÀÌ ¹®Á¦¸¦ ÇØ°á Çß´Ù. ½ºÇÁ¸µ 3.1¿¡¼­ RESTfull or RESTLike API ´Â Á» ´õ ½ÉÇÃÇÏ°Ô ¸¸µé ¼ö ÀÖ´Ù. ÀÌ°Í¿¡ ´ëÇÑ »ùÇÃÀº ÀÌÀü Æ÷½ºÆÿ¡¼­ ã¾Æº¼¼ö ÀÖ´Ù.
previous post to read more about the usage of HttpPutFormContentFilter

5. Java based configuration

±âÁ¸ÀÇ Spring MVC ¾ÖÇø®ÄÉÀ̼ÇÀÇ XML ¼³Á¤Àº ¿Ïº®ÇÏ°Ô ÀÚ¹Ù ±â¹ÝÀÇ ¼³Á¤À¸·Î º¯°æÇÒ ¼ö ÀÖ´Ù. °¡Àå °£´ÜÇÑ À¥ ¾ÖÇø®ÄÉÀ̼ÇÀÇ ¼³Á¤Àº @EnableWebMvc ¾î³ëÅ×À̼ÇÀ» »ç¿ëÇÏ´Â °ÍÀÌ´Ù.

@Configuration
@EnableWebMvc
@ComponentScan(basePackages = { "com.example" }, excludeFilters = @Filter(type = FilterType.ANNOTATION, value = Configuration.class))
@Import(PersistanceContextConfiguration.class)
public class ServletContextConfiguration extends WebMvcConfigurerAdapter {
 
    @Bean
    public TilesViewResolver configureTilesViewResolver() {
        return new TilesViewResolver();
    }
 
    @Bean
    public TilesConfigurer configureTilesConfigurer() {
        TilesConfigurer configurer = new TilesConfigurer();
        configurer.setDefinitions(new String[] { "/WEB-INF/tiles/tiles.xml",
                "/WEB-INF/views/**/views.xml" });
        return configurer;
    }
 
    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController("login");
    }
 
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/resources/").addResourceLocations(
                "/recourses/**");
    }
 
    @Override
    public void configureDefaultServletHandling(
            DefaultServletHandlerConfigurer configurer) {
        configurer.enable();
    }
}


WebMvcConfigurerAdapter¿¡ ´ëÇÑ È®ÀåÀº ÇÊ¿äÇÏÁö ¾ÊÁö¸¸ ±âÁ¸ ½ºÇÁ¸µ MVCÀÇ ¼³Á¤¹æ¹ýµµ Çã¶ôµÈ´Ù. ¾î´ðÅÍ´Â Ãß°¡ÀûÀÎ ÄÄÆ÷³ÍÆ®(Æ÷¸ËÅÍ,ÄÁ¹öÅÍ, Ä¿½ºÅÒ º§¸®µ¥ÀÌÅÍ, ÀÎÅͼÁÅ͵î)À» µî·ÏÇÒ ¼ö ÀÖµµ·Ï ÇÑ´Ù. ÀÌ »ç¿ëÀÚ Á¤ÀÇ ¼³Á¤Àº ÀÚ¹Ù Äڵ常µé »ç¿ëÇÏ¿© °¡´ÉÇÏ´Ù.  configuring a Spring MVC application with no xml in a Servlet 3.0 

Spring MVC 3.1  has a lot to offer.
½ºÇÁ¸µ MVC 3.1Àº ¸¹Àº Çâ»óÁ¡À» Á¦°øÇÑ´Ù. ÀÌ ºí·Î±×¿¡¼­ ¾ð±ÞÇÑ ±â´ÉÀº ½ºÇÁ¸µ MVC¿Í ¾ÖÇø®ÄÉÀÌ¼Ç °³¹ß¿¡ ±àÁ¤ÀûÀÎ ¿µÇâÀ» ³¢Ä¥ °ÍÀÌ´Ù. Çõ¸íÀûÀÌÁö´Â ¾ÊÁö¸¸ ½ºÇÁ¸µ 3.1¿¡¼­ ¸±¸®ÁîµÈ ¸ðµç È®Àå±â´É°ú ±â´É Çâ»ó¿¡ ´ëÇؼ­ º¸¸é ÇÁ·¹ÀÓ ¿öÅ©°¡ ¿Ã¹Ù¸¥ ¹æÇâÀ¸·Î °¡°í ÀÖ´Ù°í ´À³¥¼ö ÀÖ´Ù. ij½¬ Ãß»óÈ­, ºó ÇÁ·ÎÆÄÀÏ, ¼³Á¤ °£¼ÒÈ­ µî ¸¹Àº ÇÙ½É ±â´ÉµéÀº ´õ È¿°úÀûÀ¸·Î ¾ÖÇø®ÄÉÀÌ¼Ç °³¹ßÀ» ÇÒ ¼ö ÀÖµµ·Ï ÇÒ °ÍÀÌ´Ù.

Ãâó: http://devx.tistory.com/entry/Top-5-enhancements-of-Spring-MVC-31 [Meta Developer Story]