Skip to content
标签
远程调用
字数
2124 字
阅读时间
13 分钟

抽象配置

java

import com.commnetsoft.commons.utils.StringUtils;
import org.apache.commons.collections.MapUtils;
import org.apache.http.HttpEntity;
import org.apache.http.HttpException;
import org.apache.http.HttpHeaders;
import org.apache.http.HttpStatus;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;

import java.io.IOException;
import java.net.URISyntaxException;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;

/**
 * @ClassName AbstractHttpConfig
 * @Author wuzm
 * @Date 2020/11/9 16:31
 * @Version 1.0
 */
public abstract class AbstractHttpConfig {
    private static CloseableHttpClient httpClient = HttpClients.createDefault();

    /**
     * 默认请求连接超时时间
     */
    public static final int DEFAULT_CONN_TIMEOUT = 3000;
    /**
     * 默认请求读取超时时间
     */
    public static final int DEFAULE_READ_TIMEOUT = 30000;

    private String uri;
    private Map<String, String> headers = new HashMap<>();
    private Map<String, Object> params = new HashMap<>();
    private String contentType;
    private int connTimeOut = DEFAULT_CONN_TIMEOUT;
    private int readTimeOut = DEFAULE_READ_TIMEOUT;
    private Charset requestCharset = StandardCharsets.UTF_8;
    private Charset responseCharset = StandardCharsets.UTF_8;

    AbstractHttpConfig(String uri, Map<String, Object> params) {
        this.uri = uri;
        if(null != params) this.params = params;
    }

    AbstractHttpConfig(String uri, Map<String, Object> params, Map<String, String> headers) {
        this.uri = uri;
        if(null != params) this.params = params;
        if(null != headers) this.headers = headers;
    }

    public String getUri() {
        return uri;
    }

    public Map<String, String> getHeaders() {
        return headers;
    }

    public Map<String, Object> getParams() {
        return params;
    }

    public int getConnTimeOut() {
        return connTimeOut;
    }

    public int getReadTimeOut() {
        return readTimeOut;
    }

    protected String getContentType() {
        return contentType;
    }

    public Charset getRequestCharset() {
        return requestCharset;
    }

    public Charset getResponseCharset() {
        return responseCharset;
    }


    public AbstractHttpConfig addParam(String key, Object value){
        this.params.put(key, value);
        return this;
    }
    public AbstractHttpConfig addParams(Map<String, Object> params){
        this.params.putAll(params);
        return this;
    }
    public AbstractHttpConfig addHeader(String key, String value){
        this.headers.put(key, value);
        return this;
    }
    public AbstractHttpConfig addHeaders(Map<String, String> headers){
        this.headers.putAll(headers);
        return this;
    }

    public AbstractHttpConfig setContentType(String contentType){
        this.contentType = contentType;
        return this;
    }

    public AbstractHttpConfig setTimeOut(int connTimeOut, int readTimeOut){
        if(connTimeOut > 0){
            this.connTimeOut = connTimeOut;
        }
        if(readTimeOut > 0){
            this.readTimeOut = readTimeOut;
        }
        return this;
    }

    public AbstractHttpConfig setChartSet(Charset requestCharset, Charset responseCharset){
        this.requestCharset = requestCharset;
        this.requestCharset = responseCharset;
        return this;
    }

    /**
     * 参数校验
     *  请求路径不能为空
     * @param
     * @return void
     * @author wuzm
     * @date 2020/11/16
     */
    public void validate(){
        if(StringUtils.isBlank(uri)){
            throw new IllegalArgumentException("uri不能为空");
        }
    }

    public <T> T send(ExecuteParser<T> executeParser) throws URISyntaxException, IOException, HttpException {
        //校验数据
        validate();
        //设置通用请求头参数
        setHeaders();
        //设置请求参数
        setParams();
        //获取请求体
        HttpRequestBase requestBase = getHttpRequest();

        if(MapUtils.isNotEmpty(getHeaders())){
            getHeaders().forEach(requestBase::setHeader);
        }
        //设置默认配置
        RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(connTimeOut).setConnectionRequestTimeout(readTimeOut).build();
        requestBase.setConfig(requestConfig);

        try (CloseableHttpResponse response = httpClient.execute(requestBase)) {
            int statusCode = response.getStatusLine().getStatusCode();
            if (HttpStatus.SC_OK == statusCode) {
                HttpEntity entity = response.getEntity();
                return executeParser.parse(entity);
            } else {
                throw new HttpException("http请求失败:" + statusCode);
            }
        }
    }

