Gra*_*ner 36 java unicode servlets
假设我有:
<a href="http://www.yahoo.com/" target="_yahoo"
title="Yahoo!™" onclick="return gateway(this);">Yahoo!</a>
<script type="text/javascript">
function gateway(lnk) {
window.open(SERVLET +
'?external_link=' + encodeURIComponent(lnk.href) +
'&external_target=' + encodeURIComponent(lnk.target) +
'&external_title=' + encodeURIComponent(lnk.title));
return false;
}
</script>
Run Code Online (Sandbox Code Playgroud)
我已经确认external_title将编码Yahoo!%E2%84%A2并传递给SERVLET.如果SERVLET我在做:
Writer writer = response.getWriter();
writer.write(request.getParameter("external_title"));
Run Code Online (Sandbox Code Playgroud)
我在浏览器中获得了Yahoo!¢.如果我手动将浏览器字符编码切换为UTF-8,它将更改为Yahoo! TM(这就是我想要的).
所以我认为我发送到浏览器的编码是错误的(确实如此Content-type: text/html; charset=ISO-8859-1).我改为SERVLET:
response.setContentType("text/html; charset=utf-8");
Writer writer = response.getWriter();
writer.write(request.getParameter("external_title"));
Run Code Online (Sandbox Code Playgroud)
现在浏览器字符编码是UTF-8,但它输出Yahoo!但我无法让浏览器呈现正确的字符.
我的问题是:是否存在某些组合Content-type和/或new String(request.getParameter("external_title").getBytes(), "UTF-8");和/或其他会导致Yahoo! TM出现在SERVLET输出中?
bob*_*nce 45
你快到了.EncodeURIComponent正确编码为UTF-8,这是您今天应该始终在URL中使用的.
问题是提交的查询字符串在进入服务器端脚本的过程中变得很残缺,因为getParameter()使用ISO-8559-1而不是UTF-8.这源于古代时代之前,网站以UTF-8为URI/IRI确定,但Servlet规范尚未更新以匹配现实,或至少为其提供可靠的支持选项,这是相当可悲的.
(Servlet 2.3中有request.setCharacterEncoding,但它不影响查询字符串解析,如果之前已经读过一个参数,可能是其他一些框架元素,它根本不起作用.)
因此,您需要使用特定于容器的方法来获取正确的UTF-8,通常涉及server.xml中的内容.这对于分发应该在任何地方工作的Web应用程序来说非常糟糕 对于Tomcat,请参阅http://wiki.apache.org/tomcat/FAQ/CharacterEncoding以及Tomcat 的"URIEncoding",编码过滤器和request.setCharacterEncoding之间的区别.
小智 19
我得到了同样的问题,并通过Request.getQueryString()使用URLDecoder()解码,并在提取我的参数后解决了它.
String[] Parameters = URLDecoder.decode(Request.getQueryString(), 'UTF-8')
.splitat('&');
Run Code Online (Sandbox Code Playgroud)
Mr_*_*s_D 16
有办法在java中做(没有摆弄server.xml)
不工作 :
protected static final String CHARSET_FOR_URL_ENCODING = "UTF-8";
String uname = request.getParameter("name");
System.out.println(uname);
// ÏηγÏÏÏÏη
uname = request.getQueryString();
System.out.println(uname);
// name=%CF%84%CE%B7%CE%B3%CF%81%CF%84%CF%83%CF%82%CE%B7
uname = URLDecoder.decode(request.getParameter("name"),
CHARSET_FOR_URL_ENCODING);
System.out.println(uname);
// ÏηγÏÏÏÏη // !!!!!!!!!!!!!!!!!!!!!!!!!!!
uname = URLDecoder.decode(
"name=%CF%84%CE%B7%CE%B3%CF%81%CF%84%CF%83%CF%82%CE%B7",
CHARSET_FOR_URL_ENCODING);
System.out.println("query string decoded : " + uname);
// query string decoded : name=????????
uname = URLDecoder.decode(new String(request.getParameter("name")
.getBytes()), CHARSET_FOR_URL_ENCODING);
System.out.println(uname);
// ÏηγÏÏÏÏη // !!!!!!!!!!!!!!!!!!!!!!!!!!!
Run Code Online (Sandbox Code Playgroud)
作品:
final String name = URLDecoder
.decode(new String(request.getParameter("name").getBytes(
"iso-8859-1")), CHARSET_FOR_URL_ENCODING);
System.out.println(name);
// ????????
Run Code Online (Sandbox Code Playgroud)
工作但如果默认编码会中断!= utf-8 - 尝试这样做(省略对decode()的调用,不需要):
final String name = new String(request.getParameter("name").getBytes("iso-8859-1"),
CHARSET_FOR_URL_ENCODING);
Run Code Online (Sandbox Code Playgroud)
正如我上面所说,如果server.xml被搞砸了如下:
<Connector connectionTimeout="20000" port="8080" protocol="HTTP/1.1"
redirectPort="8443" URIEncoding="UTF-8"/>
Run Code Online (Sandbox Code Playgroud)
(注意URIEncoding="UTF-8")上面的代码会中断(导致getBytes("iso-8859-1")应该读取getBytes("UTF-8")).因此,对于防弹解决方案,您必须获取URIEncoding属性的值.遗憾的是,这似乎是容器特定的 - 甚至更糟糕的容器版本.对于tomcat 7,您需要以下内容:
import javax.management.AttributeNotFoundException;
import javax.management.InstanceNotFoundException;
import javax.management.MBeanException;
import javax.management.MBeanServer;
import javax.management.MBeanServerFactory;
import javax.management.MalformedObjectNameException;
import javax.management.ObjectName;
import javax.management.ReflectionException;
import org.apache.catalina.Server;
import org.apache.catalina.Service;
import org.apache.catalina.connector.Connector;
public class Controller extends HttpServlet {
// ...
static String CHARSET_FOR_URI_ENCODING; // the `URIEncoding` attribute
static {
MBeanServer mBeanServer = MBeanServerFactory.findMBeanServer(null).get(
0);
ObjectName name = null;
try {
name = new ObjectName("Catalina", "type", "Server");
} catch (MalformedObjectNameException e1) {
e1.printStackTrace();
}
Server server = null;
try {
server = (Server) mBeanServer.getAttribute(name, "managedResource");
} catch (AttributeNotFoundException | InstanceNotFoundException
| MBeanException | ReflectionException e) {
e.printStackTrace();
}
Service[] services = server.findServices();
for (Service service : services) {
for (Connector connector : service.findConnectors()) {
System.out.println(connector);
String uriEncoding = connector.getURIEncoding();
System.out.println("URIEncoding : " + uriEncoding);
boolean use = connector.getUseBodyEncodingForURI();
// TODO : if(use && connector.get uri enc...)
CHARSET_FOR_URI_ENCODING = uriEncoding;
// ProtocolHandler protocolHandler = connector
// .getProtocolHandler();
// if (protocolHandler instanceof Http11Protocol
// || protocolHandler instanceof Http11AprProtocol
// || protocolHandler instanceof Http11NioProtocol) {
// int serverPort = connector.getPort();
// System.out.println("HTTP Port: " + connector.getPort());
// }
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
而且你还需要为多个连接器调整它(检查注释掉的部分).然后你会使用类似的东西:
new String(parameter.getBytes(CHARSET_FOR_URI_ENCODING), CHARSET_FOR_URL_ENCODING);
Run Code Online (Sandbox Code Playgroud)
如果使用CHARSET_FOR_URI_ENCODING进行解码,则可能会失败(IIUC)parameter = request.getParameter("name");,因此使用getBytes()得到的字节不是原始字节(这就是为什么默认使用"iso-8859-1" - 它将保留字节).您可以通过手动解析以下行中的查询字符串来解决所有问题:
URLDecoder.decode(request.getQueryString().split("=")[1],
CHARSET_FOR_URL_ENCODING);
Run Code Online (Sandbox Code Playgroud)
我仍然在寻找在那里提到,在文档中的位置request.getParameter("name")并调用URLDecoder.decode() 返回而不是%CF%84%CE%B7%CE%B3%CF%81%CF%84%CF%83%CF%82%CE%B7字符串?源中的链接将非常感激.
另外,我怎样才能将字符串作为参数的值传递 =>看评论: %CE?parameter=%25CE
| 归档时间: |
|
| 查看次数: |
92988 次 |
| 最近记录: |