मैं जैक्सन के साथ एक कस्टम Serializer का उपयोग कैसे करूं?


111

मेरे पास दो जावा कक्षाएं हैं जिन्हें मैं जैक्सन को जैक्सन का उपयोग करके क्रमबद्ध करना चाहता हूं:

public class User {
    public final int id;
    public final String name;

    public User(int id, String name) {
        this.id = id;
        this.name = name;
    }
}

public class Item {
    public final int id;
    public final String itemNr;
    public final User createdBy;

    public Item(int id, String itemNr, User createdBy) {
        this.id = id;
        this.itemNr = itemNr;
        this.createdBy = createdBy;
    }
}

मैं इस JSON के लिए एक आइटम क्रमबद्ध करना चाहता हूं:

{"id":7, "itemNr":"TEST", "createdBy":3}

उपयोगकर्ता के साथ क्रमबद्ध केवल शामिल करने के लिए id। मैं भी JSON की तरह सभी उपयोगकर्ता वस्तुओं को व्यवस्थित करने में सक्षम हो जाएगा:

{"id":3, "name": "Jonas", "email": "jonas@example.com"}

इसलिए मुझे लगता है कि मुझे इसके लिए एक कस्टम धारावाहिक लिखने की ज़रूरत है Itemऔर इसके साथ प्रयास करने की आवश्यकता है :

public class ItemSerializer extends JsonSerializer<Item> {

@Override
public void serialize(Item value, JsonGenerator jgen,
        SerializerProvider provider) throws IOException,
        JsonProcessingException {
    jgen.writeStartObject();
    jgen.writeNumberField("id", value.id);
    jgen.writeNumberField("itemNr", value.itemNr);
    jgen.writeNumberField("createdBy", value.user.id);
    jgen.writeEndObject();
}

}

मैं जैक्सन को जैक्सन-टू से इस कोड के साथ क्रमबद्ध करता हूं : कस्टम सीरियल :

ObjectMapper mapper = new ObjectMapper();
SimpleModule simpleModule = new SimpleModule("SimpleModule", 
                                              new Version(1,0,0,null));
simpleModule.addSerializer(new ItemSerializer());
mapper.registerModule(simpleModule);
StringWriter writer = new StringWriter();
try {
    mapper.writeValue(writer, myItem);
} catch (JsonGenerationException e) {
    e.printStackTrace();
} catch (JsonMappingException e) {
    e.printStackTrace();
} catch (IOException e) {
    e.printStackTrace();
}

लेकिन मुझे यह त्रुटि मिली:

Exception in thread "main" java.lang.IllegalArgumentException: JsonSerializer of type com.example.ItemSerializer does not define valid handledType() (use alternative registration method?)
    at org.codehaus.jackson.map.module.SimpleSerializers.addSerializer(SimpleSerializers.java:62)
    at org.codehaus.jackson.map.module.SimpleModule.addSerializer(SimpleModule.java:54)
    at com.example.JsonTest.main(JsonTest.java:54)

मैं जैक्सन के साथ एक कस्टम Serializer का उपयोग कैसे कर सकता हूं?


इस तरह से मैं इसे Gson के साथ करूंगा:

public class UserAdapter implements JsonSerializer<User> {

    @Override 
    public JsonElement serialize(User src, java.lang.reflect.Type typeOfSrc,
            JsonSerializationContext context) {
        return new JsonPrimitive(src.id);
    }
}

    GsonBuilder builder = new GsonBuilder();
    builder.registerTypeAdapter(User.class, new UserAdapter());
    Gson gson = builder.create();
    String json = gson.toJson(myItem);
    System.out.println("JSON: "+json);

लेकिन मुझे इसे अब जैक्सन के साथ करने की आवश्यकता है, क्योंकि गॉन के पास इंटरफेस के लिए समर्थन नहीं है।


