SpringMVC Databinding(数据绑定)

转载请注明出处:http://www.jianshu.com/p/eda34afd9b8a

该文是基于Spring 4.2.3.RELEASE版本展开的

图片来自网络

在使用SpringMVC时,从页面传来的字面值要转换为相应格式的属性值,对于String,Integer等最基本的类型,Spring可以自动转换,但是对于像Date这种较为复杂的类型转换,就没有那么容易了。

在Controller中定义如下方法接收页面请求:

@RequestMapping("test")
@ResponseBody
public String test(Date date){
    return date.toString();
}

如果在页面访问,http://localhost:8080/test?date=2015-02-04 20:40:38 会报400错误,后台会抛异常:Failed to convert value of type 'java.lang.String' to required type 'java.util.Date'; 这是因为Spring没有默认实现String字面值到Date的转化。

对于上述通过url或者由表单传过来的数据,后台若想成功接收,方法有如下几种:

1.在Controller中自定义initBinder

@InitBinder("date") //注意,这里的date需要与请求中的参数名相同
protected void initBinder(WebDataBinder binder){
    binder.registerCustomEditor(Date.class, new CustomDateEditor(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"),true));
}

说明:这种方法每次只能处理一个参数,若要处理多个参数,则要写多个,并不灵活

2.自定义Converter或Formatter

自定义DateConverter类

public class DateConverter implements Converter<String, Date> {
      private SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    @Override
    public Date convert(String source) {  
        try {
            return simpleDateFormat.parse(source);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }
}

在xml中引入上述Converter

<bean id="date-converter" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
        <property name="formatters">
            <set>
                <bean class="young.test.formatter.DateFormatter" />
            </set>
        </property>
</bean>

annotation-driven中引用

<mvc:annotation-driven conversion-service="date-converter"/>

说明:这种方法是全局的设置,对所有的**@RequestParam 或 @ModelAttribute**的Date类型的绑定都有效

3.使用注解@DateTimeFormat

引入joda包

<dependency>
    <groupId>joda-time</groupId>
    <artifactId>joda-time</artifactId>
    <version>2.9</version>
</dependency>

使用注解修饰相应参数

@RequestMapping("test")
@ResponseBody
public String test(@RequestParam(name = "date") @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") Date date1){
        return date1.toString();
}
但是通过request body传过来的数据,无法运用上述方法转换

定义如下类:

public class User {

    private String name;
    
    private Integer age;
    
   // @JsonDeserialize(using = DateDeserializer.class)
    private Date birthday;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public Date getBirthday() {
        return birthday;
    }

    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }

    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", birthday=" + birthday +
                '}';
    }
}

Controller:

@RequestMapping(value = "user", method = RequestMethod.POST)
@ResponseBody
public String test2(@RequestBody User user){
    return user.toString();
}

直接post请求,后台会报birthday字段转换错误,对于这种类型的参数绑定,一般有如下两种处理方法:

1.自定义DateDeserializer

public class DateDeserializer extends JsonDeserializer<Date> {
    private static final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    @Override
    public Date deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException {
        String str = jp.getText().trim();
        try {
            return dateFormat.parse(str);
        } catch (ParseException e) {

        }
        return ctxt.parseDate(str);
    }
}

使用@JsonDeserialize(using = DateDeserializer.class)注释相应字段或参数

2.覆盖objectMapper的dateFormat

<mvc:annotation-driven>
        <mvc:message-converters>
            <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
                <property name="objectMapper">
                    <bean class="com.fasterxml.jackson.databind.ObjectMapper">
                        <property name="dateFormat">
                            <bean class="java.text.SimpleDateFormat">
                                <constructor-arg type="java.lang.String" value="yyyy-MM-dd HH:mm:ss"/>
                            </bean>
                        </property>
                    </bean>

                </property>
            </bean>
        </mvc:message-converters>
    </mvc:annotation-driven>

以上两种方法解决了request body中数据的绑定问题

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 136,338评论 19 139
  • Spring Boot 参考指南 介绍 转载自:https://www.gitbook.com/book/qbgb...
    毛宇鹏阅读 47,232评论 6 342
  • 1、Spring MVC请求流程 (1)初始化:(对DispatcherServlet和ContextLoderL...
    拾壹北阅读 2,006评论 0 12
  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 33,956评论 18 399
  • 今早起来,把儿子这两天做得好的和不好的列到小黑板上,以至提醒儿子 自省文 今天下午下起了大雨,儿子没法去锻练,老公...
    噜小噜阅读 309评论 2 5

友情链接更多精彩内容