这两天快被这个问题搞死了。。。
环境:myeclipse8.5 + jdk1.6 + jboss5.0 + httpclient3.0
首先是服务端如何支持https的问题,步骤如下。
1、生成服务端证书,cmd命令:
keytool -genkey -alias tomcat -keyalg RSA
或者
keytool -genkey -alias jboss -keyalg RSA
按照提示输入一些信息,如果是本机调试,用户名最好输入localhost,否则会出现不匹配异常。
完成后,系统默认把文件放在我的文档里面,名字默认是.keystore。
把文件复制到jboss-5.1.0.GA\server\default\conf下面。
2、在jboss-5.1.0.GA\server\default\deploy\jbossweb.sar\打开server.xml,找到如下:
<!-- SSL/TLS Connector configuration using the admin devl guide keystore-->
<Connector protocol="HTTP/1.1" SSLEnabled="true"
port="443" address="${jboss.bind.address}"
scheme="https" secure="true" clientAuth="false"
keystoreFile="${jboss.server.home.dir}/conf/.keystore"
keystorePass="123456" sslProtocol = "TLS" />
jboss默认有这些,但是注释了,如果没有就添加进去。需要注意下面几个属性值:
port是端口号,默认是8443。
keystoreFile="${jboss.server.home.dir}/conf/.keystore"是keystore文件路径。keystorePass是提示中输入的密码。
3、将系统部署后,启动,浏览器中输入https://localhost:443/projectName
理论上会提示证书不安全,点通过、继续、忽略之类的一个提示,就可以访问了。
同时不影响原来的http://localhost:8080/projectName访问。
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
然后是使用httpClient如何访问的问题。
使用https访问时,需要证书验证的。https也是通过证书验证的方式使的所提供的服务更具有安全性。上面的浏览器能够直接访问,是因为浏览器能够自动处理证书的问题,使用httpClient访问https时,只能人为的去处理证书了。有两种方式。
一、第一个是通过浏览器导出证书.cer文件,导入到在httpClient所运行的jdk中,jdk信任该证书后,就可以访问了。
二、将服务端的.keystore文件拿到客户端,程序中通过下面两行来手动信任该证书。
System.setProperty("javax.net.ssl.trustStore", "D:/B/.keystore");
System.setProperty("javax.net.ssl.trustStorePassword","123456");;
~~~~~~~~~~~~~~~~~~
第二种方式只能用于自身调试,因为在系统实际运行中,客户端不可能实时的去拿服务端的.keystore文件。详细介绍一下第一种方式。
1、通过浏览器导出证书。
在浏览器中输入https://localhost:443/projectName,根据提示导出证书。
操作过程中,发现ie8找不到导出的按钮,我用的是filefox,输入地址后,会看到证书不信任提示,按照提示一步步导出,“添加例外——查看——详细信息——导出”,保存类型选择“X509含链证书(PEM)”,即后缀为.crt
打开crt文件,选择“详细信息——复制到文件——一顿下一步”,生成.cer文件。
2、将证书导入到jdk中。
cmd中进入到jdk1.6.0_21\jre\lib\security文件夹中,命令:
keytool -import -noprompt -keystore cacerts -storepass changeit -alias zhy0105 -file D:/B/abcd.cer
提示输入密码时,密码输入:changeit
zhy0105是自定义名称,最后是证书cer文件的全路径。操作成功后会提示:“认证已添加至keystore中”。
3、注意问题。
(1)第一步会因为浏览器的不同和版本不同会有所偏差,上面这个过程只是针对于firefox,还不知道点几。据说有的浏览器可以直接导出.cer文件。
(2)注意jdk的路径:jdk1.6.0_21\jre\lib\security,是jdk下面的jre,不是和jdk平级的那个jre文件夹。别搞错了...
(3)一定要保证导入证书的jdk就是myeclipse中所配置的jdk,myeclipse中默认的jdk是它本身自带的。
如果在myeclipse中用本身自带的jdk运行httpClient,导入证书的jdk是自己安装的。运行肯定会报错,异常我贴在最下面。证书导入成功,httpClient还是访问不了https,这个问题困扰了我三天。
(4)Window7中,如果jdk安装在了c盘,系统默认是不允许修改文件的,cmd中导入证书时会提示拒绝访问,需要在文件夹中的文件属性里面修改一下权限,在执行就可以了。
~~~~~~~~~~~~~~~~~~~~~~~
以上问题处理完后,程序中就直接按照平时访问http的代码来写就可以了。
贴个以post方式访问并且带附件上传的样例:
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import org.apache.commons.httpclient.*;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.methods.multipart.MultipartRequestEntity;
import org.apache.commons.httpclient.methods.multipart.Part;
import org.apache.commons.httpclient.methods.multipart.StringPart;
import org.apache.commons.httpclient.params.HttpMethodParams;
import com.client.ctl.CustomFilePart;
public class Test {
public static void main(String[] args) throws FileNotFoundException {
HttpClient httpClient = new HttpClient();
PostMethod method = new PostMethod("https://eps.dev.surepush.cn:443/epscu/1.0/uploaditems");
File file = new File("D:/D/SVN_EPS/multiuploadClient/src/items.xml");
Part[] parts = new Part[] { new StringPart("cpid", "900", "utf-8"),
new StringPart("uploadpassword", "123456", "utf-8"),
new StringPart("itemtype", "0"),
new StringPart("uploadtype", "1"),
new CustomFilePart("items", file) };
method.setRequestEntity(new MultipartRequestEntity(parts, method.getParams()));
//使用系统提供的默认的恢复策略
method.getParams().setParameter(HttpMethodParams.RETRY_HANDLER, new DefaultHttpMethodRetryHandler());
try {
// 执行method
int statusCode = httpClient.executeMethod(method);
if (statusCode != HttpStatus.SC_OK) {
System.err.println("Method failed: " + method.getStatusLine());
}
// 读取内容
byte[] responseBody = method.getResponseBody();
// 处理内容
System.out.println(new String(responseBody));
} catch (HttpException e) {
// 发生致命的异常,可能是协议不对或者返回的内容有问题
System.out.println("Please check your provided http address!");
e.printStackTrace();
} catch (IOException e) {
// 发生网络异常
e.printStackTrace();
} finally {
// 释放连接
method.releaseConnection();
}
}
}
另外,如果系统测试所部署的服务器是linux,和开发环境中还有中转服务器的话,把下面这一行放在httpClient对象定义之后就行了。
httpClient.getHostConfiguration().setProxy("10.100.XX.XXX",8080);
~~~~~~~~~~~~~~~~~~~~~~~~~~~
到此结束了,这个HttpClient的版本好像是3.0,jar包在附件里。
最后,异常信息如下:
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:1623)
at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Handshaker.java:198)
at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Handshaker.java:192)
at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1074)
at com.sun.net.ssl.internal.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:128)
at com.sun.net.ssl.internal.ssl.Handshaker.processLoop(Handshaker.java:529)
at com.sun.net.ssl.internal.ssl.Handshaker.process_record(Handshaker.java:465)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:884)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1120)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.writeRecord(SSLSocketImpl.java:623)
at com.sun.net.ssl.internal.ssl.AppOutputStream.write(AppOutputStream.java:59)
at java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:65)
at java.io.BufferedOutputStream.write(BufferedOutputStream.java:104)
at org.apache.commons.httpclient.WireLogOutputStream.write(WireLogOutputStream.java:68)
at org.apache.commons.httpclient.methods.multipart.FilePart.sendData(FilePart.java:223)
at org.apache.commons.httpclient.methods.multipart.Part.send(Part.java:312)
at org.apache.commons.httpclient.methods.multipart.Part.sendParts(Part.java:385)
at org.apache.commons.httpclient.methods.multipart.MultipartRequestEntity.writeRequest(MultipartRequestEntity.java:164)
at org.apache.commons.httpclient.methods.EntityEnclosingMethod.writeRequestBody(EntityEnclosingMethod.java:499)
at org.apache.commons.httpclient.HttpMethodBase.writeRequest(HttpMethodBase.java:2114)
at org.apache.commons.httpclient.HttpMethodBase.execute(HttpMethodBase.java:1096)
at org.apache.commons.httpclient.HttpMethodDirector.executeWithRetry(HttpMethodDirector.java:398)
at org.apache.commons.httpclient.HttpMethodDirector.executeMethod(HttpMethodDirector.java:171)
at org.apache.commons.httpclient.HttpClient.executeMethod(HttpClient.java:397)
at org.apache.commons.httpclient.HttpClient.executeMethod(HttpClient.java:323)
at com.client.ctl.https.Test.main(Test.java:32)
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:325)
at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:219)
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:1053)
... 22 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:320)
... 28 more
这个异常这几天把我折腾的欲仙yu死...
分享到:
相关推荐
- `port`: 指定HTTPS监听的端口号,通常为8443。 - `SSLEnabled`: 启用SSL。 - `clientAuth`: 是否需要客户端验证,`false`表示不需要。 - `keystoreFile`: 指向KeyStore文件的位置。 - `keystorePass`: ...
在这个例子中,我们首先创建了一个`CloseableHttpClient`实例,然后定义了代理服务器`HttpHost`,包括主机名"proxy.example.com"、端口号8080和协议"http"。接着,我们创建`RequestConfig`并设置了代理,然后将这个...
2. **设置服务器信息**:调用 `client.begin()` 函数,传入你要访问的服务器地址和端口号,如 `client.begin("http://example.com", 80);` 3. **设置请求方法和资源**:根据需求选择 GET 或 POST 方法。对于 GET,...
HttpClient 入门和实战 HttpClient 是一个基于 HTTP/1.1 协议的客户端编程工具,可以用来发送 ...它们可以一起使用,例如使用 HttpClient 上传文件到 FastDFS 中,然后使用 FastDFS 提供的文件访问功能来下载文件。
2. **HttpHost**:定义了要访问的HTTP服务器的主机名、端口号和协议类型(HTTP或HTTPS)。 3. **HttpRequest**:表示一个HTTP请求,可以是GET、POST、PUT等各种HTTP方法。 4. **HttpResponse**:包含了服务器的响应...
HttpClient 4.3封装工具类支持配置HTTP代理或SOCKS代理,包括设置代理的主机名、端口号,以及代理认证等。这样,即使在需要代理的网络环境中,也能正常发起HTTP请求。 2. **多线程问题**:在处理大量并发请求时,...
- **路由计算:** 根据请求的目标地址和端口号确定连接的路由信息。 - **安全HTTP连接:** HTTPS协议基于SSL/TLS协议实现了安全的HTTP连接。 **2.3 HTTP连接管理器** - **管理连接和连接管理器:** 连接管理器负责...
- 构造函数可能接受服务器地址、端口号等初始化参数。 - GET方法:设置URL,发起GET请求,接收并解析服务器响应。 - POST方法:除了设置URL外,还需要提供POST数据,发送请求并处理响应。 3. 使用步骤: - 包含...
在这个例子中,“http://proxy.example.com:8080”是代理服务器的地址,8080是端口号。 三、处理身份验证 如果代理服务器需要身份验证,我们可以设置Credential属性来提供用户名和密码。例如: ```csharp handler....
通过设置URL(通常包含设备的IP地址、端口号以及API接口),可以实现获取设备状态、控制设备动作等操作。同时,需要对HTTP请求进行身份验证,通常使用Basic Auth或者Digest Auth,这可以通过HttpClient的...
3. **端口号**:默认情况下,HTTP使用80端口,HTTPS使用443端口,但可以自定义。 4. **路径**:例如/blog/547372,指示服务器上的特定资源路径。 5. **查询参数**:以问号(?)分隔,用于传递额外的信息。 6. **片段...
编辑`redis.conf`配置文件,设置必要的参数,如端口号、密码等。 ##### 3. 启动Redis服务 根据操作系统启动Redis服务,对于Linux可以通过命令`redis-server`启动服务。 ##### 4. Java客户端连接Redis 选择一个...
一个URL通常包含以下几个部分:协议(如http或https)、主机名、端口号、路径、查询参数和片段标识符。例如,`http://www.example.com:80/path?query=param#fragment`,其中: 1. 协议:http 2. 主机名:...
`Access-Control-Allow-Origin`设置为星号(*),表示允许任何源进行访问。`Access-Control-Allow-Methods`指定了GET、POST和OPTIONS请求方法,`Access-Control-Allow-Headers`允许特定的请求头。 在Cocos2d-x端,...
默认情况下,HTTP服务通常使用80端口,HTTPS服务使用443端口,但可以根据实际配置有所不同。 RSA公钥在接口说明中提到,这是一种非对称加密算法,用于加密和解密数据。公钥是公开的,任何人都可以使用它来加密信息...
- 创建一个`Socket`实例,指定服务端的IP地址和端口号。 - 读取服务端发送的数据或者向服务端发送数据。 - 关闭打开的流。 #### 四、使用HTTP协议访问网络 Android应用可以通过多种方式访问HTTP资源,例如使用`...
此外,还包括Socket通信,Socket是网络通信的基础,它代表了两个网络端点之间的连接,包含了IP地址、端口号等信息,可以进行双向数据传输。此外,Android还提供了网络状态监控接口,用于检测网络连接状态,以及WIFI...
在ServletProxyPass中,`service()`方法通常是核心,它会解析接收到的请求,并根据配置信息(如目标服务器地址、端口号等)构造一个新的HTTP请求。然后,Servlet使用诸如HttpURLConnection或Apache HttpClient等库来...