जैक्सन को आपके कस्टम सेरीलाइज़र का उपयोग करने के लिए कैसे / कहाँ मिला Item? मैं एक समस्या है जहाँ मेरे नियंत्रक विधि एक मानक क्रमांकित वस्तु देता है TypeA, लेकिन एक और विशिष्ट नियंत्रक विधि के लिए, मैं इसे अलग तरह से क्रमबद्ध करना चाहता हूँ। वो कैसा लगता है?
डॉन चीडल

मैंने जैक्सन के साथ एक कस्टम सीरियल लिखने वाले के बारे में एक पोस्ट लिखी जो कुछ लोगों के लिए उपयोगी हो सकती है।
सैम बेरी

जवाबों:


51

जैसा कि उल्लेख किया गया है, @JsonValue एक अच्छा तरीका है। लेकिन अगर आपको कोई कस्टम सीरियल बनाने वाले से कोई आपत्ति नहीं है, तो आइटम के लिए एक लिखने की ज़रूरत नहीं है, बल्कि उपयोगकर्ता के लिए एक है - यदि हां, तो यह उतना ही सरल होगा:

public void serialize(Item value, JsonGenerator jgen,
    SerializerProvider provider) throws IOException,
    JsonProcessingException {
  jgen.writeNumber(id);
}

फिर भी एक और संभावना लागू करने की है JsonSerializable, जिस स्थिति में पंजीकरण की आवश्यकता नहीं है।

त्रुटि के रूप में; यह अजीब है - आप शायद बाद के संस्करण में अपग्रेड करना चाहते हैं। लेकिन यह विस्तारित करने के लिए भी सुरक्षित है org.codehaus.jackson.map.ser.SerializerBaseक्योंकि इसमें गैर-आवश्यक तरीकों (यानी सब कुछ लेकिन वास्तविक क्रमांकन कॉल) के मानक कार्यान्वयन होंगे।


इसके साथ मुझे भी यही त्रुटि मिलती है:Exception in thread "main" java.lang.IllegalArgumentException: JsonSerializer of type com.example.JsonTest$UserSerilizer does not define valid handledType() (use alternative registration method?) at org.codehaus.jackson.map.module.SimpleSerializers.addSerializer(SimpleSerializers.java:62) at org.codehaus.jackson.map.module.SimpleModule.addSerializer(SimpleModule.java:54) at com.example.JsonTest.<init>(JsonTest.java:27) at com.exampple.JsonTest.main(JsonTest.java:102)
जोनास

मैं जैक्सकॉन के नवीनतम स्थिर संस्करण का उपयोग करता हूं, 1.8.5।
जोनास

4
धन्यवाद। बेनाम: मैं एक नज़र रखना होगा ... आह! यह वास्तव में सरल है (हालांकि त्रुटि संदेश अच्छा नहीं है) - आपको बस अलग-अलग विधि के साथ धारावाहिक को पंजीकृत करने की आवश्यकता है, वर्ग को निर्दिष्ट करने के लिए कि धारावाहिक के लिए है: यदि नहीं, तो इसे संभाला वर्ग से वापस करना होगा ()। इसलिए 'AddSerializer' का उपयोग करें जो JavaType या Class को तर्क के रूप में लेता है और इसे काम करना चाहिए।
स्टेक्समैन

अगर यह नहीं चलाया जा रहा है तो क्या होगा?
मतेज जे

62

आप @JsonSerialize(using = CustomDateSerializer.class)किसी भी दिनांक फ़ील्ड को क्रमबद्ध करने के लिए रख सकते हैं ।

public class CustomDateSerializer extends SerializerBase<Date> {

    public CustomDateSerializer() {
        super(Date.class, true);
    }

    @Override
    public void serialize(Date value, JsonGenerator jgen, SerializerProvider provider)
        throws IOException, JsonProcessingException {
        SimpleDateFormat formatter = new SimpleDateFormat("EEE MMM dd yyyy HH:mm:ss 'GMT'ZZZ (z)");
        String format = formatter.format(value);
        jgen.writeString(format);
    }

}

