优点

无需修改字段类型,无需编写多余sql,无需修改之前代码逻辑

依赖

依赖了hutool工具包,如果不想依赖自己改写一下时间戳转换时间即可

1.新建一个注解

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
package org.jeecg.common.annotation;

import com.fasterxml.jackson.annotation.JacksonAnnotationsInside;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import org.jeecg.common.annotation.implement.ToDateStrDeserialize;
import org.jeecg.common.annotation.implement.ToDateStrSerialize;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
* @author Rui
* @Classname ToDateStr
* @Description
* @Date 2021/07/02 上午 09:57
* @Created by Rui
*/
@Target({ ElementType.FIELD })
@Retention(RetentionPolicy.RUNTIME)
@JacksonAnnotationsInside
@JsonSerialize(using = ToDateStrSerialize.class)
//如果只需要传给前端的时候转换,就把下面这行注释 然后跳过第三步
@JsonDeserialize(using = ToDateStrDeserialize.class)
public @interface ToDateStr {
//转为时间后的格式
String pattern() default "yyyy-MM-dd HH:mm:ss";
// 是否为秒级时间戳
boolean isSeconds() default true;
}

2.创建序列化时候要调用的类

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
package org.jeecg.common.annotation.implement;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Console;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.ser.ContextualSerializer;
import com.fasterxml.jackson.databind.ser.std.StdSerializer;
import org.jeecg.common.annotation.ToDateStr;

import java.io.IOException;

/**
* @Classname ToDataStr
* @Description
* @Date 2021/07/01 下午 03:51
* @Created by Rui
*/
public class ToDateStrSerialize extends StdSerializer<Object> implements ContextualSerializer {
private String pattern;
private boolean isSeconds;

public ToDateStrSerialize() {
super(Object.class);
}

public ToDateStrSerialize(String pattern, boolean isSeconds) {
super(Object.class);
this.pattern = pattern;
this.isSeconds = isSeconds;
}


@Override
public void serialize(Object value, JsonGenerator gen, SerializerProvider provider) throws IOException {
long timestamp = 0;
try {
String time = value.toString();
//秒级就乘以1000 因为DateUtil.date只支持毫秒级时间戳
if (isSeconds){
timestamp = Long.parseLong(time)*1000;
}else {
timestamp = Long.parseLong(time);
}
} catch (Exception e) {
Console.log("时间戳转换时间失败!");
e.printStackTrace();
gen.writeString(value.toString());
}
if (timestamp!=0){
// 时间戳转化为时间,再格式化为标准格式返回给前端
gen.writeString(DateUtil.format(DateUtil.date(timestamp), pattern));
}else {
gen.writeString(value.toString());
}
}

@Override
public JsonSerializer<?> createContextual(SerializerProvider prov, BeanProperty property) throws JsonMappingException {
ToDateStr ann = null;
if (property != null) {
ann = property.getAnnotation(ToDateStr.class);
}
if (ann != null) {
return new ToDateStrSerialize(ann.pattern(),ann.isSeconds());
}else {
return new ToDateStrSerialize();
}
}

}

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
101
102
103
104
105
106
107
108
109
110
import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateTime;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.JsonToken;
import com.fasterxml.jackson.databind.BeanProperty;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.deser.ContextualDeserializer;
import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.annotation.ToDateStr;
import org.jeecg.common.util.StringUtils;

import java.io.IOException;

/**
* @author Rui
* @Classname ToDateStrDeserialize
* @Description
* @Date 2021/09/26 下午 03:01
* @Created by Rui
*/

@Slf4j
public class ToDateStrDeserialize extends StdDeserializer<Number> implements ContextualDeserializer {
private String pattern;
private boolean isSeconds;
private Class<? extends Number> rowClass;

public ToDateStrDeserialize(Class<? extends Number> t) {
super(t);
}

public ToDateStrDeserialize() {
super(Number.class);
}

public ToDateStrDeserialize(String pattern, boolean isSeconds) {
super(Number.class);
this.pattern = pattern;
this.isSeconds = isSeconds;
}

public ToDateStrDeserialize(String pattern, boolean isSeconds, Class<? extends Number> rowClass) {
super(rowClass);
this.pattern = pattern;
this.isSeconds = isSeconds;
this.rowClass = rowClass;
}


@Override
public Number deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException {
JsonToken currentToken = p.getCurrentToken();
//如果前端传的是a='xx'这种字符串才转换为时间戳
if (currentToken.equals(JsonToken.VALUE_STRING)) {
String text = p.getText();
if (StringUtils.isBlank(text)) {
return null;
}
DateTime dateTime = null;
try {
//按照注解的配置转换为时间
dateTime = new DateTime(text, pattern);
} catch (Exception e) {
e.printStackTrace();
}
if (dateTime != null) {
//时间转换为时间戳
long time = dateTime.getTime();
if (isSeconds) {
return Convert.convert(rowClass, time / 1000);
}
return Convert.convert(rowClass, time);
} else {
return null;
}
} else if (currentToken.equals(JsonToken.VALUE_NUMBER_INT)) {
// 如果前端传的是数字类型
return Convert.convert(rowClass, p.getText());
}

throw new RuntimeException("Can't parse dateTime value: " + p.getText());
}

@Override
public JsonDeserializer<?> createContextual(DeserializationContext ctxt, BeanProperty property) throws JsonMappingException {
ToDateStr ann = null;
if (property != null) {
ann = property.getAnnotation(ToDateStr.class);
}
if (ann != null) {
Class<?> rawClass = property.getType().getRawClass();
if (Number.class.isAssignableFrom(rawClass)) {
return new ToDateStrDeserialize(ann.pattern(), ann.isSeconds(), (Class<? extends Number>) rawClass);
} else {
log.warn("错误!不支持将此类型[{}]转为Date", rawClass);
return null;
}
} else {
return new ToDateStrDeserialize();
}
}

}



4.使用

1
2
3
@ApiModelProperty(value = "服务器接收时间")
@ToDateStr(pattern = "yyyy-MM-dd HH:mm:ss",isSeconds = false)
private java.lang.Long serverReceptionTime;

引用

jackjson自定义注解
自定义 Jackson 注解与禁用某一特定的注解
Jackson 反序列化 “Y”/“N” 为相应的布尔值