    protected void setHeaders(){
        //设置通用头信息
        if(!headers.containsKey(HttpHeaders.ACCEPT)){
            headers.put(HttpHeaders.ACCEPT, "*/*");
        }
        if(!headers.containsKey(HttpHeaders.CONNECTION)){
            headers.put(HttpHeaders.CONNECTION, "Keep-Alive");
        }
        if(!headers.containsKey(HttpHeaders.USER_AGENT)){
            headers.put(HttpHeaders.USER_AGENT, "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
        }

        //内容类型为空则从头信息中提取
        if(StringUtils.isBlank(contentType)){
            if(headers.containsKey(HttpHeaders.CONTENT_TYPE)){
                String headerContentType = headers.get(HttpHeaders.CONTENT_TYPE);
                if(StringUtils.isNotBlank(headerContentType)){
                    String[] contentArr = StringUtils.split(headerContentType, ";");
                    contentType = contentArr[0];
                    if(StringUtils.isNotBlank(contentType) && null != requestCharset){
                        headers.put(HttpHeaders.CONTENT_TYPE, contentType + ";charset=" + requestCharset.toString());
                    }
                }
            }else{
                //设置默认值
                //contentType = MediaType.APPLICATION_FORM_URLENCODED_VALUE;
                //headers.put(HttpHeaders.CONTENT_TYPE, contentType + ";charset=" + requestCharset.toString());
            }
        }else{
            if(null == requestCharset){
                headers.put(HttpHeaders.CONTENT_TYPE, contentType);
            }else{
                headers.put(HttpHeaders.CONTENT_TYPE, contentType + ";charset=" + requestCharset.toString());
            }
        }
    }

    protected void setParams(){}

    protected abstract HttpRequestBase getHttpRequest() throws URISyntaxException, IOException;





}



import org.apache.http.HttpEntity;

import java.io.IOException;

@FunctionalInterface
public interface ExecuteParser<T> {
     T parse(HttpEntity responseParser) throws IOException;
}

get配置

java

import org.apache.commons.collections.MapUtils;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.utils.URIBuilder;

import java.net.URISyntaxException;
import java.util.Map;

/**
 * @ClassName HttpGetConfig
 * @Author wuzm
 * @Date 2020/11/9 16:30
 * @Version 1.0
 */
public class HttpGetConfig extends AbstractHttpConfig {

    public HttpGetConfig(String uri, Map<String, Object> params) {
        super(uri, params);
    }

    public HttpGetConfig(String uri, Map<String, Object> params, Map<String, String> headers) {
        super(uri, params, headers);
    }


    @Override
    public HttpGet getHttpRequest() throws URISyntaxException {
        //构建uri
        URIBuilder uriBuilder = new URIBuilder(getUri());
        if(MapUtils.isNotEmpty(getParams())){
            getParams().forEach((key, value) -> {
                if(null == value){
                    uriBuilder.addParameter(key, "");
                }else{
                    uriBuilder.addParameter(key, value.toString());
                }
            });
        }
        return new HttpGet(uriBuilder.build());
    }


}

post请求

java

import com.alibaba.fastjson.JSON;
import com.commnetsoft.commons.utils.SimpleTypeUtil;
import com.commnetsoft.commons.utils.StringUtils;
import com.commnetsoft.core.utils.TemplateUtil;
import org.apache.commons.collections.MapUtils;
import org.apache.http.HttpHeaders;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.entity.mime.HttpMultipartMode;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.message.BasicNameValuePair;
import org.springframework.http.MediaType;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @ClassName HttpPostConfig
 * @Author wuzm
 * @Date 2020/11/9 16:31
 * @Version 1.0
 */
public class HttpPostConfig extends AbstractHttpConfig {

    public static final String APPLICATION_SOAP_XML_VALUE = "application/soap+xml";
    public static final String SOAP_ACTION = "SOAPAction";

    public enum SoapVersion{
        SOAP,SOAP2
    }