1
ध्यान देने योग्य: @JsonSerialize(contentUsing= ...)संग्रह (जैसे @JsonSerialize(contentUsing= CustomDateSerializer.class) List<Date> dates) को एनोटेट करते समय उपयोग करें
कोडरेटेक

33

मैंने भी ऐसा करने की कोशिश की, और जैक्सन वेब पेज पर उदाहरण कोड में एक गलती .classहै जो कॉल करने के addSerializer()तरीके ( ) को विधि में शामिल करने में विफल रहता है , जिसे इस तरह से पढ़ना चाहिए:

simpleModule.addSerializer(Item.class, new ItemSerializer());

दूसरे शब्दों में, ये वो पंक्तियाँ simpleModuleहैं जो धारावाहिक को जोड़ते हैं और धारावाहिक जोड़ते हैं (पूर्व गलत पंक्ति के साथ टिप्पणी की गई है):

ObjectMapper mapper = new ObjectMapper();
SimpleModule simpleModule = new SimpleModule("SimpleModule", 
                                          new Version(1,0,0,null));
// simpleModule.addSerializer(new ItemSerializer());
simpleModule.addSerializer(Item.class, new ItemSerializer());
mapper.registerModule(simpleModule);

FYI करें: यहाँ सही उदाहरण कोड के लिए संदर्भ है: http://wiki.fasterxml.com/JacksonFeatureModules


9

@JsonValue का उपयोग करें:

public class User {
    int id;
    String name;

    @JsonValue
    public int getId() {
        return id;
    }
}

@JsonValue केवल तरीकों पर काम करता है इसलिए आपको गेटआईड विधि को जोड़ना होगा। आपको अपने कस्टम सीरियल को पूरी तरह से छोड़ देना चाहिए।


2
मुझे लगता है कि यह उपयोगकर्ता को क्रमबद्ध करने के सभी प्रयासों को प्रभावित करेगा, जिससे JSON पर किसी उपयोगकर्ता के नाम को उजागर करना मुश्किल हो जाएगा।
पॉल एम

मैं इस समाधान का उपयोग नहीं कर सकता, क्योंकि मुझे सभी क्षेत्रों के साथ सभी उपयोगकर्ता वस्तुओं को अनुक्रमित करने में सक्षम होना चाहिए। और यह समाधान उस क्रमांकन को तोड़ देगा क्योंकि केवल आईडी-फ़ील्ड को शामिल किया जाएगा। क्या जैक्सन के लिए एक कस्टम सीरीलाइज़र बनाने का कोई तरीका नहीं है क्योंकि यह गसन के लिए है?
जोनास

1
क्या आप इस पर टिप्पणी कर सकते हैं कि JSON दृश्य (मेरे उत्तर में) आपकी आवश्यकताओं से मेल क्यों नहीं खाते हैं?
पॉल एम

@user: यह एक अच्छा समाधान हो सकता है, मैं इसके बारे में पढ़ रहा हूं और कोशिश कर रहा हूं।
जोनास

2
ध्यान दें, भी, कि आप अपनी संपत्ति (क्षेत्र या गेट्टर) के लिए विशिष्ट क्रमांकन इंगित करने के लिए @JsonSerialize (= MySerializer.class का उपयोग करके) का उपयोग कर सकते हैं, इसलिए इसका उपयोग केवल सदस्य संपत्ति के लिए किया जाता है और सभी प्रकार के उदाहरण नहीं।
StaxMan

8

मैंने एक कस्टम Timestamp.classसीरियलाइज़ेशन / डिसिएरलाइज़ेशन के लिए एक उदाहरण लिखा था , लेकिन आप कभी भी इसका उपयोग कर सकते हैं।

ऑब्जेक्ट मैपर बनाते समय ऐसा कुछ करें:

public class JsonUtils {

    public static ObjectMapper objectMapper = null;

