1

使用 get 方法提交表单时遇到参数编码问题(我不能使用 post 方法)。由于我的页面是 UTF8,因此 URL 中的一些重音字符没有转义。Spring 控制器改为检索坏字符。

我通过在我的表单上进行设置解决了这个问题accept-charset="ISO-8859-1",但是现在,我想知道哪个字符集对于所有服务器/浏览器组合都是安全的。我的表单和“获取”网址有什么推荐的吗?

4

3 回答 3

7

这对于 servlet 来说是令人沮丧的(委婉地说)。标准 URL 编码必须使用 UTF-8,但 servlet 不仅默认为 ISO-8859-1,而且不提供任何方法来使用代码更改它。

当然你可以req.setRequestEncoding("UTF-8")在你阅读任何东西之前,但出于某种不虔诚的原因,这只会影响请求正文,而不是查询字符串参数。servlet 请求接口中没有指定用于查询字符串参数的编码。

在您的表单中使用ISO-8859-1是一种技巧。使用这种古老的编码会导致比确定解决的问题更多的问题。特别是因为浏览器不支持 ISO-8859-1 并且始终将其视为 Windows-1252。而 servlet 将 ISO-8859-1 视为 ISO-8859-1,所以如果你这样做,你会变得难以置信。

例如,要在 Tomcat 中更改此设置,您可以在元素中使用该URIEncoding属性:<connector>

<connector ... URIEncoding="UTF-8" ... />

如果您不使用具有这些设置的容器,无法更改其设置或其他问题,您仍然可以使其工作,因为 ISO-8859-1 解码保留了原始二进制文件的完整信息。

String correct = new String(request.getParameter("test").getBytes("ISO-8859-1"), "UTF-8")

假设test=ä一切设置正确,浏览器会将其编码为test=%C3%A4. 您的 servlet 会错误地将其解码为 ISO-8859-1 并为您提供结果字符串"ä"。如果您应用更正,您可以ä返回:

System.out.println(new String("ä".getBytes("ISO-8859-1"), "UTF-8").equals("ä"));
//true
于 2013-03-23T13:09:28.937 回答
2

尼克多斯​​是对的。另一种方法是使用元数据标签:

<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=UTF-8">

还要记住,在服务器上处理响应时,代码也应该使用正确(相同)的编码。

例子:

利用stringParamer.getBytes("utf-8") instead of stringParamer.getBytes()

在使用 Spring 时,请确保在 DispatcherServlet 的配置文件 (XYZ_-servlet.xml) 中为消息转换器配置了正确的编码,例如:

<bean id="stringHttpMessageConverter" class="org.springframework.http.converter.StringHttpMessageConverter">
    <property name="supportedMediaTypes" value = "text/plain;charset=UTF-8"/>
</bean>
于 2013-03-22T11:44:33.983 回答
1

问题是 URL 总是被编码为 127-ASCII。因为您的表单通过 GET 发送回标准 ASCII 集之外的其他字符值,所以您遇到了几个问题:

  1. URL 限制为 2048 个字符,因此您的表单值可能会被截断
  2. 如果用户输入您在 Form 属性中设置的 ISO 接受类型之外的字符,它们将不会被正确编码到 URL 中。这是因为浏览器在第一次使用页面编码后对 URL 进行编码时会将所有内容转换为 127-ASCII。任何不在该 ISO 集中的特殊字符都将被错误编码。
  3. 浏览器总是首先使用页面编码或元标记来翻译 URL 中的字符。但是,如果有一个服务器 HTTP 标头,该编码将覆盖您的元标记编码。HTML5 页面的默认编码是 UTF-8。但是您使用的是覆盖它的 ISO 标准。即便如此,您的浏览器完成的所有编码都会用“%”替换非 ASCII 字符,后跟来自页面编码的十六进制数字,或者在您的情况下是表单的设置编码。然后将其发送到服务器,因此请查看您的 URL 以查看已发送的内容。
  4. 当您的 URL 到达服务器时,它以 127-ASCII 的形式出现,因此您需要首先将字符串作为 ASCII 获取,然后解码回页面编码,或者在您的情况下,表单接受用于获取真实值的值。

我建议您删除表单编码,使用页面 UTF-8 设置以获得更广泛的字符支持,并放入下面的这两个元标记以确保您发送回 UTF-8 编码数据,其中包括所有需要的字符并且易于解码如上面其他海报所述,在服务器上。

<meta charset="utf-8" />
<meta content="text/html; charset=utf-8" http-equiv="content-type" />
于 2018-08-29T22:08:00.850 回答