All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.amazonaws.http.JsonResponseHandler Maven / Gradle / Ivy

Go to download

The AWS SDK for Android - Core module holds the classes that is used by the individual service clients to interact with Amazon Web Services. Users need to depend on aws-java-sdk artifact for accessing individual client classes.

There is a newer version: 2.9.1
Show newest version
/*
 * Copyright 2010-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License").
 * You may not use this file except in compliance with the License.
 * A copy of the License is located at
 *
 *  http://aws.amazon.com/apache2.0
 *
 * or in the "license" file accompanying this file. This file is distributed
 * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
 * express or implied. See the License for the specific language governing
 * permissions and limitations under the License.
 */

package com.amazonaws.http;

import com.amazonaws.AmazonWebServiceResponse;
import com.amazonaws.ResponseMetadata;
import com.amazonaws.internal.CRC32MismatchException;
import com.amazonaws.transform.JsonUnmarshallerContext;
import com.amazonaws.transform.Unmarshaller;
import com.amazonaws.transform.VoidJsonUnmarshaller;
import com.amazonaws.util.CRC32ChecksumCalculatingInputStream;
import com.amazonaws.util.StringUtils;
import com.amazonaws.util.json.AwsJsonReader;
import com.amazonaws.util.json.JsonUtils;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Map;
import java.util.zip.GZIPInputStream;

/**
 * Default implementation of HttpResponseHandler that handles a successful
 * response from an AWS service and unmarshalls the result using a JSON
 * unmarshaller.
 *
 * @param  Indicates the type being unmarshalled by this response handler.
 */
public class JsonResponseHandler implements HttpResponseHandler> {

    /** The JSON unmarshaller to use when handling the response */
    private Unmarshaller responseUnmarshaller;

    /** Shared logger for profiling information */
    private static final Log log = LogFactory.getLog("com.amazonaws.request");

    public boolean needsConnectionLeftOpen = false;

    /**
     * Constructs a new response handler that will use the specified JSON
     * unmarshaller to unmarshall the service response and uses the specified
     * response element path to find the root of the business data in the
     * service's response.
     *
     * @param responseUnmarshaller The JSON unmarshaller to use on the response.
     */
    public JsonResponseHandler(Unmarshaller responseUnmarshaller) {
        this.responseUnmarshaller = responseUnmarshaller;

        /*
         * Even if the invoked operation just returns null, we still need an
         * unmarshaller to run so we can pull out response metadata. We might
         * want to pass this in through the client class so that we don't have
         * to do this check here.
         */
        if (this.responseUnmarshaller == null) {
            this.responseUnmarshaller = new VoidJsonUnmarshaller();
        }
    }

    /**
     * @see com.amazonaws.http.HttpResponseHandler#handle(com.amazonaws.http.HttpResponse)
     */
    @Override
    public AmazonWebServiceResponse handle(HttpResponse response) throws Exception {
        log.trace("Parsing service response JSON");

        String CRC32Checksum = response.getHeaders().get("x-amz-crc32");
        CRC32ChecksumCalculatingInputStream crc32ChecksumInputStream = null;

        // Get the raw content input stream to calculate the crc32 checksum on
        // gzipped data.
        InputStream content = response.getRawContent();
        if (content == null) {
            // An empty input stream to avoid NPE
            content = new ByteArrayInputStream("{}".getBytes(StringUtils.UTF8));
        }

        if (CRC32Checksum != null) {
            crc32ChecksumInputStream = new CRC32ChecksumCalculatingInputStream(content);
            content = crc32ChecksumInputStream;
        }
        if ("gzip".equals(response.getHeaders().get("Content-Encoding"))) {
            content = new GZIPInputStream(content);
        }

        AwsJsonReader jsonReader = JsonUtils.getJsonReader(new InputStreamReader(content,
                StringUtils.UTF8));

        try {
            AmazonWebServiceResponse awsResponse = new AmazonWebServiceResponse();
            JsonUnmarshallerContext unmarshallerContext = new JsonUnmarshallerContext(jsonReader,
                    response);

            T result = responseUnmarshaller.unmarshall(unmarshallerContext);

            if (CRC32Checksum != null) {
                long serverSideCRC = Long.parseLong(CRC32Checksum);
                long clientSideCRC = crc32ChecksumInputStream.getCRC32Checksum();
                if (clientSideCRC != serverSideCRC) {
                    throw new CRC32MismatchException(
                            "Client calculated crc32 checksum didn't match that calculated by server side");
                }
            }

            awsResponse.setResult(result);

            Map metadata = new HashMap();
            metadata.put(ResponseMetadata.AWS_REQUEST_ID,
                    response.getHeaders().get("x-amzn-RequestId"));
            awsResponse.setResponseMetadata(new ResponseMetadata(metadata));

            log.trace("Done parsing service response");
            return awsResponse;
        } finally {
            if (!needsConnectionLeftOpen) {
                try {
                    jsonReader.close();
                } catch (IOException e) {
                    log.warn("Error closing json parser", e);
                }
            }
        }
    }

    /**
     * Hook for subclasses to override in order to collect additional metadata
     * from service responses.
     *
     * @param unmarshallerContext The unmarshaller context used to process a
     *            service's response data.
     */
    @Deprecated
    protected void registerAdditionalMetadataExpressions(JsonUnmarshallerContext unmarshallerContext) {
    }

    /**
     * Since this response handler completely consumes all the data from the
     * underlying HTTP connection during the handle method, we don't need to
     * keep the HTTP connection open.
     *
     * @see com.amazonaws.http.HttpResponseHandler#needsConnectionLeftOpen()
     */
    @Override
    public boolean needsConnectionLeftOpen() {
        return needsConnectionLeftOpen;
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy