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

com.base4j.util.http.HttpRequest Maven / Gradle / Ivy

The newest version!
package com.base4j.util.http;

import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import com.base4j.util.CollectionUtil;
import com.base4j.util.FileUtil;
import com.base4j.util.IoUtil;
import com.base4j.util.SecureSafeUtil;
import com.base4j.util.StrUtil;
import com.base4j.util.exceptions.HttpException;
import com.base4j.util.lang.Conver;

/**
 * http请求类
 *
 * @author Looly
 */
public class HttpRequest extends HttpBase {
    private static final String BOUNDARY = "--------------------Hutool_" + SecureSafeUtil.simpleUUID();
    private static final byte[] BOUNDARY_END = StrUtil.format("--{}--\r\n", BOUNDARY).getBytes();
    private static final String CONTENT_DISPOSITION_TEMPLATE = "Content-Disposition: form-data; name=\"{}\"\r\n\r\n";
    private static final String CONTENT_DISPOSITION_FILE_TEMPLATE = "Content-Disposition: form-data; name=\"{}\"; filename=\"{}\"\r\n";
    private static final String CONTENT_TYPE_MULTIPART_PREFIX = "multipart/form-data; boundary=";
    private static final String CONTENT_TYPE_FILE_TEMPLATE = "Content-Type: {}\r\n\r\n";

    private String url = "";
    private Method method = Method.GET;
    /**
     * 默认超时
     */
    private int timeout = -1;
    /**
     * 存储表单数据
     */
    protected Map form;
    /**
     * 文件表单对象,用于文件上传
     */
    protected Map fileForm;

    /**
     * 连接对象
     */
    private HttpConnection httpConnection;

    /**
     * 构造
     *
     * @param url URL
     */
    public HttpRequest(String url) {
        this.url = url;
    }

    // ---------------------------------------------------------------- Http Method start

    /**
     * 设置请求方法
     *
     * @param method HTTP方法
     * @return HttpRequest
     */
    public HttpRequest method(Method method) {
        this.method = method;
        return this;
    }

    /**
     * POST请求
     *
     * @param url URL
     * @return HttpRequest
     */
    public static HttpRequest post(String url) {
        return new HttpRequest(url).method(Method.POST);
    }

    /**
     * GET请求
     *
     * @param url URL
     * @return HttpRequest
     */
    public static HttpRequest get(String url) {
        return new HttpRequest(url).method(Method.GET);
    }

    /**
     * HEAD请求
     *
     * @param url URL
     * @return HttpRequest
     */
    public static HttpRequest head(String url) {
        return new HttpRequest(url).method(Method.HEAD);
    }

    /**
     * OPTIONS请求
     *
     * @param url URL
     * @return HttpRequest
     */
    public static HttpRequest options(String url) {
        return new HttpRequest(url).method(Method.OPTIONS);
    }

    /**
     * PUT请求
     *
     * @param url URL
     * @return HttpRequest
     */
    public static HttpRequest put(String url) {
        return new HttpRequest(url).method(Method.PUT);
    }

    /**
     * DELETE请求
     *
     * @param url URL
     * @return HttpRequest
     */
    public static HttpRequest delete(String url) {
        return new HttpRequest(url).method(Method.DELETE);
    }

    /**
     * TRACE请求
     *
     * @param url URL
     * @return HttpRequest
     */
    public static HttpRequest trace(String url) {
        return new HttpRequest(url).method(Method.TRACE);
    }
    // ---------------------------------------------------------------- Http Method end

    // ---------------------------------------------------------------- Http Request Header start

    /**
     * 设置contentType
     *
     * @param contentType contentType
     * @return HttpRequest
     */
    public HttpRequest contentType(String contentType) {
        header(Header.CONTENT_TYPE, contentType);
        return this;
    }

    /**
     * 设置是否为长连接
     *
     * @param isKeepAlive 是否长连接
     * @return HttpRequest
     */
    public HttpRequest keepAlive(boolean isKeepAlive) {
        header(Header.CONNECTION, isKeepAlive ? "Keep-Alive" : "Close");
        return this;
    }

    /**
     * @return 获取是否为长连接
     */
    public boolean isKeepAlive() {
        String connection = header(Header.CONNECTION);
        if (connection == null) {
            return !httpVersion.equalsIgnoreCase(HTTP_1_0);
        }

        return !connection.equalsIgnoreCase("close");
    }

    /**
     * 获取内容长度
     *
     * @return String
     */
    public String contentLength() {
        return header(Header.CONTENT_LENGTH);
    }

    /**
     * 设置内容长度
     *
     * @param value 长度
     * @return HttpRequest
     */
    public HttpRequest contentLength(int value) {
        header(Header.CONTENT_LENGTH, String.valueOf(value));
        return this;
    }
    // ---------------------------------------------------------------- Http Request Header end

    // ---------------------------------------------------------------- Form start

