SpringMVC @RequestBody Date类型的Json转换
正常使用Json或Gson对Date类型序列化成字符串时,得到的是类似”Dec 5, 2017 8:03:34 PM”这种形式的字符串,前端得到了这种格式的很难明白这个具体是什么时间,可读性很低。
同时如果用这种形式的字符串来反序列化为Date对象,也会失败,这个过程是不可逆的。如何将Date对象序列化为指定格式的字符串,比如”yyyy-MM-dd”格式的字符串,以Gson的使用为例来说明。
对于Gson对象,可以使用GsonBuilder来实例化
通过GsonBuilder设置DateFormat的格式
1
|
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对象
以零配置框架为例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
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对象的序列化和反序列化的解析器时
以零配置形式框架下的代码实现为例讲解
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
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字符串
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
|
<? 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类代码
1
2
3
4
5
6
7
8
9
10
11
12
13
|
@RequestMapping (value= "/addDicAppUsers.do" )
@ResponseBody
public boolean addDicAppUsers( @RequestBody DicAppUsersModel dicAppUsersModel)
{
if (dicAppUsersService.addDicAppUsers(dicAppUsersModel))
{
return true ;
}
else
{
return false ;
}
}
|
3.实体类对象代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
|
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类代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
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类代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
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类型保存日期数据了。
以上为个人经验,希望能给大家一个参考,也希望大家多多支持服务器之家。
原文链接:https://jiangjibo.blog.csdn.net/article/details/78724737