模拟奇数乱码请求问题

  乱码问题非常多见,但是奇数乱码问题,有时候我们遇到的就不那么多。网上搜了些资料,说的是GBK编码是一个中文2个字节,而UTF-8编码是一个中文3个字节。所以在进行转换的时候容易出现奇数乱码问题。网上说了很多方法,设置ContentType,设置请求和响应编码,使用new String(xxx.getBytes("ISO-8859-1"),"UTF-8");等等网上有的解决方法,楼主都试了,然后并没有什么卵用。  下面模拟一下情景。

  前端页面使用ajax请求数据,动态生成页面。后台数据通过调用接口获取。下面是后台的代码:

  @RequestMapping(params = { "getAreaList" }, method = RequestMethod.POST)
    @ResponseBody
    public List<Map<String,Object>> getAreaList(HttpServletRequest request,HttpServletResponse response) {
        
        List<Map<String,Object>> result = new ArrayList<Map<String,Object>>();
        result = (List<Map<String, Object>>) HttpUtil.httpRequest(HttpUtil.areaRequestUrl,HttpUtil.requestMethod,null);
       
        return result;
    }

其中HttpUtil.httpRequest代码为:

public static Object httpRequest(String requestUrl,
            String requestMethod, String outputStr) {
        Object jsonObject = null;
        StringBuffer buffer = new StringBuffer();
        InputStream inputStream = null;
        InputStreamReader inputStreamReader = null;
        BufferedReader bufferedReader = null;
        OutputStream outputStream = null;
        try {
        
            URL url = new URL(requestUrl);
            URLConnection httpUrlConn = url
                    .openConnection();

            httpUrlConn.setDoOutput(true);
            httpUrlConn.setDoInput(true);
            httpUrlConn.setUseCaches(false);
            
            // 设置请求方式(GET/POST)
            ((HttpURLConnection) httpUrlConn).setRequestMethod(requestMethod);

            // 当有数据需要提交时
            if (null != outputStr) {
                outputStream = httpUrlConn.getOutputStream();
                // 注意编码格式,防止中文乱码
                outputStream.write(outputStr.getBytes("utf-8"));
            }

            // 将返回的输入流转换成字符串
            inputStream = httpUrlConn.getInputStream();
            inputStreamReader = new InputStreamReader(inputStream);
            bufferedReader = new BufferedReader(inputStreamReader);
            String str = "";
            while ((str = bufferedReader.readLine()) != null) {
                buffer.append(str);
            }

            httpUrlConn.connect();
            //处理乱码--楼主最后使用的解决方式
            String result = new String(buffer.toString().getBytes(),"utf-8");
            result = URLDecoder.decode(result,"utf-8");
            //去掉首尾“
            if(StringUtil.isNotEmpty(result)&&result.startsWith(""")){
                result = result.replaceFirst(""", "");
                result = result.substring(0, result.lastIndexOf("""));
            }
            //支持返回类型为map和list
            if(StringUtil.isNotEmpty(result)&&result.startsWith("{")){
                jsonObject = JSONObject.fromObject(result);
            }else{
                jsonObject = JSONArray.fromObject(result);
            }
            
        } catch (ConnectException ce) {
           ce.printStackTrace();
            System.out.print("连接超时");
        } catch (Exception e) {
            e.printStackTrace();
            System.out.print("http请求出错");
        }finally{
            try {
                if(null!=bufferedReader){
                    bufferedReader.close();//释放资源
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if(null!=inputStreamReader){
                    inputStreamReader.close();//释放资源
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if(null!=inputStream){
                    inputStream.close();//释放资源
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if(null!=outputStream){
                    outputStream.close();//释放资源
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return jsonObject;
    }

其中第三方接口返回的数据处理方式:

     JSONArray jsonArray = JSONArray.fromObject(areaList);
        String res = "";
        try {
            res = URLEncoder.encode(jsonArray.toString(), "utf-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return res;

最后问题解决了。解决方式就是:第三方接口将数据转为json格式,然后进行URLEncoder.encode(,“utf-8”);

接收的时候

String result = new String(buffer.toString().getBytes(),"utf-8");
result = URLDecoder.decode(result,"utf-8");
//去掉首尾“
if(StringUtil.isNotEmpty(result)&&result.startsWith(""")){
     result = result.replaceFirst(""", "");
     result = result.substring(0, result.lastIndexOf("""));
 }

其实也不是什么难得技术难点。只不过因为这个问题,给我搞的很恼火,也耽误了不少时间。特此记录一下。其实是想找到这种乱码的原因。编码格式统一使用的都是utf-8,然后将tomcat编码也进行了设定。也没有什么效果。最后只能使用这种不是本质的方法。也算解决了,记录一下,供后来人参考。

原文地址:https://www.cnblogs.com/xu-lei/p/6255800.html