有一种在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);
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);
uname = URLDecoder.decode(new String(request.getParameter("name")
.getBytes()), CHARSET_FOR_URL_ENCODING);
System.out.println(uname);
Works :
final String name = URLDecoder
.decode(new String(request.getParameter("name").getBytes(
"iso-8859-1")), CHARSET_FOR_URL_ENCODING);
System.out.println(name);
虽然可以工作但如果默认编码不是utf-8就会出问题 - 请尝试使用这个方法(省略调用decode()的部分,因为它不是必需的):
final String name = new String(request.getParameter("name").getBytes("iso-8859-1"),
CHARSET_FOR_URL_ENCODING)
如我上面所说,如果server.xml
文件被篡改了,例如:
<Connector connectionTimeout="20000" port="8080" protocol="HTTP/1.1"
redirectPort="8443" URIEncoding="UTF-8"/>
注意上面的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;
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();
CHARSET_FOR_URI_ENCODING = uriEncoding;
}
}
}
}
你仍然需要调整这些内容以适应多个连接器(请查看已注释的部分)。然后你可以使用类似以下的方式:
new String(parameter.getBytes(CHARSET_FOR_URI_ENCODING), CHARSET_FOR_URL_ENCODING)
如果使用 CHARSET_FOR_URI_ENCODING 对 parameter = request.getParameter("name");
进行解码时出现损坏,那么 getBytes() 获得的字节就不是原始字节,这样可能导致操作失败(如果我理解的没错的话)。因此默认情况下会使用 "iso-8859-1" 编码 - 它将保留字节。你可以按以下方式手动解析查询字符串来消除所有这些问题:
URLDecoder.decode(request.getQueryString().split("=")[1],
CHARSET_FOR_URL_ENCODING)
我仍在查找文档中提到的request.getParameter("name")
调用URLDecoder.decode()
而不是返回%CF%84%CE%B7%CE%B3%CF%81%CF%84%CF%83%CF%82%CE%B7
字符串的位置。非常感谢源代码中的链接。
另外,我如何将字符串%CE
作为参数的值传递?=>请参见注释:parameter=%25CE
request.getParameter("name")
打印为ÏηγÏÏÏÏη
。request.getQueryString()
打印为name=%CF%84%CE%B7%CE%B3%CF%81%CF%84%CF%83%CF%82%CE%B7
- 如果传递给URLDecoder.decode()
,则可以正常解码。请问 _为什么getParameter()
不返回百分号编码的字符串_?ISO-8559-1 不是 ASCII 的超集吗? - Mr_and_Mrs_DgetParameter
旨在为您处理解码输入 - 浏览器在提交表单值时使用百分比对其进行编码,因此您必须对其进行解码以获取用户的输入。 必须使用某种编码将输入中的字节转换为字符,并且浏览器不总是使用相同的编码。 不幸的是,Servlet会为您选择一个编码,它的选择并不好,并且不允许您覆盖该选择 - 与URLDecoder.decode
不同,没有“enc”参数。 - bobincegetQueryString()
并自行解析,而不是让Servlet来处理。 - bobince