2013-08-11 14 views
8

JSONとJavaの間でデータをマーシャリングおよびアンマーシャリングするためにjacksonフレームワークを使用しています。すべては限り入力などの任意の文字が含まれていない、うまく機能:org.codehaus.jackson.JsonParseException:無効なUTF-8中間バイト0xdf

  • ö
  • ß
  • Ä
  • Ö
  • U

    入力データの場合:

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

    と私は同じ例外を取得、すべての時間。 Javaのエンティティ・オブジェクトを介して行われるまで

    JSONデータからマッピング:

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

    Iはまた、上記の文字と、予想されるように動作JSONデータの検証を行います。

    このようなデータはどのように処理する必要がありますか?

    UPDATE これらは、唯一の有効なエンコーディングがUTF-8であることを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

    stringToStreamコードもご提供いただけますか? – Jk1

    +0

    ソースが追加されました、thx – 123456789

    答えて

    9

    JSON仕様状態、UTF-16とUTF-32の重要な部分です。他のエンコーディング(Latin-1など)は使用できません。 stringToStreamの実装では、エンコードを明示的に設定していないため、システムのデフォルトが使用されます。それはあなたが非utfストリームを得た方法です。次のステップで、JaksonはUTFエンコーディングの1つを使用してストリームを解析しようとしています(検出アルゴリズムが組み込まれています)、失敗します。明示的なエンコーディングを設定してみてください:

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

    あなたはすでに答えを得たが、ここでは1つの明白な質問はこれです:なぜあなたは、ストリームにStringから変換していますか?それは不必要で無駄なことです - そのままストリングを渡してください。これにより問題も解決されます。文字列にはエンコード自体はありません(つまり、メモリ内に1つの表現があり、変換は必要ありません)。

    +0

    ああ、ありがとう!あなたは、以下のように簡略化することができるアンマーシャリングコールを参照しています: 'Tエンティティ=(T)m.readValue(jsonData、readableClass);' さらに改善はありますか? – 123456789

    +0

    ファイルを文字列として読み込み、基本的な 'InputStreamReader'を使う方が、行単位ではなく' StringBuilder'を使って追加する方が良いでしょう。または、JSON Schema Validatorが 'Reader'ま​​たは' InputStream'から読み込むことができれば、それを渡します。 – StaxMan

    関連する問題