но теперь я отправляю японские строки в URL запроса. Я кодирую параметр по UTF-8 перед отправкой, и я должен декодировать их с помощью UTF-8.
Ответ 2
Это хороший вопрос, который потенциально может дать много сомнений в том, как обрабатывается информация (кодируется и декодируется) между системами.
Прежде чем продолжить, я должен сказать, что у вас есть справедливое понимание Charset, Encoding и т.д. Вы можете прочитать этот ответ для быстрого хэдз-ап.
Это должно выглядеть с двух сторон - браузера и сервера.
Взгляд браузера на кодирование
Каждый браузер будет отображать информацию/текст, теперь, чтобы отобразить информацию/текст, он должен знать, как интерпретировать эти биты/байты, чтобы он мог корректно отображать (прочитайте мой ответ 3-й маркер, что как одни и те же биты могут представлять разные символы в другой схеме кодирования).
Кодировка страницы браузера
- Каждый браузер будет иметь ассоциированную с ним кодировку по умолчанию. Проверьте это, как увидеть кодировку по умолчанию браузера.
- Если вы не укажете какую-либо кодировку на своей HTML-странице, тогда будет использоваться кодировка браузера по умолчанию и отобразит страницу в соответствии с этими правилами кодирования. поэтому, если кодировка по умолчанию - ASCII, и вы используете японский или китайский или символы из дополнительной плоскости Unicode, тогда вы увидите значение мусора.
- Вы можете указать браузеру, который не использует схему кодирования по умолчанию, но использовать эту для рендеринга через веб-сайт, используя
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
.
- И это именно то, что вы сделали/нашли, и вы были в порядке, потому что этот тег
meta
существенно перепробовал кодировку браузера по умолчанию.
- Другой способ добиться такого же эффекта - это не использовать этот метатег, а просто изменить кодировку по умолчанию браузера, и все равно вы будете в порядке. Но это не рекомендуется, и рекомендуется использовать метатег
Content-Type
в вашем JSP.
Попробуйте сыграть с кодировкой по умолчанию браузера и тегом meta
, используя ниже простой HTML.
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body>
の, は, でした <br></br>
昨夜, 最高
</body>
</html>
Перспектива сервера для кодирования
Сервер также должен знать, как интерпретировать входящий поток данных, что в основном означает, какую схему кодирования использовать (часть сервера сложна, потому что есть несколько возможностей). Читайте ниже здесь
Когда данные, введенные в HTML-формы, отправляются, форма имена полей и значения кодируются и отправляются на сервер в HTTP запросить сообщение, используя метод GET или POST, или, исторически, по электронной почте. Кодировка, используемая по умолчанию, основана на очень ранней версии общие правила кодирования URI, с рядом модификаций такие как нормализация новой строки и замена пробелов на "+" вместо "%20". Тип данных MIME, закодированный таким образом, application/x-www-form-urlencoded, и в настоящее время он определен (все еще очень устаревшим образом) в спецификациях HTML и XForms. В Кроме того, спецификация CGI содержит правила того, как веб-серверы декодировать данные этого типа и сделать их доступными для приложений.
У этого снова есть 2 части того, как сервер должен декодировать входящий поток запросов и как он должен кодировать исходящий поток ответа.
Существует несколько способов сделать это в зависимости от варианта использования, например:
- В HTTP-запросе и объекте ответа есть методы типа
setCharacterEncoding
, setContentType
и т.д., которые могут использоваться для установки кодировки.
- Это именно то, что вы сделали в своем случае, что вы сказали серверу, использующему схему кодирования UTF-8 для декодирования данных запроса, потому что я ожидаю дополнительных символов Unicode для дополнительной плоскости. Но это еще не все, пожалуйста, прочитайте ниже.
- Установите кодировку на уровне сервера или JVM, используя атрибуты JVM, такие как
-Dfile.encoding=utf8
. Прочитайте эту статью о том, как установить серверную кодировку.
В вашем случае вы извлекали японские символы из строки запроса URL-адреса, а строка запроса была частью объекта запроса HTTP, поэтому, используя request.setCharacterEncoding("UTF-8");
, вы смогли получить желаемый результат кодирования.
Но то же самое не будет работать для кодировки URL, которая отличается от кодировки запроса (ваш случай). Рассмотрим пример ниже, и в sysout
вы не сможете увидеть желаемый эффект кодирования даже после использования request.setCharacterEncoding("UTF-8");
, потому что здесь вы хотите кодирование URL, так как URL-адрес будет выглядеть как http://localhost:7001/springapp/forms/executorTest/encodingTest/hellothere 昨夜, 最高
и в этом URL-адресе нет запроса строка.
@RequestMapping(value="/encodingTest/{quertStringValue}", method=RequestMethod.GET)
public ModelAndView encodingTest(@PathVariable("quertStringValue") String quertStringValue, ModelMap model, HttpServletRequest request) throws UnsupportedEncodingException {
System.out.println("############### quertStringValue " + quertStringValue);
request.setCharacterEncoding("UTF-8");
System.out.println("############### quertStringValue " + quertStringValue);
return new ModelAndView("ThreadInfo", "ThreadInfo", "@@@@@@@ This is my encoded output " + quertStringValue);
}
В зависимости от используемой структуры вам может потребоваться дополнительная настройка, чтобы указать кодировку символов для запросов или URL-адресов, чтобы вы могли либо применить собственную кодировку, если запрос еще не указал кодировку, либо принудительно применяет кодировку в любом случае. Это полезно, потому что текущие браузеры обычно не устанавливают кодировку символов, даже если они указаны в HTML-странице или форме.
В Spring для настройки кодировки запроса существует org.springframework.web.filter.CharacterEncodingFilter
. Прочитайте этот похожий интересный вопрос, который основан на этом факте.
В ореховой оболочке
Каждая компьютерная программа, будь то сервер приложений, веб-сервер, браузер, среда IDE и т.д., понимает только биты, поэтому ему необходимо знать, как интерпретировать биты, чтобы сделать ожидаемый смысл, потому что в зависимости от используемой кодировки одни и те же биты могут представлять разные символы. И что там, где "Кодирование" входит в картину, предоставляя уникальный идентификатор для представления символа, чтобы все компьютерные программы, различные ОС и т.д. знали точно правильный способ их интерпретации.