জ্যাকসন জেএসওএন প্রসেসরের সাথে জোদা ডেটটাইম সিরিয়ালাইজ করবেন কীভাবে?


118

আমি কীভাবে জ্যাকসনকে আমার জোদা ডেটটাইম অবজেক্টটি একটি সাধারণ প্যাটার্ন অনুসারে ("ডিডি-এমএম-ইয়াই" এর মতো) সিরিয়ালায়িত করতে পারি?

আমি চেষ্টা করেছিলাম:

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

আমি চেষ্টা করেছি:

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

ধন্যবাদ!


উপরের দু'টিই প্রকৃতপক্ষেও কাজ করা উচিত (@ জেসনসিরিয়েলাইজকে বোঝানো উচিত যে ক্ষেত্রটি সিরিয়াল করা উচিত; এবং তারিখের ফর্ম্যাটটিও আদর্শভাবে জোদার ক্ষেত্রে প্রয়োগ করা উচিত), তাই আপনি jira.codehaus.org/browse/JACKSON এ একটি জিরা বাগ ফাইল করতে পারেন ।
স্টেক্সম্যান

আমি বুঝতে পারি এই প্রশ্নটি কিছুক্ষণ আগেই এসেছে, তবে ভবিষ্যতের রেফারেন্সের জন্য অবজেক্টম্যাপার.সেটরিয়ালাইজেশন কনফিগ () .সেটডেটফর্ম্যাট (ডিএফ) এখন অবচয় করা হয়েছে। অবজেক্টম্যাপার.সেটডেটফর্ম্যাট (ডিএফ) এখন প্রস্তাবিত।
প্যাট্রিক

উত্তর:


146

এটি জ্যাকসন ২.০ এবং জোদা মডিউল দিয়ে খুব সহজ হয়ে গেছে।

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
আপনি কি এই উপর প্রসারিত করতে পারেন? এই কোডটি কোথায় যায় এবং কীভাবে অবজেক্টম্যাপার উদাহরণটি ব্যবহৃত হয়?
পল

আপনার জ্যাকসনের এপিআই এবং মাভেনের ব্যবহার সম্পর্কিত নির্দিষ্ট প্রশ্ন জিজ্ঞাসা করা উচিত। কোডটি কোথায় যায় তার উপর নির্ভর করে আপনি কোনও ফ্রেমওয়ার্ক ব্যবহার করেন কিনা / আপনি কীভাবে আপনার অ্যাপ্লিকেশনটিকে বুটস্ট্র্যাপ করেন।
কিম্বলে

4
যখন আমি যুক্ত করি যে আমি সংকলনের ত্রুটিটি পেয়েছি "বেমানান ধরণের: জোদামোডুল মডিউলটিতে রূপান্তর করা যায় না" - পদ্ধতিটি একটি org.codehaus.jackson.map.Module প্রত্যাশা করে তবে জোদামোডুলের এর উত্তরাধিকারসূত্রে এটি নেই তাই এই কাজটি কীভাবে সম্ভব?
মার্টিন চার্লসওয়ার্থ

