【问题标题】:write regex in JsonFormat pattern以 JsonFormat 模式编写正则表达式
【发布时间】:2017-05-01 11:15:41
【问题描述】:
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern ="yyyy-MM-dd'T'HH:mm:ss.SSS")

是否可以在模式中编写正则表达式?我不能

pattern ="yyyy-MM-dd'T'HH:mm:ss.SSS(Z?)"

我想将 Z 设为可选

有什么链接建议吗?

【问题讨论】:

    标签: json spring


    【解决方案1】:

    我最终基于LocalDateDeserializer.INSTANCE 创建了自定义反序列化器并将正则表达式移到那里。

    在将反序列化器和对象映射器注册为自定义模块后,不再需要 @JsonFormat 注释:

        @Bean
        public ObjectMapper createObjectMapper() {
            return new ObjectMapper()
                  .configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false)
                  .registerModule(new JavaTimeModule())
                  .registerModule(new CustomTimeModule());
        }
    

    并在CustomTimeModule中定义了反序列化器

        class CustomTimeModule extends SimpleModule {
            public CustomTimeModule() {
                super();
                addDeserializer(LocalDate.class, CustomLocalDateDeserializer.INSTANCE);
            }
        }
    

    最后是正则表达式部分,在我的例子中是切割可选的非标准时区,我有时会在日期之后得到,但可以很容易地扩展以匹配你的情况:

            public class CustomLocalDateDeserializer extends JSR310DateTimeDeserializerBase<LocalDate> {
                private static final long serialVersionUID = 1L;
    
                private static final DateTimeFormatter DEFAULT_FORMATTER = DateTimeFormatter.ISO_LOCAL_DATE;
    
                public static final CustomLocalDateDeserializer INSTANCE = new CustomLocalDateDeserializer();
    
                private CustomLocalDateDeserializer() {
                    this(DEFAULT_FORMATTER);
                }
    
                public CustomLocalDateDeserializer(DateTimeFormatter dtf) {
                    super(LocalDate.class, dtf);
                }
    
                @Override
                protected JsonDeserializer<LocalDate> withDateFormat(DateTimeFormatter dtf) {
                    return new CustomLocalDateDeserializer(dtf);
                }
    
                @Override
                public LocalDate deserialize(JsonParser parser, DeserializationContext context) throws IOException
                {
                    if (parser.hasToken(JsonToken.VALUE_STRING)) {
                        String string = parser.getText().trim();
                        if (string.length() == 0) {
                            return null;
                        }
    
    
    
                        // >>>>>>> regex part comes here <<<<<<<
                        string = parser.getText().trim().substring(0, 10);
                        // >>>>>>> regex part comes here <<<<<<<
    
    
    
                        // as per [datatype-jsr310#37], only check for optional (and, incorrect...) time marker 'T'
                        // if we are using default formatter
                        try {
                            return LocalDate.parse(string, _formatter);
                        } catch (DateTimeException e) {
                            return _handleDateTimeException(context, e, string);
                        }
                    }
                    if (parser.isExpectedStartArrayToken()) {
                        JsonToken t = parser.nextToken();
                        if (t == JsonToken.END_ARRAY) {
                            return null;
                        }
                        if (context.isEnabled(DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS)
                                && (t == JsonToken.VALUE_STRING || t==JsonToken.VALUE_EMBEDDED_OBJECT)) {
                            final LocalDate parsed = deserialize(parser, context);
                            if (parser.nextToken() != JsonToken.END_ARRAY) {
                                handleMissingEndArrayForSingle(parser, context);
                            }
                            return parsed;
                        }
                        if (t == JsonToken.VALUE_NUMBER_INT) {
                            int year = parser.getIntValue();
                            int month = parser.nextIntValue(-1);
                            int day = parser.nextIntValue(-1);
    
                            if (parser.nextToken() != JsonToken.END_ARRAY) {
                                throw context.wrongTokenException(parser, handledType(), JsonToken.END_ARRAY,
                                        "Expected array to end");
                            }
                            return LocalDate.of(year, month, day);
                        }
                        context.reportInputMismatch(handledType(),
                                "Unexpected token (%s) within Array, expected VALUE_NUMBER_INT",
                                t);
                    }
                    if (parser.hasToken(JsonToken.VALUE_EMBEDDED_OBJECT)) {
                        return (LocalDate) parser.getEmbeddedObject();
                    }
                    // 06-Jan-2018, tatu: Is this actually safe? Do users expect such coercion?
                    if (parser.hasToken(JsonToken.VALUE_NUMBER_INT)) {
                        return LocalDate.ofEpochDay(parser.getLongValue());
                    }
                    return _handleUnexpectedToken(context, parser, "Expected array or string.");
                }
    
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-03-26
      • 1970-01-01
      • 2021-09-21
      • 2020-11-06
      • 1970-01-01
      • 2010-10-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多