    static {
        objectMapper = new ObjectMapper();
        SimpleModule s = new SimpleModule();
        s.addSerializer(Timestamp.class, new TimestampSerializerTypeHandler());
        s.addDeserializer(Timestamp.class, new TimestampDeserializerTypeHandler());
        objectMapper.registerModule(s);
    };
}

उदाहरण के लिए java eeआप इसे इसके साथ आरंभ कर सकते हैं:

import java.time.LocalDateTime;

import javax.ws.rs.ext.ContextResolver;
import javax.ws.rs.ext.Provider;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;

@Provider
public class JacksonConfig implements ContextResolver<ObjectMapper> {

    private final ObjectMapper objectMapper;

    public JacksonConfig() {
        objectMapper = new ObjectMapper();
        SimpleModule s = new SimpleModule();
        s.addSerializer(Timestamp.class, new TimestampSerializerTypeHandler());
        s.addDeserializer(Timestamp.class, new TimestampDeserializerTypeHandler());
        objectMapper.registerModule(s);
    };

    @Override
    public ObjectMapper getContext(Class<?> type) {
        return objectMapper;
    }
}

जहां धारावाहिक को कुछ इस तरह होना चाहिए:

import java.io.IOException;
import java.sql.Timestamp;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;

public class TimestampSerializerTypeHandler extends JsonSerializer<Timestamp> {

    @Override
    public void serialize(Timestamp value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException {
        String stringValue = value.toString();
        if(stringValue != null && !stringValue.isEmpty() && !stringValue.equals("null")) {
            jgen.writeString(stringValue);
        } else {
            jgen.writeNull();
        }
    }

    @Override
    public Class<Timestamp> handledType() {
        return Timestamp.class;
    }
}

और deserializer कुछ इस तरह से:

import java.io.IOException;
import java.sql.Timestamp;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.SerializerProvider;

public class TimestampDeserializerTypeHandler extends JsonDeserializer<Timestamp> {

    @Override
    public Timestamp deserialize(JsonParser jp, DeserializationContext ds) throws IOException, JsonProcessingException {
        SqlTimestampConverter s = new SqlTimestampConverter();
        String value = jp.getValueAsString();
        if(value != null && !value.isEmpty() && !value.equals("null"))
            return (Timestamp) s.convert(Timestamp.class, value);
        return null;
    }

    @Override
    public Class<Timestamp> handledType() {
        return Timestamp.class;
    }
}

7

ये व्यवहार पैटर्न हैं जिन्हें मैंने जैक्सन क्रमांकन को समझने की कोशिश करते हुए देखा है।

1) मान लें कि एक ऑब्जेक्ट क्लासरूम और एक क्लास स्टूडेंट है। मैंने सब कुछ सार्वजनिक कर दिया है और आसानी के लिए अंतिम।

public class Classroom {
    public final double double1 = 1234.5678;
    public final Double Double1 = 91011.1213;
    public final Student student1 = new Student();
}

public class Student {
    public final double double2 = 1920.2122;
    public final Double Double2 = 2324.2526;
}

2) मान लें कि ये वे सीरियलाइज़र हैं जिनका उपयोग हम JSON में ऑब्जेक्ट्स को क्रमांकित करने के लिए करते हैं। अगर यह ऑब्जेक्ट मैपर के साथ पंजीकृत है, तो राइटऑब्जेक्टफिल्ड ऑब्जेक्ट के स्वयं के सीरीज़र का उपयोग करता है; यदि नहीं, तो यह इसे POJO के रूप में क्रमबद्ध करता है। TheNumberNieldField विशेष रूप से केवल प्राथमिकताओं को तर्क के रूप में स्वीकार करता है।

public class ClassroomSerializer extends StdSerializer<Classroom> {
    public ClassroomSerializer(Class<Classroom> t) {
        super(t);
    }

