2011-06-14 11 views
17

मैं जैक्सन उदाहरण के साथ खेल रहा हूँ और कुछ परेशानी अपरिवर्तनीय वर्गों और इंटरफेस के साथ काम करने के लिए अक्रमांकन हो रही हो रहा है।जैक्सन JSON, अपरिवर्तनीय क्लासेस, और इंटरफेस

package com.art.starter.jackson_starter; 

import java.io.IOException; 
import java.io.StringReader; 
import java.io.StringWriter; 

import org.codehaus.jackson.JsonGenerationException; 
import org.codehaus.jackson.map.JsonMappingException; 
import org.codehaus.jackson.map.ObjectMapper; 
/** * Hello world! * */ public class App { 
    public static void main(String[] args) throws JsonGenerationException, JsonMappingException, IOException 
    { 
     System.out.println("Hello World!"); 

     AddressImpl.AddressBuilder builder = new AddressImpl.AddressBuilder(); 
     NameImpl.Builder nameBuilder = new NameImpl.Builder(); 
     UserImpl.Builder userBuilder = new UserImpl.Builder(); 


     Name name = nameBuilder.first("FirstName") 
        .last("LastName") 
        .build(); 

     Address address = builder.setCity("TestCity") 
       .setCountry("TestCountry") 
       .setState("PA") 
       .setStreet("TestAddress") 
       .setZip(123) 
       .build();  

     User user = userBuilder.address(address) 
       .gender(User.Gender.MALE) 
       .isVerified(true) 
       .userImage(new byte[5]) 
       .build(); 

     System.out.println(address);   
     System.out.println(name); 
     System.out.println(user); 

     StringWriter sw = new StringWriter(); 
     ObjectMapper mapper = new ObjectMapper(); 
     mapper.writeValue(sw, user); 
     System.out.println(sw); 


     StringReader sr = new StringReader("{\"address\":{\"state\":\"PA\",\"country\":\"TestCountry\",\"street\":\"TestAddress\",\"city\":\"TestCity\",\"zip\":123},\"verified\":true,\"gender\":\"MALE\",\"userImage\":\"AAAAAAA=\"}"); 

     /* 
      This line throws the Exception   
     */ 
     User user2 = mapper.readValue(sr, UserImpl.class); 

     System.out.println(user2); 
    } } 

package com.art.starter.jackson_starter; 

import java.util.Arrays; 

import org.codehaus.jackson.annotate.JsonCreator; 
import org.codehaus.jackson.annotate.JsonProperty; 

public final class UserImpl implements User 
{ 
    private final Address address; 
    private final Gender gender; 
    private final byte[] userImage; 
    private final boolean isVerified; 

    public static class Builder 
    { 
     private Address address; 
     private Gender gender; 
     //  private Name name; 
     private byte[] userImage; 
     private boolean isVerified; 

     public Builder address(Address address) 
     { 
     this.address = address; 
     return this; 
     } 

     public Builder gender(Gender gender) 
     { 
     this.gender = gender; 
     return this; 
     } 

     //  public Builder name(Name name) 
     //  { 
     //   this.name = name; 
     //   return this; 
     //  } 

     public Builder userImage(byte[] userImage) 
     { 
     this.userImage = userImage; 
     return this; 
     } 

     public Builder isVerified(boolean isVerified) 
     { 
     this.isVerified = isVerified; 
     return this; 
     } 

     public UserImpl build() 
     { 
     return new UserImpl(address, gender, userImage, isVerified); 
     } 
    } 

    @JsonCreator 
    public UserImpl(@JsonProperty("address") Address address, @JsonProperty("gender") Gender gender, @JsonProperty("userImage") byte[] userImage, 
     @JsonProperty("verified") boolean isVerified) 
    { 
     super(); 
     this.address = address; 
     this.gender = gender; 
     this.userImage = userImage; 
     this.isVerified = isVerified; 
    } 

    public Address getAddress() 
    { 
     return address; 
    } 

    public Gender getGender() 
    { 
     return gender; 
     } 

    public byte[] getUserImage() 
    { 
     return userImage; 
    } 

    public boolean isVerified() 
    { 
     return isVerified; 
    } 

