xiaoyong931011
2022-07-28 363c0f2d5ac2cec13e28bcba4f46f272dff448dc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
package cc.mrbird.febs.pay.util;
 
import cc.mrbird.febs.pay.service.IServiceRequest;
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.xml.DomDriver;
import com.thoughtworks.xstream.io.xml.XmlFriendlyNameCoder;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ConnectTimeoutException;
import org.apache.http.conn.ConnectionPoolTimeoutException;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLContexts;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
 
import javax.net.ssl.SSLContext;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.SocketTimeoutException;
import java.security.*;
import java.security.cert.CertificateException;
 
/**
 * User: rizenguo
 * Date: 2014/10/29
 * Time: 14:36
 */
public class HttpsRequest2 implements IServiceRequest {
 
    public interface ResultListener {
 
 
        public void onConnectionPoolTimeoutError();
 
    }
 
    //表示请求器是否已经做了初始化工作
    private boolean hasInit = false;
 
    //连接超时时间,默认10秒
    private int socketTimeout = 10000;
 
    //传输超时时间,默认30秒
    private int connectTimeout = 30000;
 
    //请求器的配置
    private RequestConfig requestConfig;
 
    //HTTP请求器
    private CloseableHttpClient httpClient;
    //证书地址
    private String  certLocalPath;
    //商户号
    private String mchId;
 
    public HttpsRequest2() throws UnrecoverableKeyException, KeyManagementException, NoSuchAlgorithmException, KeyStoreException, IOException {
 
    }
 
    private void init() throws IOException, KeyStoreException, UnrecoverableKeyException, NoSuchAlgorithmException, KeyManagementException {
 
        KeyStore keyStore = KeyStore.getInstance("PKCS12");
        FileInputStream instream = new FileInputStream(new File(certLocalPath));//加载本地的证书进行https加密传输
        try {
            keyStore.load(instream, mchId.toCharArray());//设置证书密码
        } catch (CertificateException e) {
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } finally {
            instream.close();
        }
        // Trust own CA and all self-signed certs
        SSLContext sslcontext = SSLContexts.custom()
                .loadKeyMaterial(keyStore, mchId.toCharArray())
                .build();
        // Allow TLSv1 protocol only
        SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
                sslcontext,
                new String[]{"TLSv1"},
                null,
                SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);
 
 
        httpClient = HttpClients.custom()
                .setSSLSocketFactory(sslsf)
                .build();
        // httpClient = HttpClients.custom().build();
        //根据默认超时限制初始化requestConfig
        requestConfig = RequestConfig.custom().setSocketTimeout(socketTimeout).setConnectTimeout(connectTimeout).build();
        hasInit = true;
    }
 
    /**
     * 通过Https往API post xml数据
     *
     * @param url    API地址
     * @param xmlObj 要提交的XML数据对象
     * @return API回包的实际数据
     * @throws IOException
     * @throws KeyStoreException
     * @throws UnrecoverableKeyException
     * @throws NoSuchAlgorithmException
     * @throws KeyManagementException
     */
 
    public String sendPost(String url, Object xmlObj) throws IOException, KeyStoreException, UnrecoverableKeyException, NoSuchAlgorithmException, KeyManagementException {
 
        if (!hasInit) {
            init();
        }
 
        String result = null;
 
        HttpPost httpPost = new HttpPost(url);
 
        //解决XStream对出现双下划线的bug
        XStream xStreamForRequestPostData = new XStream(new DomDriver("UTF-8", new XmlFriendlyNameCoder("-_", "_")));
 
        //将要提交给API的数据对象转换成XML格式数据Post给API
        String postDataXML = xStreamForRequestPostData.toXML(xmlObj);
 
        //得指明使用UTF-8编码,否则到API服务器XML的中文不能被成功识别
        StringEntity postEntity = new StringEntity(postDataXML, "UTF-8");
        httpPost.addHeader("Content-Type", "text/xml");
        httpPost.setEntity(postEntity);
 
        //设置请求器的配置
        httpPost.setConfig(requestConfig);
 
 
        try {
            HttpResponse response = httpClient.execute(httpPost);
 
            HttpEntity entity = response.getEntity();
 
            result = EntityUtils.toString(entity, "UTF-8");
 
        } catch (ConnectionPoolTimeoutException e) {
//            log.e("http get throw ConnectionPoolTimeoutException(wait time out)");
 
        } catch (ConnectTimeoutException e) {
//            log.e("http get throw ConnectTimeoutException");
 
        } catch (SocketTimeoutException e) {
//            log.e("http get throw SocketTimeoutException");
 
        } catch (Exception e) {
            e.printStackTrace();
//            log.e("http get throw Exception");
 
        } finally {
            httpPost.abort();
        }
 
        return result;
    }
 
    /**
     * 设置连接超时时间
     *
     * @param socketTimeout 连接时长,默认10秒
     */
    public void setSocketTimeout(int socketTimeout) {
        this.socketTimeout = socketTimeout;
        resetRequestConfig();
    }
 
    /**
     * 设置传输超时时间
     *
     * @param connectTimeout 传输时长,默认30秒
     */
    public void setConnectTimeout(int connectTimeout) {
        this.connectTimeout = connectTimeout;
        resetRequestConfig();
    }
 
    private void resetRequestConfig(){
        requestConfig = RequestConfig.custom().setSocketTimeout(socketTimeout).setConnectTimeout(connectTimeout).build();
    }
 
    /**
     * 允许商户自己做更高级更复杂的请求器配置
     *
     * @param requestConfig 设置HttpsRequest的请求器配置
     */
    public void setRequestConfig(RequestConfig requestConfig) {
        this.requestConfig = requestConfig;
    }
 
 
    public String getMchId() {
        return mchId;
    }
 
    public void setMchId(String mchId) {
        this.mchId = mchId;
    }
 
    public String getCertLocalPath() {
        return certLocalPath;
    }
 
    public void setCertLocalPath(String certLocalPath) {
        this.certLocalPath = certLocalPath;
    }
}