Att svara mig själv som den här sidans vanliga frågor uppmuntrar det. Det här fungerar för mig:
Oftast är tecken äåö inget problem då standardteckenuppsättningen som används av webbläsare och tomcat/java för webbappar är latin1 dvs. ISO-8859-1 som "förstår" dessa tecken.
För att få UTF-8 att fungera under Java+Tomcat+Linux/Windows+Mysql krävs följande:
Konfigurera Tomcats server.xml
Det är nödvändigt att konfigurera att anslutaren använder UTF-8 för att koda url-parametrar (GET-begäran):
<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"
/>
Nyckeldelen är URIEncoding="UTF-8" i exemplet ovan. Detta garanterar att Tomcat hanterar alla inkommande GET-parametrar som UTF-8-kodade. Som ett resultat, när användaren skriver följande till webbläsarens adressfält:
https://localhost:8443/ID/Users?action=search&name=*ж*
Tecknet ж hanteras som UTF-8 och kodas till (vanligtvis av webbläsaren innan ens kommer till servern) som %D0%B6 .
POST-förfrågan påverkas inte av detta.
CharsetFilter
Då är det dags att tvinga Java-webbappen att hantera alla förfrågningar och svar som UTF-8-kodade. Detta kräver att vi definierar ett teckenuppsättningsfilter som följande:
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() {
}
}
Det här filtret ser till att om webbläsaren inte har ställt in kodningen som används i begäran, att den är inställd på UTF-8.
Den andra saken som detta filter gör är att ställa in standardsvarskodningen, dvs. kodningen i vilken den returnerade html/whatever är. Alternativet är att ställa in svarskodning etc. i varje styrenhet i applikationen.
Detta filter måste läggas till i web.xml eller distributionsbeskrivningen för webbappen:
<!--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>
Instruktionerna för att göra detta filter finns på tomcat-wikin ( http://wiki.apache.org/tomcat/Tomcat/UTF-8 )
JSP-sidkodning
I din web.xml , lägg till följande:
<jsp-config>
<jsp-property-group>
<url-pattern>*.jsp</url-pattern>
<page-encoding>UTF-8</page-encoding>
</jsp-property-group>
</jsp-config>
Alternativt skulle alla JSP-sidor i webbappen behöva ha följande överst:
<%@page pageEncoding="UTF-8" contentType="text/html; charset=UTF-8"%>
Om någon form av layout med olika JSP-fragment används, så behövs detta i alla av dem.
HTML-metataggar
JSP-sidakodning säger åt JVM att hantera tecknen på JSP-sidan med korrekt kodning. Sedan är det dags att tala om för webbläsaren i vilken kodning HTML-sidan är:
Detta görs med följande högst upp på varje xhtml-sida som produceras av webbappen:
<?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-anslutning
När du använder en db måste det definieras att anslutningen använder UTF-8-kodning. Detta görs i context.xml eller varhelst JDBC-anslutningen är definierad enligt följande:
<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-databas och tabeller
Den använda databasen måste använda UTF-8-kodning. Detta uppnås genom att skapa databasen med följande:
CREATE DATABASE `ID_development`
/*!40100 DEFAULT CHARACTER SET utf8 COLLATE utf8_swedish_ci */;
Sedan måste alla tabeller också vara 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;
Nyckeldelen är CHARSET=utf8 .
MySQL-serverkonfiguration
MySQL serveri måste också konfigureras. Vanligtvis görs detta i Windows genom att ändra my.ini -fil och i Linux genom att konfigurera my.cnf -fil.I dessa filer bör det definieras att alla klienter som är anslutna till servern använder utf8 som standardteckenuppsättning och att standardteckenuppsättningen som används av servern också är utf8.
[client]
port=3306
default-character-set=utf8
[mysql]
default-character-set=utf8
Mysql-procedurer och funktioner
Dessa måste också ha teckenuppsättningen definierad. Till exempel:
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-förfrågningar:latin1 och UTF-8
Om och när det är definierat i tomcats server.xml att GET-begäransparametrar är kodade i UTF-8, hanteras följande GET-begäranden korrekt:
https://localhost:8443/ID/Users?action=search&name=Petteri
https://localhost:8443/ID/Users?action=search&name=ж
Eftersom ASCII-tecken är kodade på samma sätt både med latin1 och UTF-8, hanteras strängen "Petteri" korrekt.
Det kyrilliska tecknet ж förstås inte alls på latin1. Eftersom Tomcat instrueras att hantera begärandeparametrar som UTF-8 kodar den det tecknet korrekt som %D0%B6 .
Om och när webbläsare instrueras att läsa sidorna i UTF-8-kodning (med förfrågningsrubriker och html-metatagg), kodar åtminstone Firefox 2/3 och andra webbläsare från denna period själva tecknet som %D0% B6 .
Slutresultatet är att alla användare med namnet "Petteri" hittas och även alla användare med namnet "ж" hittas.
Men hur är det med äåö?
HTTP-specifikationen definierar att webbadresser som standard kodas som latin1. Detta resulterar i att firefox2, firefox3 etc. kodar följande
https://localhost:8443/ID/Users?action=search&name=*Päivi*
in i den kodade versionen
https://localhost:8443/ID/Users?action=search&name=*P%E4ivi*
På latin1 tecknet ä är kodad som %E4 . Även om sidan/förfrågan/allt är definierad för att använda UTF-8 . Den UTF-8-kodade versionen av ä är %C3%A4
Resultatet av detta är att det är helt omöjligt för webbappen att korrekt hantera förfrågningsparametrarna från GET-förfrågningar, eftersom vissa tecken är kodade i latin1 och andra i UTF-8.Obs:POST-förfrågningar fungerar eftersom webbläsare kodar alla förfrågningsparametrar från formulär helt i UTF-8 om sidan är definierad som UTF-8
Saker att läsa
Ett mycket stort tack till skribenterna av följande för att de gav svaren på mitt 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/
Viktig anmärkning
mysql
stöder Basic Multilingual Plane
med 3-byte UTF-8-tecken. Om du behöver gå utanför det (vissa alfabet kräver mer än 3-byte UTF-8), måste du antingen använda en smak av VARBINARY
kolumntyp eller använd utf8mb4 teckenuppsättning
(vilket kräver MySQL 5.5.3 eller senare). Tänk bara på att använda utf8
teckenuppsättning i MySQL fungerar inte 100 % av tiden.
Tomcat med Apache
En sak till Om du använder Apache + Tomcat + mod_JK-kontakt måste du också göra följande ändringar:
- Lägg till URIEncoding="UTF-8" i filen tomcat server.xml för 8009-anslutningen, den används av mod_JK-anslutningen.
- Gå till din apache-mapp, dvs.
/etc/httpd/conf
och lägg tillAddDefaultCharset utf-8
ihttpd.conf-fil
. Obs! Kontrollera först att den finns eller inte. Om det finns kan du uppdatera det med den här raden. Du kan också lägga till den här raden längst ner.