Кодирование и декодирование
На следующем рисунке мы можем понять, где есть транскодирование в Javaweb:
Пользователь хочет, чтобы сервер отправил HTTP -запрос. Требуются места, где кодирование - URL, файлы cookie и параметры. После кодирования сервер принимает HTTP -запрос, анализирует HTTP -запрос, а затем декодирует URL, файлы cookie и параметр. Во время обработки бизнес -логики сервера может потребоваться прочитать базы данных, локальные файлы или другие файлы в сети и т. Д., И эти процессы требуют кодирования и декодирования. После завершения обработки сервер кодирует данные и отправляет их клиенту, а браузер отображает его пользователю после декодирования. Во всем этом процессе связано много кодировки и декодирования, и наиболее вероятным местом для появления является процесс взаимодействия с сервером и клиентом.
Весь процесс выше, приведенный выше, можно суммировать следующим образом: кодируемые страницей данные передаются на сервер, а сервер декодирует полученные данные, а после некоторой обработки бизнес-логики конечный результат закодирован и обрабатывается, а клиент декодирует и отображает его пользователю. Итак, ниже я попрошу объяснить кодирование и декодирование Javaweb.
Если клиент хочет, чтобы сервер отправил запрос, он пройдет четыре ситуации:
1. Прямой доступ к URL.
2. Ссылка страницы.
3.
4. Форма после отправки
Метод URL: для URL -адресов, если все URL -адреса на английском языке, проблем нет. Если есть китайский, кодирование будет задействовано. Как кодировать? Какие правила вы хотите кодировать? Так как это декодировать? Ответы будут отвечать один за другим ниже! Сначала посмотрите на компоненты URL:
В этом URL браузер будет кодировать путь и параметр. Чтобы лучше объяснить процесс кодирования, используйте следующий URL -адрес
http://127.0.0.1:8080/perbank/i Am CM? Имя = I Am Cm
Введите вышеуказанный адрес в поле URL -адреса браузера. Просмотрев информацию о заголовке сообщений HTTP, мы можем увидеть, как его кодирует браузер. Вот условия кодирования трех браузеров:
Вы можете видеть, что кодирование «Я есть» в основных браузерах, заключается в следующем:
Часть пути | Строка запроса | |
Firefox | E6 88 91 E6 98 AF | E6 88 91 E6 98 AF |
Хром | E6 88 91 E6 98 AF | E6 88 91 E6 98 AF |
Т.е. | E6 88 91 E6 98 AF | CE D2 CA C7 |
Protected void converturi (MessageBytes URI, запрос запроса) бросает исключение {Bytechunk BC = uri.getBytechunk (); int length = bc.getLength (); Charchunk cc = uri.getcharchunk (); cc.allocate (длина, -1); String enc = connector.geturienCoding (); // Получите набор декодирования URI if (ec! = Null) {b2cconverter conv = request.geturiconverter (); попробуйте {if (conv == null) {conv = new b2cconverter (anc); request.seturiconverter (conv); }} catch (ioException e) {...} if (conv! = null) {try {conv.convert (bc, cc, cc.getbuffer (). length - cc.getend ()); uri.setchars (cc.getbuffer (), cc.getstart (), cc.getlength ()); возвращаться; } catch (ioException e) {...}}} // Кодирование по умолчанию: быстрое преобразование byte [] bbuf = bc.getbuffer (); char [] cbuf = cc.getbuffer (); int start = bc.getstart (); for (int i = 0; i <length; i ++) {cbuf [i] = (char) (bbuf [i+start] & 0xff); } uri.setchars (cbuf, 0, длина); } Из приведенного выше кода мы видим, что операция декодирования URI заключается в том, чтобы сначала получить набор декодирования разъема, который настроен в Server.xml
<Connector uriencoding = "utf-8" />
Если не определено, кодирование по умолчанию ISO-8859-1 будет использоваться для анализа.
Для части строки запроса мы знаем, что независимо от того, отправляем ли мы ее через get или post, все параметры сохраняются в параметрах, а затем мы используем request.getParameter, работа декодирования выполняется, когда метод GetParameter называется в первый раз. Внутри метода GetParameter он вызывает метод parseParameters org.apache.catalina.connector.request, который декодирует пропущенные параметры. Следующий код является лишь частью метода ParseParameters:
// Получить кодирующую строку ec = getCharacterCoding (); // Получить Boolean Charset Defined в ContentType Использование CodyEncodingForuri = connector.getUseBodyEncodingForuri (); if (enc! = null) {// Если кодирование не является пустым, установите кодирование на параметры enc.setEncoding (enc); if (используйте bodyencodingforuri) {// Если установлен диаграмма, установите декодирование QueryString на параметры диаграммы. SetqueryStringEncoding (ec); }} else {// Установить метод декодирования по умолчанию. if (используйте bodyencodingforuri) {parameters.setquerystringencoding (org.apache.coyote.constants.default_character_encoding); }} Из приведенного выше кода мы видим, что формат декодирования строки запроса либо использует набор диаграммы, либо использует формат декодирования по умолчанию ISO-8859-1. Обратите внимание, что диаграмма в этом настройке является ContentType, определенным в заголовке HTTP. В то же время, если нам нужно изменить указанный атрибут, чтобы вступить в силу, нам нужно настроить следующее:
<Connector uriencoding = "utf-8" используйте codyencodingforuri = "true"/>
Приведенная выше часть вводит процесс кодирования и декодирования запросов URL. На самом деле, для нас, наши больше способов - представить в форме.
Форма получить
Мы знаем, что представление данных с помощью URL -адресов легко вызвать искаженные проблемы с кодом, поэтому мы склонны использовать формы форм. Когда пользователь нажимает на отправку формы, браузер установит больше кодов для передачи данных на сервер. Данные, представленные через GET, сплайсируются после URL -адреса (можно ли рассматривать его как строку запроса? Сервер Tomcat будет декодировать в соответствии с установленным выведением, и если он не установлен, он будет использовать ISO-8859-1 по умолчанию для декодирования. Если мы установим кодирование в UTF-8 на странице, а уризодирование не установлено или не установлено, то искаженные коды возникнут при декодировании сервера. В настоящее время мы обычно можем получить правильные данные через форму новой строки (request.getParameter («имя»). GetBytes («iso-8859-1»), «UTF-8»).
Форма поста
Для метода POST использующий его кодирование также определяется страницей, то есть ContentType. Когда я отправляю форму, нажав кнопку «Отправить» на странице, браузер сначала кодирует параметры формы сообщения в соответствии с форматом кодирования charset ontenttype и отправит ее на сервер. На стороне сервера он также использует набор символов в ContentType для декодирования (он отличается от метода GET здесь). Это означает, что параметры, представленные через форму после, обычно не имеют искаженных проблем. Конечно, мы можем установить набор символов, кодируя себя: request.setcharacterencoding (charset).
Решите проблему искаженных URL -адресов на китайском языке
В основном мы отправляем запросы на сервер через две формы представления: URL и форма. Форма, как правило, не имеет искаженных проблем, а искаженные проблемы в основном на URL. Благодаря введению предыдущих блогов мы знаем, что процесс отправки запроса, кодирующего на сервере с помощью URL, действительно слишком запутан. Различные операционные системы, разные браузеры и разные наборы веб -символов приведут к совершенно разным результатам кодирования. Разве это не слишком страшно, если программисты хотят принять во внимание все результаты? Есть ли способ гарантировать, что клиент использует только один метод кодирования для выпуска запроса на сервер?
иметь! Здесь я в основном предоставляю следующие методы
JavaScript
Использование кодирования JavaScript не дает браузеру возможность вмешаться. После кодирования отправьте запрос на сервер, а затем декодируйте его на сервере. При освоении этого метода нам нужны три метода кодирования JavaScript: ascod (), encodeuri () и encodeuricomponent ().
побег
Указанная строка кодируется с использованием набора символов SIO. Все символы, не являющиеся ASCII, кодируются как строки в формате %xx, где XX представляет шестнадцатеричное число, соответствующее символу в наборе символов. Например, кодирование, соответствующее формату, равна %20. Его соответствующий метод декодирования - Unescape ().
Фактически, escep () не может быть использован непосредственно для кодирования URL, его реальная функция-вернуть значение, кодируемое юникодом симвода. Например, результат «I Am CM» выше - %U6211 %U662FCM, где соответствующее кодирование «I» составляет 6211, кодирование «да» составляет 662F, а кодирование «CM» - CM.
Обратите внимание, что escep () не кодируется "+". Но мы знаем, что когда веб -страница представляет форму, если есть места, она будет преобразована в + символы. Когда сервер обрабатывает данные, знак + знак будет обработана в пространство. Поэтому будьте осторожны при его использовании.
Encodeuri
Кодируя весь URL, он использует формат UTF-8 для вывода кодируемой строки. Тем не менее, Encodeuri не будет кодировать некоторые специальные символы, кроме кодирования ASCII, таких как:! @ # $ & * () =: /; ? + '.
Encodeuricomponent
Превратите строки URI в строки формата побега в формате кодирования UTF-8. По сравнению с Encodeuri, Encodeuricomponent будет более мощным, и он будет кодироваться для символов (; /?: @ & = + $, #), Которые не кодируются в encodeuri (). Тем не менее, Encodeuricomponent будет кодировать компоненты URL -адреса отдельно и не будет использоваться для кодирования всего URL. Соответствующий метод функции декодирования декодеурикупонент.
Конечно, мы обычно используем партию Encodeuri для выполнения операций кодирования. Так называемый кодирование и декодирование JavaScript дважды в фоновом режиме-использовать этот метод. Есть два решения для решения этой проблемы в JavaScript: один транскодирование и два метода транскодирования.
Транскодирование один раз
JavaScript Transcoding:
var url = '<s: value = "webpath" />/showmoblieqrcode.servlet?name=i am cm'; window.location.href = encodeuri (url);
Транскодированный URL: http://127.0.0.1:8080/perbank/showmoblieqrcode.servlet?name=%E6%88%91%E6%98%AFCM
Обработка бэкэнд:
String name = request.getParameter ("name"); System.out.println ("Входящие параметры переднего плана:" + name); name = new String (name.getBytes ("iso-8859-1"), "UTF-8"); System.out.println ("Декодированные параметры:" + name); Результат вывода:
Входящие параметры в стойку регистрации: ??????
После декодирования параметров: я CM
Вторичное транскодирование
JavaScript
var url = '<s: value = "webpath" />/showmoblieqrcode.servlet?name=i am cm'; window.location.href = encodeuri (encodeuri (url));
Транскодированный URL: http://127.0.0.1:8080/perbank/showmoblieqrcode.servlet?name=%25E6%2588%2591%25E6%2598%25afcm
Обработка бэкэнд:
String name = request.getParameter ("name"); System.out.println ("Входящие параметры переднего плана:" + name); name = urldecoder.decode (name, "utf-8"); System.out.println ("Декодированные параметры:" + name); Результат вывода:
Входящие параметры фронта: E68891E698AFCM
После декодирования параметров: я CM
фильтр
Используя фильтры, фильтры предоставляют два типа, первым является установка кодирования, а вторым является выполнение операций декодирования непосредственно в фильтре.
Фильтр 1
Этот фильтр напрямую устанавливает формат кодирования запроса.
Общедоступный класс символ Особого реализует фильтр {Private FilterConfig Config; String Encoding = null; public void destress () {config = null; } public void dofilter (запрос ServletRequest, ответ ServletResponse, FilterChain Chain) бросает ioException, servletexception {request.setcharacterencoding (кодирование); chain.dofilter (запрос, ответ); } public void init (config filterConfig) Throws ServletException {this.config = config; // Получить параметры конфигурации string str = config.getinitParameter ("Кодирование"); if (str! = null) {encoding = str; }}} Конфигурация:
<!-- Chinese filter configuration --> <filter> <filter-name>chineseEncoding</filter-name> <filter-class>com.test.filter.CharacterEncoding</filter-class> <init-param> <param-name>encoding</param-name> <param-value>utf-8</param-value> </init-param> </filter> <filter-mapping> <Filter-name> китайский экодинг </filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
Фильтр 2
В методе обработки фильтр непосредственно декодирует параметры, а затем сбрасывает декодированные параметры в атрибут запроса.
Public Class HearlyCoding реализует Filter {Protected FilterConfig FilterConfig; String Encoding = null; public void destress () {this.filterConfig = null; } / *** Инициализировать* / public void init (filterConfig filterConfig) {this.filterConfig = filterConfig; } / *** Преобразовать instr в форму кодирования UTF -8** @param instr string* @return utf - 8 Строка кодирования 8* @Throws UnsUpportEncodingException* / private String TOUTF (String instr) Throws UnsupportEncodingException {String upstr = ""; if (instr! = null) {outstr = new String (instr.getbytes ("iso-8859-1"), "UTF-8"); } return outstr; } / *** Китайская исчезненная обработка фильтрации* / public void dofilter (servletrequest servletrequest, Servletresponse Servletresponse, FilterChain Chain) Throws IoException, ServletException {httpservletRequest запрос = (httpservletrequest) servletrequest; Httpservletresponse response = (httpservletresponse) Servletresponse; // метод получения запроса (1.post или 2.get), и различная обработка выполняется в соответствии с различными методами запроса string method = request.getmethod (); // 1. Для запросов, представленных в сообщении, напрямую установите кодирование UTF-8 if (method.equalsignorecase ("post")) {try {request.setcharacterencoding ("utf-8"); } catch (unsupportEncodingexception e) {e.printstacktrace (); }} // 2. Запрос, представленный в get else {// получить набор параметров, представленных клиентским перечислением <string> paramnames = request.getParameternames (); // Переносить параметр, установленный, чтобы получить имя и значение каждого параметра while (paramnames.hasmoreelements ()) {string name = paramnames.nextelement (); // Выработать имя имени параметра // Установите его значение в соответствии с именем параметра // Если набор значений параметра не является пустым, если (values! = Null) {// Траверсировать значение параметра для (int i = 0; i <values.length; i ++) {try {// cluck sack и вызов каждого значения toutf (values [i]), чтобы преобразовать символ символов значения параметра string vlur vlur = toutf valustf valust = valustf (i]); значения [i] = vlustr; } catch (unsupportEncodingexception e) {e.printstacktrace (); }} // скрыть значение в форме атрибута в запросе запроса запроса. SetatatTribute (name, values); }}} // Установить метод ответа и поддержать китайский набор символов. // продолжать выполнять следующий фильтр. Если нет фильтра, запрос будет wave.dofilter (запрос, ответ); }} Конфигурация:
<!-Конфигурация китайского фильтра-> <Filter> <Filter-name> китайский экодинг </filter-name> <filter-class> com.test.filter.characterencoding </filter-class> </filter> <Filter-MAPPIN
другой
1. Установите Pageencoding и ContentType
<%@ page language = "java" contentType = "text/html; charset = utf-8" pageencoding = "utf-8"%>
2. Установите уризодирование Tomcat
По умолчанию сервер Tomcat использует формат кодирования ISO-8859-1 для кодирования URL-адреса, запрашиваемого параметром Uriencoding, поэтому нам нужно только добавить Uriencoding = "UTF-8" к тегу <nenector> файла Server.xml Tomcat.