com.blacklocus.jres.http.HttpMethods.java Source code

Java tutorial

Introduction

Here is the source code for com.blacklocus.jres.http.HttpMethods.java

Source

/**
 * Copyright 2013 BlackLocus
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License 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.blacklocus.jres.http;

import com.blacklocus.jres.strings.ObjectMappers;
import com.blacklocus.misc.ExceptingRunnable;
import com.google.common.collect.ImmutableMap;
import org.apache.commons.io.IOUtils;
import org.apache.http.HttpEntity;
import org.apache.http.HttpEntityEnclosingRequest;
import org.apache.http.client.methods.HttpDelete;
import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpHead;
import org.apache.http.client.methods.HttpOptions;
import org.apache.http.client.methods.HttpPatch;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.client.methods.HttpTrace;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.InputStreamEntity;
import org.apache.http.entity.StringEntity;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.io.InputStream;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;
import java.net.URI;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class HttpMethods {

    private static final Logger LOG = LoggerFactory.getLogger(HttpMethods.class);

    private static final Map<String, HttpMethod> METHODS = ImmutableMap.<String, HttpMethod>builder()
            .put(HttpGet.METHOD_NAME, new HttpMethod() {
                @Override
                public HttpRequestBase newMethod(String url) {
                    return new HttpGet(url);
                }
            }).put(HttpPost.METHOD_NAME, new HttpMethod() {
                @Override
                public HttpRequestBase newMethod(String url) {
                    return new HttpPost(url);
                }
            }).put(HttpPut.METHOD_NAME, new HttpMethod() {
                @Override
                public HttpRequestBase newMethod(String url) {
                    return new HttpPut(url);
                }
            }).put(HttpDelete.METHOD_NAME, new HttpMethod() {
                @Override
                public HttpRequestBase newMethod(String url) {
                    HttpEntityEnclosingRequestBase request = new HttpEntityEnclosingRequestBase() {
                        @Override
                        public String getMethod() {
                            return HttpDelete.METHOD_NAME;
                        }
                    };
                    request.setURI(URI.create(url));
                    return request;
                }
            }).put(HttpHead.METHOD_NAME, new HttpMethod() {
                @Override
                public HttpRequestBase newMethod(String url) {
                    return new HttpHead(url);
                }
            }).put(HttpOptions.METHOD_NAME, new HttpMethod() {
                @Override
                public HttpRequestBase newMethod(String url) {
                    return new HttpOptions(url);
                }
            }).put(HttpTrace.METHOD_NAME, new HttpMethod() {
                @Override
                public HttpRequestBase newMethod(String url) {
                    return new HttpTrace(url);
                }
            }).put(HttpPatch.METHOD_NAME, new HttpMethod() {
                @Override
                public HttpRequestBase newMethod(String url) {
                    return new HttpPatch(url);
                }
            }).build();

    private static final ExecutorService PIPER = Executors.newCachedThreadPool();

    /**
     * @param method  http method, case-insensitive
     * @param url     destination of request
     * @param payload (optional) request body. An InputStream or String will be sent as is, while any other type will
     *                be serialized with {@link ObjectMappers#NORMAL} to JSON.
     * @return HttpUriRequest with header <code>Accept: application/json; charset=UTF-8</code>
     */
    public static HttpUriRequest createRequest(String method, String url, final Object payload) {

        LOG.debug("{} {}", method, url);

        HttpUriRequest httpUriRequest = METHODS.get(method.toUpperCase()).newMethod(url);
        httpUriRequest.addHeader("Accept", ContentType.APPLICATION_JSON.toString());

        if (payload != null) {
            try {

                // This cast will except if a body is given for non-HttpEntityEnclosingRequest types. Deal with it later.
                ((HttpEntityEnclosingRequest) httpUriRequest).setEntity(createEntity(payload));

            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
        return httpUriRequest;
    }

    static HttpEntity createEntity(final Object payload) throws IOException {
        final HttpEntity entity;
        if (payload instanceof InputStream) {

            if (LOG.isDebugEnabled()) {
                String stream = IOUtils.toString((InputStream) payload);
                LOG.debug(stream);
                entity = new StringEntity(stream, ContentType.APPLICATION_JSON);
            } else {
                entity = new InputStreamEntity((InputStream) payload, ContentType.APPLICATION_JSON);
            }

        } else if (payload instanceof String) {

            LOG.debug((String) payload);
            entity = new StringEntity((String) payload, ContentType.APPLICATION_JSON);

        } else { // anything else will be serialized with Jackson

            if (LOG.isDebugEnabled()) {
                String json = ObjectMappers.toJson(payload);
                LOG.debug(json);
                entity = new StringEntity(json, ContentType.APPLICATION_JSON);

            } else {
                final PipedOutputStream pipedOutputStream = new PipedOutputStream();
                final PipedInputStream pipedInputStream = new PipedInputStream(pipedOutputStream);
                PIPER.submit(new ExceptingRunnable() {
                    @Override
                    protected void go() throws Exception {
                        try {
                            ObjectMappers.NORMAL.writeValue(pipedOutputStream, payload);
                            pipedOutputStream.flush();
                        } finally {
                            IOUtils.closeQuietly(pipedOutputStream);
                        }
                    }
                });
                entity = new InputStreamEntity(pipedInputStream, ContentType.APPLICATION_JSON);
            }

        }
        return entity;
    }
}