问题描述
最近在做有关物流商城的项目,其中有一个需求是接入英国ups系统,由于过程中出现了一些问题,所以作者在这里记录一下。
解决步骤
首先,进入英国ups官网的开发者工具,如果打开比较慢,可以使用梯子。
ups开发者工具地址:Developer Resource Center | UPS - United Kingdom
进入后,按照提示进行登陆注册、选择我们要使用的api、下载我们要使用的api、获取我们的请求密钥。
提示:接口文档中会提到许多种接口,如果你使用的是restful形式的接口的话,那么你可以直接看resultful形式的接口就好。
在熟悉完接口文档后,我们就可以着手来编写我们的接口。
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.security.GeneralSecurityException;
import java.security.NoSuchAlgorithmException;
import java.util.Map;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
public class test2 {
public static void main(String[] args) {
try {
System.out.println(post("https://wwwcie.ups.com/track/v1/details/7798339175",null));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
public static String post(String path,Map<String, String> parameters) throws IOException, NoSuchAlgorithmException, GeneralSecurityException{
// 创建SSLContext对象,并使用我们指定的信任管理器初始化
TrustManager[] tm = { new MyX509TrustManager() };
SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");
sslContext.init(null, tm, new java.security.SecureRandom());
// 从上述SSLContext对象中得到SSLSocketFactory对象
SSLSocketFactory ssf = sslContext.getSocketFactory();
URL url = new URL(path);
HttpsURLConnection httpsConn = (HttpsURLConnection) url.openConnection();
httpsConn.setSSLSocketFactory(ssf);
// 设置请求头参数
httpsConn.setRequestProperty("transId","12345");
httpsConn.setRequestProperty("transactionSrc","TestTrack");
httpsConn.setRequestProperty("Username","username");
httpsConn.setRequestProperty("Password","password");
httpsConn.setRequestProperty("AccessLicenseNumber","accesslicenseNumber");
httpsConn.setDoInput(true);// 打开输入流,以便从服务器获取数据
httpsConn.setDoOutput(true);// 打开输出流,以便向服务器提交数据
if (parameters != null) {
url = new URL(url.toString() + buildGetParameterString(parameters));
}
BufferedReader in = new BufferedReader(new InputStreamReader(
httpsConn.getInputStream()));
String line;
StringBuffer rt = new StringBuffer();
while ((line = in.readLine()) != null) {
rt.append(line);
}
return rt.toString();
}
private static String buildGetParameterString(Map<String, String> parameters)
{
String getParameterString = "";
for(Map.Entry<String, String> param : parameters.entrySet())
{
if(param.getValue() == null)
{
continue;
}
getParameterString += (getParameterString.length() < 1) ? ("?") : ("&");
getParameterString += param.getKey() + "=" + param.getValue();
}
return (getParameterString);
}
}
在请求时可能会出现,ssl证书认证错误,这是因为ups官网的证书不在我们所信任的范围内,我们可以信任管理器来解决这个问题。
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import javax.net.ssl.X509TrustManager;
/**
*
* @author hukai
*实现不需要加载证书,访问https网站或者接口
*
*
*/
public class MyX509TrustManager implements X509TrustManager {
/*
* The default X509TrustManager returned by SunX509. We'll delegate
* decisions to it, and fall back to the logic in this class if the
* default X509TrustManager doesn't trust it.
*/
/*
* Delegate to the default trust manager.
*/
public void checkClientTrusted(X509Certificate[] chain, String authType)
throws CertificateException {
}
/*
* Delegate to the default trust manager.
*/
public void checkServerTrusted(X509Certificate[] chain, String authType)
throws CertificateException {
}
/*
* Merely pass this through.
*/
public X509Certificate[] getAcceptedIssuers() {
return null;
}
}
自此,这个需求的demo就被我们实现,后续只需要规范一下接口的写法就可以使用。