Apache HTTPクライアントを使用してHTTPPost呼び出しを行ってから、ジャクソンを使用して応答からオブジェクトを作成しようとしています。ここに私のコードがあります:
private static final Logger log = Logger.getLogger(ReportingAPICall.class);
ObjectMapper mapper = new ObjectMapper();
public void makePublisherApiCall(String jsonRequest)
{
String url = ReaderUtility.readPropertyFile().getProperty("hosturl");
DefaultHttpClient client = new DefaultHttpClient();
try {
HttpPost postRequest = new HttpPost(url);
StringEntity entity = new StringEntity(jsonRequest);
postRequest.addHeader("content-type", "application/json");
log.info("pub id :"+ExcelReader.publisherId);
postRequest.addHeader("accountId", ExcelReader.publisherId);
postRequest.setEntity(entity);
HttpResponse postResponse = client.execute(postRequest);
log.info(EntityUtils.toString(postResponse.getEntity()));
// Response<PublisherReportResponse> response = mapper.readValue(postResponse.getEntity().getContent(), Response.class);
// log.info("Reponse "+response.toString());
} catch (UnsupportedEncodingException ex) {
log.error(ex.getMessage());
log.error(ex);
Assert.assertTrue(false, "Exception : UnsupportedEncodingException");
} catch (ClientProtocolException ex) {
log.error(ex.getMessage());
log.error(ex);
Assert.assertTrue(false, "Exception : ClientProtocolException");
} catch (IOException ex) {
log.error(ex.getMessage());
log.error(ex);
Assert.assertTrue(false, "Exception : IOException");
}
メソッドmakePublisherApiCall()は、たとえば100回実行されるループで呼び出されます。基本的に、行のコメントを外すと問題が発生します。
// Response<PublisherReportResponse> response = mapper.readValue(postResponse.getEntity().getContent(), Response.class);
// log.info("Reponse "+response.toString());
コメントを外した後、私は例外を受け取っています:
Attempted read from closed stream.
17:26:59,384 ERROR com.inmobi.reporting.automation.reportingmanager.ReportingAPICall - Java.io.IOException: Attempted read from closed stream.
それ以外の場合は正常に動作します。誰かが私が間違っていることを教えてください。
EntityUtils.toString(postResponse.getEntity())
は応答エンティティで何をしますか?エンティティのコンテンツストリームを消費していると思われます。 HttpClient javadoc は、繰り返し可能なエンティティのみを複数回使用できることを示しています。したがって、エンティティが繰り返し可能でない場合、コンテンツストリームをマッパーに再度フィードすることはできません。これを回避するには、マッパーにストリームの消費のみを許可する必要があります。コンテンツのログが必要な場合は、解析されたResponseオブジェクトをログに記録します。
同じ問題がありました。 IDEの「ウォッチ」または「検査」セクションでエンティティのコンテンツストリームを消費していないことを確認してください。消費(読み取り)された後、閉じられます。
そして、私の英語がすみません。
同じ問題がありました。
考えは、postResponseを使用する場合、別の場所で再び使用するために変数に配置する必要があるということです。そうでない場合、接続は閉じられ、同じ応答を再び使用することはできなくなります。
(デバッグ目的で)ログに記録していましたが、常に失敗します。
私の場合、この問題は別の理由に関連していたため、使用していないため、この問題が発生しています
closeableresponce=client.Getmethod(FinalUrl);
私の最初のTest1では言及されていましたが、Test2で見逃したとき、このコードを忘れてしまい、ストリームが閉じられたというメッセージが表示されます...
public void getapiwithheader() throws ParseException, IOException
{
client = new RestClient();
closeableresponce=client.Getmethod(FinalUrl);
HashMap<String, String> headermap = new HashMap<>();
headermap.put("content-type", "application/json");
//****************************************************************************
//Status code
//****************************************************************************
int statuscode =closeableresponce.getStatusLine().getStatusCode();
System.out.println("Status code "+statuscode);
Assert.assertEquals(statuscode,RESPONSE_STATUS_CODE_200, "Status code is not 200");
//****************************************************************************
// Json String
//****************************************************************************
String responsestring= EntityUtils.toString(closeableresponce.getEntity(),"UTF-8");
JSONObject respjsonobj = new JSONObject(responsestring);
System.out.println("Respose Json API"+respjsonobj);
//****************************************************************************
// Verify the value of the JSON
//****************************************************************************
String Email =TestUtil.getValueByJPath(respjsonobj,"/email");
System.out.println("******************************************");
System.out.println("Print the value of Email "+Email);
Assert.assertEquals(Email, "[email protected]");
}