Top 5 enhancements of Spring MVC 3.1

Spring MVC 3.1带来了多项增强特性,包括闪存属性支持、@Validated注解支持JSR-303验证组、@Valid在@RequestBody方法参数上的支持、PUT请求中表单编码数据的支持以及Java配置的支持。这些特性简化了开发流程并提高了应用的灵活性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Top 5 enhancements of Spring MVC 3.1
from http://blog.goyello.com/2011/12/16/enhancements-spring-mvc31/

After many months of development, Spring 3.1 has been finally released. The release is shipped with some exciting features like caching abstraction, bean profiles and container configuration simplifications. However, in this blog post I will describe my top 5 enhancements of Spring MVC 3.1.
[b]1. Flash attributes support[/b]

Flash attributes are used to store attributes between requests and are used mostly in Post/Redirect/Get pattern. Prior to Spring 3.1 some additional (repeatable) steps were required to utilize flash attributes in Spring MVC based applications:
Create or copy FlashMap object to hold flash attributes

public class FlashMap implements Serializable  {
// implementation omitted
}
Create or copy FlashMapFilter to your project

public class FlashMapFilter extends OncePerRequestFilter {
// implementation omitted
}

Include FlashMapFilter in web.xml
Put flash attributes in the controller when needed

@PreAuthorize("hasRole('ROLE_USER')")
@RequestMapping(value = Routing.SOME_ROUTING, method = RequestMethod.POST)
public String processForm(@Valid Form form, BindingResult result) {

// process the form
// ...

// add flash attribute
FlashMap.addAttribute("message", "Form processed");

// redirect
return RoutingHelper.redirect(Routing.SOME_OTHER_ROUTING);
}

With Spring 3.1 flash attributes support is enabled by default. No additional configuration is required. @Controller method accepts the argument of a type RedirectAttributes. RedirectAttributes is an interface that extends from standard Spring MVC Model interface and it may be used to store flash attributes that will be available after the redirection.

@PreAuthorize("hasRole('ROLE_USER')")
@RequestMapping(value = Routing.SOME_ROUTING, method = RequestMethod.POST)
public String processForm(@Valid Form form, BindingResult result, RedirectAttributes redirectAttributes) {

// process the form
// ...

// add flash attribute
redirectAttributes.addFlashAttribute("message", "Form processed");

// redirect
return RoutingHelper.redirect(Routing.SOME_OTHER_ROUTING);
}

[b]2. @Validated annotation with support for JSR-303 validation groups
[/b]
Spring MVC Bean Validation support has been extended with a new @Validated annotation that provides support of JSR 303 validation groups. A group defines a subset of constraints that is validated for a given object graph. Each constraint declaration may define the group or the list of groups it belongs to.

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 {

}

The example usage of the new @Validated annotation is shown in the following example:

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

The support for validation groups as added to Spring 3.1 is really handy. To read more about validation groups download and read the JSR 303 specification.
[b]3. Support @Valid on @RequestBody method arguments[/b]

The @RequestMapping handler methods support @RequestBody annotated parameter for accessing the HTTP request body. The conversion is done through the available message converters, including FormHttpMessageConverter (application/x-www-form-urlencoded), MarshallingHttpMessageConverter (application/xml), MappingJacksonHttpMessageConverter (application/json) and others. But the @RequestBody annotated method argument could not be automatically validated. Manual validation was required:

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

In Spring 3.1 the @RequestBody method argument can be annotated with @Valid to invoke automatic validation. This makes the code can be simplified:

@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();
}
}

In the above example, Spring automatically performs the validation and in case of error MethodArgumentNotValidException is thrown. Optional @ExceptionHandler method may be easily created to add custom behavior for handling this type of exception.

[b]4. Supporting PUT request with form encoded data[/b]

The limitation of Servlet implementation is that it does not handle the encoded data of the HTTP PUT request properly. Introduction of the new HttpPutFormContentFilter solves that problem. With Spring 3.1 developing a RESTfull or RESTlike API became much simpler. See my previous post to read more about the usage of HttpPutFormContentFilter in a web application.
[b]5. Java based configuration[/b]

The xml configuration of a Spring MVC application may be completely replaced by the Java based configuration. The simplest way to configure a web application is to use the @EnableWebMvc annotation:

@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();
}
}

Extending from WebMvcConfigurerAdapter is not required, but it allows for the customization of the default Spring MVC configuration. The adapter enables us to register additional components like formatters, converters, custom validators, interceptors etc. This way the custom configuration can be done by Java code only. See my previous post about configuring a Spring MVC application with no xml in a Servlet 3.0 based environment.
Spring MVC 3.1 has a lot to offer

Spring MVC 3.1 brings many enhancements. The features mentioned in this blog post should have a positive impact on the application development with Spring MVC. They are not revolutionary, though. However, when I look at all the Spring features and enhancements shipped within the 3.1 release, I feel that the framework is going in the right direction. The caching abstraction, bean profiles, configuration simplifications and many other core features should allow to develop applications more efficiently.
References:

http://blog.springsource.org/2011/12/13/spring-framework-3-1-goes-ga/
http://static.springsource.org/spring/docs/3.1.x/spring-framework-reference/html/new-in-3.1.html
http://static.springsource.org/spring/docs/3.1.x/spring-framework-reference/html/
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值