1

Spring MVC Java アプリケーションでは、Jersey REST API を使用しています。JSON処理にJacksonを使用しています。一部のクラスの一部のフィールドをフィルタリングするために、Gensonをプロジェクトに追加しました。そして、そのためだけにジェンソンを使用しようとしており、残りはジャクソンを使用したい.

しかし、Jarがクラスパスにある場合、デフォルトでJerseyが有効なGensonとしてJersey REST APIを使用しているときに例外が発生します(このリンクから知っています)。

これは、Webサービスに接続してデータを取得し、Jacksonを使用して文字列に変換する私のコードです

public String connect() throws Exception {
        Client client = Client.create();
        try {
            String auth = new String(Base64.encode(userName + COLON + password));
            WebResource webResource = client
                    .resource(webServiceUrl);
            ClientResponse response = webResource
                    .header(AUTHORIZATION, BASIC + auth).type(APPLICATION_JSON)
                    .accept(APPLICATION_JSON).get(ClientResponse.class);
            //code to check response status code.
                stringResponse = response.getEntity(String.class);

        } catch (ClientHandlerException e) {
            throw new Exception("Not a Valid Url.");
        } finally {
            client.destroy();
        }
        return stringResponse;
}

次の例外が発生しています

javax.ws.rs.WebApplicationException: com.owlike.genson.JsonBindingException: Could not deserialize to type class java.lang.String
    at com.owlike.genson.ext.jaxrs.GensonJsonConverter.readFrom(GensonJsonConverter.java:130)
    at com.sun.jersey.api.client.ClientResponse.getEntity(ClientResponse.java:553)
    at com.sun.jersey.api.client.ClientResponse.getEntity(ClientResponse.java:506)
    at com.myapp.WebHttpClient.connect(WebHttpClient.java:74)
    at com.myapp.connection.connectors.WebConnector.getData(WebConnector.java:39)
    at com.myapp.adapter.impl.SourceAdapter.getData(SourceAdapter.java:29)
    at com.myapp.service.impl.WebServiceImpl.adapter(WebServiceImpl.java:174)
    at com.myapp.service.impl.WebServiceImpl.connect(WebServiceImpl.java:107)
    ... 41 more
Caused by: com.owlike.genson.JsonBindingException: Could not deserialize to type class java.lang.String
    at com.owlike.genson.Genson.deserialize(Genson.java:398)
    at com.owlike.genson.ext.jaxrs.GensonJsonConverter.readFrom(GensonJsonConverter.java:128)
    ... 48 more
Caused by: com.owlike.genson.stream.JsonStreamException: Readen value can not be converted to String
    at com.owlike.genson.stream.JsonReader.valueAsString(JsonReader.java:200)
    at com.owlike.genson.convert.DefaultConverters$StringConverter.deserialize(DefaultConverters.java:364)
    at com.owlike.genson.convert.DefaultConverters$StringConverter.deserialize(DefaultConverters.java:351)
    at com.owlike.genson.convert.NullConverter$NullConverterWrapper.deserialize(NullConverter.java:56)
    at com.owlike.genson.Genson.deserialize(Genson.java:396)
    ... 49 more

74 行目は を参照してい stringResponse = response.getEntity(String.class);ます。

Genson for Jersey を無効にする方法、または Genson を使用してこの問題を解決するにはどうすればよいですか?

ありがとう

4

2 に答える 2

4

Genson の最新のドキュメントは、github http://owlike.github.io/genson/でホストされています。

実際に何が起こるか

私には、Genson をどこでどのように使用したいのか明確ではありません。シリアル化のみに Genson を使用していますか? ジャージを通して使用していますか、それとも直接使用していますか?

getEntity(String.class) を実行すると、Jersey は Genson に着信 json を文字列に変換するように要求します。一般に、json 形式では文字列をルート値として使用できないことに注意してください。

ソリューション

  1. jersey 2.X (および最新の Genson リリース) にアップグレードします。新しい Jersey バージョンでは、入力を文字列として要求すると、MessageBodyReader に委任されません (正しい動作 IMO)。次に、この文字列を使用して、必要なタイプに変換できます。

  2. ClientResponse の getEntityInputStream メソッドを使用して生の InputStream を取得し、それを文字列に変換します。

  3. 別の解決策は、Gensons の MessageBodyReader の実装をオーバーライドして、deser を String に処理しないようにすることです。


JSON 変換を同時に処理する複数のライブラリを持つことは、私には正しく聞こえません。特に、両方 (Jackson と Genson) はいくつかの類似した機能を提供します。JAX-RS アプリで Genson を無効にできるイシューをオープンしました。

Genson 1.3 以降を更新すると、Jax-RS アプリで Genson を無効にするシステムが提供さます

于 2015-01-21T04:53:04.937 に答える
0

ソリューション2の例を次に示します...

ClientResponse の getEntityInputStream メソッドを使用して生の InputStream を取得し、文字列に変換します。

private String responseString(ClientResponse response) {
    InputStream stream = response.getEntityInputStream();
    StringBuilder textBuilder = new StringBuilder();
    try (Reader reader = new BufferedReader(new InputStreamReader(stream, Charset.forName(StandardCharsets.UTF_8.name())))) {
        int c = 0;
        while ((c = reader.read()) != -1) {
            textBuilder.append((char) c);
        }
        return textBuilder.toString();
    } catch (IOException e) {
        e.printStackTrace();
        return null;
    }
}
于 2020-03-03T04:38:39.773 に答える