今天在调用某接口查询企业名称的时候碰到奇怪的问题。
在页面上输入拼音能搜索到数据,输入汉字则不行。
询问了对方的技术人员,他说我传的内容是空的,这就奇怪了,我后台明明已经接收到“浙江”这个值了。
我用单元测试测了一下,接口没问题,但是在页面上查询就没数据。
为了确认一下接口没问题,我在调用对方接口的代码里把参数“浙江”两个字写死了:
public static String get(String sendUrl) {
StringBuffer receive = new StringBuffer();
HttpURLConnection URLConn = null;
BufferedReader in = null;
try {
sendUrl = "http://***/APIService/search/advanceSearchNew?secret_key=***&appkey=***&keyword=浙江";
System.out.println("sendUrl:" + sendUrl);
URL url = new URL(sendUrl);
URLConn = (HttpURLConnection) url.openConnection();
URLConn.setDoInput(true);
URLConn.connect();
in = new BufferedReader(new InputStreamReader(URLConn.getInputStream(), "UTF-8"));
String line;
while ((line = in.readLine()) != null) {
receive.append(line);
}
} catch (IOException e) {
receive.append("访问产生了异常-->").append(e.getMessage());
e.printStackTrace();
} finally {
if (in != null) {
try {
in.close();
} catch (java.io.IOException ex) {
ex.printStackTrace();
}
in = null;
}
URLConn.disconnect();
}
return receive.toString();
}
这时候奇怪的事情发生了,从单元测试调用这个方法是正常的,而从页面上通过ajaix调用这个方法还是找不到数据,注意:这里的关键字“浙江”已经写死在代码里了,也就是说不管传什么参数都是一样的。
它们之间的区别仅仅是调用的路径不同,一个是从单元测试调用的,一个是从页面上调用的。
单元测试
代码如下:
@Test
public void searchCompany() {
String baseUrl = "http://******/APIService/search/advanceSearchNew";
Map<String, String> urlParams = new HashMap<String, String>();
urlParams.put("appkey", "******");
urlParams.put("secret_key", "******");
urlParams.put("keyword", "浙江");
List<String> concatParams = new ArrayList<String>();
for (String s : urlParams.keySet()) {
concatParams.add(s + "=" + urlParams.get(s));
}
try {
String response = HttpService.get(baseUrl + "?" + String.join("&", concatParams));
System.out.println(response);
} catch (Exception e) {
e.printStackTrace();
}
}
这时候能成功调用,返回正常的结果:
sendUrl:http:/APIService/search/advanceSearchNew?secret_key=****&appkey=****&keyword=浙江
{"status":"200","message":"操作成功","sign":"44200167b7e4cf3c6edd2fd043c613e7" ...}}
页面调用
通过页面ajax调用接口:
参数也能正常传到Controller,问题是sendUrl我已经在方法里写死了,却得到了不一样的结果:
public static List<Map<String, String>> companyList(String keyword) {
String baseUrl = "http://****/APIService/search/advanceSearchNew";
Map<String, String> urlParams = new HashMap<String, String>();
urlParams.put("appkey", "****");
urlParams.put("secret_key", "****");
urlParams.put("keyword", keyword);
List<String> concatParams = new ArrayList<String>();
for (String s : urlParams.keySet()) {
concatParams.add(s + "=" + urlParams.get(s));
}
try {
String response = HttpService.get(baseUrl + "?" + String.join("&", concatParams));
System.out.println(response);
return getCompanyList(response);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
这时返回查询无结果:
sendUrl:http:/APIService/search/advanceSearchNew?secret_key=****&appkey=****&keyword=浙江
{"status":"201","message":"查询无结果","sign":"f310015b7409b768bc61fc03a6a43d0b","data":{"total":0,"items":[]}}
再次提醒:keyword我已经在get方法里写死了。 真是百思不得其解啊!
后来通过wireshark抓包,终于知道问题的原因是编码问题。
这是通过单元测试的方法发送的请求,编码没有问题:
这是通过页面发送的请求,编码就有问题了:
不同的方式调用同一个方法,为什么会有这样的区别呢?真是搞不明白。。。
不过,既然知道是编码的问题,那么把参数编码成UTF-8是不是就行了?
public static String get(String sendUrl) {
StringBuffer receive = new StringBuffer();
HttpURLConnection URLConn = null;
BufferedReader in = null;
try {
sendUrl = "http://****/APIService/search/advanceSearchNew?secret_key=****&appkey=****&keyword=" + URLEncoder.encode("浙江","UTF-8");
System.out.println("sendUrl:" + sendUrl);
...
把参数编码一下,添加URLEncoder.encode(“浙江”,“UTF-8”),试试看,结果返回正常:
sendUrl:http:/APIService/search/advanceSearchNew?secret_key=****&appkey=****&keyword=%E6%B5%99%E6%B1%9F
{"status":"200","message":"操作成功","sign":"7afbd8dcda84f29a679420f4d4552dab","data":{...}}
抓包截图:
恩,这样就正常了。
但是单元测试的时候,为什么不编码也可以呢?而从页面上通过Controller调用就有编码问题?
这个疑问还没解开。。。
如果有大神知道,请不吝赐教,谢谢!
|