2013-08-11 17 views
8

JSON ve Java arasındaki marshaling ve unmarshalling verileri için jackson çerçevesini kullanıyorum.org.codehaus.jackson.JsonParseException: Geçersiz UTF-8 orta bayt 0xdf

  • ö
  • Ö
  • Ä
  • Ü
  • ß
ü ä: Her şey sürece girdi herhangi karakterler gibi içermez, iyi çalışıyor

Girdi verileri için denedim:

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

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

ve her zaman aynı durum olsun. Ayrıca, aynı zamanda, yukarıda karakter ile, beklenen gibi çalışan bir json veri doğrulama gerçekleştirmek

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

: ile

Java işletme nesnesine json verilerinden eşleme

yapılır.

Bu tür veriler nasıl ele alınmalıdır? Bu

GÜNCELLEME yalnızca geçerli kodlamalar olduğunu,

@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

Ayrıca lütfen bize stringToStream kodunu da verebilir misiniz? – Jk1

+0

Kaynak eklendi, thx – 123456789

cevap

9

JSON şartname devletler MessageBodyReader sınıfının önemli parçalarıdır UTF-8, UTF-16 ve UTF-32. Başka hiçbir kodlama (Latin-1 gibi) kullanılamaz. StringToStream uygulamanız kodlamayı açık bir şekilde ayarlamıyor, dolayısıyla sistem varsayılanı kullanılıyor. Utfî olmayan akışınız böyle. Sonraki adımda Jakson, UTF kodlamalarından birini kullanarak akışı ayrıştırmaya çalışır (yerleşik olarak algılama algoritmasına sahiptir) ve başarısız olur. Açık bir kodlama belirlemeyi deneyin: Zaten bir cevap var

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

, ama burada bir bariz soru şudur: neden bir akışa bir String dönüştürme var? Bu yapmak gereksiz ve savurgan bir şey - bu yüzden sadece Dize olarak-geçmek. Bu da sorunu kaldıracak; Dizeler kendiliğinden şifrelemeye sahip değildir (yani: sadece bir bellek içi gösterim vardır ve hiçbir dönüşüm gerekmez).

+0

Oh, teşekkürler! Basitleştirilebilen çağrısız çağrıya yönlendiriyorsunuz: 'T varlık = (T) m.readValue (jsonData, okunabilir Sınıf); Başka iyileştirmeler var mı? – 123456789

+0

Bir dosyayı bir String olarak okurken, temel 'InputStreamReader 'işlevini kullanmak daha iyi, satır-by-line yerine' StringBuilder' kullanarak ekleyin. Ya da, JSON Schema Validator bir “Reader” veya “InputStream” 'den okuyabiliyorsa, bunları iletin - aynı zamanda Jackson'ı da kaputun altında kullanabilir. – StaxMan

İlgili konular