sql >> Databáze >  >> RDS >> Mysql

Jak zprovoznit UTF-8 ve webových aplikacích Java?

Vybízí to k tomu, abych odpověděl na často kladené otázky tohoto webu. Toto funguje pro mě:

Znaky äåö většinou nejsou problematické, protože výchozí znaková sada používaná prohlížeči a tomcat/java pro webové aplikace je latin1, tzn. ISO-8859-1, která těmto znakům „rozumí“.

Chcete-li, aby UTF-8 fungovalo pod Java+Tomcat+Linux/Windows+Mysql, vyžaduje se následující:

Konfigurace serveru Tomcat.xml

Je nutné nakonfigurovat, aby konektor používal UTF-8 ke kódování parametrů url (požadavek 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"
/>

Klíčovou částí je URIEncoding="UTF-8" ve výše uvedeném příkladu. To zaručuje, že Tomcat zpracovává všechny příchozí parametry GET jako kódování UTF-8. V důsledku toho, když uživatel napíše do adresního řádku prohlížeče následující:

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

znak ж je zpracován jako UTF-8 a je zakódován (obvykle prohlížečem ještě předtím, než se dostane na server) jako %D0%B6 .

Požadavek POST není tímto ovlivněn.

CharsetFilter

Pak je čas přinutit webovou aplikaci Java zpracovávat všechny požadavky a odpovědi jako kódování UTF-8. To vyžaduje, abychom definovali filtr znakové sady, jako je tento:

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() {
    }
}

Tento filtr zajišťuje, že pokud prohlížeč nenastavil kódování použité v požadavku, že je nastaveno na UTF-8.

Další věcí, kterou tento filtr dělá, je nastavení výchozího kódování odpovědi, tzn. kódování, ve kterém je vrácený html/whatever. Alternativou je nastavení kódování odezvy atd. v každém ovladači aplikace.

Tento filtr musí být přidán do web.xml nebo deskriptor nasazení webové aplikace:

 <!--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>

Pokyny pro vytvoření tohoto filtru naleznete na tomcat wiki ( http://wiki.apache.org/tomcat/Tomcat/UTF-8 )

Kódování stránky JSP

Ve vašem web.xml , přidejte následující:

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

Případně by všechny JSP stránky webové aplikace musely mít v horní části následující:

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

Pokud se používá nějaký druh rozvržení s různými JSP fragmenty, pak je to potřeba ve všech z nich.

HTML-metaznačky

Kódování stránky JSP říká JVM, aby zpracoval znaky na stránce JSP ve správném kódování. Pak je čas sdělit prohlížeči, ve kterém kódování je stránka html:

To se provádí pomocí následujícího v horní části každé stránky xhtml vytvořené webovou aplikací:

   <?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' />
   ...

Připojení JDBC

Při použití db musí být definováno, že připojení používá kódování UTF-8. To se provádí v context.xml nebo kdekoli, kde je připojení JDBC defend následovně:

      <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"
    />

Databáze a tabulky MySQL

Použitá databáze musí používat kódování UTF-8. Toho je dosaženo vytvořením databáze s následujícím:

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

Poté musí být všechny tabulky také v 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;

Klíčovou částí je CHARSET=utf8 .

Konfigurace serveru MySQL

Je třeba nakonfigurovat také servery MySQL. Obvykle se to ve Windows provádí úpravou my.ini -file a v Linuxu konfigurací my.cnf -file.V těchto souborech by mělo být definováno, že všichni klienti připojení k serveru používají utf8 jako výchozí znakovou sadu a že výchozí znakovou sadu používanou serverem je také utf8.

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

   [mysql]
   default-character-set=utf8

Procedury a funkce Mysql

Tyto také potřebují mít definovanou znakovou sadu. Například:

   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 ;

Požadavky GET:latin1 a UTF-8

Pokud a když je v tomcat's server.xml definováno, že parametry požadavku GET jsou kódovány v UTF-8, budou následující požadavky GET zpracovány správně:

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

Protože jsou znaky ASCII kódovány stejným způsobem jak v latin1, tak v UTF-8, je řetězec "Petteri" zpracován správně.

Azbuka ж není v latině vůbec srozumitelná1. Protože je Tomcat instruován, aby zpracovával parametry požadavku jako UTF-8, kóduje tento znak správně jako %D0%B6 .

Pokud a když prohlížeče dostanou pokyn číst stránky v kódování UTF-8 (s záhlavími požadavků a metaznačkou html), alespoň Firefox 2/3 a další prohlížeče z tohoto období kódují znak samy jako %D0% B6 .

Konečným výsledkem je, že jsou nalezeni všichni uživatelé se jménem "Petteri" a také všichni uživatelé se jménem "ж".

Ale co äåö?

Specifikace HTTP definuje, že výchozí adresy URL jsou kódovány jako latin1. Výsledkem je, že firefox2, firefox3 atd. kóduje následující

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

do zakódované verze

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

V latin1 znak ä je zakódováno jako %E4 . Přestože stránka/požadavek/vše je definováno pro použití UTF-8 . Verze ä s kódováním UTF-8 je %C3%A4

Výsledkem toho je, že je zcela nemožné, aby webová aplikace správně zpracovala parametry požadavku z požadavků GET, protože některé znaky jsou kódovány v latin1 a jiné v UTF-8.Upozornění:Požadavky POST fungují, protože prohlížeče kódují všechny parametry požadavku z formulářů zcela v UTF-8, pokud je stránka definována jako UTF-8

Věci ke čtení

Velmi děkuji autorům následujícího článku za odpovědi na můj problém:

  • 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/

Důležitá poznámka

podporuje Základní vícejazyčnou rovinu pomocí 3bajtových znaků UTF-8. Pokud potřebujete jít mimo (některé abecedy vyžadují více než 3 bajty UTF-8), musíte buď použít variantu VARBINARY typ sloupce nebo použijte utf8mb4 znaková sada (což vyžaduje MySQL 5.5.3 nebo novější). Jen si uvědomte, že pomocí utf8 znaková sada v MySQL nebude fungovat 100 % času.

Tomcat s Apache

Ještě jedna věc Pokud používáte konektor Apache + Tomcat + mod_JK, musíte také provést následující změny:

  1. Přidejte URIEncoding="UTF-8" do souboru tomcat server.xml pro konektor 8009, používá ho konektor mod_JK.
  2. Přejděte do složky Apache, tj. /etc/httpd/conf a přidejte AddDefaultCharset utf-8 v souboru httpd.conf . Poznámka: Nejprve zkontrolujte, zda existuje nebo ne. Pokud existuje, můžete jej aktualizovat pomocí tohoto řádku. Tento řádek můžete také přidat na konec.


  1. Rekurzivní kategorie s jediným dotazem?

  2. Rozšířené události pro SSAS

  3. MySQL, Získejte hodnocení uživatelů

  4. Jak mohu získat seznam tabulek v uložené proceduře?