SpringMVC @RequestBody Date類型的Json轉(zhuǎn)換方式
SpringMVC @RequestBody Date類型的Json轉(zhuǎn)換
正常使用Json或Gson對Date類型序列化成字符串時,得到的是類似”Dec 5, 2017 8:03:34 PM”這種形式的字符串,前端得到了這種格式的很難明白這個具體是什么時間,可讀性很低。
同時如果用這種形式的字符串來反序列化為Date對象,也會失敗,這個過程是不可逆的。如何將Date對象序列化為指定格式的字符串,比如”yyyy-MM-dd”格式的字符串,以Gson的使用為例來說明。
對于Gson對象,可以使用GsonBuilder來實例化
通過GsonBuilder設(shè)置DateFormat的格式
Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-dd HH:mm:ss").create();
經(jīng)過這樣設(shè)置后,使用toJson(Object obj)方法對Date對象序列化時,會輸出”yyyy-MM-dd HH:mm:ss”格式的字符串;
也可以將”yyyy-MM-dd HH:mm:ss”格式的字符串反序列化為一個Date對象。值得注意的是,當(dāng)一個Date對象未指定”HH:mm:ss”時,會使用當(dāng)前時間來填充以補齊格式長度。
以上講的是Date對象的序列化和反序列化為字符串的方法,在SpingMVC框架中并不適用,下面講SpringMVC中Date的序列化和反序列化。
SpringMVC中,如果前端以GET的形式傳遞字符串,后端想將此字符串反序列化為Date對象,最常用的就是注冊Formatter對象
以零配置框架為例
public class String2DateFormatter implements Formatter<Date> {
private static final String DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss";
private static final String DATE_FORMAT = "yyyy-MM-dd";
@Override
public String print(Date object, Locale locale) {
return new GsonBuilder().setDateFormat(DATE_TIME_FORMAT).create().toJson(object);
}
@Override
public Date parse(String text, Locale locale) throws ParseException {
if (text.length() > 10) {
return new SimpleDateFormat(DATE_TIME_FORMAT).parse(text);
} else {
return new SimpleDateFormat(DATE_FORMAT).parse(text);
}
}
}
public class MvcContextConfig extends WebMvcConfigurerAdapter {
......
@Override
public void addFormatters(FormatterRegistry registry) {
registry.addFormatter(new String2DateFormatter());
}
......
}
當(dāng)然也可以用配置文件的形式配置,具體方法請百度。
當(dāng)前端傳遞字符串,Controller用Date類型的參數(shù)接受時,會使用Formatter將字符串反序列化為Date對象。
如果前端以POST形式傳遞一個Json對象,對象內(nèi)部有一個Date屬性,前端傳遞的是字符串,后端用一個標識@RequestBody的復(fù)合對象接收時,F(xiàn)ormatter是不會起作用的。
此時起作用的是HttpMessageConverter的實現(xiàn)類。正常情況下項目內(nèi)有Jackson或Gson依賴,能夠?qū)son反序列化為復(fù)合對象。
如果依賴了Jackson,且使用Jackson的HttpMessageConverter反序列化Json,那么僅支持反序列化簡單數(shù)據(jù)類型的屬性,不支持Date類型;但是如果是Gson類型,是支持”yyyy-MM-dd HH:mm:ss”格式的反序列化的,確定不支持”yyyy-MM-dd”格式,其他格式不確定。
也就是說依賴Gson可以將前端的”yyyy-MM-dd HH:mm:ss”格式的字符串反序列化為Date對象,但是將Date對象返回給前端時,解析得到的還是類似”Dec 5, 2017 8:03:34 PM”這種形式的字符串,并不可取。
當(dāng)我們使用Jackson作為Json對象的序列化和反序列化的解析器時
以零配置形式框架下的代碼實現(xiàn)為例講解
public class MvcContextConfig extends WebMvcConfigurerAdapter {
......
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
StringHttpMessageConverter stringConverter = new StringHttpMessageConverter(Charset.forName("UTF-8"));
stringConverter.setWriteAcceptCharset(false);
converters.add(stringConverter);
converters.add(new ByteArrayHttpMessageConverter());
converters.add(new ResourceHttpMessageConverter());
converters.add(new MappingJackson2XmlHttpMessageConverter());
//設(shè)置Date類型使用HttpMessageConverter轉(zhuǎn)換后的格式,或者注冊一個GsonHttpMessageConverter,能直接支持字符串到日期的轉(zhuǎn)換
//當(dāng)指定了日期字符串格式后,如果傳的日志格式不符合,則會解析錯誤
converters.add(new MappingJackson2HttpMessageConverter(
new ObjectMapper().setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"))));
//GsonHttpMessageConverter不支持yyyy-MM-dd形式的字符串轉(zhuǎn)換為日期
//converters.add(new GsonHttpMessageConverter());
}
......
}
當(dāng)我們選擇使用Jackson作為Json的解析器時,需要注冊一個MappingJackson2HttpMessageConverter,對內(nèi)部默認的objectMapper對象做一個拓展,需要指定日期格式化器,當(dāng)我們指定了具體的格式時,只支持這種格式的轉(zhuǎn)換,其他的格式轉(zhuǎn)換時會報錯。
因此需要前端在傳遞日期字符串時,加上默認的時間,比如”2017-12-2 00:00:00”,雖然多了點工作,但是能確保格式轉(zhuǎn)換的正確。
當(dāng)然并不是一定要”yyyy-MM-dd HH:mm:ss”,其他的格式也都支持的,比如”yyyy-MM-dd”等等,具體可以看項目需求自定義,前端傳遞日期字符串的格式需要符合自定義的格式。
當(dāng)配置了DateFormat時,傳遞對象給前端,對象內(nèi)部有Date屬性,也會將其序列化為這個格式的字符串。
XML文件形式配置HttpMessageConverter的方法可自行百度。
@RequestBody接收json字符串,自動將日期字符串轉(zhuǎn)換為java.util.Date
1.配置springMVC可以接收json字符串
<?xml version="1.0" encoding="UTF-8"?>
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.1.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd">
<!-- 解決@ResponseBody返回中文亂碼,解決@RequestBody接收Json字符串自動轉(zhuǎn)換為實體、List、Map格式轉(zhuǎn)換器 -->
<bean
class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
<property name="messageConverters">
<list>
<!--
<bean
class="org.springframework.http.converter.StringHttpMessageConverter">
<property name="supportedMediaTypes">
<list>
<value>text/html;charset=UTF-8</value>
</list>
</property>
</bean>
-->
<bean
class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">
<property name="supportedMediaTypes">
<list>
<value>application/json;charset=UTF-8</value>
</list>
</property>
</bean>
</list>
</property>
</bean>
<!-- 掃描包,應(yīng)用Spring的注解 -->
<context:component-scan base-package="com.mvc.action"></context:component-scan>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"
p:viewClass="org.springframework.web.servlet.view.JstlView"
p:prefix="/"
p:suffix=".jsp">
</bean>
<!-- SpringMVC自定義攔截器,使SpringMVC開啟CORS支持 -->
<!--
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/*"/>
<bean class="com.mvc.dao.CorsInterceptor"></bean>
</mvc:interceptor>
</mvc:interceptors>
-->
<context:annotation-config/>
<mvc:annotation-driven/>
</beans>
2.@Controller類代碼
@RequestMapping(value="/addDicAppUsers.do")
@ResponseBody
public boolean addDicAppUsers(@RequestBody DicAppUsersModel dicAppUsersModel)
{
if(dicAppUsersService.addDicAppUsers(dicAppUsersModel))
{
return true;
}
else
{
return false;
}
}
3.實體類對象代碼
package com.mvc.model;
import java.util.Date;
import org.codehaus.jackson.map.annotate.JsonDeserialize;
import org.codehaus.jackson.map.annotate.JsonSerialize;
import com.mvc.imp.DateJsonDeserializer;
import com.mvc.imp.DateJsonSerializer;
/**
* 用戶視圖類
* @author suyunlong
*
*/
@SuppressWarnings("serial")
public class DicAppUsersModel implements java.io.Serializable
{
private long id;
private String loginid;
private String loginname;
private String loginpassword;
private String loginunitcode;
private String workplace;
@JsonSerialize(using=DateJsonSerializer.class)
@JsonDeserialize(using=DateJsonDeserializer.class)
private Date addtime;
private long sourceid;
@JsonSerialize(using=DateJsonSerializer.class)
@JsonDeserialize(using=DateJsonDeserializer.class)
private Date createdate;
public DicAppUsersModel() {
super();
}
public DicAppUsersModel(long id, String loginid, String loginname,
String loginpassword, String loginunitcode, String workplace,
Date addtime, long sourceid, Date createdate) {
super();
this.id = id;
this.loginid = loginid;
this.loginname = loginname;
this.loginpassword = loginpassword;
this.loginunitcode = loginunitcode;
this.workplace = workplace;
this.addtime = addtime;
this.sourceid = sourceid;
this.createdate = createdate;
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getLoginid() {
return loginid;
}
public void setLoginid(String loginid) {
this.loginid = loginid;
}
public String getLoginname() {
return loginname;
}
public void setLoginname(String loginname) {
this.loginname = loginname;
}
public String getLoginpassword() {
return loginpassword;
}
public void setLoginpassword(String loginpassword) {
this.loginpassword = loginpassword;
}
public String getLoginunitcode() {
return loginunitcode;
}
public void setLoginunitcode(String loginunitcode) {
this.loginunitcode = loginunitcode;
}
public String getWorkplace() {
return workplace;
}
public void setWorkplace(String workplace) {
this.workplace = workplace;
}
public Date getAddtime() {
return addtime;
}
public void setAddtime(Date addtime) {
this.addtime = addtime;
}
public long getSourceid() {
return sourceid;
}
public void setSourceid(long sourceid) {
this.sourceid = sourceid;
}
public Date getCreatedate() {
return createdate;
}
public void setCreatedate(Date createdate) {
this.createdate = createdate;
}
}
4.DateJsonSerializer類代碼
package com.mvc.imp;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.codehaus.jackson.JsonGenerator;
import org.codehaus.jackson.JsonProcessingException;
import org.codehaus.jackson.map.JsonSerializer;
import org.codehaus.jackson.map.SerializerProvider;
public class DateJsonSerializer extends JsonSerializer<Date>
{
public static final SimpleDateFormat format=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
public void serialize(Date date,JsonGenerator jsonGenerator,SerializerProvider serializerProvider)
throws IOException,JsonProcessingException
{
jsonGenerator.writeString(format.format(date));
}
}
5.DateJsonDeserializer類代碼
package com.mvc.imp;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.codehaus.jackson.JsonParser;
import org.codehaus.jackson.JsonProcessingException;
import org.codehaus.jackson.map.DeserializationContext;
import org.codehaus.jackson.map.JsonDeserializer;
public class DateJsonDeserializer extends JsonDeserializer<Date>
{
public static final SimpleDateFormat format=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
public Date deserialize(JsonParser jsonParser,DeserializationContext deserializationContext)
throws IOException,JsonProcessingException
{
try
{
return format.parse(jsonParser.getText());
}
catch(Exception e)
{
System.out.println(e.getMessage());
throw new RuntimeException(e);
}
}
}
這樣,就可以把接收到的json日期字符串轉(zhuǎn)換為Date了。后面,就可以直接通過Date類型保存日期數(shù)據(jù)了。
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
java實現(xiàn)微信公眾平臺自定義菜單的創(chuàng)建示例
這篇文章主要介紹了java實現(xiàn)微信公眾平臺自定義菜單的創(chuàng)建示例,需要的朋友可以參考下2014-04-04
Guava自動加載緩存LoadingCache使用實戰(zhàn)詳解
這篇文章主要為大家介紹了Guava自動加載緩存LoadingCache使用實戰(zhàn)詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-12-12
Java關(guān)鍵字this(動力節(jié)點Java學(xué)院整理)
java中的this隨處可見,用法也多。通常情況下理解this關(guān)鍵字還是很容易的,但是在我初學(xué)的時候,有一個疑問卻一直不能很清晰的理解,現(xiàn)在慢慢的理解了,下面通過本文給大家記錄下,有需要的朋友參考下2017-03-03
Java中的遞歸詳解(用遞歸實現(xiàn)99乘法表來講解)
這篇文章主要介紹了Java中的遞歸詳解(用遞歸實現(xiàn)99乘法表來講解),本文給出了普通的99乘法實現(xiàn)方法和用遞歸實現(xiàn)的方法,并對比它們的不同,體現(xiàn)出遞歸的運用及理解,需要的朋友可以參考下2015-03-03
SpringBoot使用Editor.md構(gòu)建Markdown富文本編輯器示例
這篇文章主要介紹了SpringBoot使用Editor.md構(gòu)建Markdown富文本編輯器示例,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-03-03

