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

com.star.net.http.HttpRequest Maven / Gradle / Ivy

package com.star.net.http;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.util.Base64;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.UUID;
import java.util.Map.Entry;

import com.star.collection.ArrayUtil;
import com.star.collection.CollectionUtil;
import com.star.exception.pojo.ToolException;
import com.star.io.IoUtil;
import com.star.lang.Assert;
import com.star.object.ObjectUtil;
import com.star.string.StringUtil;
import com.star.uuid.NessUUID;

/**
 * http请求类
 * 
 * @author http://git.oschina.net/loolly/hutool
 *
 */
public class HttpRequest extends AbstractHttpBase {

	/** 分隔文本的开始 上传用 */
	private static final String BOUNDARY = "--------------------starimba_"
			+ NessUUID.toString(UUID.randomUUID()).replace("-", "");
	/** 分隔文本的结束 上传用 */
	private static final byte[] BOUNDARY_END = StringUtil.format("--{}--\r\n", BOUNDARY).getBytes();
	/** 不知道派啥用处,好像是文件上传下载描述用的 */
	private static final String CD_TEMPLATE = "Content-Disposition: form-data; name=\"{}\"\r\n\r\n";
	/** 不知道派啥用处,好像是文件上传下载描述用的 */
	private static final String CD_FILE_TEMPLATE = "Content-Disposition: form-data; name=\"{}\"; filename=\"{}\"\r\n";
	/** 不知道派啥用处,好像是文件上传下载描述用的 */
	private static final String CT_MULTIPART_PREFIX = "multipart/form-data; boundary=";
	/** 不知道派啥用处,好像是文件上传下载描述用的 */
	private static final String CT_FILE_TEMPLATE = "Content-Type: {}\r\n\r\n";

	/** 地址 */
	private transient String url;
	/** 请求方法 */
	private transient HttpMethod method = HttpMethod.GET;
	/** 默认超时 */
	private transient int timeout = -1;
	/** 存储表单数据 */
	protected transient Map form;
	/** 文件表单对象,用于文件上传 */
	protected transient Map fileForm;

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

	/**
	 * 构造方法
	 */
	public HttpRequest(final String url) {
		super();
		this.url = url;
	}

	/**
	 * 设置请求方法
	 */
	public HttpRequest setMethod(final HttpMethod method) {
		this.method = method;
		return this;
	}

	/**
	 * new 请求,同时设置方法
	 */
	public static HttpRequest getRequest(final String url, final HttpMethod method) {
		Assert.notBlank(url, "get http request failure,the input url is blank");
		Assert.notNull(method, "get http request failure,the input http method is null");
		return new HttpRequest(url).setMethod(method);
	}

	/**
	 * 设置contenttype
	 */
	public HttpRequest contentType(final String contentType) {
		setHeader(HttpHeader.CONTENT_TYPE, contentType, true);
		return this;
	}

	/**
	 * 设置是否常连接
	 */
	public HttpRequest keepAlive(final boolean isKeepAlive) {
		setHeader(HttpHeader.CONNECTION, isKeepAlive ? "Keep-Alive" : "Close", true);
		return this;
	}

	/**
	 * 是否为长连接
	 */
	public boolean isKeepAlive() {
		final String connection = getHeader(HttpHeader.CONNECTION);

		return Objects.isNull(connection) ? !HttpVersion.HTTP_1_0.toString().equalsIgnoreCase(httpVersion)
				: !"close".equalsIgnoreCase(connection);
	}

	/**
	 * 获取内容长度
	 */
	public String contentLength() {
		return getHeader(HttpHeader.CONTENT_LENGTH);
	}

	/**
	 * 设置内容长度
	 */
	public HttpRequest contentLength(final int value) {
		setHeader(HttpHeader.CONTENT_LENGTH, String.valueOf(value), true);
		return this;
	}

	/**
	 * 设置表单数据
	 */
	public HttpRequest setForm(final String name, final Object value) {
		this.body = "";

		if (value instanceof File) {
			return this.setForm(name, (File) value);
		} else if (this.form == null) {
			form = new HashMap<>();
		}

		String strValue;
		if (value instanceof List) {
			strValue = CollectionUtil.join((List) value, ',');
		} else if (ObjectUtil.isArray(value)) {
			strValue = ArrayUtil.join((Object[]) value, ',');
		} else if (value instanceof String) {
			strValue = (String) value;
		} else {
			strValue = value == null ? "" : value.toString();
		}

		form.put(name, strValue);
		return this;
	}

	/**
	 * 文件表单项
	 */
	public HttpRequest setForm(final String name, final File file) {
		if (!Objects.isNull(file)) {
			if (!isKeepAlive()) {
				keepAlive(true);
			}

			if (CollectionUtil.isEmpty(fileForm)) {
				fileForm = new HashMap();
			}
			// 文件对象
			this.fileForm.put(name, file);
		}
		return this;
	}

	/**
	 * 设置map类型表单数据
	 * 
	 */
	public HttpRequest setForm(final Map formMap) {
		for (final Map.Entry entry : formMap.entrySet()) {
			setForm(entry.getKey(), entry.getValue());
		}
		return this;
	}

