我的代码执行顺序如下:
1.我自己的java类
OauthApi oauth = new OauthApi();
OauthToken ot = oauth.getOauthToken(code, WeixinUtil.appId, WeixinUtil.appSecret);
2.OauthApi类
protected final WeixinRequestExecutor weixinExecutor;
public BaseApi() {
this.weixinExecutor = new WeixinRequestExecutor();
}
public OauthToken getOauthToken(String code, String appid, String appsecret)
throws WeixinException {
String user_token_uri = getRequestUri("sns_user_token_uri");
WeixinResponse response = weixinExecutor.get(String.format(
user_token_uri, appid, appsecret, code));
return response.getAsObject(new TypeReference<OauthToken>() {
});
}
3.WeixinRequestExecutor类
public WeixinResponse get(String url) throws WeixinException {
HttpRequest request = new HttpRequest(HttpMethod.GET, url);
return doRequest(request);
}
public WeixinResponse doRequest(HttpRequest request) throws WeixinException {
request.setParams(params);
try {
HttpResponse httpResponse = httpClient.execute(request);
HttpHeaders headers = httpResponse.getHeaders();
WeixinResponse response = new WeixinResponse(httpResponse);
String contentType = headers.getFirst(HttpHeaders.CONTENT_TYPE);
String disposition = headers
.getFirst(HttpHeaders.CONTENT_DISPOSITION);
// json
if (contentType
.contains(ContentType.APPLICATION_JSON.getMimeType())
|| (disposition != null && disposition.indexOf(".json") > 0)) {
checkJson(response);
} else if (contentType.contains(ContentType.TEXT_XML.getMimeType())) {
checkXml(response);
} else if (contentType.contains(ContentType.TEXT_PLAIN
.getMimeType())
|| contentType
.contains(ContentType.TEXT_HTML.getMimeType())) {
try {
checkJson(response);
return response;
} catch (JSONException e) {
;
}
try {
checkXml(response);
return response;
} catch (IllegalArgumentException ex) {
;
}
throw new WeixinException(response.getAsString());
}
return response;
} catch (HttpClientException e) {
throw new WeixinException(e);
}
}
4.HttpComponent4_2类
public HttpResponse execute(HttpRequest request) throws HttpClientException {
HttpResponse response = null;
try {
HttpRequestBase uriRequest = methodMap.get(request.getMethod());
uriRequest.setURI(request.getURI());
boolean useSSL = "https".equals(request.getURI().getScheme());
SSLContext sslContext = null;
X509HostnameVerifier hostnameVerifier = null;
HttpParams params = request.getParams();
if (params != null) {
Builder requestConfig = RequestConfig.custom()
.setSocketTimeout(params.getSocketTimeout())
.setConnectTimeout(params.getConnectTimeout())
.setConnectionRequestTimeout(params.getReadTimeout());
if (params.getProxy() != null) {
InetSocketAddress socketAddress = (InetSocketAddress) params
.getProxy().address();
HttpHost proxy = new HttpHost(socketAddress.getHostName(),
socketAddress.getPort());
requestConfig.setProxy(proxy);
useSSL = false;
}
uriRequest.setConfig(requestConfig.build());
sslContext = params.getSSLContext();
hostnameVerifier = new CustomHostnameVerifier(
params.getHostnameVerifier());
}
if (useSSL) {
if (sslContext == null) {
sslContext = HttpClientFactory.allowSSLContext();
}
if (hostnameVerifier == null) {
hostnameVerifier = SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER;
}
httpClient = HttpClients.custom()
.setHostnameVerifier(hostnameVerifier)
.setSslcontext(sslContext).build();
}
addHeaders(request.getHeaders(), uriRequest);
addEntity(request.getEntity(), uriRequest);
CloseableHttpResponse httpResponse = httpClient.execute(uriRequest);
response = new HttpComponent4_2Response(httpResponse,
getContent(httpResponse));
handleResponse(response);
} catch (IOException e) {
throw new HttpClientException("I/O error on "
+ request.getMethod().name() + " request for ""
+ request.getURI().toString() + "":" + e.getMessage(), e);
} finally {
if (response != null) {
response.close();
}
}
return response;
}
5.CustomHostnameVerifier
protected static class CustomHostnameVerifier implements
X509HostnameVerifier {
private final HostnameVerifier hostnameVerifier;
public CustomHostnameVerifier(HostnameVerifier hostnameVerifier) {
this.hostnameVerifier = hostnameVerifier;
}
@Override
public boolean verify(String hostname, SSLSession session) {
return hostnameVerifier.verify(hostname, session);
}
@Override
public void verify(String host, SSLSocket ssl) throws IOException {
}
@Override
public void verify(String host, X509Certificate cert)
throws SSLException {
}
@Override
public void verify(String host, String[] cns, String[] subjectAlts)
throws SSLException {
}
}
在第2步的时候,我们有new 一个WeixinRequestExecutor,看代码:
public WeixinRequestExecutor() {
this(new HttpParams());
}
我们接着new 了一个HttpParams,HttpParams中有一个属性:private HostnameVerifier hostnameVerifier; 上面new的时候没有赋值,导致第5步的public boolean verify(String hostname, SSLSession session) 执行时报空指针异常。