37

アプリには 2 つの部分があります。
サーバー - REST サービスを提供する
クライアント - Spring を介してそれらを消費する restTemplate

HTTP ステータスに加えて、サーバーはエラーを詳細に説明する JSON を含む HTTP 本文を返します。そのため、カスタム エラー ハンドラを restTemplate に追加して、コード化された一部のエラーを非エラーとして処理しました。これは、HTTP 本文の解析に非常に役立ちます。

しかし、HTTP/1.1 401 Unauthorized の場合、HTTP 本文の解析によって例外が発生します。他のすべてのエラー コードは正常に処理されます (400、402 など)。エラーの場合に HTTP 応答を送信する単純なサーバー ロジックを使用しています。さまざまな種類のエラーに対する特別なルールはありません。

writeErrorToResponse(int status, String errMsg, HttpServletResponse resp) throws IOException {
        response.setStatus(status);
        response.setContentType(MediaType.APPLICATION_JSON_VALUE);
        String message = String.format("{\"error\":\"%s\"}", StringUtils.escapeJson(errMsg));
        resp.getWriter().println(message);
    }

ただし、クライアントのみで HTTP/1.1 401 が例外をスローします -"java.net.HttpRetryException: cannot retry due to server authentication, in streaming mode"

デバッグを行ったところ、問題の原因は SimpleClientHttpResponse のコードにあることがわかりました。

HttpURLConnection.getInputStream()

Fiddler を使用したトレースには、次の応答があります。メッセージはクライアントで正しく解析されます。

HTTP/1.1 402 Payment Required
X-Powered-By: Servlet/3.0
Content-Type: application/json
Content-Language: en-GB
Content-Length: 55
Connection: Close
Date: Sat, 25 May 2013 10:10:44 GMT
Server: WebSphere Application Server/8.0

{"error":"I cant find that user.  Please try again."}

そして、例外の原因となるメッセージ:

HTTP/1.1 401 Unauthorized
X-Powered-By: Servlet/3.0
Content-Type: application/json
Content-Language: en-GB
Content-Length: 55
Date: Sat, 25 May 2013 11:00:21 GMT
Server: WebSphere Application Server/8.0

{"error":"I cant find that user.  Please try again."}

この状況で java.net.HttpRetryException の原因は何でしょうか?

さらに: 少し前まで、このメカニズムは正常に機能していました。しかし、アプリで多くのコードを変更したため.

4

5 に答える 5

10

構成済みの HttpComponentsClientHttpRequestFactory を RestTemplate に渡すと役立つと思います。 ここで、それを行う方法に関する解決策を見つけることができます。

このような開発ソリューションを使用した理由は、401 や 404 などの HTTP エラー応答の本文で応答メッセージを処理し、アプリケーションを実サーバー側の環境にデプロイできるようにするためでした。

于 2015-04-06T08:45:49.787 に答える