जैक्सन JSON प्रोसेसर के साथ Joda DateTime को कैसे अनुक्रमित करें?


118

एक साधारण पैटर्न (जैसे "dd-MM-yyyy") के अनुसार मैं अपने Joda DateTime वस्तु को क्रमबद्ध करने के लिए जैक्सन कैसे प्राप्त करूं?

मैंने कोशिश की:

@JsonSerialize(using=DateTimeSerializer.class)
private final DateTime date;

मैंने भी कोशिश की है:

ObjectMapper mapper = new ObjectMapper()
    .getSerializationConfig()
    .setDateFormat(df);

धन्यवाद!


उपरोक्त दोनों को वास्तव में भी काम करना चाहिए (@JsonSerialize का अर्थ यह होना चाहिए कि फ़ील्ड को क्रमबद्ध किया जाना है; और दिनांक प्रारूप भी आदर्श रूप से Joda पर लागू होना चाहिए), इसलिए आप jira.codehaus.org/rowrowse/JACKSON पर Jira बग दर्ज कर सकते हैं ।
स्टेक्समैन

मुझे एहसास है कि यह सवाल थोड़ी देर से है, लेकिन भविष्य के संदर्भ के लिए, objectMapper.getSerializationConig ()। setDateFormat (df) अब पदावनत कर दिया गया है। objectMapper.setDateFormat (df) अब सुझाया गया है।
पैट्रिक

यह भी देखें stackoverflow.com/questions/27952472/...
Raedwald

जवाबों:


146

यह जैक्सन 2.0 और जोडा मॉड्यूल के साथ बहुत आसान हो गया है।

ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new JodaModule());

मावेन निर्भरता:

<dependency>
  <groupId>com.fasterxml.jackson.datatype</groupId>
  <artifactId>jackson-datatype-joda</artifactId>
  <version>2.1.1</version>
</dependency>  

कोड और प्रलेखन: https://github.com/FasterXML/jackson-datatype-joda

बायनेरिज़: http://repo1.maven.org/maven2/com/fasterxml/jackson/datatype/jackson-datatype-joda/


13
क्या आप इस पर विस्तार कर सकते हैं? यह कोड कहाँ जाता है और ObjectMapper उदाहरण का उपयोग कैसे किया जाता है?
पॉल

आपको जैक्सन के एपी और मावेन के उपयोग के संबंध में विशिष्ट प्रश्न पूछना चाहिए। कोड कहां जाता है यह इस बात पर निर्भर करता है कि आप किसी भी ढांचे का उपयोग करते हैं / आप अपने आवेदन को कैसे बूटस्ट्रैप करते हैं।
किम्बल

4
जब मैं यह जोड़ता हूं कि मुझे संकलित त्रुटि "असंगत प्रकार: JodaModule को मॉड्यूल में परिवर्तित नहीं किया जा सकता है" - विधि एक org.codehaus.jackson.map.Module की अपेक्षा करती है, लेकिन JodaModule के पास इसके उत्तराधिकार में नहीं है तो यह काम कैसे हो सकता है?
मार्टिन चार्ल्सवर्थ