    /**
     * 设置表单数据
* * @param name 名 * @param value 值 */ public HttpRequest form(String name, Object value) { // 停用body this.body = null; if (value instanceof File) { return this.form(name, (File) value); } else if (this.form == null) { form = new HashMap(); } String strValue; if (value instanceof List) { // 列表对象 strValue = CollectionUtil.join((List) value, ","); } else if (CollectionUtil.isArray(value)) { // 数组对象 strValue = CollectionUtil.join((Object[]) value, ","); } else { // 其他对象一律转换为字符串 strValue = Conver.toStr(value, null); } form.put(name, strValue); return this; } /** * 设置表单数据 * * @param name 名 * @param value 值 * @param parameters 参数对,奇数为名,偶数为值 */ public HttpRequest form(String name, Object value, Object... parameters) { form(name, value); for (int i = 0; i < parameters.length; i += 2) { name = parameters[i].toString(); form(name, parameters[i + 1]); } return this; } /** * 设置map类型表单数据 * * @param formMap */ public HttpRequest form(Map formMap) { for (Entry entry : formMap.entrySet()) { form(entry.getKey(), entry.getValue()); } return this; } /** * 文件表单项
* 一旦有文件加入,表单变为multipart/form-data * * @param name 名 * @param file 文件 * @return HttpRequest */ public HttpRequest form(String name, File file) { if (null == file) { return this; } if (false == isKeepAlive()) { keepAlive(true); } if (this.fileForm == null) { fileForm = new HashMap(); } // 文件对象 this.fileForm.put(name, file); return this; } /** * 获取表单数据 * * @return Map */ public Map form() { return form; } // ---------------------------------------------------------------- Form end // ---------------------------------------------------------------- Body start /** * 设置内容主体 * * @param body */ public HttpRequest body(String body) { this.body = body; this.form = null; // 当使用body时,废弃form的使用 contentLength(body.length()); return this; } /** * 设置主体字节码 * * @param content * @param contentType */ public HttpRequest body(byte[] content, String contentType) { return body(StrUtil.str(content, charset)); } // ---------------------------------------------------------------- Body end /** * 设置超时 * * @param milliseconds * @return HttpRequest */ public HttpRequest timeout(int milliseconds) { this.timeout = milliseconds; return this; } /** * 执行Reuqest请求 * * @return HttpResponse */ public HttpResponse execute() { if (Method.GET.equals(method)) { // 优先使用body形式的参数,不存在使用form if (StrUtil.isNotBlank(this.body)) { this.url = HttpUtil.urlWithForm(this.url, this.body); } else { this.url = HttpUtil.urlWithForm(this.url, this.form); } } // 初始化 connection this.httpConnection = HttpConnection.create(url, method, timeout).header(this.headers, true); // 覆盖默认Header // 发送请求 try { if (Method.POST.equals(method) || Method.PUT.equals(method)) { send();// 发送数据 } else { this.httpConnection.connect(); } } catch (IOException e) { throw new HttpException(e.getMessage(), e); } // 获取响应 HttpResponse httpResponse = HttpResponse.readResponse(httpConnection); this.httpConnection.disconnect(); return httpResponse; } /** * 简单验证 * * @param username 用户名 * @param password 密码 * @return HttpRequest */ public HttpRequest basicAuth(String username, String password) { final String data = username.concat(":").concat(password); final String base64 = SecureSafeUtil.base64(data, charset); header("Authorization", "Basic " + base64, true); return this; } // ---------------------------------------------------------------- Private method start /** * 发送数据流 * * @throws IOException */ private void send() throws IOException { if (CollectionUtil.isNotEmpty(fileForm)) { sendMltipart(); } else { // Write的时候会优先使用body中的内容,write时自动关闭OutputStream String content; if (StrUtil.isNotBlank(this.body)) { content = this.body; } else { content = HttpUtil.toParams(this.form); } IoUtil.write(this.httpConnection.getOutputStream(), this.charset, true, content); } } /** * 发送多组件请求(例如包含文件的表单) * * @throws IOException */ private void sendMltipart() throws IOException { setMultipart();//设置表单类型为Multipart this.httpConnection.disableCache(); final OutputStream out = this.httpConnection.getOutputStream(); try { writeFileForm(out); writeForm(out); formEnd(out); } catch (IOException e) { throw e; } finally { IoUtil.close(out); } } // 普通字符串数据 /** * 发送普通表单内容 * * @param out 输出流 * @throws IOException */ private void writeForm(OutputStream out) throws IOException { if (CollectionUtil.isNotEmpty(this.form)) { StringBuilder builder = StrUtil.builder(); for (Entry entry : this.form.entrySet()) { builder.append("--").append(BOUNDARY).append(StrUtil.CRLF); builder.append(StrUtil.format(CONTENT_DISPOSITION_TEMPLATE, entry.getKey())); builder.append(entry.getValue()).append(StrUtil.CRLF); } IoUtil.write(out, this.charset, false, builder.toString()); } } /** * 发送文件对象表单 * * @param out 输出流 * @throws IOException */ private void writeFileForm(OutputStream out) throws IOException { File file; for (Entry entry : this.fileForm.entrySet()) { file = entry.getValue(); StringBuilder builder = StrUtil.builder().append("--").append(BOUNDARY).append(StrUtil.CRLF); builder.append(StrUtil.format(CONTENT_DISPOSITION_FILE_TEMPLATE, entry.getKey(), file.getName())); builder.append(StrUtil.format(CONTENT_TYPE_FILE_TEMPLATE, HttpUtil.getMimeType(file.getName()))); IoUtil.write(out, this.charset, false, builder.toString()); FileUtil.writeToStream(file, out); IoUtil.write(out, this.charset, false, StrUtil.CRLF); } } // 添加结尾数据 /** * 上传表单结束 * * @param out 输出流 * @throws IOException */ private void formEnd(OutputStream out) throws IOException { out.write(BOUNDARY_END); out.flush(); } /** * 设置表单类型为Multipart(文件上传) * * @return HttpConnection */ private void setMultipart() { this.httpConnection.header(Header.CONTENT_TYPE, CONTENT_TYPE_MULTIPART_PREFIX + BOUNDARY, true); } // ---------------------------------------------------------------- Private method end }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy