Spring 4.x官方参考文档中文版——第21章 Web MVC框架(11)

自定义WebDataBinder的初始化

       为了在Spring的WebDataBinder里,使用PropertyEditors来自定义请求参数的绑定,你能在你的controller中,使用@InitBinder方法,或在@ControllerAdvice注解了的类中使用@InitBinder,或者自己实现WebBingdingInitializer来自定义请求参数绑定。详见”使用@ControllerAdvice对controller做横切通知”这一章节。

 

使用@InitBinder自定义数据绑定

       在controller中的方法上写上@InitBinder,可以在你的controller类上直接配置web数据绑定。@InitBinder可以识别出初始化了WebDataBinder的方法,这个初始化了的WebDataBinder对象会被注解过的handler处理器方法的指令和表单对象入参所填充。

       这个init-binder(初始化绑定的)方法与@RequestMapping支持的入参类型相同。除了指令/表单对象和匹配验证结果的对象外,这个初始化绑定的方法必须无返回值。因此,它们通常被声明为void。一般来讲,与WebRequest或java.util.Local结合的WebDataBinder入参,允许在代码中注册特定context的编辑器。

       下面的例子展示了使用@InitBinder来为所有java.util.Data表单属性配置一个CustomDataEditor。

       在Spring4.2中,可以考虑使用addCustomFormatter来定义Formatter实现,来代替使用PropertyEditor实例。同时,当你在一个共享的FormattingConversionService中存在一个基于Formatter的组织结构时,这也是特别有用的,稍微调整一下绑定规则就可在特定controller中以同样的方式进行复用。

@Controller
public class MyFormController {
 
    @InitBinder
    public void initBinder(WebDataBinder binder) {
        binder.addCustomFormatter(new DateFormatter("yyyy-MM-dd"));
    }
 
    // ...
}
 

 

配置一个自定义的WebBindingInitializer

       为了实现绑定的初始化,你能够通过实现WebBindingInitializer接口来自定义它。之后,需要为AnnotationMethodHandlerAdapter提供一个自定的bean配置,因此,需要覆写配置文档中默认的配置。

       下面的例子来自于PetClinic应用,这个配置例子自定义实现了WebBindingInitializer接口,还有在PetClinic应用中,配置了PropertyEditors的controller所需的org.springframework.samples.petclinic.web.ClinicBindingInitialzier。

<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
    <property name="cacheSeconds" value="0"/>
    <property name="webBindingInitializer">
        <bean class="org.springframework.samples.petclinic.web.ClinicBindingInitializer"/>
    </property>
</bean>

       在@ControllerAdvice注解了的类中也能定义@InitBinder方法来匹配对应的controller。这种定义的方法使用了WebBindingInitializer的另一种方式。详见”使用@ControllerAdvice对controller做横切通知”。

 

使用@ControllerAdvice对controller做advice(横切通知)

       @ControllerAdvice的实现类能够通过classpath扫描自动检测到。当使用MVC 命名空间或 MVC  java配置时,这是被自动启用的。

       注解了@ControllerAdvice的类可以包含@ExceptionHandler,@InitBinder和@ModelAttribute方法。这些方法能够应用到所有controller结构中的@RequestMapping方法上,而不单是在它所在的类中。

       @ControllerAdvice注解也能指定特定controller,这些controller可以带有它的属性:

// 指定所有注释了@RestController的controller
@ControllerAdvice(annotations = RestController.class)
public class AnnotationAdvice {}
 
// 指定特定包下的所有controller
@ControllerAdvice("org.example.controllers")
public class BasePackageAdvice {}
 
// 指定所有可指定的特定类
@ControllerAdvice(assignableTypes = {ControllerInterface.class, AbstractController.class})
public class AssignableTypesAdvice {}

       详见@ControllerAdvice的说明文档

 

Jackson 序列化视图的支持

       有些时候,过滤那些要在HTTP响应主体中被序列化的context化的对象是很有用的。为了提供这种功能,Spring MVC内置了对使用Jackson’s  Serialization View渲染的支持。

       当与@ResponseBody的controller方法或返回了ResponseEntity的controller方法配合使用时,可以添加@JsonView,这个@JsonView里带有需要使用的视图类或接口的入参:

@RestController
public class UserController {
 
    @RequestMapping(path = "/user", method = RequestMethod.GET)
    @JsonView(User.WithoutPasswordView.class)
    public User getUser() {
        return new User("eric", "7!jd#h23");
    }
}
 
public class User {
 
    public interface WithoutPasswordView {};
    public interface WithPasswordView extends WithoutPasswordView {};
 
    private String username;
    private String password;
 
    public User() {
    }
 
    public User(String username, String password) {
        this.username = username;
        this.password = password;
    }
 
    @JsonView(WithoutPasswordView.class)
    public String getUsername() {
        return this.username;
    }
 
    @JsonView(WithPasswordView.class)
    public String getPassword() {
        return this.password;
    }
}

小提示:

         请注意,虽然@JsonView可以指定多个类,但是在controller方法上使用时只支持一个类的入参。如果需要启用多个视图类,可以指定其使用的接口来实现。


         对于依赖于视图解析的controller,可以在模型中添加这个序列化的视图类:

@Controller
public class UserController extends AbstractController {
 
    @RequestMapping(path = "/user", method = RequestMethod.GET)
    public String getUser(Model model) {
        model.addAttribute("user", new User("eric", "7!jd#h23"));
        model.addAttribute(JsonView.class.getName(), User.WithoutPasswordView.class);
        return "userView";
    }
}


Jackson JSONP支持

       为了在@ResponseBody方法和返回ResponseEntity的方法中启用JSONP的支持,可以声明继承了AbstractJsonpResponseBodyAdvice的@ControllerAdvice的bean,下面的例子展示了在这个构造器入参中,在何处指定JSONP的查询参数名。

@ControllerAdvice
public class JsonpAdvice extends AbstractJsonpResponseBodyAdvice {
 
    public JsonpAdvice() {
        super("callback");
    }
}

       对于依赖于视图解析的controller,当请求中存在命名为jsonp或callback的查询参数时,JSONP会自动启用,你也能够在jsonParameterNames属性中自定义这些命名。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值