Mysql
 sql >> база данни >  >> RDS >> Mysql

Как да накарам UTF-8 да работи в уеб приложения на Java?

Отговарям сам, тъй като често задаваните въпроси на този сайт го насърчават. Това работи за мен:

Предимно символите äåö не са проблем, тъй като наборът от символи по подразбиране, използван от браузърите и tomcat/java за уеб приложения, е latin1 т.е. ISO-8859-1, който "разбира" тези знаци.

За да накарате UTF-8 да работи под Java+Tomcat+Linux/Windows+Mysql изисква следното:

Конфигуриране на server.xml на Tomcat

Необходимо е да конфигурирате, че конекторът използва UTF-8 за кодиране на параметри на url (GET заявка):

<Connector port="8080" maxHttpHeaderSize="8192"
 maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
 enableLookups="false" redirectPort="8443" acceptCount="100"
 connectionTimeout="20000" disableUploadTimeout="true" 
 compression="on" 
 compressionMinSize="128" 
 noCompressionUserAgents="gozilla, traviata" 
 compressableMimeType="text/html,text/xml,text/plain,text/css,text/ javascript,application/x-javascript,application/javascript"
 URIEncoding="UTF-8"
/>

Ключовата част е URIEncoding="UTF-8" в горния пример. Това гарантира, че Tomcat обработва всички входящи GET параметри като UTF-8 кодирани. В резултат на това, когато потребителят напише следното в адресната лента на браузъра:

 https://localhost:8443/ID/Users?action=search&name=*ж*

символът ж се обработва като UTF-8 и се кодира (обикновено от браузъра, преди дори да стигне до сървъра) като %D0%B6 .

POST заявките не са засегнати от това.

CharsetFilter

Тогава е време да принудите java webapp да обработва всички заявки и отговори като UTF-8 кодирани. Това изисква да дефинираме филтър за набор от знаци, както следва:

package fi.foo.filters;

import javax.servlet.*;
import java.io.IOException;

public class CharsetFilter implements Filter {

    private String encoding;

    public void init(FilterConfig config) throws ServletException {
        encoding = config.getInitParameter("requestEncoding");
        if (encoding == null) encoding = "UTF-8";
    }

    public void doFilter(ServletRequest request, ServletResponse response, FilterChain next)
            throws IOException, ServletException {
        // Respect the client-specified character encoding
        // (see HTTP specification section 3.4.1)
        if (null == request.getCharacterEncoding()) {
            request.setCharacterEncoding(encoding);
        }

        // Set the default response content type and encoding
        response.setContentType("text/html; charset=UTF-8");
        response.setCharacterEncoding("UTF-8");

        next.doFilter(request, response);
    }

    public void destroy() {
    }
}

Този филтър гарантира, че ако браузърът не е задал кодирането, използвано в заявката, то е настроено на UTF-8.

Другото нещо, което прави този филтър е да зададе кодирането на отговора по подразбиране, т.е. кодирането, в което е върнатият html/каквото и да е. Алтернативата е да зададете кодиране на отговор и т.н. във всеки контролер на приложението.

Този филтър трябва да бъде добавен към web.xml или дескриптора за внедряване на уеб приложението:

 <!--CharsetFilter start--> 

  <filter>
    <filter-name>CharsetFilter</filter-name>
    <filter-class>fi.foo.filters.CharsetFilter</filter-class>
      <init-param>
        <param-name>requestEncoding</param-name>
        <param-value>UTF-8</param-value>
      </init-param>
  </filter>

  <filter-mapping>
    <filter-name>CharsetFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>

