如何使REST服务为Java 8(本地|偏移)DateTime(使用Swagger时)生成一个简单的字符串?

时间:2017-10-05 15:53:32

标签: java json java-8 swagger swagger-codegen

问题:当我们的REST服务返回带有日期/日期时间字段的对象时,这些字段被编码为JSON格式的复杂结构:

    ...
    "createdTimestamp": {
        "offset": {
            "totalSeconds": 0,
            "id": "Z",
            "rules": {
                "fixedOffset": true,
                "transitionRules": [],
                "transitions": []
            }
        },
        "nano": 257353000,
        "hour": 16,
        "minute": 5,
        "second": 25,
        "month": "OCTOBER",
        "year": 2017,
        "dayOfMonth": 5,
        "dayOfWeek": "THURSDAY",
        "dayOfYear": 278,
        "monthValue": 10
    },
    ...

我希望将这些时态数据类型序列化为一个简单的格式,如" 2017-10-05T16:05:25"。

该项目最初基于Java 7 API,java.util.Date在任何地方都使用过 - 而且它有效。当我切换到Java 8并开始使用新的java.time类时,除了将日期/时间对象序列化为JSON之外,一切都有效。

我知道我可以再次使用java.util.Date类型,但我更喜欢使用新的数据类型。

REST服务使用Swagger定义并使用Maven构建。使用swagger-codegen-maven-plugin,具有以下配置:

  • 插件版本:2.2.3
  • 语言:jaxrs-cxf-cdi
  • dateLibrary:java8

以下是其他相关库的版本(在POM中定义):

  • swagger-codegen:2.2.3
  • cxf-bundle-jaxrs:2.7.18
  • gson:2.8.1

我对REST服务很陌生(我直到最近才使用SOAP服务)。

我试图找到一种自定义序列化输出到JSON的方法,但没有成功。我发现OffsetDateTime应该是受支持的类型(关于序列化),应该很好地序列化。我还尝试配置Maven插件以使用Java库' java8-localdatetime'使用LocalDateTime类型 - 但它没有帮助 - LocalDateTime的序列化实例仍然被转换为复杂的JSON对象。

你可以帮我这个吗?感谢。

2 个答案:

答案 0 :(得分:0)

今天我遇到了同样的问题,我的方法是遵循从生成的ApiClient开始的依赖项:

private DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSZ");

// create a message converter for jackson using a prepared objectMapper
ObjectMapper mapper = objectMapper();
MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter(mapper);
rest = new RestTemplate();
// add the converter at first position to converter list of the rest template
rest.getMessageConverters().add(0, converter );

// finally create the ApiClient with the configured restTemplate
ApiClient defaultClient = new ApiClient(rest);



    public ObjectMapper objectMapper() {
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.findAndRegisterModules();
        JavaTimeModule module = new JavaTimeModule();

        module.addDeserializer(OffsetDateTime.class, new StdDeserializer<OffsetDateTime>(OffsetDateTime.class) {

            @Override
            public OffsetDateTime deserialize(JsonParser p, DeserializationContext ctxt)
                    throws IOException {
                return OffsetDateTime.parse(p.getText());
            }
        });
        module.addSerializer(OffsetDateTime.class, new StdSerializer<OffsetDateTime>(OffsetDateTime.class) {

            @Override
            public void serialize( OffsetDateTime value, JsonGenerator gen, SerializerProvider provider) throws IOException {
                gen.writeString( dtf.format( value ));
            }
        });
        // possible alternative to custom serializer if default format is sufficient
        //objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
        objectMapper.registerModule(module);
        return objectMapper;
    }

使用的配置:

  1. swagger-codegen-cli-3.0.14.jar -l java --library resttemplate

  2. config.json“ dateLibrary”:“ java8”中的选项(创建OffsetDateTime 在客户代码中)

  3. Jackson版本2.10.2

Maven依赖项:

<dependency>
    <groupId>com.fasterxml.jackson.datatype</groupId>
    <artifactId>jackson-datatype-jdk8</artifactId>
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.datatype</groupId>
    <artifactId>jackson-datatype-jsr310</artifactId>
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
</dependency>

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-core</artifactId>
</dependency>   

另请参阅:

答案 1 :(得分:0)

一个简单的答案是编写一个类,该类将是您的REST服务的返回值,如下所示:

public class MyDto {
    ZonedDateTime time = ZonedDateTime.now();

    @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSZ")
    public ZonedDateTime getTime() {
        return time;
    }

有关此问题的详细信息,请参见:Spring Data JPA - ZonedDateTime format for json serialization