近来调EMS的下单接口,总是不成功,还有调韵达的接口,总是报签名错误,弄了两天也没找出来啥原因,后来老司机不造咋地就找到了原因,原来是在对参数进行base64加密的时候使用了jdk自带的base64进行编码(sun.misc.BASE64Encoder),编码结果会在最后面多加换行,导致参数不正确,换成Apache包下的base64就可以了(1.8中的java.util.Base64也可以)。
特此测试了一下:
package com.core.base64;
import sun.misc.BASE64Encoder;
import java.io.UnsupportedEncodingException;
public class Base64Test {
public static void main(String[] args) throws UnsupportedEncodingException {
String str = "46264845615ddddfs1f865dsa2ffeeff";
String charset = "UTF-8";
String apacheEncode = new String(new org.apache.commons.codec2.binary.Base64().encode(str.getBytes(charset)));
String newJdkEncode = java.util.Base64.getEncoder().encodeToString(str.getBytes(charset));
String jdkEncode = new BASE64Encoder().encode(str.getBytes(charset));
System.out.println("jdk自带:->"+jdkEncode);
System.out.println("apache:->"+apacheEncode);
System.out.println("util:->"+newJdkEncode);
}
}
输出结果是:(看起来没多大区别)
jdk自带:->NDYyNjQ4NDU2MTVkZGRkZnMxZjg2NWRzYTJmZmVlZmYK
apache:->NDYyNjQ4NDU2MTVkZGRkZnMxZjg2NWRzYTJmZmVlZmYK
util:->NDYyNjQ4NDU2MTVkZGRkZnMxZjg2NWRzYTJmZmVlZmYK
当str的值很长的时候,就出现不同了:
jdk自带:->MTRmZjE1OTI2NWRmc2FmZHNmZHNhMzU4OTc5MzIzODQ2MjY0ODQ1NjE1ZGRkZGZzMWY4NjVkc2Ey
ZmZlZWZm
apache:->MTRmZjE1OTI2NWRmc2FmZHNmZHNhMzU4OTc5MzIzODQ2MjY0ODQ1NjE1ZGRkZGZzMWY4NjVkc2EyZmZlZWZm
util:->MTRmZjE1OTI2NWRmc2FmZHNmZHNhMzU4OTc5MzIzODQ2MjY0ODQ1NjE1ZGRkZGZzMWY4NjVkc2EyZmZlZWZm
而我这边调接口一般都是xml格式的参数,先不论参数,只是那些个标签就很长了,这就是问题的根源了。
如果要用的话,就用Apache或util包下的:
org.apache.commons.codec.binary.Base64 java.util.Base64
快递接口调用过程中,还有一个地方容易出错,就是在post传参数的时候,记住要urlEncode一次,有的时候在put的时候urlEncode了一下,在httpPost调用的时候,方法会在内部再重新urlEncode一下,这样就得不到正确的参数了。
// 需要把表单包装到Entity对象中。StringEntity
StringEntity entity = new UrlEncodedFormEntity(formList, "utf-8");
如果在工具类中有类似这样代码的话,在封装请求参数的时候就不用再urlEncode了。