2013-08-11 8 views
8

मैं जेएसओएन और जावा के बीच मार्शलिंग और अनमर्शलिंग डेटा के लिए जैक्सन फ्रेमवर्क का उपयोग कर रहा हूं। सब कुछ अच्छी तरह से काम करता है, जब तक इनपुट कोई भी वर्ण की तरह शामिल नहीं है:org.codehaus.jackson.JsonParseException: अवैध यूटीएफ -8 मध्य बाइट 0xdf

  • ö
  • ä
  • ü
  • Ö
  • Ä
  • Ü
  • ß

इनपुट डेटा के लिए मैंने कोशिश की:

String jsonData = "{\"id\":1,\"street\":\"Straße\",\"number\":\"1c\",\"zipCode\":1111,\"city\":\"MyCity\"}"; 

के साथ-साथ:

String jsonData = "{\"id\":1,\"street\":\"Stra\u00DFe\",\"number\":\"1c\",\"zipCode\":1111,\"city\":\"MyCity\"}"; 

और हर समय मैं एक ही अपवाद मिलता है।

जावा इकाई वस्तु को json डेटा से मानचित्रण के माध्यम से किया जाता है:

/* 
* Convert stream to data entity 
*/ 
ObjectMapper m = new ObjectMapper(); 
T entity = (T) m.readValue(stringToStream(jsonData), readableClass); 

मैं भी एक json डेटा सत्यापन जो उम्मीद की तरह काम करता है, यह भी ऊपर वर्ण के साथ प्रदर्शन करते हैं।

इस तरह के डेटा को कैसे संभाला जाना चाहिए?

अद्यतन ये MessageBodyReader वर्ग के महत्वपूर्ण हिस्से

@Override 
public T readFrom(Class<T> type, Type genericType, 
     Annotation[] annotations, MediaType mediaType, 
     MultivaluedMap<String, String> httpHeaders, InputStream entityStream) 
     throws IOException, WebApplicationException { 

    final String jsonData = getStringFromInputStream(entityStream); 
    System.out.println(jsonData); 

    InputStream isSchema = new FileInputStream(jsonSchemaFile); 
    String jsonSchema = getStringFromInputStream(isSchema); 

    /* 
    * Perform JSON data validation against schema 
    */ 
    validateJsonData(jsonSchema, jsonData); 

    /* 
    * Convert stream to data entity 
    */ 
    ObjectMapper m = new ObjectMapper(); 
    T entity = (T) m.readValue(stringToStream(jsonData), readableClass); 

    return entity; 
} 

/** 
* Validate the given JSON data against the given JSON schema 
* 
* @param jsonSchema 
*   as String 
* @param jsonData 
*   as String 
* @throws MessageBodyReaderValidationException 
*    in case of an error during validation process 
*/ 
private void validateJsonData(final String jsonSchema, final String jsonData) 
     throws MessageBodyReaderValidationException { 
    try { 
     final JsonNode d = JsonLoader.fromString(jsonData); 
     final JsonNode s = JsonLoader.fromString(jsonSchema); 

     final JsonSchemaFactory factory = JsonSchemaFactory.byDefault(); 
     JsonValidator v = factory.getValidator(); 

     ProcessingReport report = v.validate(s, d); 
     System.out.println(report); 
     if (!report.toString().contains("success")) { 
      throw new MessageBodyReaderValidationException(
        report.toString()); 
     } 

    } catch (IOException e) { 
     throw new MessageBodyReaderValidationException(
       "Failed to validate json data", e); 
    } catch (ProcessingException e) { 
     throw new MessageBodyReaderValidationException(
       "Failed to validate json data", e); 
    } 
} 

/** 
* Taken from <a href= 
* "http://www.mkyong.com/java/how-to-convert-inputstream-to-string-in-java/" 
* >www.mkyong.com</a> 
* 
* @param is 
*   {@link InputStream} 
* @return Stream content as String 
*/ 
private String getStringFromInputStream(InputStream is) { 
    BufferedReader br = null; 
    StringBuilder sb = new StringBuilder(); 

    String line; 
    try { 

     br = new BufferedReader(new InputStreamReader(is)); 
     while ((line = br.readLine()) != null) { 
      sb.append(line); 
     } 

    } catch (IOException e) { 
     e.printStackTrace(); 
    } finally { 
     if (br != null) { 
      try { 
       br.close(); 
      } catch (IOException e) { 
       e.printStackTrace(); 
      } 
     } 
    } 

    return sb.toString(); 
} 

private InputStream stringToStream(final String str) { 
    return new ByteArrayInputStream(str.getBytes()); 
} 
+0

क्या आप हमें स्ट्रिंगटॉस्ट्रीम कोड भी प्रदान कर सकते हैं? – Jk1

+0

स्रोत जोड़ा गया, thx – 123456789

उत्तर

9

JSON विनिर्देश राज्य हैं, कि वैध एनकोडिंग हैं UTF-8, UTF-16 और UTF-32। कोई अन्य एन्कोडिंग (जैसे लैटिन -1) का उपयोग किया जा सकता है। आपका स्ट्रिंगटॉस्ट्रीम कार्यान्वयन एन्कोडिंग को स्पष्ट रूप से सेट नहीं कर रहा है, इसलिए सिस्टम डिफ़ॉल्ट का उपयोग किया जाता है। इस तरह आप गैर-utf स्ट्रीम मिला है। अगले चरण पर जैक्सन यूटीएफ एन्कोडिंग्स में से एक का उपयोग करके स्ट्रीम को पार्स करने का प्रयास कर रहा है (इसमें डिटेक्शन एल्गोरिदम बनाया गया है) और विफल रहता है। एक स्पष्ट एन्कोडिंग सेट करके देखें:

new ByteArrayInputStream(str.getBytes("UTF-8")); 
1

आप पहले से ही एक जवाब मिल गया है, लेकिन एक स्पष्ट यहाँ सवाल यह है: तुम क्यों एक String से एक धारा में परिवर्तित कर रहे हैं? यह अनावश्यक और अपर्याप्त चीज है - तो बस स्ट्रिंग को पास करें। यह समस्या को भी हटा देगा; स्ट्रिंग्स में प्रति एन्कोडिंग नहीं है (यानी: केवल एक ही इन-मेमोरी प्रस्तुति है और कोई रूपांतरण की आवश्यकता नहीं है)।

+0

ओह, धन्यवाद! आप unmarshalling कॉल को प्रतिबिंबित कर रहे हैं जिसे 'टी इकाई = (टी) m.readValue (jsonData, readableClass);' क्या और सुधार हैं? – 123456789

+0

स्ट्रिंग के रूप में फ़ाइल पढ़ने पर, मूल 'इनपुटस्ट्रीम रीडर' का उपयोग करना बेहतर होता है, लाइन-बाय-लाइन के बजाय 'स्ट्रिंगबिल्डर' का उपयोग करके संलग्न करें। या, यदि JSON स्कीमा वैलिडेटर 'रीडर' या 'इनपुटस्ट्रीम' से पढ़ सकता है, तो उनको पास करें - यह अच्छी तरह से जैक्स का उपयोग हुड के नीचे भी कर सकता है। – StaxMan

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