4
প্রতিশ্রুতিবদ্ধ তবে বর্তমানে প্রায় অকেজো কারণ আমরা পার্স করার জন্য তারিখের ফর্ম্যাটটি নির্দিষ্ট করতে পারি না :(
ভিনসেন্ট মিমুন-প্রট

10
আপনাকে টাইমস্ট্যাম্পস অবজেক্টম্যাপার.ডিজিয়েবল (সিরিয়ালাইজেশন ফিচার। WRITE_DATES_AS_TIMESTAMPS) হিসাবে সিরিয়ালাইজেশন অক্ষম করতে হবে;
মারেকএম 11

74

বস্তুটিতে আপনি ম্যাপিং করছেন:

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

কাস্টমডেটরিশায়ালাইজারে:

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
কিভাবে বসন্ত এমভিসি 3 এ কাস্টমডেটশিরাইজার রেজিস্ট্রেশন করবেন?
digz6666

1
আমি স্প্রিং এমভিসি 3 সম্পর্কে জানি না, তবে আপনি জ্যাকসন ম্যাপার অবজেক্টে একটি কাস্টম সিরিয়ালাইজার যুক্ত করতে পারেন। জ্যাকসনে এই এন্ট্রিটি দেখুন আপনার সেই সিম্পলমডিউল isoDateTimeModule = নতুন সিম্পলমডুল ("ISODateTimeModule", নতুন সংস্করণ (1, 0, 0, নাল)) জন্য একটি সাধারণ মডিউল তৈরি করতে হবে; আইসোডেটটাইমমডিউল.এডিডিআরশায়ালাইজার (নতুন জসনআইসোডেটটাইমফর্ম্যাটর্মিয়াল ()); mapper.registerModule (isoDateTimeModule);
গিলিয়াম বেলরোজ

1
@ digz6666 স্প্রিং MVC 3 আমার উত্তর এখানে দেখুন: stackoverflow.com/questions/7854030/...
অরামের Kocharyan

দ্রষ্টব্য - নিশ্চিত করুন থেকে উপরে শ্রেণীর ব্যবহার করতে org.codehaus.jacksonবদলে com.fasterxml.jackson.core। দ্বিতীয় প্যাকেজটি ব্যবহার করা আমার পক্ষে কার্যকর হয়নি। আসলে, আমার জার্সির অ্যাপ্লিকেশন এমনকি @JsonSerializedটীকাটিকে সম্মান জানায় না ।
কেভিন মেরেডিথ

উত্তরটি আমার পক্ষে কাজ করেছিল। তবে এটি সমস্ত ক্ষেত্রে এই টিকা প্রয়োজন require জ্যাকসনের সাথে কাজ করে এমন কি কিছু বৈশ্বিক কনফিগারেশন রয়েছে?
তাহের

26

@ কিম্বল যেমন বলেছেন, জ্যাকসন ২-এর সাথে, ডিফল্ট বিন্যাসটি ব্যবহার করা খুব সহজ; কেবল JodaModuleআপনার উপর নিবন্ধন করুন ObjectMapper

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

কাস্টম সিরিয়ালাইজেশন / ডি-সিরিয়ালাইজেশনের জন্য DateTimeআপনাকে নিজের StdScalarSerializerএবং বাস্তবায়ন করতে হবে StdScalarDeserializer; এটি বেশ জটিল, তবে যাই হোক না কেন।

উদাহরণস্বরূপ, এখানে একটি DateTimeসিরিয়াল রয়েছে যা ISODateFormatইউটিসি সময় অঞ্চলটি ব্যবহার করে :

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());

ডিসিরিলেজড ডেটাটাইম অবজেক্টটি ইউটিসি টাইমজোন বা অন্য ব্রাউজারগুলির
টাইমজোনটিতে রয়েছে

এটি কী বিশ্বব্যাপী ম্যাপার (এবং মডিউলগুলি) নিবন্ধভুক্ত করে?
রাফিয়ান

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>

কাস্টমবজেক্টম্যাপারের জন্য:

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)"));
    }
}

অবশ্যই, সিম্পলডিটফর্ম্যাট আপনার প্রয়োজনীয় যে কোনও ফর্ম্যাট ব্যবহার করতে পারে।


4
setDateFormat(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssz"));আমার জন্য কৌতুকটি করেছিলেন,
THX

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();
}

এবং আপনি যদি নতুন জাভা 8 টাইম মডিউলটি ব্যবহার করতে চান তবে jsr-310।

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

3

দেখে মনে হচ্ছে জ্যাকসনের ১.৯.১২ এর জন্য ডিফল্টরূপে এমন কোনও সম্ভাবনা নেই, কারণ:

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);
    }
}

এই শ্রেণিটি জোডা ডেটটাইম-এর টু স্ট্রিং () পদ্ধতি ব্যবহার করে ডেটাটিকে সিরিয়ালাইজ করে।

রুস্টি কুন্তজের প্রস্তাবিত পদ্ধতির বিষয়টি আমার ক্ষেত্রে উপযুক্ত।


আপনি এখনও কাস্টম সিরিয়ালাইজার এবং ডিসরিওলাইজার নিবন্ধভুক্ত করতে পারেন এবং সেগুলি ডিফল্ট বাস্তবায়নের চেয়ে অগ্রাধিকার পাবে।
স্টেক্সম্যান

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());
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.