package com.mgm.mcrm.common.httpclient; import com.mgm.mcrm.common.enums.HttpMethods; import org.apache.hc.client5.http.classic.HttpClient; import org.apache.hc.client5.http.config.RequestConfig; import org.apache.hc.client5.http.entity.mime.Header; import org.apache.hc.core5.http.protocol.HttpContext; import org.apache.hc.core5.util.Timeout; import java.io.OutputStream; import java.nio.charset.Charset; import java.util.HashMap; import java.util.Map; import com.mgm.mcrm.common.httpclient.HttpEntityBuilder; /** * HTTP 请求选项类 * * 用于构建 HTTP 请求的选项对象,支持链式调用。 * 注意:此类不是 Spring 配置类,而是 HTTP 请求参数的构建器。 * * @author Aaka */ public class HttpRequestOptions { private HttpRequestOptions(){}; /** * 获取实例 * @return 返回当前对象 */ public static HttpRequestOptions create(){ return new HttpRequestOptions(); } /** * HttpClient对象 */ private HttpClient client; /** * Header头信息 */ private Header[] headers; /** * 是否返回response的headers */ private boolean isReturnRespHeaders; /** * 请求方法 */ private HttpMethods method=HttpMethods.GET; /** * 请求方法名称 */ private String methodName; /** * 用于cookie操作 */ private HttpContext context; /** * 以json格式作为输入参数 */ private String json; /** * 输入输出编码 */ private String encoding= Charset.defaultCharset().displayName(); /** * 输入编码 */ private String inenc; /** * 输出编码 */ private String outenc; /** * 设置RequestConfig */ private RequestConfig requestConfig; /** * 当前请求的输出流 */ private OutputStream out; /** * 当前请求的 URL */ private String url; /** * 当前请求的参数,随实例保存,避免线程复用时混入上一次请求的数据 */ private Map parameters; /** * @param client HttpClient对象 * @return 返回当前对象 */ public HttpRequestOptions client(HttpClient client) { this.client = client; return this; } /** * @param url 资源url * @return 返回当前对象 */ public HttpRequestOptions url(String url) { this.url = url; return this; } /** * @param headers Header头信息 * @return 返回当前对象 */ public HttpRequestOptions headers(Header[] headers) { this.headers = headers; return this; } /** * Header头信息(是否返回response中的headers) * * @param headers Header头信息 * @param isReturnRespHeaders 是否返回response中的headers * @return 返回当前对象 */ public HttpRequestOptions headers(Header[] headers, boolean isReturnRespHeaders) { this.headers = headers; this.isReturnRespHeaders=isReturnRespHeaders; return this; } /** * @param method 请求方法 * @return 返回当前对象 */ public HttpRequestOptions method(HttpMethods method) { this.method = method; return this; } /** * @param methodName 请求方法 * @return 返回当前对象 */ public HttpRequestOptions methodName(String methodName) { this.methodName = methodName; return this; } /** * @param context cookie操作相关 * @return 返回当前对象 */ public HttpRequestOptions context(HttpContext context) { this.context = context; return this; } /** * @param map 传递参数 * @return 返回当前对象 */ public HttpRequestOptions map(Map map) { if (map == null) { parameters = null; } else if (parameters == null || map.isEmpty()) { parameters = new HashMap<>(map); } else { parameters.putAll(map); } return this; } /** * @param json 以json格式字符串作为参数 * @return 返回当前对象 */ public HttpRequestOptions json(String json) { this.json = json; parameters = new HashMap<>(); parameters.put(HttpEntityBuilder.ENTITY_JSON, json); return this; } /** * @param filePaths 待上传文件所在路径 * @return 返回当前对象 */ public HttpRequestOptions files(String[] filePaths) { return files(filePaths, "file"); } /** * 上传文件时用到 * @param filePaths 待上传文件所在路径 * @param inputName 即file input 标签的name值,默认为file * @return 返回当前对象 */ public HttpRequestOptions files(String[] filePaths, String inputName) { return files(filePaths, inputName, false); } /** * 上传文件时用到 * @param filePaths 待上传文件所在路径 * @param inputName 即file input 标签的name值,默认为file * @param forceRemoveContentTypeChraset 是否强制一处content-type中设置的编码类型 * @return 返回当前对象 */ public HttpRequestOptions files(String[] filePaths, String inputName, boolean forceRemoveContentTypeChraset) { if (parameters == null) { parameters = new HashMap<>(); } parameters.put(HttpEntityBuilder.ENTITY_MULTIPART, filePaths); parameters.put(HttpEntityBuilder.ENTITY_MULTIPART+".name", inputName); parameters.put(HttpEntityBuilder.ENTITY_MULTIPART+".rmCharset", forceRemoveContentTypeChraset); return this; } /** * @param encoding 输入输出编码 * @return 返回当前对象 */ public HttpRequestOptions encoding(String encoding) { //设置输入输出 inenc(encoding); outenc(encoding); this.encoding = encoding; return this; } /** * @param inenc 输入编码 */ public void inenc(String inenc) { this.inenc = inenc; } /** * @param outenc 输出编码 */ public void outenc(String outenc) { this.outenc = outenc; } /** * @param out 输出流对象 * @return 返回当前对象 */ public HttpRequestOptions out(OutputStream out) { this.out = out; return this; } /** * 设置超时时间 * * @param timeout 超时时间,单位-毫秒 * @return 返回当前对象 */ public HttpRequestOptions timeout(int timeout){ return timeout(timeout, true); } /** * 设置超时时间以及是否允许网页重定向(自动跳转 302) * * @param timeout 超时时间,单位-毫秒 * @param redirectEnable 自动跳转 * @return 返回当前对象 */ public HttpRequestOptions timeout(int timeout, boolean redirectEnable){ // 配置请求的超时设置 // 注意:HttpClient 5 中需要使用 Timeout 对象,而不是直接的 int 值 Timeout timeoutValue = Timeout.ofMilliseconds(timeout); RequestConfig config = RequestConfig.custom() .setConnectionRequestTimeout(timeoutValue) .setResponseTimeout(timeoutValue) .setRedirectsEnabled(redirectEnable) .build(); return timeout(config); } /** * 设置代理、超时时间、允许网页重定向等 * * @param requestConfig 超时时间,单位-毫秒 * @return 返回当前对象 */ public HttpRequestOptions timeout(RequestConfig requestConfig){ this.requestConfig = requestConfig; return this; } public HttpClient client() { return client; } public Header[] headers() { return headers; } public boolean isReturnRespHeaders() { return isReturnRespHeaders; } public String url() { return url; } public HttpMethods method() { return method; } public String methodName() { return methodName; } public HttpContext context() { return context; } public Map map() { return parameters; } public String json() { return json; } public String encoding() { return encoding; } public String inenc() { return inenc == null ? encoding : inenc; } public String outenc() { return outenc == null ? encoding : outenc; } public OutputStream out() { return out; } public RequestConfig requestConfig() { return requestConfig; } }