1.javax.net.ssl.SSLHandshakeException:
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
原因:服务器的证书不被信任。一般是这样造成的。
解决办法,
1.导入办法:
打开命令行窗口,并到<java-home>\lib\security\ 目录下,运行下面的命令:
keytool -import -noprompt -keystore cacerts -storepass changeit -alias yourEntry1 -file your.cer
最后一个是服务端导出的证书,其他可以默认。如果报名字错误,可以把alias名字改成别的
另外附带一下相关命令:
导入证书库
keytool -import -noprompt -keystore cacerts -storepass changeit -alias yourEntry1 -file your.cer
查看证书库
keytool -v -list -keystore cacerts -storepass changeit
删除
keytool -delete -alias yourEntry1 -keystore cacerts -storepass changeit
要注意的是,如果客户端电脑上装有许多个JAVA版本,要确定你导入的证书的JAVA版本是你TOMCAT使用的那个,一般TOMCAT使用的是环境变量指向的那个JAVA版本。
如果是在ECLIPSE中建立的TOMCAT服务器,新建时会要你选择默认JRE还是指向的JAVA,这里一定要选指向刚才导入的那个JAVA的路径,不然,你导入的证书库也没效果。
2.JAVA代码办法
//设置系统参数
System.setProperty("javax.net.ssl.trustStore", sslTrustStore);
System.setProperty("javax.net.ssl.trustStorePassword",sslTrustStorePassword);
加的位置只要在发送数据前都可以。
另外注意的是,如果采用了上面的两种方法中的一种,还是报同样的错误,那么可以怀疑,证书本来是有问题的。
我们的项目就是用上面的方法后还是一直错误,结果才知道证书本来就有问题。解决办法就是换一个正确的证书。
2.redirect
重定向
表示发送数据的网址被重定向。原因一般是,很多系统在你访问一个链接时,会检查登录信息,没有则转向登录页面。当向服务端发送数据时,一般是没有登录信息的。那么就会被重定向到登录页面。解决办法是服务器对客户端发送的那个地址不验证登录信息。
3.java.net.SocketException: Connection reset
连接被重置。
一般是防火墙的原因。在SSL双向链接时,客户端没有向服务端提供证书信息,也会报这样的错。
4. java.security.NoSuchAlgorithmException
一般来说是密钥库类型不对,如上面的sslKeyStoreType = "JKS" 却写成PKCS12。
也有可能是证书的问题。
5. java.net.UnknownHostException
服务端地址不对。
6.java.net.SocketException: Unexpected end of file from server
这个异常说明数据已经发送成功。有可能服务端是防火墙的原因,没有处理客户端发来的数据。也有可能是客户端的数据不符合要求,服务端没有做出响应。数据不符合要求可能是传送的数据含有奇怪的字符。也有可能是两边编码不一致导致。客户端将字符串变成字节数据传送时需要指定编码格式,如str.getBytes("UTF-8");如不指定,可能导致上面的错误。另外有人说当URL过长时也会发生此错误,当使用URL发送数据时,可以参考此意见。
在我们与平安做接口时,碰到这个Unexpected end of file from server诡异的错误。但大致原因可以确定是服务端(平安)对我们发送过去的数据没有处理。具体的原因有下:
我们的系统是UTF-8编码的,他们是GBK编码的。编码不一致导致错误。另外传输消息时最好设定编码格式,如str.getBytes("UTF-8")。
但这样处理后还是出问题。那就是测试环境可以成功,而线上环境不能成功。查了很久也查不到原因,最后弄一个和测试环境一样的服务器,专门来放接口才解决问题。
对于最后这个问题,可能原因如下:
a. 线上环境做了某种限制,使证书信息不能发送出去。
b。线上环境的外网出口IP和测试环境外网出口IP不同。或许平安会将第一次发送证书时,IP和证书记住。如果下次IP和证书有一项不符合,则认为无效,不给回应。我们先在测试环境上发送成功,平安记住了IP和证书。然后在线上环境发送时,由于IP不同,平安认为证书无效,不给回应。
7.java.io.IOException:server returned HTTP response code :500
这个异常是服务端代码的问题。服务端相应代码执行时抛出了异常。
最后 如果返回的状态码是200 ,表示成功。