    @Override
    public void serialize(Classroom value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonGenerationException {
        jgen.writeStartObject();
        jgen.writeObjectField("double1-Object", value.double1);
        jgen.writeNumberField("double1-Number", value.double1);
        jgen.writeObjectField("Double1-Object", value.Double1);
        jgen.writeNumberField("Double1-Number", value.Double1);
        jgen.writeObjectField("student1", value.student1);
        jgen.writeEndObject();
    }
}

public class StudentSerializer extends StdSerializer<Student> {
    public StudentSerializer(Class<Student> t) {
        super(t);
    }

    @Override
    public void serialize(Student value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonGenerationException {
        jgen.writeStartObject();
        jgen.writeObjectField("double2-Object", value.double2);
        jgen.writeNumberField("double2-Number", value.double2);
        jgen.writeObjectField("Double2-Object", value.Double2);
        jgen.writeNumberField("Double2-Number", value.Double2);
        jgen.writeEndObject();
    }
}

3) डेसीमलफ़ॉर्मैट आउटपुट पैटर्न के साथ केवल SimpleSodule में एक DoubleSerializer रजिस्टर करें ###,##0.000और आउटपुट है:

{
  "double1" : 1234.5678,
  "Double1" : {
    "value" : "91,011.121"
  },
  "student1" : {
    "double2" : 1920.2122,
    "Double2" : {
      "value" : "2,324.253"
    }
  }
}

आप देख सकते हैं कि POJO क्रमांकन डबल और डबल के बीच अंतर करता है, डबल के लिए DoubleSerialzer का उपयोग कर रहा है और युगल के लिए एक नियमित स्ट्रिंग प्रारूप का उपयोग कर रहा है।

4) स्टूडेंटसैराइज़र के बिना DoubleSerializer और ClassroomSerializer पंजीकृत करें। हम उम्मीद करते हैं कि आउटपुट ऐसा हो कि अगर हम किसी वस्तु के रूप में डबल लिखते हैं, तो वह डबल की तरह व्यवहार करता है, और अगर हम एक संख्या के रूप में डबल लिखते हैं, तो यह एक डबल की तरह व्यवहार करता है। छात्र उदाहरण चर को POJO के रूप में लिखा जाना चाहिए और ऊपर दिए गए पैटर्न का पालन करना चाहिए क्योंकि यह पंजीकृत नहीं है।

{
  "double1-Object" : {
    "value" : "1,234.568"
  },
  "double1-Number" : 1234.5678,
  "Double1-Object" : {
    "value" : "91,011.121"
  },
  "Double1-Number" : 91011.1213,
  "student1" : {
    "double2" : 1920.2122,
    "Double2" : {
      "value" : "2,324.253"
    }
  }
}

5) सभी धारावाहिकों को पंजीकृत करें। आउटपुट है:

{
  "double1-Object" : {
    "value" : "1,234.568"
  },
  "double1-Number" : 1234.5678,
  "Double1-Object" : {
    "value" : "91,011.121"
  },
  "Double1-Number" : 91011.1213,
  "student1" : {
    "double2-Object" : {
      "value" : "1,920.212"
    },
    "double2-Number" : 1920.2122,
    "Double2-Object" : {
      "value" : "2,324.253"
    },
    "Double2-Number" : 2324.2526
  }
}

जैसी उम्मीद थी।

एक और महत्वपूर्ण नोट: यदि आपके पास एक ही मॉड्यूल के साथ पंजीकृत एक ही वर्ग के लिए कई धारावाहिक हैं, तो मॉड्यूल उस वर्ग के लिए धारावाहिक का चयन करेगा जो हाल ही में सूची में जोड़ा गया है। इसका उपयोग नहीं किया जाना चाहिए - यह भ्रामक है और मुझे यकीन नहीं है कि यह कितना सुसंगत है

Moral: यदि आप अपनी वस्तु में प्राइमरी के क्रमांकन को अनुकूलित करना चाहते हैं, तो आपको ऑब्जेक्ट के लिए अपना स्वयं का सीरलाइज़र लिखना होगा। आप POJO जैक्सन क्रमांकन पर भरोसा नहीं कर सकते।


आप क्लासरूम की घटनाओं को संभालने के लिए ClassroomSerializer को कैसे पंजीकृत करते हैं?
Trismegistos

