用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類型時間戳問題的小李子就完成了


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM