错误的URI编码出现了一个奇怪的问题,非常感谢任何帮助!
该项目使用JSP,Servlets,Jquery,Tomcat 6。
JSP中的Charset设置为UTF-8,所有Tomcat连接器都使用URIEncoding = UTF-8,我还使用了here所述的字符编码过滤器。 此外,我在元标记中设置了contentType,我的浏览器正确检测到它。
在使用Jquery的Ajax调用中,我在要用作URL参数的术语上使用encodeURIComponent(),然后使用$ .param()序列化整个参数集。在被调用的servlet中,这些参数使用Java.net.URLDecoder.decode(术语“UTF-8”)正确解码。
在某些地方,我从JSP中的参数映射生成href元素的URL。每个参数值在JSP端使用Java.net.URLEncoder.encode(值,“UTF-8”)进行编码,然后以与之前相同的方式对其进行解码,从而导致特殊字符损坏。相反,我必须在JSP中将其编码为“ISO-8859-2”,然后在servlet中将其正确解码为“UTF-8”。
澄清的一个例子: 术语“überfall”通过Javascript(%C3%BCberfall)进行URIEncoded,并发送到servlet进行解码和处理,这有效。将它传回JSP后,我将其编码为UTF-8并构建URL,例如:
<a href="/myWebapp/servletPath?term=%C3%BCberfall">Click here</a>
但是,单击此链接会将参数“%C3%83%C2%BCberfall”发送到解码为“überfall”的servlet。没有编码时会发生同样的情况。
当使用“ISO-8859-2”进行编码时,我得到:
<a href="/myWebapp/servletPath?term=%FCberfall">Click here</a>
单击此链接时,我可以在Wireshark中观察到%C3%BCberfall作为参数发送,再次解码为“überfall”!
谁能告诉我哪里错过了什么?
编辑: 在观察Firebug中的网络选项卡时,我意识到使用
$.param({term : encodeURIComponent(term)});
该术语是UTF-8编码两次,导致“%25C3%25BCberfall”,即百分比符号也是百分比编码的。类似地,如果我对参数图中的每个值调用encode(term,“UTF-8”)两次,它对我有用。
编码一次而不解码字符串会再次导致“überfall”。
答案 0 :(得分:1)
Java在内部使用什么编码?您是否以
开始申请?-Dfile.encoding=utf-8
请说明定义“JSP中的参数映射”的位置。它是来自某些持久性数据存储,还是代码中给出的字符串作为文字?
对正在发生的事情的一些想法,这可能会有所帮助:
ü
是在UTF-8
编码ü
读取期望ISO-8859-1
时,每个字节自行解码时出现的内容。 %C3%BC
是UTF-8
UTF-8
的{{1}}字节的URI编码表示形式。我认为这就是发生的事情:
ü
将错误地解码为→ %C3%BC
,其编码为→ {{1然后再次解码为 ü
,以便最终得到%C3%83%C2%BC
。
所以我想,您使用错误的编码来解码URI编码的字符串。这可能与Java / JVM使用的内部编码有关:
答案 1 :(得分:1)
我想我现在肯定已经解决了这个问题。
根据Jontro的评论,我编写了所有URL参数值一次,并删除了手动servlet端解码。
在Firebug的“网络”标签中发送ü
应该看起来像%C3%BC
,它在servlet中提供了ü
。
Java肯定是使用-Dfile.encoding参数设置为“UTF-8”内部编码。
我将问题跟踪到这样的request.getParameter()方法。 request.getQueryString没问题,但在提取实际参数时失败了:
request.getCharacterEncoding())=&gt; UTF-8
request.getContentType()=&gt;空
request.getQueryString()=&gt;从= 0&安培; = RESULTCOUNT 10安培; sortAsc =真安培;检索类别=快速和安培;术语=%C3%BC
request.getParameter(“term”)=&gt;那张
Charset.defaultCharset()=&gt; UTF-8
OutputStreamWriter.getEncoding()=&gt; UTF8
new String(request.getParameter(“term”)。getBytes(),UTF-8)=&gt;那张
System.getProperty(“file.encoding”)=&gt; UTF-8
通过查看实现request.getParameter()的Tomcat和Coyote的来源,我发现了问题:来自连接器的URIEncoding始终为null,在这种情况下,它默认为org.apache.coyote.Constants.DEFAULT_CHARACTER_ENCODING,这是像Wolfram所说的“ISO-8859-1”。
长话短说:我的错误是在Tomcat的conf目录中编辑server.xml,当在服务器视图中创建新服务器时,该目录仅将ONCE加载到Eclipse中!之后,必须编辑Servers项目中的单独server.xml。执行此操作后,连接器设置将正确加载,一切正常。
感谢您的评论!希望这有助于某人...