Java 为什么杰克逊';s的默认反序列化程序是否将区域设置为UTC而不是Z?

Java 为什么杰克逊';s的默认反序列化程序是否将区域设置为UTC而不是Z?,java,json,jackson,zoneddatetime,Java,Json,Jackson,Zoneddatetime,我想我一定是误解了分区在java的ZoneDateTime类中是如何工作的。当我使用Jackson序列化然后立即反序列化()时,反序列化的值的getZone()==“UTC”而不是序列化值中的“Z”。谁能解释一下为什么会这样,我应该怎么做 下面的代码打印: {"t":"2017-11-24T18:00:08.425Z"} Data [t=2017-11-24T18:00:08.425Z] Data [t=2017-11-24T18:00:08.425Z[UTC]] Z UTC java源代码:

我想我一定是误解了分区在java的ZoneDateTime类中是如何工作的。当我使用Jackson序列化然后立即反序列化()时,反序列化的值的getZone()==“UTC”而不是序列化值中的“Z”。谁能解释一下为什么会这样,我应该怎么做

下面的代码打印:

{"t":"2017-11-24T18:00:08.425Z"}
Data [t=2017-11-24T18:00:08.425Z]
Data [t=2017-11-24T18:00:08.425Z[UTC]]
Z
UTC
java源代码:

<!-- language: java -->

package model;

import static org.junit.Assert.*;

import java.io.IOException;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;

import org.junit.Test;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;

public class ZonedDateTimeSerializationTest {

    static public class Data {
        @Override
        public String toString() {
            return "Data [t=" + t + "]";
        }

        public ZonedDateTime getT() {
            return t;
        }

        public void setT(ZonedDateTime t) {
            this.t = t;
        }

        ZonedDateTime t = ZonedDateTime.now(ZoneOffset.UTC);
    };

    @Test
    public void testDeSer() throws IOException {
        Data d = new Data();
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.findAndRegisterModules();
        String serialized = objectMapper.writer()
                .without(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
                .writeValueAsString(d);
        System.out.println(serialized);

        Data d2 = objectMapper.readValue(serialized, Data.class);
        System.out.println(d);
        System.out.println(d2);
        System.out.println(d.getT().getZone());
        System.out.println(d2.getT().getZone());

        // this fails
        assertEquals(d, d2);
    }
}

包装模型;
导入静态org.junit.Assert.*;
导入java.io.IOException;
导入java.time.ZoneOffset;
导入java.time.ZonedDateTime;
导入org.junit.Test;
导入com.fasterxml.jackson.core.JsonProcessingException;
导入com.fasterxml.jackson.databind.ObjectMapper;
导入com.fasterxml.jackson.databind.SerializationFeature;
公共类ZonedDateTimeSerializationTest{
静态公共类数据{
@凌驾
公共字符串toString(){
返回“数据[t=“+t+”]”;
}
公共分区DateTime getT(){
返回t;
}
公共无效设置(分区截止时间t){
t=t;
}
ZoneDateTime t=ZoneDateTime.now(ZoneOffset.UTC);
};
@试验
public void testdesr()引发IOException{
数据d=新数据();
ObjectMapper ObjectMapper=新的ObjectMapper();
objectMapper.findAndRegisterModules();
字符串序列化=objectMapper.writer()
.without(SerializationFeature.WRITE_DATES_作为时间戳)
.writeValueAsString(d);
System.out.println(序列化);
Data d2=objectMapper.readValue(序列化的Data.class);
系统输出打印ln(d);
系统输出打印项次(d2);
System.out.println(d.getT().getZone());
System.out.println(d2.getT().getZone());
//这失败了
资产质量(d、d2);
}
}

默认情况下,在反序列化
ZoneDateTime
期间,Jackson会将解析的时区调整为上下文提供的时区。您可以使用此设置修改此行为,以便解析的
zoneDateTime
将保持在
Z

objectMapper.disable(DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE);

更多细节

我这样做是为了保留时区:

mapper.enable(SerializationFeature.WRITE_DATES_WITH_ZONE_ID)
mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)

我相信
Z
来自
ZoneOffset.UTC
,而
UTC
来自
ZoneId.of(“UTC”)
ZoneOffset
ZoneId
的子类,因此
ZoneOffset
可以用作
ZoneId
)。这并不是回答你的问题…你问的原因是好奇(我也这么认为),或者其他原因?Ole V.V.-我的单元测试在一些简单的web服务调用中失败,这些调用需要ISO8601日期时间,我不明白为什么。哦-我在我的模型对象中使用IDE生成的equals(),它使用equals()而不是相等的。谢谢你!“上下文提供”,这是指JVM的时区设置和/或类似的设置吗?如果一个时区是“上下文提供的”,反序列化是否也可以将
ZonedDateTime
移动到另一个时区?只是好奇。附议。感谢you@OleV.V. “上下文提供”指由
反序列化上下文#getTimeZone()
返回的内容。时区默认为UTC,而不是JVM默认值。它可以通过
ObjectMapper#setTimeZone()
进行修改。