0

I am sending the following Sig4 request:

 Response response = new AmazonHttpClient(new ClientConfiguration())
                .requestExecutionBuilder()
                .executionContext(new ExecutionContext(true))
                .request(request)
                .errorResponseHandler(new AWSErrorResponseHandler(false))
                .execute(new AWSResponseHandler(false));

I then convert the response to httpResponse: (not sure if its needed)

com.amazonaws.http.HttpResponse httpResponse =  response.getHttpResponse();

My issue is that I was unable to find a simple explanation on how to extract the actual JSON response string out of my response.

EDIT: Note that when I follow the SDK doc and try to extract the content as an input stream:

IOUtils.toString(response.getHttpResponse().getContent());

I get the following exception:

java.io.IOException: Attempted read from closed stream.
    at org.apache.http.impl.io.ContentLengthInputStream.read(ContentLengthInputStream.java:165)
    at org.apache.http.conn.EofSensorInputStream.read(EofSensorInputStream.java:135)
    at com.amazonaws.internal.SdkFilterInputStream.read(SdkFilterInputStream.java:90)
    at com.amazonaws.event.ProgressInputStream.read(ProgressInputStream.java:180)
    at java.base/java.io.FilterInputStream.read(FilterInputStream.java:106)
    at com.amazonaws.util.IOUtils.toByteArray(IOUtils.java:44)
    at com.amazonaws.util.IOUtils.toString(IOUtils.java:58)

Any assistant would be highly appreciated :)

PloniStacker
  • 574
  • 4
  • 23
  • `getContent()` does give you an input stream that you should then consume into a String which you then can parse as JSON - at least that is what I would do by looking at the docs. – luk2302 Jan 14 '21 at 11:32
  • That was my first attempt using String text = IOUtils.toString(httpResponse.getContent()), but I got an "Attempted read from closed stream" exception: java.io.IOException: Attempted read from closed stream. at org.apache.http.impl.io.ContentLengthInputStream.read(ContentLengthInputStream.java:165) at org.apache.http.conn.EofSensorInputStream.read(EofSensorInputStream.java:135) at com.amazonaws.internal.SdkFilterInputStream.read(SdkFilterInputStream.java:90) at com.amazonaws.event.ProgressInputStream.read(ProgressInputStream.java:180) – PloniStacker Jan 14 '21 at 13:15
  • maybe try different InputStream to String variants [StackOverFlow - InputStream to String](https://stackoverflow.com/questions/309424/how-do-i-read-convert-an-inputstream-into-a-string-in-java) – RatzzFatzz Jan 14 '21 at 14:11

2 Answers2

0

For HTTP responses I used RestAssured. With this it should work like this:

Response response = new AmazonHttpClient().execute() // build and run your query
String json = response.getBody().prettyPrint();

If you want to use the information of the json directly afterwards within the code I can recommend creating a POJO and then doing the following:

AmazonResponseDto dto = response.as(AmazonResponseDto.class)

A quick look up of the com.amazonaws.http.HttpResponse docs showed me, that you can get an InputStream from it, but not directly a json. I don't know the package of the Response you used in your first code block, that's why I recommended RestAssured.

RatzzFatzz
  • 144
  • 1
  • 7
  • Thanks for your answer! Unfortunately I cant use additional dependencies in my project so RestAssured is not an option. I am using beans so to be able to use the result straight into a bean would be great but I am not sure how to go about this. At the moment I am turning String to bean as such: gson.fromJson(jsonString, SomeClass.class) Regarding the InputStream that I get from result, I am unable to use it as I am getting an "Attempted read from closed stream" exception. (See my answer to the comment on my original question) – PloniStacker Jan 14 '21 at 13:24
  • @PloniStacker which package is Response from? – RatzzFatzz Jan 14 '21 at 13:27
  • com.amazonaws.Response – PloniStacker Jan 14 '21 at 13:30
  • @PloniStacker For the com.amazonws.Response the `getAwsResponse()` may work. I don't know the possible return types (since it's a generic), but maybe something like `Object object = response.getAwsResponse()` and then parsing it. If you know the possible return types, obviously use those. – RatzzFatzz Jan 14 '21 at 13:57
0

I found the reason for my issue. As some have suggested, the response is an input stream, yet when I tried to extract it to starting I either got a closed connection exception or nothing. To fix this I had to change .execute(new AWSResponseHandler(true)); to true instead of false in order to keep the connection open. AWSResponseHandler implements HttpResponseHandler and sets the following:

public AWSResponseHandler(boolean connectionLeftOpen) {
        this.needsConnectionLeftOpen = connectionLeftOpen;
    }

I hope this helps anyone who gets into a similar situation.

PloniStacker
  • 574
  • 4
  • 23