首页 > 代码库 > 用springmvc的@RequestBody和@ResponseBody 接收和响应json格式数据

用springmvc的@RequestBody和@ResponseBody 接收和响应json格式数据

1.controller

@Controller
@RequestMapping("/rest/v1")
public class WelcomeController {
 @RequestMapping(value="/date/json/next",
            method=RequestMethod.POST,consumes="application/json"
            ,produces="application/json")
    @ResponseBody
    public DateTime getNextDateJson(@RequestBody DateTime date)
    {
        date.getNowDate().setTime(
                date.getNowDate().getTime());
        return date;
    }   
}

2.请求参数类和返回类DateTime(DateTime原本是用来测试返回时间格式的,这里犯懒请求和返回都用同一个类)

package com.cici.example.view.domain;

import java.sql.Timestamp;

import com.cici.utils.TimestampSerializer;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;

public class DateTime {
    String name;
    @JsonSerialize(using=TimestampSerializer.class)
    Timestamp nowDate;
    public Timestamp getNowDate() {
        return nowDate;
    }
    public void setNowDate(Timestamp nowDate) {
        this.nowDate = nowDate;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    
    
}

启动Tomcat然后用chrome的postman或者Firefox的httprequester发送json参数的post请求,请求参数如下

{
"nowDate":"2016-7-8T16:33:15.687",
"name":"cc"
}

如果这时候返回415 unsupport media type,有可能是下面两个原因(具体配置在 maven构建springmvc项目 中有配置)

1)messageConverters没有配置支持application/json类型

2)pom.xml没有配置Jackson的依赖(fasterxml或者haus包)

 

这时候nowDate的Timestamp类型springmvc是无法解析的,请求会返回400 bad request

因为我用的Jackson包是fasterxml的,所以有两种解决方式(如果用haus可能会有三种)

1)在DateTime.java类的nowDate属性上加上一句@DateTimeFormat(pattern = "yyyy-MM-dd‘T‘HH:mm:ss.SSSZ"),不过这种方式需要在每个类的每个timestamp类型的属性上都配置过一次,不推荐这种方法

2)自定义一个converter,这种方式只需要配置一次,推荐这种方式

DateConverter.java

package com.cici.utils;

import java.sql.Timestamp;

import org.springframework.core.convert.converter.Converter;

public class DateConverter implements Converter<String,Timestamp>{

    @Override
    public Timestamp convert(String date) {
        if(null != date)
        {
            return Timestamp.valueOf(date);         
        }
        return null;
    }
}

然后在dispatcher-servlet.xml配置

<!--这里是把conversion-service="conversionService"加到原来的annotation-driven-->
<mvc:annotation-driven conversion-service="conversionService"/>

<bean id="conversionService"
        class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
        <property name="converters">
            <list>
                <bean class="com.cici.utils.DateConverter" >
                </bean>
            </list>
        </property>
    </bean>

 

然鹅这时候response中的nowDate返回的还是long类型的时间戳,不是具体的时间,可以针对timestamp类型的属性写一个jsonserializer(这种方法需要每个属性都配置一次,但目前没找到更好的解决方法)

TimestampSerializer.java

技术分享
package com.cici.utils;

import java.io.IOException;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;

import com.cici.example.view.domain.DateTime;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;

/**
 * @author cc
 * 为每个类写一个serializer
 */
public class TimestampSerializer extends JsonSerializer<Timestamp>{

    @Override
    public void serialize(Timestamp dateTime, JsonGenerator generator,
            SerializerProvider provider) throws IOException,
            JsonProcessingException {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
        String dateTimeFormated = sdf.format(dateTime);
        generator.writeString(dateTimeFormated);
    }

}
View Code

然后在属性的getter方法上配置

@JsonSerialize(using=TimestampSerializer.class)
    Timestamp nowDate;
    public Timestamp getNowDate() {
        return nowDate;
    }

以上是踩到的两个坑

这个时候请求和返回如下

技术分享

用json做请求体和响应体顺便处理Date类型返回Long类型时间戳问题的小李子就完成了

用springmvc的@RequestBody和@ResponseBody 接收和响应json格式数据