	/**
	 * 获取表单数据
	 */
	public Map getForm() {
		return form;
	}

	/**
	 * 设置内容主体
	 */
	public HttpRequest body(final String body) {
		this.body = body;
		this.form = Collections.emptyMap(); // 当使用body时,废弃form的使用
		contentLength(body.length());
		return this;
	}

	/**
	 * 设置超时
	 */
	public HttpRequest setTimeout(final int milliseconds) {
		this.timeout = milliseconds;
		return this;
	}

	/**
	 * 执行请求
	 */
	public HttpResponse execute() {
		if (HttpMethod.GET.equals(method)) {
			this.url = StringUtil.isBlank(body) ? HttpUtil.urlWithForm(url, this.form)
					: HttpUtil.urlWithForm(url, this.body);
		}

		this.httpConnection = new HttpConnection(url, method, timeout).header(headers, true).initconn();

		try {
			if (HttpMethod.PUT.equals(method) || HttpMethod.POST.equals(method)) {
				send();
			} else {
				this.httpConnection.connect();
			}
		} catch (IOException e) {
			throw new ToolException(StringUtil.format("send request failue,the reason is: {}", e.getMessage()), e);
		}

		final HttpResponse httpResponse = HttpResponse.readResponse(httpConnection);

		this.httpConnection.disconnect();
		return httpResponse;
	}

	/** basic验证 */
	public HttpRequest basicAuth(final String username, final String password) {
		final String data = username.concat(":").concat(password);
		String base64;
		try {
			base64 = new String(Base64.getDecoder().decode(data), charset);
		} catch (UnsupportedEncodingException e) {
			throw new ToolException(StringUtil.format("basic verify failue,system not supports {} charset", charset),
					e);
		}
		setHeader("Authorization", "Basic " + base64, true);
		return this;
	}

	/**
	 * 发送数据流
	 */
	private void send() throws IOException {
		if (fileForm.isEmpty()) {
			// Write的时候会优先使用body中的内容,write时自动关闭OutputStream
			final String content = StringUtil.isBlank(this.body) ? HttpUtil.toParams(this.form) : this.body;
			final OutputStream output = this.httpConnection.getOutputStream();
			try {
				IoUtil.write(output, this.charset, content);
			} finally {
				IoUtil.close(output);
			}
		} else {
			sendMltipart();
		}
	}

	/**
	 * 发送多组件请求,上传文件用
	 */
	private void sendMltipart() {
		setMultipart();
		this.httpConnection.disableCache();
		final OutputStream out = this.httpConnection.getOutputStream();
		try {
			writeFileForm(out);
			writeForm(out);
			formEnd(out);
		} catch (IOException e) {
			throw new ToolException(
					StringUtil.format("send mltipart request failure,the reason is: {}", e.getMessage()), e);
		} finally {
			IoUtil.close(out);
		}
	}

	/**
	 * 普通字符串数据
	 */
	private void writeForm(final OutputStream output) throws IOException {
		if (!CollectionUtil.isEmpty(form)) {
			final StringBuilder builder = new StringBuilder();
			for (final Entry entry : this.form.entrySet()) {
				builder.append("--").append(BOUNDARY).append(StringUtil.CRLF)
						.append(StringUtil.format(CD_TEMPLATE, entry.getKey())).append(entry.getValue())
						.append(StringUtil.CRLF);
			}
			IoUtil.write(output, this.charset, builder.toString());
		}
	}

	/**
	 * 发送文件对象表单
	 */
	private void writeFileForm(final OutputStream output) {
		for (final Entry entry : this.fileForm.entrySet()) {
			final File file = entry.getValue();
			final StringBuilder builder = new StringBuilder();
			builder.append("--").append(BOUNDARY).append(StringUtil.CRLF)
					.append(StringUtil.format(CD_FILE_TEMPLATE, entry.getKey(), file.getName()))
					.append(StringUtil.format(CT_FILE_TEMPLATE, HttpUtil.getMimeType(file.getName())));
			IoUtil.write(output, this.charset, builder.toString());
			try {
				IoUtil.copy(new FileInputStream(file), output, 0);
			} catch (FileNotFoundException e) {
				throw new ToolException(
						StringUtil.format("send form object failure,the file {} not exists", file.getName()), e);
			}
			IoUtil.write(output, this.charset, StringUtil.CRLF);

		}
	}

	/**
	 * 添加结尾数据
	 */
	private void formEnd(final OutputStream output) {
		try {
			output.write(BOUNDARY_END);
			output.flush();
		} catch (IOException e) {
			throw new ToolException(StringUtil.format("upload file failure,the reason is: {}", e.getMessage()), e);
		}
	}

	/**
	 * 设置表单类型为Multipart(文件上传)
	 */
	private void setMultipart() {
		this.httpConnection.header(HttpHeader.CONTENT_TYPE, CT_MULTIPART_PREFIX + BOUNDARY, true);
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy