柯桥增值式服务
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

186 lignes
8.0KB

  1. package com.ningdatech.kqapi.common.converter;
  2. import com.fasterxml.jackson.annotation.JsonFormat;
  3. import com.fasterxml.jackson.core.JsonParser;
  4. import com.fasterxml.jackson.core.JsonToken;
  5. import com.fasterxml.jackson.core.JsonTokenId;
  6. import com.fasterxml.jackson.databind.DeserializationContext;
  7. import com.fasterxml.jackson.databind.DeserializationFeature;
  8. import com.fasterxml.jackson.datatype.jsr310.deser.JSR310DateTimeDeserializerBase;
  9. import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
  10. import java.io.IOException;
  11. import java.time.*;
  12. import java.time.format.DateTimeFormatter;
  13. import static com.ningdatech.kqapi.common.util.NdDateUtils.*;
  14. /**
  15. * 字段类型是LocalDateTime时,可以按照以下6种格式反序列化:
  16. * 1. yyyy-MM-dd
  17. * 2. yyyy年MM月dd日
  18. * 3. yyyy/MM/dd
  19. * 4. yyyy-MM-dd HH:mm:ss
  20. * 5. yyyy年MM月dd日HH时mm分ss秒
  21. * 6. yyyy/MM/dd HH:mm:ss
  22. *
  23. * @author WendyYang
  24. * @date 2020/6/18 上午10:50
  25. */
  26. @SuppressWarnings("ALL")
  27. public class NdLocalDateTimeDeserializer extends JSR310DateTimeDeserializerBase<LocalDateTime> {
  28. public static final NdLocalDateTimeDeserializer INSTANCE = new NdLocalDateTimeDeserializer();
  29. private static final long serialVersionUID = 1L;
  30. private static final DateTimeFormatter DEFAULT_FORMATTER = DateTimeFormatter.ISO_LOCAL_DATE_TIME;
  31. /**
  32. * 以下是支持的6种参数格式
  33. */
  34. private static final DateTimeFormatter DEFAULT_DATE_FORMAT_DTF = DateTimeFormatter.ofPattern(DEFAULT_DATE_FORMAT);
  35. private static final DateTimeFormatter DEFAULT_DATE_FORMAT_EN_DTF = DateTimeFormatter.ofPattern(DEFAULT_DATE_FORMAT_EN);
  36. private static final DateTimeFormatter SLASH_DATE_FORMAT_DTF = DateTimeFormatter.ofPattern(SLASH_DATE_FORMAT);
  37. private static final DateTimeFormatter DEFAULT_DATE_TIME_FORMAT_DTF = DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_FORMAT);
  38. private static final DateTimeFormatter DEFAULT_DATE_TIME_FORMAT_EN_DTF = DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_FORMAT_EN);
  39. private static final DateTimeFormatter SLASH_DATE_TIME_FORMAT_DTF = DateTimeFormatter.ofPattern(SLASH_DATE_TIME_FORMAT);
  40. @Override
  41. protected JSR310DateTimeDeserializerBase<LocalDateTime> withShape(JsonFormat.Shape shape) {
  42. return this;
  43. }
  44. private NdLocalDateTimeDeserializer() {
  45. this(DEFAULT_FORMATTER);
  46. }
  47. public NdLocalDateTimeDeserializer(DateTimeFormatter formatter) {
  48. super(LocalDateTime.class, formatter);
  49. }
  50. protected NdLocalDateTimeDeserializer(NdLocalDateTimeDeserializer base, Boolean leniency) {
  51. super(base, leniency);
  52. }
  53. @Override
  54. protected NdLocalDateTimeDeserializer withLeniency(Boolean leniency) {
  55. return new NdLocalDateTimeDeserializer(this, leniency);
  56. }
  57. @Override
  58. protected JSR310DateTimeDeserializerBase<LocalDateTime> withDateFormat(DateTimeFormatter formatter) {
  59. return new LocalDateTimeDeserializer(formatter);
  60. }
  61. private LocalDateTime convert(String source) {
  62. if (source.matches(DEFAULT_DATE_FORMAT_MATCHES)) {
  63. return LocalDateTime.of(LocalDate.parse(source, DEFAULT_DATE_FORMAT_DTF), LocalTime.MIN);
  64. }
  65. if (source.matches(DEFAULT_DATE_FORMAT_EN_MATCHES)) {
  66. return LocalDateTime.of(LocalDate.parse(source, DEFAULT_DATE_FORMAT_EN_DTF), LocalTime.MIN);
  67. }
  68. if (source.matches(SLASH_DATE_FORMAT_MATCHES)) {
  69. return LocalDateTime.of(LocalDate.parse(source, SLASH_DATE_FORMAT_DTF), LocalTime.MIN);
  70. }
  71. if (source.matches(DEFAULT_DATE_TIME_FORMAT_MATCHES)) {
  72. return LocalDateTime.parse(source, DEFAULT_DATE_TIME_FORMAT_DTF);
  73. }
  74. if (source.matches(DEFAULT_DATE_TIME_FORMAT_EN_MATCHES)) {
  75. return LocalDateTime.parse(source, DEFAULT_DATE_TIME_FORMAT_EN_DTF);
  76. }
  77. if (source.matches(SLASH_DATE_TIME_FORMAT_MATCHES)) {
  78. return LocalDateTime.parse(source, SLASH_DATE_TIME_FORMAT_DTF);
  79. }
  80. return null;
  81. }
  82. @Override
  83. public LocalDateTime deserialize(JsonParser parser, DeserializationContext context) throws IOException {
  84. // 字符串
  85. if (parser.hasTokenId(JsonTokenId.ID_STRING)) {
  86. String string = parser.getText().trim();
  87. if (string.length() == 0) {
  88. return null;
  89. }
  90. try {
  91. if (_formatter == null) {
  92. return convert(string);
  93. }
  94. if (_formatter == DEFAULT_FORMATTER) {
  95. // JavaScript by default includes time and zone in JSON serialized Dates (UTC/ISO instant format).
  96. if (string.length() > 10 && string.charAt(10) == 'T') {
  97. if (string.endsWith("Z")) {
  98. return LocalDateTime.ofInstant(Instant.parse(string), ZoneOffset.UTC);
  99. } else {
  100. return LocalDateTime.parse(string, DEFAULT_FORMATTER);
  101. }
  102. }
  103. return convert(string);
  104. }
  105. return LocalDateTime.parse(string, this._formatter);
  106. } catch (DateTimeException e) {
  107. return _handleDateTimeException(context, e, string);
  108. }
  109. }
  110. // 数组
  111. if (parser.isExpectedStartArrayToken()) {
  112. JsonToken t = parser.nextToken();
  113. if (t == JsonToken.END_ARRAY) {
  114. return null;
  115. }
  116. if ((t == JsonToken.VALUE_STRING || t == JsonToken.VALUE_EMBEDDED_OBJECT)
  117. && context.isEnabled(DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS)) {
  118. final LocalDateTime parsed = deserialize(parser, context);
  119. if (parser.nextToken() != JsonToken.END_ARRAY) {
  120. handleMissingEndArrayForSingle(parser, context);
  121. }
  122. return parsed;
  123. }
  124. if (t == JsonToken.VALUE_NUMBER_INT) {
  125. LocalDateTime result;
  126. int year = parser.getIntValue();
  127. int month = parser.nextIntValue(-1);
  128. int day = parser.nextIntValue(-1);
  129. int hour = parser.nextIntValue(-1);
  130. int minute = parser.nextIntValue(-1);
  131. t = parser.nextToken();
  132. if (t == JsonToken.END_ARRAY) {
  133. result = LocalDateTime.of(year, month, day, hour, minute);
  134. } else {
  135. int second = parser.getIntValue();
  136. t = parser.nextToken();
  137. if (t == JsonToken.END_ARRAY) {
  138. result = LocalDateTime.of(year, month, day, hour, minute, second);
  139. } else {
  140. int partialSecond = parser.getIntValue();
  141. if (partialSecond < 1_000 &&
  142. !context.isEnabled(DeserializationFeature.READ_DATE_TIMESTAMPS_AS_NANOSECONDS)) {
  143. // value is milliseconds, convert it to nanoseconds
  144. partialSecond *= 1_000_000;
  145. }
  146. if (parser.nextToken() != JsonToken.END_ARRAY) {
  147. throw context.wrongTokenException(parser, handledType(), JsonToken.END_ARRAY, "Expected array to end");
  148. }
  149. result = LocalDateTime.of(year, month, day, hour, minute, second, partialSecond);
  150. }
  151. }
  152. return result;
  153. }
  154. context.reportInputMismatch(handledType(), "Unexpected token (%s) within Array, expected VALUE_NUMBER_INT", t);
  155. }
  156. // 数字
  157. if (parser.hasToken(JsonToken.VALUE_NUMBER_INT)) {
  158. return Instant.ofEpochMilli(parser.getLongValue()).atZone(ZoneOffset.ofHours(8)).toLocalDateTime();
  159. }
  160. // 没看懂这个是啥
  161. if (parser.hasToken(JsonToken.VALUE_EMBEDDED_OBJECT)) {
  162. return (LocalDateTime) parser.getEmbeddedObject();
  163. }
  164. return _handleUnexpectedToken(context, parser, "当前参数需要数组、字符串、时间戳。");
  165. }
  166. }