    /**
     * soap的版本 SoapVersion.SOAP:soap 1.1 SoapVersion.SOAP2:soap 1.2
     */
    private SoapVersion soapVersion;
    /**
     * soap请求的目标方法名
     */
    private String targetAction;
    /**
     * 目标名称空间,格式:xmls:[prefix]="[namespace]"
     * 如:xmlns:ser="http://service.api.commnetsoft.com"
     */
    private String targetNamespace;
    /**
     * 内容模板,如果不为空,则会用params进行参数填充,然后只发送该模板内容
     * 如果是soap请求,但是没有该模板时候,则会用params构建soap内容模板
     */
    private String template;

    private String prefix;
    private String namespace;


    public HttpPostConfig(String uri, Map<String, Object> params) {
        super(uri, params);
    }

    public HttpPostConfig(String uri, Map<String, Object> params, Map<String, String> headers) {
        super(uri, params, headers);
    }

    public SoapVersion getSoapVersion() {
        return soapVersion;
    }

    public HttpPostConfig soapVersion(SoapVersion soapVersion){
        this.soapVersion = soapVersion;
        return this;
    }

    public String getTemplate() {
        return template;
    }

    public HttpPostConfig setTemplate(String template) {
        this.template = template;
        return this;
    }

    public String getTargetAction() {
        return targetAction;
    }

    public HttpPostConfig setTargetAction(String targetAction) {
        this.targetAction = targetAction;
        return this;
    }

    public String getTargetNamespace() {
        return targetNamespace;
    }

    public void setTargetNamespace(String targetNamespace) {
        this.targetNamespace = targetNamespace;
    }



    @Override
    public void validate() {
        super.validate();
        //soap校验
        if(null != soapVersion){
            if(StringUtils.isBlank(targetAction)){
                throw new IllegalArgumentException("targetAction不能为空");
            }
        }
    }

    @Override
    protected void setHeaders() {
        super.setHeaders();
        //如果是soap,设置soap头信息
        if(null != soapVersion){
            //1.2版本
            if(SoapVersion.SOAP2.equals(soapVersion)){
                addHeader(HttpHeaders.CONTENT_TYPE, APPLICATION_SOAP_XML_VALUE);
            }else{
                //1.1版本设置头信息
                addHeader(HttpHeaders.CONTENT_TYPE, MediaType.TEXT_XML_VALUE);
                //获取目标名称空间的前缀和内容
                if(StringUtils.isNotBlank(targetNamespace)){
                    prefix = StringUtils.substringBetween(targetNamespace, ":", "=");
                    namespace = StringUtils.substringBetween(targetNamespace, "\"");
                }
                String soapAction;
                if(StringUtils.isNotBlank(namespace)){
                    if(!namespace.endsWith("/")){
                        namespace += "/";
                    }
                    soapAction = namespace + targetAction;
                }else{
                    soapAction = targetAction;
                }
                addHeader(SOAP_ACTION, StringUtils.defaultString(soapAction,""));
            }
        }
    }

    @Override
    protected void setParams() {
        super.setParams();
        //构建消息模板
        if (StringUtils.isNotBlank(template)) {
            if(MapUtils.isNotEmpty(getParams())){
                setTemplate(TemplateUtil.buildTemplate(template, getParams()));
            }
        }else {
            //如果是soap,并且消息模板是空的,则构建soap消息模板
            if((null != soapVersion) && StringUtils.isBlank(template) && MapUtils.isNotEmpty(getParams())){
                //构建soap消息模板
                template = BuildSoapContent(soapVersion, getParams());
            }
        }
    }

