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); } }
然后在属性的getter方法上配置
@JsonSerialize(using=TimestampSerializer.class) Timestamp nowDate; public Timestamp getNowDate() { return nowDate; }
以上是踩到的两个坑
这个时候请求和返回如下
用json做请求体和响应体顺便处理Date类型返回Long类型时间戳问题的小李子就完成了