Передача параметров запроса в кодированные строки UTF-8
Я создаю простую страницу входа, и я хочу передать параметры входа и пароля в кодированные строки UTF-8. Как вы можете видеть в приведенном ниже коде, первая строка - это то, где я устанавливаю кодировку в UTF-8, но, похоже, это бессмысленно, потому что это не работает. Когда я использую параметры входа и пароля с акцентами, страница результатов получает странные символы.
Как правильно установить кодировку символов таким образом, что это работает во всех браузерах?
<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>My Page</title>
</head>
<body>
<h1>Welcome to My Page</h1>
<form name="login" action="login.jsp" method="POST">
Login:<br/>
<input type="text" name="login" value="" /><br/>
Password:<br/>
<input type="password" name="password" value="" /><br/>
<br/>
<input type="submit" value="Login" /><br/>
</form>
</body>
</html>
Ответы
Ответ 1
pageEncoding
устанавливает только кодировку символов ответа и атрибут charset
заголовка HTTP Content-Type
. В основном, он сообщает серверу, чтобы декодировать символы, созданные JSP как UTF-8, перед отправкой его клиенту, и заголовок сообщает клиенту кодировать их с использованием UTF-8, а также использовать его, когда любые формы на одной и той же странице для отправки обратно на сервер. contentType
уже по умолчанию имеет значение text/html
, поэтому ниже достаточно:
<%@page pageEncoding="UTF-8"%>
Метатег HTML игнорируется, когда страница передается через HTTP. Он использовался только тогда, когда страница была сохранена клиентом как файл HTML на локальной дисковой системе, а затем открыта URI file://
в браузере.
В вашем конкретном случае кодировка тела запроса HTTP, по-видимому, не установлена в UTF-8. Кодирование тела запроса должно быть установлено ServletRequest#setCharacterEncoding()
в сервлет или фильтр до того, как первый вызов request.getXxx()
будет когда-либо сделан в любой сервлет или фильтр, участвующие в запросе.
request.setCharacterEncoding("UTF-8");
String login = request.getParameter("login");
String password = request.getParameter("password");
// ...
См. также:
Ответ 2
Вызов ServletRequest # setCharacterEncoding() по-прежнему будет терпеть неудачу в некоторых случаях.
Если ваш контейнер внимательно следит за спецификацией сервлета (как и tomcat), он будет интерпретировать параметры сообщений как ISO-8859-1 по умолчанию. Это может исказить символы UTF-8 (например, японский язык в последнем случае, когда я работал), прежде чем они когда-либо попадут в ваш код, особенно если у вас есть фильтр сервлета, который проверяет параметры запроса с помощью getParameter()
или getParameters()
. Эти два метода принудительно декодируют параметры, а декодирование выполняется только один раз.
Вот ссылка, как обойти это в Tomcat, если у вас есть фильтры, которые смотрят на параметры запроса. Люди захотят проверить документы для своего конкретного контейнера.
http://wiki.apache.org/tomcat/FAQ/CharacterEncoding#Q1
Ключ от этого:
Добавить
useBodyEncodingForURI="true" URIEncoding="UTF-8"
для элемента Context в Tomcat server.xml и добавьте
<filter>
<filter-name>Character Encoding Filter</filter-name>
<filter-class>org.apache.catalina.filters.SetCharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>Character Encoding Filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
как и перед любым фильтром, который вызывает getParameter() или getParameters() в web.xml. Я обнаружил, что хотя ссылка выше делает два атрибута для элемента контекста похожими на альтернативы, useBodyEncodingForURI один абсолютно необходим, или tomcat не будет устанавливать кодировку для запроса. Из запроса .java в tomcat 7.0.42:
boolean useBodyEncodingForURI = connector.getUseBodyEncodingForURI();
if (enc != null) {
parameters.setEncoding(enc);
if (useBodyEncodingForURI) {
parameters.setQueryStringEncoding(enc);
}
} else {
parameters.setEncoding
(org.apache.coyote.Constants.DEFAULT_CHARACTER_ENCODING);
if (useBodyEncodingForURI) {
parameters.setQueryStringEncoding
(org.apache.coyote.Constants.DEFAULT_CHARACTER_ENCODING);
}
}
Ответ 3
Проблема зависит от того, какой сервер приложений используется. Даже страницы настроены правильно, например. к UTF8 попытка получить параметр в правильной форме (согласно ожидаемому языку) не дает хороших результатов, то есть request.getParameter(...) возвращает не ожидаемые символы, потому что кодовая страница по умолчанию для параметров в основном составляет 8859-1. Это означает, что кодовая страница для параметров независима от кодовой страницы JSP, а кодовая страница по умолчанию для параметров влияет на результат. Лучшее описание, которое я нашел здесь:
[1]: http://docs.cksource.com/CKFinder_2.x/Developers_Guide/Java/Configuration/URI_Encoding.
На некоторых серверах приложений "request.setCharacterEncoding(...)" не влияет. Вы должны установить кодировку параметров в дескрипторе. Самыми сложными являются JBoss, Apache Tomcat, в середине - Glassfish. Лучше WebLogic, лучше всего Jetty (настройка UTF-8 по умолчанию). В моем случае я должен создать дескриптор Glassfish-web.xml и поместить там тег-кодировку параметра. В моем случае (GlassFish):
<glassfish-web-app error-url="">
<!-- request.setCharacterEncoding("UTF-8") not functioning -->
<parameter-encoding default-charset="UTF-8" />
</glassfish-web-app>
Ответ 4
Недавно я столкнулся с этой проблемой и не нашел ответа здесь. Я использую Weblogic, и большинство решений для Tomcat.
Для кодирования для работы с Weblogic вы должны поместить это в свой weblogic.xml
<charset-params>
<input-charset>
<resource-path>/*</resource-path>
<java-charset-name>UTF-8</java-charset-name>
</input-charset>
</charset-params>
Источник: weblogic.xml docs
ПРИМЕЧАНИЕ. У меня также есть эти параметры в моих _JAVA_OPTIONS, но не знаю, нужны ли они.
-Dweblogic.webservice.i18n.charset=utf-8
-Dfile.encoding=UTF-8
Ответ 5
Пример символа Кодировка:
<%@ page language="java" pageEncoding="utf8" contentType="text/html;charset=UTF-8" %>