第一个Java实现的接口测试
御都
字数 1065 · 阅读 0
2019-04-09 08:14
一、背景
使用HttpClient框架提交一个post&get申请,并对打印出返回值和状态码
二、操作步骤
1、在eclipse中创建一个maven工程,设置依赖关系
1.1 使用maven工程的原因:在pom.xml中设置依赖关系后会自动下载相应版本的jar包,减少了人工查找和安装jar包的步骤。
1.2 设置依赖关系
实质上就是将需要使用到的某个版本的jar包挂在该工程下,使得该工程下的类都能导入该jar包中的类进行使用。
【设置的具体内容】
<dependencies>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.2</version>
</dependency>
</dependencies>
【设置后的效果】
在Maven Dependencies下能够看到该版本的http jar包
image.png
1.3代码
package com.cn;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.utils.URLEncodedUtils;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
public class Demo {
public static void main(String[] args) {
doGet();
}
private static void doGet() {
String url = "https://edu.csdn.net/course/detail/3328";
//准备参数
List<BasicNameValuePair> param = new ArrayList<BasicNameValuePair>();
/*BasicNameValuePair pwd = new BasicNameValuePair("pwd","123456");
BasicNameValuePair phoneN = new BasicNameValuePair("phoneN","15284691234");
param.add(pwd);
param.add(phoneN);*/
/*BasicNameValuePair tn = new BasicNameValuePair("tn","62095104_8_oem_dg");
param.add(tn);
//参数转换为字符串
String paramStr = URLEncodedUtils.format(param, "UTF-8");
//拼接url
url += "?"+paramStr;*/
System.out.println("url为:"+url);
//创建Get对象
HttpGet get = new HttpGet(url);
//创建客户端对象
CloseableHttpClient client = HttpClients.createDefault();
try {
//提交get请求,client调用execute方法会要求抛出try cathch的异常
CloseableHttpResponse response = client.execute(get);
//获取状态码
int code = response.getStatusLine().getStatusCode();
//获取返回值信息
String result = EntityUtils.toString(response.getEntity());
System.out.println("返回码为:"+code);
System.out.println("返回内容为:"+result);
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
【报错 SSLHandshakeException】
url为:https://edu.csdn.net/course/detail/3328
javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:174)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1591)
at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Handshaker.java:187)
at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Handshaker.java:181)
at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:975)
at com.sun.net.ssl.internal.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:123)
at com.sun.net.ssl.internal.ssl.Handshaker.processLoop(Handshaker.java:516)
at com.sun.net.ssl.internal.ssl.Handshaker.process_record(Handshaker.java:454)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:884)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1096)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1123)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1107)
at org.apache.http.conn.ssl.SSLConnectionSocketFactory.createLayeredSocket(SSLConnectionSocketFactory.java:394)
at org.apache.http.conn.ssl.SSLConnectionSocketFactory.connectSocket(SSLConnectionSocketFactory.java:353)
at org.apache.http.impl.conn.DefaultHttpClientConnectionOperator.connect(DefaultHttpClientConnectionOperator.java:141)
at org.apache.http.impl.conn.PoolingHttpClientConnectionManager.connect(PoolingHttpClientConnectionManager.java:353)
at org.apache.http.impl.execchain.MainClientExec.establishRoute(MainClientExec.java:380)
at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:236)
at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:184)
at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:88)
at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:110)
at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:184)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:82)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:107)
at com.cn.Demo.doGet(Demo.java:47)
at com.cn.Demo.main(Demo.java:19)
Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:285)
at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:191)
at sun.security.validator.Validator.validate(Validator.java:218)
at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:126)
at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:209)
at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:249)
at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:954)
... 21 more
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:174)
at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:238)
at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:280)
... 27 more
【原因分析证书问题】
只要是你用Java去访问https的网站或者服务,都会碰到类似的错误,最根本的原因是CNNIC所颁发的证书并不被JDK所认可。
参考博客:
(https://blog.csdn.net/lovme_huan/article/details/75087618)
https://blog.csdn.net/fhx007/article/details/52251893
https://blog.csdn.net/paradise003/article/details/72876153
【解决方法信任所有的证书】
代码中加入createSSLClientDefault方法,用该方法返回一个客户端对象
public static CloseableHttpClient createSSLClientDefault() {
try {
SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy() {
public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException {
return true;
}
}).build();
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext);
return HttpClients.custom().setSSLSocketFactory(sslsf).build();
} catch (KeyManagementException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (KeyStoreException e) {
e.printStackTrace();
}
return HttpClients.createDefault();
}
【修改后的代码如下】
package interfaceDemo;
import java.io.IOException;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import javax.net.ssl.SSLContext;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLContextBuilder;
import org.apache.http.conn.ssl.TrustStrategy;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
public class Demo1 {
public static void main(String[] args) {
String url = "https://news.cnblogs.com/";
get(url);
}
public static void get(String url){
//创建一个get对象
HttpGet get = new HttpGet(url);
//创建一个client对象
CloseableHttpClient client = createSSLClientDefault();
try {
//使用client对象发送get请求
HttpResponse respons = client.execute(get);
//获取响应的结果
HttpEntity entity = respons.getEntity();
//将响应结果转换为字符串
String result = EntityUtils.toString(entity,"utf-8");
System.out.println("响应结果为:"+result);
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static CloseableHttpClient createSSLClientDefault() {
try {
SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy() {
public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException {
return true;
}
}).build();
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext);
return HttpClients.custom().setSSLSocketFactory(sslsf).build();
} catch (KeyManagementException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (KeyStoreException e) {
e.printStackTrace();
}
return HttpClients.createDefault();
}
}
【运行结果】
一个html,截取了开头的部分
响应结果为:<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="referrer" content="always" />
<title>IT新闻 - 博客园</title>
<meta name="keywords" content="IT新闻,it news,互联网新闻,业界新闻,IT资讯,IT业界,新闻频道" />
<meta name="description">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
<link id="rsslink" title="rss" type="application/rss+xml" rel="alternate"
【遗留_关于证书】
1、为什么会有证书这个东西呢?通过浏览器访问百度的网址时,没看到证书的相关东西
2 所有网址都需要证书吗?
3 上面那种解决方案是属于信任所有证书吗?还有其他解决方法吗?代码怎么写?
网友评论