`
maosuhan
  • 浏览: 112345 次
  • 性别: Icon_minigender_1
  • 来自: 南京
社区版块
存档分类
最新评论

在做google map api时遇到的字符串编码的各种纠结

    博客分类:
  • java
阅读更多

我们的架构是b/s的,后台用的是tomcat,和google的webservice打交道还用到一个gae做代理。

之前的博文我们说过在tomcat和浏览器之间的ajax交互时要用一种客户端encode两次加上一个辅助函数加工然后服务端decode两次的恶心解决方案。后来我们研究了一下tomcat,发现其实问题是这样的。

 

tomcat默认使用iso-8859-1来解释request的,所以我们用ff提交参数时用的是utf8,我们在浏览器里输入“大学”,其实是被ff encode过的(被转成%B5%33形式),传到服务器时tomcat又用iso-8859-1 decode了。所以我们想到解决方案如下

	String keyword =URLEncoder.encode(request.getParameter("keyword"),"ISO-8859-1");
		keyword=URLDecoder.decode(keyword, "UTF-8");

 这样子我们反过来弄一下就ok了。

这里还要说一下,如果换成时ie的话,默认“大学”这个url参数会用gbk,如果还是用上面的那个,其实就会出现乱码。这里还要说glassfish貌似也是用的iso-8859-1

 

这里还要讲一个关于HTTPURLConnection的事情,我们在tomcat用HTTPURLConnection时,我在设置parameter的时候没有encode我的参数,我就这样传过去了,而在本地的jetty服务器的gae上接收到了我的字符串竟然是对的,看来HttpURLConnection会自动帮我们按照默认的charset(linux下是utf8)把字符串编码再传过去。然后再我们本地的gae上,可以直接写这样的code

     String keyword = req.getParameter("keyword");
        String center = req.getParameter("center");
        String range = req.getParameter("range");

 这个可能gae用的jetty服务器又自动帮我们decode了,这里虽然我们没有decode和encode,但是程序都自动帮我们完成了。但是必须满足客户端和服务器用的默认的编码是一样的。

 

这里讲一下什么是decode什么是encode,比如,我们对一个“作者”encode,这里会encode成     %E4%BD%9C%E8%80%85这样的,再encode一下会,encode成“%25E4%25BD%259C%25E8%2580%2585”这样,%会转成%25。   而decode呢?如果我们对“%25E4%25BD%259C%25E8%2580%2585” decode会变成“%E4%BD%9C%E8%80%85”,而对“%25E4%25BD%259C%25E8%2580%2585大学” decode会变成“%E4%BD%9C%E8%80%85大学”,也就是说decode可能只会对%开头的东西进行decode。而encode比较诡异,处理%的手段让人搞不懂。

 

话说回来,我做了几次实验,我发现URLConnection会自动帮助我们进行编码的,而且很智能,如果我们事先encode过,他就不会再帮我们encode。而本地gae会用默认的utf8方式编码。设想一个情况,我们用gbk encode参数然后再传到gae上,我们就需要在gae上先encode("UTF-8")在decode 成gbk。这里的道理是一样的。而我们可以用一个函数就是request.setCharsetEncoding("GBK")来直接来让服务器帮我们用GBK转,这样就不要先encode再decode了。

 

现在我们看age里面的代码,我们需要请求google的web service。这时,我们仍然是需要用HTTPURLConnection这个类,但是我们在没有encode参数的时候,发给google api时竟然说url是不合法的,一定要实现encode才可以。这就不懂了,为什么一定要我们手动encode呢,不是HTTPURLConnection自动帮我们encode了吗?我想这是不是同一个版本的URLCOnnection啊?我看了一下原来不加encode的错误堆栈信息,原来最后会调用一个什么httpclient的类,而这个类不是标准库里的,是外部的,也不知道这里面到底出了什么鬼!!!就连我step into进去HTTPURLConnection,里面的堆栈也是不一样的,诡异啊!!!

 

接着我们从webservice里获得了json字符串,里面也还是没有decode过的utf8,随即

String allString=URLDecoder.decode(all.toString(),"UTF-8");

 最后还要返回给tomcat结果,此时如果我们不用以下这个字符编码限定会出问题

        resp.setContentType("text/json");
        resp.setCharacterEncoding("UTF-8");
        PrintWriter writer=resp.getWriter();

 我不知道这个是为什么!我看本地的age上默认是utf8啊,难道传过来的时候就不是utf8?

后来我又搞成这样子,在本地gae上这样写

		OutputStream writer = resp.getOutputStream();
		writer.write(jsonString.getBytes());
		writer.close();

 在tomcat上这样写

		byte[] bytes=new byte[10000];
		InputStream inputStream=connection.getInputStream();
		inputStream.read(bytes);
		String string=new String(bytes);

 这样我们用纯字节进行传递就不可能会有错了!!!这里我没有指定到底用什么编码传递,这个时候会用默认的,我始linux的,所以java的默认编码用utf8。

 

 

我们把age部署到服务器,在服务器上出现了诡异,原来服务器上用的是一个us什么的默认编码格式。真正的age要想正常返回给我们字符串,需要加上这么一句话

	BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream(),"UTF-8"));
				StringBuilder all = new StringBuilder();
				String line = null;
				while ((line = reader.readLine()) != null) {
					all.append(line);
				}
				
 

 在我本地gae是不需要加第一句话中的UTF-8的。因为在服务器上的gae是us编码的,所以需要这么转,否则默认就转成us这种东西了。

这里就又有一个问题了,service传过来的是一个需要decode的东西,我在本地的gae上用

new BufferedReader(new InputStreamReader(connection.getInputStream(),"UTF-8"));

得到的字符串是需要再一次decode的,而在服务器上的gae是不需要再一次被decode的。

 

终其所述,无论本地还是服务器的age下的HTTPURLConnection和普通java的不一样,它不会帮我们encode;而服务器上gae的InputStreamReader和本地的gae和普通java也不一样,他会自动转码。

 

 

 

分享到:
评论

相关推荐

    谷歌地图Google Map API V3中文开发文档

    谷歌地图 Google Map API V3 中文开发文档是 Google 公司提供的一种基于 Web 的地图应用程序接口,允许开发者在自己的网站或应用程序中嵌入谷歌地图,以提供地图检索、路线规划、地标显示等功能。本文档旨在为开发者...

    Google Map API 使用示例

    Google Map API 是一款强大的工具,它允许开发者在自己的网站或应用程序中嵌入地图功能,提供定位、导航、地理编码、路线规划等多种服务。本示例将深入探讨如何使用 Google Map API,帮助你理解和掌握其核心概念及...

    google map api学习

    谷歌地图API(Google Maps API)是谷歌提供的一套强大的开发工具,允许开发者在自己的网站或应用中嵌入交互式地图,实现地理位置相关的功能。通过学习谷歌地图API,你可以创建定制的地图,添加标记、路径、信息窗口...

    google map api开发源代码

    Google Map API是一个强大的工具,允许开发者在网页或应用程序中集成地图功能,进行各种定制和交互。这个源代码压缩包提供了一种实现Google Map API二次开发的实例,对于想要深入理解和应用这一技术的人来说非常有...

    GOOGLE MAPapi示例

    ### GOOGLE MAP API 示例知识点解析 #### 一、Google Maps JavaScript API 概述 Google Maps JavaScript API 是一个功能强大的工具包,允许开发者将交互式的地图嵌入到网页中。通过使用这个API,开发者可以轻松地...

    google map api v3.18.0 离线开发包

    总的来说,"google map api v3.18.0 离线开发包"为开发者提供了在无网络环境下使用谷歌地图API的功能,使得地图服务在多种场景下都具备了可行性。通过熟练掌握和应用这个API,开发者可以创建出丰富多样的地图应用。

    GoogleMap API + ASP.NET(C#)

    在IT行业中,Google Map API 和 ASP.NET(C#)的结合应用是构建地理位置服务的重要技术组合。Google Map API 提供了丰富的地图展示和地理定位功能,而ASP.NET(C#)则是一个强大的Web应用程序开发框架,两者结合可以创建...

    google map api v3源码

    谷歌地图API V3是Google提供的一种用于在网页上嵌入交互式地图的服务,它基于JavaScript编程语言,允许开发者创建各种地图应用。这个源码可能是谷歌地图API V3的一个示例项目,不含任何特定的API密钥,因此可以作为...

    Google Map Api

    Google Map API 是一款由谷歌公司提供的强大工具,用于在网页或移动应用中集成地图功能。这个API允许开发者将交互式地图集成到他们的网站或应用程序中,提供定位、导航、地理编码、路线规划等多种功能。最新版的...

    Google Map Api 调用样例程序(Java版)

    2. **API密钥**:在调用Google Map API时,需要一个有效的API密钥,这通常会存储在配置文件或环境变量中,确保安全。 3. **位置标记**:Java代码可能包含方法来创建和管理`Marker`对象,这些对象表示地图上的特定点...

    Google Map API获取地理位置信息

    在IT领域,Google Map API是开发人员常用的工具之一,它允许我们通过JavaScript编程语言与Google Maps服务进行交互,获取和处理地理位置信息。本篇文章将详细探讨如何利用Google Map API来获取地点的经纬度坐标以及...

    Google Map API基本源码

    Google Map API是一个强大的工具,它允许开发者在网页或应用程序中集成地图功能,提供导航、定位、地理编码等服务。这个“Google Map API基本源码”很可能是为了帮助初学者理解和应用这一API而准备的示例代码集合。...

    google map api 实现自定义mark和其移动

    google map api 实现自定义mark和其移动

    Google Map api V3 (3.9.12)的离线开发包

    Google Map API V3(3.9.12)是谷歌提供的一个用于在网页上嵌入交互式地图的服务,它是Google Maps JavaScript API的第三个主要版本。这个离线开发包允许开发者在没有网络连接的情况下进行地图应用的开发和测试,这...

    google map api 最新参考文档

    google map api 参考文档google map api 参考文档google map api 参考文档google map api 参考文档google map api 参考文档google map api 参考文档

    google map api 实例

    最后,记得在使用谷歌地图API时要考虑性能和费用。频繁的API调用可能会产生费用,因此在实际应用中应合理使用API,考虑缓存策略,避免不必要的请求。 总之,谷歌地图API提供了强大的地图集成能力,通过实例化地图...

    GoogleMap Api二次开发+Asp.Net+数据库+GPS

    在本实例中,我们主要探讨如何使用GoogleMap API进行二次开发,并结合Asp.Net、数据库以及GPS技术,创建一个功能丰富的Web应用。首先,我们来深入理解这些关键知识点。 1. GoogleMap API: GoogleMap API是Google...

    google map api 及范例

    谷歌地图API(Google Maps API)是谷歌提供的一套强大的开发工具,允许开发者在自己的网站或应用中嵌入交互式地图,实现地理位置相关的功能。这个压缩包包含两份重要的资源:《google_map_api中文手册.chm》和...

    map中字符串与结构体作key效率比较

    在这个场景中,我们关注的是在C++ STL中的`map`容器中,使用字符串(`std::string`)作为键(key)与使用自定义结构体(struct)作为键在查找效率上的比较。`map`是一个关联容器,它提供了基于键的有序存储,通常...

    Google Map API 开发实例

    在IT行业中,Google Map API是一个强大的工具,它允许开发者集成地图功能到他们的应用程序或网站中,从而实现丰富的地理定位和导航服务。这个压缩包文件似乎包含了一系列关于如何使用Google Map API进行二次开发的...

Global site tag (gtag.js) - Google Analytics