    @Override 
    public String toString() 
    { 
     StringBuilder builder2 = new StringBuilder(); 
     builder2.append("UserImpl [address="); 
     builder2.append(address); 
     builder2.append(", gender="); 
     builder2.append(gender); 
     builder2.append(", isVerified="); 
     builder2.append(isVerified); 
     builder2.append(", name="); 
     builder2.append(", userImage="); 
     builder2.append(Arrays.toString(userImage)); 
     builder2.append("]"); 
     return builder2.toString(); 
    } 

} 

package com.art.starter.jackson_starter; 

import org.codehaus.jackson.annotate.JsonCreator; 
import org.codehaus.jackson.annotate.JsonProperty; 

public final class AddressImpl implements Address 
{ 
    private final String city; 
    private final String country; 
    private final String street; 
    private final String state; 
    private final int zip; 

    public static class AddressBuilder 
    { 
     private String city; 
     private String country; 
     private String street; 
     private String state; 
     private int zip; 

     public AddressBuilder setCity(String city) 
     { 
     this.city = city; 
     return this; 
     } 

     public AddressBuilder setCountry(String country) 
     { 
     this.country = country; 
     return this; 
     } 

     public AddressBuilder setStreet(String street) 
     { 
     this.street = street; 
     return this; 
     } 

     public AddressBuilder setState(String state) 
     { 
     this.state = state; 
     return this; 
     } 

     public AddressBuilder setZip(int zip) 
     { 
     this.zip = zip; 
     return this; 
     } 

     public AddressImpl build() 
     { 
     return new AddressImpl(city, country, street, state, zip); 
     } 

    } 

    @JsonCreator 
    public AddressImpl(@JsonProperty("city") String city, @JsonProperty("country") String country, @JsonProperty("street") String street, 
     @JsonProperty("state") String state, @JsonProperty("zip") int zip) 
    { 
     this.city = city; 
     this.country = country; 
     this.street = street; 
     this.state = state; 
     this.zip = zip; 
    } 

    public String getCity() 
    { 
     return city; 
    } 

    public String getCountry() 
    { 
     return country; 
    } 

    public String getStreet() 
    { 
     return street; 
    } 

    public String getState() 
    { 
     return state; 
    } 

    public int getZip() 
    { 
     return zip; 
    } 

    @Override 
    public String toString() 
    { 
     StringBuilder builder = new StringBuilder(); 
     builder.append("AddressImpl [city="); 
     builder.append(city); 
     builder.append(", country="); 
     builder.append(country); 
     builder.append(", state="); 
     builder.append(state); 
     builder.append(", street="); 
     builder.append(street); 
     builder.append(", zip="); 
     builder.append(zip); 
     builder.append("]"); 
     return builder.toString(); 
    } 

} 

मुद्दे के समाधान के साथ हो गया लगता है:

नीचे मेरी कोड है।

Exception in thread "main" org.codehaus.jackson.map.JsonMappingException: Can not construct instance of com.art.starter.jackson_starter.Address, problem: abstract types can only be instantiated with additional type information 
at [Source: [email protected]; line: 1, column: 2] 
    at org.codehaus.jackson.map.JsonMappingException.from(JsonMappingException.java:163) 
    at org.codehaus.jackson.map.deser.StdDeserializationContext.instantiationException(StdDeserializationContext.java:212) 
    at org.codehaus.jackson.map.deser.AbstractDeserializer.deserialize(AbstractDeserializer.java:97) 
    at org.codehaus.jackson.map.deser.SettableBeanProperty.deserialize(SettableBeanProperty.java:230) 
    at org.codehaus.jackson.map.deser.BeanDeserializer._deserializeUsingPropertyBased(BeanDeserializer.java:595) 
    at org.codehaus.jackson.map.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:472) 
    at org.codehaus.jackson.map.deser.BeanDeserializer.deserialize(BeanDeserializer.java:350) 
    at org.codehaus.jackson.map.ObjectMapper._readMapAndClose(ObjectMapper.java:2391) 
    at org.codehaus.jackson.map.ObjectMapper.readValue(ObjectMapper.java:1614) 
    at com.art.starter.jackson_starter.App.main(App.java:56) 