    @Override
    public HttpPost getHttpRequest() {
        HttpPost httpPost = new HttpPost(getUri());
        if(MapUtils.isEmpty(getParams()) && StringUtils.isBlank(template)){
            return httpPost;
        }
        if(StringUtils.equalsIgnoreCase(MediaType.MULTIPART_FORM_DATA_VALUE,getContentType())){
            //多文本类型发送
            MultipartEntityBuilder bulider = MultipartEntityBuilder.create().setCharset(getRequestCharset()).setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
            if(MapUtils.isNotEmpty(getParams())){
                getParams().forEach((key, value) -> {
                    if(null != value){
                        if(value instanceof FileBody){
                            bulider.addPart(key, (FileBody) value);
                        }else if(SimpleTypeUtil.isSimpleType(value.getClass())){
                            bulider.addTextBody(key, StringUtils.defaultString(value, ""), ContentType.create(MediaType.TEXT_PLAIN_VALUE, getRequestCharset()));
                        }else{
                            bulider.addTextBody(key, JSON.toJSONString(value), ContentType.create(MediaType.APPLICATION_JSON_VALUE, getRequestCharset()));
                        }
                    }else {
                        bulider.addTextBody(key, "", ContentType.create(MediaType.TEXT_PLAIN_VALUE, getRequestCharset()));
                    }
                });
            }
            httpPost.setEntity(bulider.build());
        } else if (StringUtils.equalsIgnoreCase(MediaType.APPLICATION_FORM_URLENCODED_VALUE, getContentType())) {
            //表单形式发送
            if (StringUtils.isNotBlank(template)) {
                httpPost.setEntity(new StringEntity(template,getRequestCharset()));
            } else if (MapUtils.isNotEmpty(getParams())) {
                List<NameValuePair> pairList = new ArrayList<>(getParams().size());
                getParams().forEach((key, value) -> {
                    NameValuePair pair = new BasicNameValuePair(key, value == null ? "" : value.toString());
                    pairList.add(pair);
                });
                UrlEncodedFormEntity urlEncodedFormEntity = new UrlEncodedFormEntity(pairList, getRequestCharset());
                httpPost.setEntity(urlEncodedFormEntity);
            }
        } else {
            if (StringUtils.isNotBlank(template)) {
                httpPost.setEntity(new StringEntity(template, getRequestCharset()));
            } else if (MapUtils.isNotEmpty(getParams())) {
                httpPost.setEntity(new StringEntity(JSON.toJSONString(getParams()), getRequestCharset()));
            }
        }
        return httpPost;
    }