5

जैक्सन का JSON दृश्य आपकी आवश्यकताओं को प्राप्त करने का एक सरल तरीका हो सकता है, खासकर यदि आपके JSON प्रारूप में कुछ लचीलापन हो।

यदि {"id":7, "itemNr":"TEST", "createdBy":{id:3}}एक स्वीकार्य प्रतिनिधित्व है तो यह बहुत कम कोड के साथ प्राप्त करना बहुत आसान होगा।

आप उपयोगकर्ता के नाम फ़ील्ड को केवल एक दृश्य के भाग के रूप में एनोटेट करेंगे, और अपने क्रमांकन अनुरोध में एक अलग दृश्य निर्दिष्ट करेंगे (अन-एनोटेट फ़ील्ड डिफ़ॉल्ट रूप से शामिल होंगे)

उदाहरण के लिए: विचारों को परिभाषित करें:

public class Views {
    public static class BasicView{}
    public static class CompleteUserView{}
}

उपयोगकर्ता को सूचित करें:

public class User {
    public final int id;

    @JsonView(Views.CompleteUserView.class)
    public final String name;

    public User(int id, String name) {
        this.id = id;
        this.name = name;
    }
}

और धारावाहिक एक दृश्य का अनुरोध करता है जिसमें वह क्षेत्र नहीं है जिसे आप छिपाना चाहते हैं (गैर-एनोटेट फ़ील्ड डिफ़ॉल्ट रूप से क्रमबद्ध हैं):

objectMapper.getSerializationConfig().withView(Views.BasicView.class);

मैं जैक्सन JSON दृश्य का उपयोग करने के लिए कठिन लगता है, और इस समस्या के लिए एक अच्छा समाधान नहीं मिल सकता है।
जोनास

जोनास - मैंने एक उदाहरण जोड़ा है। मुझे लगता है कि एक ही वस्तु को विभिन्न तरीकों से क्रमबद्ध करने के लिए एक बहुत अच्छा समाधान मिला।
पॉल एम

एक अच्छे उदाहरण के लिए धन्यवाद। यह अब तक का सबसे अच्छा समाधान है। लेकिन क्या createdByवस्तु के बजाय मूल्य के रूप में पाने का कोई तरीका नहीं है ?
जोनास

setSerializationView()लगता है कि मैं mapper.viewWriter(JacksonViews.ItemView.class).writeValue(writer, myItem);इसके बजाय इस्तेमाल किया जा सकता है।
जोनास

मुझे शक है कि यह json साक्षात्कार का उपयोग कर रहा है। एक त्वरित और गंदा समाधान जो मैंने विचारों की खोज करने से पहले उपयोग किया था, बस उन गुणों को कॉपी करना था जो मुझे एक मानचित्र में, और फिर मानचित्र को क्रमबद्ध करने में दिलचस्पी थी।
पॉल एम

5

मेरे मामले में (स्प्रिंग 3.2.4 और जैक्सन 2.3.1), एक्सएमएल विन्यास के लिए कस्टम धारावाहिक:

<mvc:annotation-driven>
    <mvc:message-converters register-defaults="false">
        <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
            <property name="objectMapper">
                <bean class="org.springframework.http.converter.json.Jackson2ObjectMapperFactoryBean">
                    <property name="serializers">
                        <array>
                            <bean class="com.example.business.serializer.json.CustomObjectSerializer"/>
                        </array>
                    </property>
                </bean>
            </property>
        </bean>
    </mvc:message-converters>
</mvc:annotation-driven>

अस्पष्टीकृत तरीके से कुछ के द्वारा डिफ़ॉल्ट रूप से वापस लिख दिया गया था।

यह मेरे लिए काम किया:

CustomObject.java

@JsonSerialize(using = CustomObjectSerializer.class)
public class CustomObject {

    private Long value;

    public Long getValue() {
        return value;
    }

    public void setValue(Long value) {
        this.value = value;
    }
}

