前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >HttpURLConnection调用get方法碰到奇怪的编码问题--不同的方式调用同一个方法竟然有不同的结果

HttpURLConnection调用get方法碰到奇怪的编码问题--不同的方式调用同一个方法竟然有不同的结果

作者头像
zhanyd
发布2022-05-16 14:03:31
1.4K0
发布2022-05-16 14:03:31
举报
文章被收录于专栏:编程我也会

今天在调用某接口查询企业名称的时候碰到奇怪的问题。

在页面上输入拼音能搜索到数据,输入汉字则不行。

询问了对方的技术人员,他说我传的内容是空的,这就奇怪了,我后台明明已经接收到“浙江”这个值了。

我用单元测试测了一下,接口没问题,但是在页面上查询就没数据。

为了确认一下接口没问题,我在调用对方接口的代码里把参数“浙江”两个字写死了:

代码语言:javascript
复制
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调用这个方法还是找不到数据,注意:这里的关键字“浙江”已经写死在代码里了,也就是说不管传什么参数都是一样的。

它们之间的区别仅仅是调用的路径不同,一个是从单元测试调用的,一个是从页面上调用的。

单元测试

代码如下:

代码语言:javascript
复制
 @Test
 public void searchCompany() {
     String baseUrl = "http://******/APIService/search/advanceSearchNew";
     Map<String, String> urlParams = new HashMap<String, String>();
     // 设置url参数
     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 {
         // 发送get请求,得到响应
         String response = HttpService.get(baseUrl + "?" + String.join("&", concatParams));
         System.out.println(response);
     } catch (Exception e) {
         e.printStackTrace();
     }
 }

这时候能成功调用,返回正常的结果:

代码语言:javascript
复制
sendUrl:http://****/APIService/search/advanceSearchNew?secret_key=****&appkey=****&keyword=浙江
{"status":"200","message":"操作成功","sign":"44200167b7e4cf3c6edd2fd043c613e7" ...}}

页面调用

通过页面ajax调用接口:

参数也能正常传到Controller,问题是sendUrl我已经在方法里写死了,却得到了不一样的结果:

代码语言:javascript
复制
     /**
     * 获取公司列表
     */
    public static List<Map<String, String>> companyList(String keyword) {
        String baseUrl = "http://****/APIService/search/advanceSearchNew";
        Map<String, String> urlParams = new HashMap<String, String>();
        // 设置url参数
        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 {
            // 发送get请求,得到响应
            String response = HttpService.get(baseUrl + "?" + String.join("&", concatParams));
            System.out.println(response);
            // 获取公司列表
            return getCompanyList(response);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

这时返回查询无结果:

代码语言:javascript
复制
sendUrl:http://****/APIService/search/advanceSearchNew?secret_key=****&appkey=****&keyword=浙江
{"status":"201","message":"查询无结果","sign":"f310015b7409b768bc61fc03a6a43d0b","data":{"total":0,"items":[]}}

再次提醒:keyword我已经在get方法里写死了。

真是百思不得其解啊!

后来通过wireshark抓包,终于知道问题的原因是编码问题。

这是通过单元测试的方法发送的请求,编码没有问题:

这是通过页面发送的请求,编码就有问题了:

不同的方式调用同一个方法,为什么会有这样的区别呢?真是搞不明白。。。

不过,既然知道是编码的问题,那么把参数编码成UTF-8是不是就行了?

代码语言:javascript
复制
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"),试试看,结果返回正常:

代码语言:javascript
复制
sendUrl:http://****/APIService/search/advanceSearchNew?secret_key=****&appkey=****&keyword=%E6%B5%99%E6%B1%9F
{"status":"200","message":"操作成功","sign":"7afbd8dcda84f29a679420f4d4552dab","data":{...}}

抓包截图:

恩,这样就正常了。

但是单元测试的时候,为什么不编码也可以呢?而从页面上通过Controller调用就有编码问题?

这个疑问还没解开。。。

如果有大神知道原因,请不吝赐教,谢谢!

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-07-15,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 编程我也会 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 单元测试
  • 页面调用
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档