At svare mig selv som ofte stillede spørgsmål på dette websted opmuntrer det. Dette virker for mig:
For det meste tegn äåö er ikke et problem, da standardtegnsættet brugt af browsere og tomcat/java til webapps er latin1 dvs. ISO-8859-1, som "forstår" disse tegn.
For at få UTF-8 til at fungere under Java+Tomcat+Linux/Windows+Mysql kræves følgende:
Konfiguration af Tomcats server.xml
Det er nødvendigt at konfigurere, at connectoren bruger UTF-8 til at kode url-parametre (GET request):
<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"
/>
Nøgledelen er URIEncoding="UTF-8" i ovenstående eksempel. Dette garanterer, at Tomcat håndterer alle indgående GET-parametre som UTF-8-kodet. Som et resultat, når brugeren skriver følgende til adresselinjen i browseren:
https://localhost:8443/ID/Users?action=search&name=*ж*
tegnet ж håndteres som UTF-8 og er kodet til (normalt af browseren, før det overhovedet kommer til serveren) som %D0%B6 .
POST-anmodning påvirkes ikke af dette.
TegnsætFilter
Så er det tid til at tvinge java-webappen til at håndtere alle anmodninger og svar som UTF-8-kodet. Dette kræver, at vi definerer et tegnsætfilter som følgende:
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() {
}
}
Dette filter sikrer, at hvis browseren ikke har indstillet den kodning, der blev brugt i anmodningen, er den indstillet til UTF-8.
Den anden ting, som dette filter gør, er at indstille standardresponskodningen, dvs. den kodning, hvori den returnerede html/whatever er. Alternativet er at indstille svarkodning osv. i hver controller i applikationen.
Dette filter skal tilføjes til web.xml eller webappens implementeringsbeskrivelse:
<!--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>
Instruktionerne til at lave dette filter findes på tomcat-wikien ( http://wiki.apache.org/tomcat/Tomcat/UTF-8 )
JSP-sidekodning
I din web.xml , tilføj følgende:
<jsp-config>
<jsp-property-group>
<url-pattern>*.jsp</url-pattern>
<page-encoding>UTF-8</page-encoding>
</jsp-property-group>
</jsp-config>
Alternativt skal alle JSP-sider i webappen have følgende øverst:
<%@page pageEncoding="UTF-8" contentType="text/html; charset=UTF-8"%>
Hvis der bruges en form for layout med forskellige JSP-fragmenter, er dette nødvendigt i alle af dem.
HTML-metatags
JSP-sidekodning fortæller JVM at håndtere tegnene på JSP-siden i den korrekte kodning. Så er det tid til at fortælle browseren, hvilken kodning html-siden er i:
Dette gøres med følgende øverst på hver xhtml-side produceret af webappen:
<?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-forbindelse
Når du bruger en db, skal det defineres, at forbindelsen bruger UTF-8-kodning. Dette gøres i context.xml eller hvor som helst JDBC-forbindelsen er defineret som følger:
<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&characterEncoding=UTF-8"
/>
MySQL-database og tabeller
Den brugte database skal bruge UTF-8-kodning. Dette opnås ved at oprette databasen med følgende:
CREATE DATABASE `ID_development`
/*!40100 DEFAULT CHARACTER SET utf8 COLLATE utf8_swedish_ci */;
Så skal alle tabellerne også være i 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;
Nøgledelen er CHARSET=utf8 .
MySQL-serverkonfiguration
MySQL serveri skal også konfigureres. Dette gøres typisk i Windows ved at ændre my.ini -fil og i Linux ved at konfigurere my.cnf -file.I disse filer skal det defineres, at alle klienter, der er forbundet til serveren, bruger utf8 som standardtegnsæt, og at standardtegnsættet, der bruges af serveren, også er utf8.
[client]
port=3306
default-character-set=utf8
[mysql]
default-character-set=utf8
Mysql-procedurer og -funktioner
Disse skal også have karaktersættet defineret. For eksempel:
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-anmodninger:latin1 og UTF-8
Hvis og når det er defineret i tomcats server.xml, at GET-anmodningsparametre er kodet i UTF-8, håndteres følgende GET-anmodninger korrekt:
https://localhost:8443/ID/Users?action=search&name=Petteri
https://localhost:8443/ID/Users?action=search&name=ж
Fordi ASCII-tegn er kodet på samme måde både med latin1 og UTF-8, håndteres strengen "Petteri" korrekt.
Det kyrilliske tegn ж forstås slet ikke på latin1. Fordi Tomcat bliver bedt om at håndtere anmodningsparametre som UTF-8, koder den det tegn korrekt som %D0%B6 .
Hvis og når browsere bliver bedt om at læse siderne i UTF-8-kodning (med anmodningsheadere og html-metatag), koder mindst Firefox 2/3 og andre browsere fra denne periode alle tegnet selv som %D0% B6 .
Slutresultatet er, at alle brugere med navnet "Petteri" er fundet, og også alle brugere med navnet "ж" er fundet.
Men hvad med äåö?
HTTP-specifikationen definerer, at URL'er som standard kodes som latin1. Dette resulterer i, at firefox2, firefox3 osv. koder følgende
https://localhost:8443/ID/Users?action=search&name=*Päivi*
ind i den kodede version
https://localhost:8443/ID/Users?action=search&name=*P%E4ivi*
På latin1 tegnet ä er kodet som %E4 . Selvom siden/anmodningen/alt er defineret til at bruge UTF-8 . Den UTF-8-kodede version af ä er %C3%A4
Resultatet af dette er, at det er helt umuligt for webappen at håndtere anmodningsparametrene fra GET-anmodninger korrekt, da nogle tegn er kodet i latin1 og andre i UTF-8.Bemærk:POST-anmodninger fungerer, da browsere koder alle anmodningsparametre fra formularer helt i UTF-8, hvis siden er defineret som værende UTF-8
Ting at læse
En meget stor tak til skribenten af følgende for at give svarene på mit problem:
- 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/
Vigtig bemærkning
mysql
understøtter Basic Multilingual Plane
ved hjælp af 3-byte UTF-8-tegn. Hvis du har brug for at gå uden for det (visse alfabeter kræver mere end 3-bytes UTF-8), så skal du enten bruge en smag af VARBINARY
kolonnetype eller brug utf8mb4 tegnsæt
(som kræver MySQL 5.5.3 eller nyere). Bare vær opmærksom på, at du bruger utf8
tegnsæt i MySQL virker ikke 100 % af tiden.
Tomcat med Apache
En ting mere Hvis du bruger Apache + Tomcat + mod_JK-stik, skal du også foretage følgende ændringer:
- Tilføj URIEncoding="UTF-8" til tomcat server.xml-fil til 8009-stikket, det bruges af mod_JK-stikket.
- Gå til din apache-mappe, dvs.
/etc/httpd/conf
og tilføjAddDefaultCharset utf-8
ihttpd.conf-fil
. Bemærk: Tjek først, om den eksisterer eller ej. Hvis det findes, kan du opdatere det med denne linje. Du kan også tilføje denne linje nederst.