4
होनहार लेकिन वर्तमान में लगभग बेकार है क्योंकि हम पार्स करने की तिथि प्रारूप को निर्दिष्ट नहीं कर सकते हैं :(
विंसेंट मिमौन-प्रेट जूल 15'14

10
आपको टाइमस्टैम्प ऑब्जेक्ट के रूप में क्रमांकन को अक्षम करने की आवश्यकता है। Mapper.disable (सीरियललाइज़ेशन फ़ीचर .RITE_DATES_AS_TIMESTAMPS);
मारेकएम

74

ऑब्जेक्ट में आप मैपिंग कर रहे हैं:

@JsonSerialize(using = CustomDateSerializer.class)
public DateTime getDate() { ... }

CustomDateSerializer में:

public class CustomDateSerializer extends JsonSerializer<DateTime> {

    private static DateTimeFormatter formatter = 
        DateTimeFormat.forPattern("dd-MM-yyyy");

    @Override
    public void serialize(DateTime value, JsonGenerator gen, 
                          SerializerProvider arg2)
        throws IOException, JsonProcessingException {

        gen.writeString(formatter.print(value));
    }
}

4
CustomDateSerializer को स्प्रिंग mvc 3 में कैसे पंजीकृत करें?
digz6666

1
मैं स्प्रिंग एमवीसी 3 के बारे में नहीं जानता, लेकिन आप जैक्सन मैपर ऑब्जेक्ट के लिए एक कस्टम धारावाहिक जोड़ सकते हैं। जैक्सन में इस प्रविष्टि को देखें। आपको उस SimpleModule isoDateTimeModule = नए SimpleModule ("ISODateTimeModule", नए संस्करण (1, 0, 0, null) के लिए एक सरल मॉड्यूल बनाने की आवश्यकता है; isoDateTimeModule.addSerializer (नया JsonISODateTimeFormatSerializer ()); mapper.registerModule (isoDateTimeModule);
गिलाइम बेलरोज़

1
@ digz6666 स्प्रिंग एमवीसी 3 के लिए यहां मेरा जवाब देखें: stackoverflow.com/questions/7854030/…
अराम कोचरन

नोट - उपर्युक्त वर्गों का उपयोग करने के org.codehaus.jacksonबजाय सुनिश्चित करें com.fasterxml.jackson.core। दूसरे पैकेज का उपयोग करना मेरे लिए कारगर नहीं रहा। वास्तव में, मेरे जर्सी ऐप ने @JsonSerializedएनोटेशन का भी सम्मान नहीं किया ।
केविन मेरेडिथ

जवाब मेरे काम आया। लेकिन इसे सभी क्षेत्रों पर इस एनोटेशन की आवश्यकता होगी। क्या इसके लिए कुछ वैश्विक विन्यास है जो जैक्सन के साथ काम करता है?
ताहिर

26

जैसा कि @Kbleble ने कहा है कि जैक्सन 2 के साथ, डिफ़ॉल्ट स्वरूपण का उपयोग करना बहुत आसान है; बस JodaModuleअपने पर रजिस्टर करें ObjectMapper

ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new JodaModule());

कस्टम क्रमांकन / de- क्रमांकन के लिए DateTime, आपको अपना StdScalarSerializerऔर कार्यान्वित करने की आवश्यकता हैStdScalarDeserializer ; यह बहुत जटिल है, लेकिन वैसे भी।

उदाहरण के लिए, यहां एक DateTimeधारावाहिक है जो ISODateFormatUTC समय क्षेत्र के साथ उपयोग करता है :

public class DateTimeSerializer extends StdScalarSerializer<DateTime> {

    public DateTimeSerializer() {
        super(DateTime.class);
    }

    @Override
    public void serialize(DateTime dateTime,
                          JsonGenerator jsonGenerator,
                          SerializerProvider provider) throws IOException, JsonGenerationException {
        String dateTimeAsString = ISODateTimeFormat.withZoneUTC().print(dateTime);
        jsonGenerator.writeString(dateTimeAsString);
    }
}

और संबंधित डी-सीरियलाइज़र:

public class DateTimeDesrializer extends StdScalarDeserializer<DateTime> {

    public DateTimeDesrializer() {
        super(DateTime.class);
    }

    @Override
    public DateTime deserialize(JsonParser jsonParser,
                                DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
        try {
            JsonToken currentToken = jsonParser.getCurrentToken();
            if (currentToken == JsonToken.VALUE_STRING) {
                String dateTimeAsString = jsonParser.getText().trim();
                return ISODateTimeFormat.withZoneUTC().parseDateTime(dateTimeAsString);
            }
        } finally {
            throw deserializationContext.mappingException(getValueClass());
        }
    }

फिर एक मॉड्यूल के साथ एक साथ इन टाई:

public class DateTimeModule extends SimpleModule {

    public DateTimeModule() {
        super();
        addSerializer(DateTime.class, new DateTimeSerializer());
        addDeserializer(DateTime.class, new DateTimeDeserializer());
    }
}

फिर अपने पर मॉड्यूल रजिस्टर करें ObjectMapper:

ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new DateTimeModule());

deserilazed DatatIme ऑब्जेक्ट UTC टाइमज़ोन में है या फिर ब्राउज़र
टाइमज़ोन

क्या यह विश्व स्तर पर मैपर (और मॉड्यूल) को पंजीकृत करता है?
राफिन

16

आसान उपाय

मुझे इसी तरह की समस्या का सामना करना पड़ा है और मेरा समाधान ऊपर की तुलना में बहुत स्पष्ट है।

मैंने बस एनोटेशन में पैटर्न का उपयोग किया@JsonFormat

मूल रूप से मेरी कक्षा में एक DateTimeफ़ील्ड है, इसलिए मैंने गेट्टर के चारों ओर एक एनोटेशन रखा:

@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
public DateTime getDate() {
    return date;
}

मैं वर्ग को क्रमबद्ध करता हूं ObjectMapper

    ObjectMapper mapper = new ObjectMapper();
    mapper.registerModule(new JodaModule());
    mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
    ObjectWriter ow = mapper.writer();
    try {
        String logStr = ow.writeValueAsString(log);
        outLogger.info(logStr);
    } catch (IOException e) {
        logger.warn("JSON mapping exception", e);
    }

हम जैक्सन 2.5.4 का उपयोग करते हैं


15

https://stackoverflow.com/a/10835114/1113510

यद्यपि आप प्रत्येक दिनांक फ़ील्ड के लिए एनोटेशन लगा सकते हैं, अपने ऑब्जेक्ट मैपर के लिए वैश्विक कॉन्फ़िगरेशन करने के लिए बेहतर है। यदि आप जैकसन का उपयोग करते हैं तो आप अपने स्प्रिंग को निम्नानुसार कॉन्फ़िगर कर सकते हैं:

<bean id="jacksonObjectMapper" class="com.company.CustomObjectMapper" />

<bean id="jacksonSerializationConfig" class="org.codehaus.jackson.map.SerializationConfig"
    factory-bean="jacksonObjectMapper" factory-method="getSerializationConfig" >
</bean>

CustomObjectMapper के लिए:

public class CustomObjectMapper extends ObjectMapper {

    public CustomObjectMapper() {
        super();
        configure(Feature.WRITE_DATES_AS_TIMESTAMPS, false);
        setDateFormat(new SimpleDateFormat("EEE MMM dd yyyy HH:mm:ss 'GMT'ZZZ (z)"));
    }
}

बेशक, SimpleDateFormat आप की जरूरत है किसी भी प्रारूप का उपयोग कर सकते हैं।


4
setDateFormat(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssz"));मेरे लिए चाल
चली

8

इस बीच जब जैकोमॉड्यूल क्लासपाथ में होता है तो जैक्सन स्वचालित रूप से जोडा मॉड्यूल को पंजीकृत करता है। मैंने सिर्फ जेवन-डेटेटाइप-जोडा को मावेन में जोड़ा और यह तुरंत काम किया।

<dependency>
  <groupId>com.fasterxml.jackson.datatype</groupId>
  <artifactId>jackson-datatype-joda</artifactId>
  <version>2.8.7</version>
</dependency>

JSON आउटपुट:

{"created" : "2017-03-28T05:59:27.258Z"}

6

स्प्रिंग बूट वाले लोगों के लिए आपको अपने संदर्भ में मॉड्यूल जोड़ना होगा और इसे इस तरह आपके कॉन्फ़िगरेशन में जोड़ा जाएगा।

@Bean
public Module jodaTimeModule() {
    return new JodaModule();
}

और अगर आप नए java8 टाइम मॉड्यूल jsr-310 का उपयोग करना चाहते हैं।

@Bean
public Module jodaTimeModule() {
    return new JavaTimeModule();
}

3

ऐसा लगता है कि जैक्सन 1.9.12 के लिए डिफ़ॉल्ट रूप से ऐसी कोई संभावना नहीं है, क्योंकि:

public final static class DateTimeSerializer
    extends JodaSerializer<DateTime>
{
    public DateTimeSerializer() { super(DateTime.class); }

    @Override
    public void serialize(DateTime value, JsonGenerator jgen, SerializerProvider provider)
        throws IOException, JsonGenerationException
    {
        if (provider.isEnabled(SerializationConfig.Feature.WRITE_DATES_AS_TIMESTAMPS)) {
            jgen.writeNumber(value.getMillis());
        } else {
            jgen.writeString(value.toString());
        }
    }

    @Override
    public JsonNode getSchema(SerializerProvider provider, java.lang.reflect.Type typeHint)
    {
        return createSchemaNode(provider.isEnabled(SerializationConfig.Feature.WRITE_DATES_AS_TIMESTAMPS)
                ? "number" : "string", true);
    }
}

यह वर्ग जोडा डेटाइम की विधि (.String) का उपयोग करके डेटा को क्रमबद्ध करता है।

Rusty Kuntz द्वारा प्रस्तावित दृष्टिकोण मेरे मामले के लिए एकदम सही काम करता है।


आप अभी भी कस्टम सीरियलाइज़र और डिसेरिएलाइज़र को पंजीकृत कर सकते हैं, और उन पर डिफ़ॉल्ट कार्यान्वयन पर पूर्वता होगी।
StaxMan

2

मैं जावा 8 का उपयोग कर रहा हूं और यह मेरे लिए काम कर रहा है।

पर निर्भरता जोड़ें pom.xml

<dependency>
    <groupId>com.fasterxml.jackson.datatype</groupId>
    <artifactId>jackson-datatype-jsr310</artifactId>
    <version>2.4.0</version>
</dependency>

और अपने पर JodaModule जोड़ें ObjectMapper

ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new JodaModule());
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.