CustomObjectSerializer.java

public class CustomObjectSerializer extends JsonSerializer<CustomObject> {

    @Override
    public void serialize(CustomObject value, JsonGenerator jgen,
        SerializerProvider provider) throws IOException,JsonProcessingException {
        jgen.writeStartObject();
        jgen.writeNumberField("y", value.getValue());
        jgen.writeEndObject();
    }

    @Override
    public Class<CustomObject> handledType() {
        return CustomObject.class;
    }
}

<mvc:message-converters>(...)</mvc:message-converters>मेरे समाधान में कोई XML कॉन्फ़िगरेशन ( ) की आवश्यकता नहीं है।


1

यदि आपके कस्टम सीरियललाइज़र में आपकी एकमात्र आवश्यकता है, के nameक्षेत्र को क्रमबद्ध करना छोड़ना User, इसे क्षणिक के रूप में चिह्नित करना । जैक्सन, क्षणिक क्षेत्रों को क्रमबद्ध या डिसेर्बलाइज नहीं करेगा ।

[यह भी देखें: जावा में क्षणिक क्षेत्र क्यों हैं? ]


मैं इसे कहां चिह्नित करूं? में Userस्तरीय? लेकिन मैं सभी उपयोगकर्ता-वस्तुओं को भी अनुक्रमित करूंगा। उदाहरण के लिए, पहले केवल सभी को क्रमबद्ध करें items(केवल userIdउपयोगकर्ता ऑब्जेक्ट के संदर्भ के रूप में) और फिर सभी को क्रमबद्ध करें users। इस मामले में मैं इन User-क्लास में फ़ेल्स को चिह्नित नहीं कर सकता ।
जोनास

इस नई जानकारी के प्रकाश में, यह दृष्टिकोण आपके लिए काम नहीं करेगा। ऐसा लगता है कि जैक्सन कस्टम धारावाहिक के लिए अधिक जानकारी की तलाश कर रहा है (हैंड हेल्ड टाइप () विधि की आवश्यकता ओवरराइडिंग?)
माइक जी

हां, लेकिन handledType()मेरे द्वारा लिंक किए गए दस्तावेज़ में विधि के बारे में नोटिंग है और जब एक्लिप्स लागू करने के तरीके handledType()उत्पन्न करता है, तो मैं उलझन में हूं।
जोनास

मुझे यकीन नहीं है क्योंकि आपके द्वारा जोड़ा गया विकी इसे संदर्भित नहीं करता है, लेकिन संस्करण 1.5.1 में एक हैंडल्ड टाइप () है और अपवाद उस विधि की शिकायत करने लगता है जो अनुपलब्ध या अमान्य है (बेस क्लास विधि से शून्य है)। jackson.codehaus.org/1.5.1/javadoc/org/codehaus/jackson/map/…
माइक जी


0

आपके मामले में समस्या यह है कि ItemSerializer पद्धति को संभाल रहा है अनुपलब्ध है () जिसे JsonSerializer से ओवरराइड करने की आवश्यकता है

    public class ItemSerializer extends JsonSerializer<Item> {

    @Override
    public void serialize(Item value, JsonGenerator jgen,
            SerializerProvider provider) throws IOException,
            JsonProcessingException {
        jgen.writeStartObject();
        jgen.writeNumberField("id", value.id);
        jgen.writeNumberField("itemNr", value.itemNr);
        jgen.writeNumberField("createdBy", value.user.id);
        jgen.writeEndObject();
    }

   @Override
   public Class<Item> handledType()
   {
    return Item.class;
   }
}

इसलिए आपको स्पष्ट त्रुटि मिल रही है कि हैंडल्ड टाइप () परिभाषित नहीं है

Exception in thread "main" java.lang.IllegalArgumentException: JsonSerializer of type com.example.ItemSerializer does not define valid handledType() 

आशा है कि यह किसी की मदद करता है। मेरा जवाब पढ़ने के लिए धन्यवाद।

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