मुझे यकीन है कि यह है जैक्सन पता जो AddressImpl के लिए एक इंटरफेस एक ठोस कार्यान्वयन है जो हल करने के लिए कोई रास्ता नहीं है क्योंकि वहाँ हूं: मैं इस अपवाद मिलता है। मैं दस्तावेज़ों के माध्यम से पोकिंग कर रहा हूं और @JsonDeserialize (as = AddressImpl.class) के बारे में कुछ लेख देखे हैं, लेकिन यह काम नहीं करता है। तो मैं फंस गया हूँ। क्या किसी ने इसे कभी काम करने के लिए प्राप्त किया है, क्या यह भी समर्थित है?

UserImpl कक्षा में AddressImpl के साथ Address को प्रतिस्थापित करता है तो यह एक चैंप की तरह काम करता है।

+0

लाइन 56 ठीक है जो? हैं पता करने के लिए वास्तव में क्या कोड फेंकता पूर्व –

+0

@ हारून-खेद जोड़ा संपादित मदद - अपनी static void मुख्य – nsfyn55

+0

की अंतिम पंक्ति के बगल में मैं कुछ इसी तरह की समस्या हुई, इस संसाधन मदद कर सकता है: http: //wiki.fasterxml। com/JacksonPolymorphicDeserialization – will824

उत्तर

20

शायद ज़रुरत पड़े तो आप इसे नहीं देखा था, यहाँ एक blog entry कि अपरिवर्तनीय वस्तुओं और जैक्सन के साथ काम करने की चर्चा है।

लेकिन आपको निश्चित रूप से @JsonDeserialize(as=AddressImpl.class); का उपयोग एड्रेस.जावा इंटरफ़ेस (या तो सीधे या मिश्रण-इन का उपयोग करके) या इसे क्षेत्र या संपत्ति में जोड़कर उपयोग करने में सक्षम होना चाहिए। ध्यान देने योग्य बात यह है कि deserialization के लिए, यह आपके द्वारा उपयोग किए जाने वाले एक्सेसर के बगल में होना चाहिए; अगर आपके पास फ़ील्ड के बगल में एक है, तो सेटर। टिप्पणियां (अभी तक) एक्सेसर्स के बीच साझा नहीं हैं; इसलिए उदाहरण के लिए इसे 'गेटर' में जोड़ना काम नहीं करेगा।

जैक्सन 1.8 अंततः अमूर्त-से-ठोस प्रकारों के पंजीकरण की अनुमति देता है (अधिक जानकारी के लिए http://jira.codehaus.org/browse/JACKSON-464 देखें) जो 'पता' के लिए 'पताImpl' का उपयोग करने का सबसे अच्छा विकल्प हो सकता है।

+0

हम्म मुझे इस – nsfyn55

+2

वहाँ की कोशिश हम चलते हैं! मैंने इंटरफ़ेस में @JsonDeserialize (as = AddressImpl.class) जोड़ा और यह एक चैंप की तरह काम करता था। ऐसा लगता है कि इस सदस्य के ऊपर UserImpl क्लास को जोड़ने के लिए यह और अधिक समझदार होगा, इंटरफेस में कंक्रीट कार्यान्वयन को निर्दिष्ट करना ऐसा लगता है कि यह उद्देश्य को हरा देता है, भले ही यह एक एनोटेशन हो। आपकी सहायताके लिए धन्यवाद! – nsfyn55

+0

हां, इसे इंटरफ़ेस में जोड़ना सुंदर नहीं है; लेकिन दुर्भाग्यवश विपरीत करना मुश्किल है (यदि असंभव नहीं है), क्योंकि सभी वर्गों पर गणना करने का कोई तरीका नहीं है JVM लोड किया गया है (एनोटेशन देखने के लिए)। इसके अलावा, आप (http://wiki.fasterxml.com/JacksonMixInAnnotations देखें), या निर्माता पैरामीटर कि पता लगते हैं करने के लिए जोड़ा मिश्रण-इन के माध्यम से एनोटेशन या तो जोड़ने पर विचार कर सकता है; @JsonProperty – StaxMan

संबंधित मुद्दे