Инструкциите за създаване на този филтър се намират в tomcat wiki ( http://wiki.apache.org/tomcat/Tomcat/UTF-8 )

JSP кодиране на страница

Във вашия web.xml , добавете следното:

<jsp-config>
    <jsp-property-group>
        <url-pattern>*.jsp</url-pattern>
        <page-encoding>UTF-8</page-encoding>
    </jsp-property-group>
</jsp-config>

Като алтернатива, всички JSP-страници на уеб приложението ще трябва да имат следното в горната част на тях:

 <%@page pageEncoding="UTF-8" contentType="text/html; charset=UTF-8"%>

Ако се използва някакъв вид оформление с различни JSP-фрагменти, то това е необходимо във всички от тях.

HTML-мета тагове

JSP кодирането на страницата казва на JVM да обработва знаците в JSP страницата в правилното кодиране. След това е време да каже на браузъра в кое кодиране е html страницата:

Това се прави със следното в горната част на всяка xhtml страница, създадена от уеб приложението:

   <?xml version="1.0" encoding="UTF-8"?>
   <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
   <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="fi">
   <head>
   <meta http-equiv='Content-Type' content='text/html; charset=UTF-8' />
   ...

JDBC-връзка

Когато използвате db, трябва да се дефинира, че връзката използва UTF-8 кодиране. Това се прави в context.xml или където и да се дефинира JDBC връзката, както следва:

      <Resource name="jdbc/AppDB" 
        auth="Container"
        type="javax.sql.DataSource"
        maxActive="20" maxIdle="10" maxWait="10000"
        username="foo"
        password="bar"
        driverClassName="com.mysql.jdbc.Driver" url="jdbc:mysql://localhost:3306/      ID_development?useEncoding=true&amp;characterEncoding=UTF-8"
    />

MySQL база данни и таблици

Използваната база данни трябва да използва UTF-8 кодиране. Това се постига чрез създаване на база данни със следното:

   CREATE DATABASE `ID_development` 
   /*!40100 DEFAULT CHARACTER SET utf8 COLLATE utf8_swedish_ci */;

След това всички таблици трябва също да са в UTF-8:

   CREATE TABLE  `Users` (
    `id` int(10) unsigned NOT NULL auto_increment,
    `name` varchar(30) collate utf8_swedish_ci default NULL
    PRIMARY KEY  (`id`)
   ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_swedish_ci ROW_FORMAT=DYNAMIC;

Ключовата част е CHARSET=utf8 .

Конфигурация на MySQL сървър

MySQL сървърите също трябва да бъдат конфигурирани. Обикновено това се прави в Windows чрез модифициране на my.ini -file и в Linux, като конфигурирате my.cnf -file. В тези файлове трябва да се дефинира, че всички клиенти, свързани към сървъра, използват utf8 като набор от символи по подразбиране и че наборът от знаци по подразбиране, използван от сървъра, също е utf8.

   [client]
   port=3306
   default-character-set=utf8

   [mysql]
   default-character-set=utf8

Mysql процедури и функции

Те също трябва да имат дефиниран набор от знаци. Например:

   DELIMITER $$

   DROP FUNCTION IF EXISTS `pathToNode` $$
   CREATE FUNCTION `pathToNode` (ryhma_id INT) RETURNS TEXT CHARACTER SET utf8
   READS SQL DATA
   BEGIN

    DECLARE path VARCHAR(255) CHARACTER SET utf8;

   SET path = NULL;

   ...

   RETURN path;

   END $$

   DELIMITER ;

GET заявки:latin1 и UTF-8

Ако и когато в server.xml на tomcat е дефинирано, че параметрите на GET заявка са кодирани в UTF-8, следните GET заявки се обработват правилно:

   https://localhost:8443/ID/Users?action=search&name=Petteri
   https://localhost:8443/ID/Users?action=search&name=ж

Тъй като ASCII-символите са кодирани по един и същи начин както с latin1, така и с UTF-8, низът „Petteri“ се обработва правилно.

Кирилицата ж изобщо не се разбира на латиница1. Тъй като Tomcat е инструктиран да обработва параметрите на заявката като UTF-8, той кодира този знак правилно като %D0%B6 .

Ако и когато браузърите са инструктирани да четат страниците в UTF-8 кодиране (със заглавки на заявка и html мета-таг), поне Firefox 2/3 и други браузъри от този период всички кодират самите символа като %D0% B6 .

Крайният резултат е, че всички потребители с име "Petteri" са открити, както и всички потребители с името "ж".

Но какво ще кажете за äåö?

HTTP-спецификацията дефинира, че по подразбиране URL адресите са кодирани като latin1. Това води до firefox2, firefox3 и т.н., които кодират следното

    https://localhost:8443/ID/Users?action=search&name=*Päivi*

в кодираната версия

    https://localhost:8443/ID/Users?action=search&name=*P%E4ivi*

В latin1 знакът ä е кодиран като %E4 . Въпреки че страницата/заявката/всичко е дефинирано да използва UTF-8 . Кодираната в UTF-8 версия на ä е %C3%A4

Резултатът от това е, че е доста невъзможно уеб приложението да обработва правилно параметрите на заявката от GET заявки, тъй като някои знаци са кодирани в latin1, а други в UTF-8.Забележка:POST заявките работят, тъй като браузърите кодират всички параметри на заявката от формуляри изцяло в UTF-8, ако страницата е дефинирана като UTF-8

Неща за четене

Много благодаря на авторите на следното, че дадоха отговорите на моя проблем:

  • http://tagunov.tripod.com/i18n/i18n.html
  • http://wiki.apache.org/tomcat/Tomcat/UTF-8
  • http://java.sun.com/developer/technicalArticles/Intl/HTTPCharset/
  • http://dev.mysql.com/doc/refman/5.0/en/charset-syntax.html
  • http://cagan327.blogspot.com/2006/05/utf-8-encoding-fix-tomcat-jsp-etc.html
  • http://cagan327.blogspot.com/2006/05/utf-8-encoding-fix-for-mysql-tomcat.html
  • http://jeppesn.dk/utf-8.html
  • http://www.nabble.com/request-parameters-mishandle-utf-8-encoding-td18720039.html
  • http://www.utoronto.ca/webdocs/HTMLdocs/NewHTML/iso_table.html
  • http://www.utf8-chartable.de/

Важна забележка

поддържа Основна многоезична равнина използвайки 3-байтови UTF-8 символи. Ако трябва да излезете извън това (определени азбуки изискват повече от 3 байта UTF-8), тогава или трябва да използвате VARBINARY тип колона или използвайте utf8mb4 набор от символи (което изисква MySQL 5.5.3 или по-нова версия). Само имайте предвид, че с помощта на utf8 наборът от символи в MySQL няма да работи в 100% от случаите.

Tomcat с Apache

Още нещо Ако използвате Apache + Tomcat + mod_JK конектор, тогава трябва да направите и следните промени:

  1. Добавете URIEncoding="UTF-8" във файла tomcat server.xml за 8009 конектор, използва се от mod_JK конектор.
  2. Отидете до вашата папка Apache, т.е. /etc/httpd/conf и добавете AddDefaultCharset utf-8 в httpd.conf файл . Забележка: Първо проверете дали съществува или не. Ако има, можете да го актуализирате с този ред. Можете също да добавите този ред в долната част.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Колона за промяна на таблицата на MySQL

  2. Значението на дължината на varchar в таблицата на MySQL

  3. Как да проектираме mysql база данни с множество наематели

  4. Код на грешка:2013. Загубена връзка с MySQL сървър по време на заявка

  5. Каква е разликата между INNER JOIN, LEFT JOIN, DIGHT JOIN и FULL JOIN?