    /**
     * 构建soap模板
     * @param soapVersion 是否是soap2.0
     * @param params 参数集合
     * @return java.lang.String
     * @author wuzm
     * @date 2020/11/13
     */
    private String BuildSoapContent(SoapVersion soapVersion,Map<String, Object> params){
        String soap = "soap";
        String soapenv = "xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\"  ";

        if(SoapVersion.SOAP2.equals(soapVersion)){
            soap = "soap12";
            soapenv = "xmlns:soap12=\"http://www.w3.org/2003/05/soap-envelope\"";
        }

        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append("<").append(soap).append(":Envelope ")
                .append("xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" ")
                .append("xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" ");

        if (StringUtils.isNotBlank(targetNamespace)) {
            stringBuilder.append(targetNamespace);
        }

        String method = StringUtils.isBlank(prefix) ? targetAction : prefix + ":" + targetAction;
        stringBuilder.append(soapenv)
                .append("> ")
                .append("<soapenv:Header/> ")
                .append("<").append(soap).append(":Body> ")
                .append("<").append(method).append(">");
        if(MapUtils.isNotEmpty(params)){
            params.forEach((key, value) -> stringBuilder.append("<").append(key).append(">").append(value).append("</").append(key).append(">"));
        }
        stringBuilder.append("</").append(method).append(">")
                .append("</").append(soap).append(":Body> ")
                .append("</").append(soap).append(":Envelope>");

        return stringBuilder.toString();
    }

}

工具类

java

import com.alibaba.fastjson.JSON;
import com.commnetsoft.commons.utils.HttpUtils;
import com.commnetsoft.commons.utils.StringUtils;
import org.apache.commons.io.FileUtils;
import org.apache.http.HttpException;
import org.apache.http.HttpHeaders;
import org.apache.http.util.EntityUtils;
import org.springframework.http.MediaType;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URISyntaxException;
import java.util.HashMap;
import java.util.Map;

/**
 * @ClassName HttpUtil
 * @Author wuzm
 * @Date 2020/11/9 16:30
 * @Version 1.0
 */
public class HttpUtil extends HttpUtils {
    public enum Method {
        POST, GET,
        ;
    }

    /**
     * 发送json格式请求
     * @param method 方法
     * @param uri 请求路径
     * @param params 参数
     * @param headers 头信息
     * @return java.lang.String
     * @author wuzm
     * @date 2020/11/16
     */
    public static String sendJson(Method method, String uri, Map<String, Object> params, Map<String, String> headers) throws URISyntaxException, IOException, HttpException {
        if(null == headers){
            headers = new HashMap<>();
        }
        headers.put(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_UTF8_VALUE);
        return sendCallBackString(method, uri, params, headers);
    }

    /**
     * POST方式发送MULTIPART_FORM_DATA请求
     * @param uri 请求路径
     * @param params 参数
     * @param headers 头信息
     * @return java.lang.String
     * @author wuzm
     * @date 2020/11/16
     */
    public static String postFormData(String uri, Map<String, Object> params, Map<String, String> headers) throws URISyntaxException, IOException, HttpException {
        if(null == headers){
            headers = new HashMap<>();
        }
        headers.put(HttpHeaders.CONTENT_TYPE, MediaType.MULTIPART_FORM_DATA_VALUE);
        return sendCallBackString(Method.POST, uri, params, headers);
    }

    /**
     * POST方式发送FORM_URLENCODED请求
     * @param uri 请求路径
     * @param params 参数
     * @param headers 头信息
     * @return java.lang.String
     * @author wuzm
     * @date 2020/11/16
     */
    public static String postFormUrlEncode(String uri, Map<String, Object> params, Map<String, String> headers) throws URISyntaxException, IOException, HttpException {
        if(null == headers){
            headers = new HashMap<>();
        }
        headers.put(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_FORM_URLENCODED_VALUE);
        return sendCallBackString(Method.POST, uri, params, headers);
    }

    /**
     * 发送消息返回String结果
     * @param method 请求方法{@link Method}
     * @param uri 请求路径
     * @param params 请求参数集合
     * @param headers 请求头信息
     * @return java.lang.String
     * @author wuzm
     * @date 2020/11/13
     */
    public static String sendCallBackString(Method method, String uri, Map<String, Object> params, Map<String, String> headers) throws HttpException, IOException, URISyntaxException {
        AbstractHttpConfig httpConfig = configHttp(method, uri, params, headers);
        if (null != httpConfig) {
            return httpConfig.send(httpEntity -> EntityUtils.toString(httpEntity, httpConfig.getResponseCharset()));
        }
        return null;
    }


    /**
     * 发送消息请求返回Map结果
     * @param method 请求方法{@link Method}
     * @param uri 请求路径
     * @param params 请求参数集合
     * @param headers 请求头信息集合
     * @return java.util.Map<java.lang.String,java.lang.Object>
     * @author wuzm
     * @date 2020/11/13
     */
    public static Map<String,Object> sendCallBackMap(Method method, String uri, Map<String, Object> params, Map<String, String> headers) throws HttpException, IOException, URISyntaxException {
        AbstractHttpConfig httpConfig = configHttp(method, uri, params, headers);
        if (null != httpConfig) {
            return httpConfig.send(httpEntity -> {
                String response = EntityUtils.toString(httpEntity, httpConfig.getResponseCharset());
                if(StringUtils.isNotBlank(response)){
                    return JSON.parseObject(response);
                }
                return new HashMap<>();
            });
        }
        return null;
    }

    /**
     * 发送消息请求返回File结果
     * @param method 请求方法{@link Method}
     * @param uri 请求路径
     * @param params 请求参数集合
     * @param headers 请求头信息集合
     * @return java.util.Map<java.lang.String,java.lang.Object>
     * @author wuzm
     * @date 2020/11/13
     */
    public static File sendCallBackFile(Method method, String uri, Map<String, Object> params, Map<String, String> headers,String filePath) throws HttpException, IOException, URISyntaxException {
        AbstractHttpConfig httpConfig = configHttp(method, uri, params, headers);
        if (null != httpConfig) {
            return httpConfig.send(httpEntity -> {
                InputStream is = httpEntity.getContent();
                File file = new File(filePath);
                FileUtils.copyInputStreamToFile(is, file);
                return file;
            });
        }
        return null;
    }

    /**
     * 设置请求配置信息
     * @param method 请求方法{@link Method}
     * @param uri 请求路径
     * @param params 请求参数集合
     * @param headers 请求头信息集合
     * @return com.commnetsoft.core.utils.http.AbstractHttpConfig
     * @author wuzm
     * @date 2020/11/13
     */
    public static AbstractHttpConfig configHttp(Method method, String uri, Map<String, Object> params, Map<String,String> headers){
        if (Method.POST.equals(method)) {
            return configPost(uri, params, headers);
        } else if (Method.GET.equals(method)) {
            return configGet(uri, params, headers);
        }
        return null;
    }

    public static HttpPostConfig configPost(String uri, Map<String, Object> params, Map<String,String> headers){
        return new HttpPostConfig(uri, params, headers);
    }

    public static HttpGetConfig configGet(String uri, Map<String, Object> params, Map<String, String> headers) {
        return new HttpGetConfig(uri, params, headers);
    }

}