SpringMVC @RequestBody Date类型的Json转换方式
springmvc @requestbody date类型的json转换
正常使用json或gson对date类型序列化成字符串时,得到的是类似”dec 5, 2017 8:03:34 pm”这种形式的字符串,前端得到了这种格式的很难明白这个具体是什么时间,可读性很低。
同时如果用这种形式的字符串来反序列化为date对象,也会失败,这个过程是不可逆的。如何将date对象序列化为指定格式的字符串,比如”yyyy-mm-dd”格式的字符串,以gson的使用为例来说明。
对于gson对象,可以使用gsonbuilder来实例化
通过gsonbuilder设置dateformat的格式
gson gson = new gsonbuilder().setdateformat("yyyy-mm-dd hh:mm:ss").create();
经过这样设置后,使用tojson(object obj)方法对date对象序列化时,会输出”yyyy-mm-dd hh:mm:ss”格式的字符串;
也可以将”yyyy-mm-dd hh:mm:ss”格式的字符串反序列化为一个date对象。值得注意的是,当一个date对象未指定”hh:mm:ss”时,会使用当前时间来填充以补齐格式长度。
以上讲的是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()); } ...... }
当然也可以用配置文件的形式配置,具体方法请百度。
当前端传递字符串,controller用date类型的参数接受时,会使用formatter将字符串反序列化为date对象。
如果前端以post形式传递一个json对象,对象内部有一个date属性,前端传递的是字符串,后端用一个标识@requestbody的复合对象接收时,formatter是不会起作用的。
此时起作用的是httpmessageconverter的实现类。正常情况下项目内有jackson或gson依赖,能够将json反序列化为复合对象。
如果依赖了jackson,且使用jackson的httpmessageconverter反序列化json,那么仅支持反序列化简单数据类型的属性,不支持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”这种形式的字符串,并不可取。
当我们使用jackson作为json对象的序列化和反序列化的解析器时
以零配置形式框架下的代码实现为例讲解
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()); //设置date类型使用httpmessageconverter转换后的格式,或者注册一个gsonhttpmessageconverter,能直接支持字符串到日期的转换 //当指定了日期字符串格式后,如果传的日志格式不符合,则会解析错误 converters.add(new mappingjackson2httpmessageconverter( new objectmapper().setdateformat(new simpledateformat("yyyy-mm-dd hh:mm:ss")))); //gsonhttpmessageconverter不支持yyyy-mm-dd形式的字符串转换为日期 //converters.add(new gsonhttpmessageconverter()); } ...... }
当我们选择使用jackson作为json的解析器时,需要注册一个mappingjackson2httpmessageconverter,对内部默认的objectmapper对象做一个拓展,需要指定日期格式化器,当我们指定了具体的格式时,只支持这种格式的转换,其他的格式转换时会报错。
因此需要前端在传递日期字符串时,加上默认的时间,比如”2017-12-2 00:00:00”,虽然多了点工作,但是能确保格式转换的正确。
当然并不是一定要”yyyy-mm-dd hh:mm:ss”,其他的格式也都支持的,比如”yyyy-mm-dd”等等,具体可以看项目需求自定义,前端传递日期字符串的格式需要符合自定义的格式。
当配置了dateformat时,传递对象给前端,对象内部有date属性,也会将其序列化为这个格式的字符串。
xml文件形式配置httpmessageconverter的方法可自行百度。
@requestbody接收json字符串,自动将日期字符串转换为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字符串自动转换为实体、list、map格式转换器 --> <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> <!-- 扫描包,应用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日期字符串转换为date了。后面,就可以直接通过date类型保存日期数据了。
以上为个人经验,希望能给大家一个参考,也希望大家多多支持。
推荐阅读
-
springmvc 获取@Requestbody转换的异常处理方式
-
spring boot @ResponseBody转换JSON 时 Date 类型处理方法,Jackson和FastJson两种方式。
-
SpringMVC @RequestBody Date类型的Json转换方式
-
SpringMVC修改返回值类型后的消息转换器处理方式
-
Java将Date日期类型字段转换成json字符串的方法
-
springmvc 获取@Requestbody转换的异常处理方式
-
spring boot @ResponseBody转换JSON 时 Date 类型处理方法,Jackson和FastJson两种方式。
-
SpringMVC修改返回值类型后的消息转换器处理方式
-
SpringMVC @RequestBody Date类型的Json转换方式