Trả lời bản thân mình như Câu hỏi thường gặp của trang web này khuyến khích nó. Điều này làm việc cho tôi:
Hầu hết các ký tự không phải là một vấn đề vì bộ ký tự mặc định được sử dụng bởi các trình duyệt và tomcat / java cho webapps là latin1 tức là. ISO-8859-1 "hiểu" các ký tự đó.
Để UTF-8 hoạt động theo Java + Tomcat + Linux / Windows + Mysql cần có:
Định cấu hình máy chủ của Tomcat
Cần phải định cấu hình trình kết nối sử dụng UTF-8 để mã hóa các tham số url (yêu cầu 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"
/>
Phần quan trọng là URIEncoding = "UTF-8" trong ví dụ trên. Việc kiểm dịch này mà Tomcat xử lý tất cả các tham số GET đến dưới dạng UTF-8 được mã hóa. Kết quả là, khi người dùng viết như sau vào thanh địa chỉ của trình duyệt:
https://localhost:8443/ID/Users?action=search&name=*ж*
ký tự được xử lý dưới dạng UTF-8 và được mã hóa (thường là bởi trình duyệt trước khi đến máy chủ) dưới dạng % D0% B6 .
Yêu cầu POST không bị ảnh hưởng bởi điều này.
Bộ ký tự
Sau đó, đã đến lúc buộc ứng dụng web java xử lý tất cả các yêu cầu và phản hồi dưới dạng UTF-8 được mã hóa. Điều này yêu cầu chúng tôi xác định bộ lọc bộ ký tự như sau:
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() {
}
}
Bộ lọc này đảm bảo rằng nếu trình duyệt chưa đặt mã hóa được sử dụng trong yêu cầu, thì nó sẽ được đặt thành UTF-8.
Một điều khác được thực hiện bởi bộ lọc này là đặt mã hóa phản hồi mặc định tức là. mã hóa trong đó html / trả về bất cứ thứ gì. Cách khác là đặt mã hóa đáp ứng, vv trong mỗi bộ điều khiển của ứng dụng.
Bộ lọc này phải được thêm vào tệp web.xml hoặc bộ mô tả triển khai của ứng dụng web:
<!--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>
Các hướng dẫn để tạo bộ lọc này được tìm thấy tại wiki tomcat ( http://wiki.apache.org/tomcat/Tomcat/UTF-8 )
Mã hóa trang JSP
Trong tệp web của bạn , hãy thêm vào như sau:
<jsp-config>
<jsp-property-group>
<url-pattern>*.jsp</url-pattern>
<page-encoding>UTF-8</page-encoding>
</jsp-property-group>
</jsp-config>
Ngoài ra, tất cả các trang JSP của ứng dụng web sẽ cần phải có các mục sau ở đầu chúng:
<%@page pageEncoding="UTF-8" contentType="text/html; charset=UTF-8"%>
Nếu một kiểu bố trí nào đó với các đoạn JSP khác nhau được sử dụng, thì điều này là cần thiết trong tất cả chúng.
Thẻ HTML-meta
Mã hóa trang JSP báo cho JVM xử lý các ký tự trong trang JSP theo mã hóa chính xác. Sau đó, đã đến lúc nói với trình duyệt trong đó mã hóa trang html là:
Điều này được thực hiện với phần sau ở đầu mỗi trang xhtml do webapp tạo ra:
<?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' />
...
Kết nối JDBC
Khi sử dụng db, phải xác định rằng kết nối sử dụng mã hóa UTF-8. Này được thực hiện trong context.xml hoặc bất cứ nơi nào kết nối JDBC là defiend như sau:
<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"
/>
Cơ sở dữ liệu và bảng MySQL
Cơ sở dữ liệu được sử dụng phải sử dụng mã hóa UTF-8. Điều này đạt được bằng cách tạo cơ sở dữ liệu với các mục sau:
CREATE DATABASE `ID_development`
/*!40100 DEFAULT CHARACTER SET utf8 COLLATE utf8_swedish_ci */;
Sau đó, tất cả các bảng cũng cần có trong 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;
Phần quan trọng là CHARSET = utf8 .
Cấu hình máy chủ MySQL
MySQL serveri cũng phải được cấu hình. Thông thường, điều này được thực hiện trong Windows bằng cách sửa đổi my.ini -file và trong Linux bằng cách định cấu hình my.cnf -file. Trong các tệp đó, cần xác định rằng tất cả các máy khách được kết nối với máy chủ sử dụng utf8 làm bộ ký tự mặc định và bộ ký tự mặc định được sử dụng bởi máy chủ cũng là utf8.
[client]
port=3306
default-character-set=utf8
[mysql]
default-character-set=utf8
Các thủ tục và chức năng của Mysql
Những điều này cũng cần phải có bộ ký tự được xác định. Ví dụ:
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 ;
NHẬN yêu cầu: latin1 và UTF-8
Nếu và khi được xác định trong tệp tin serverDB của tomcat, các tham số yêu cầu GET được mã hóa trong UTF-8, các yêu cầu GET sau đây được xử lý đúng cách:
https://localhost:8443/ID/Users?action=search&name=Petteri
https://localhost:8443/ID/Users?action=search&name=ж
Vì các ký tự ASCII được mã hóa theo cùng một cách cả với latin1 và UTF-8, chuỗi "Petteri" được xử lý chính xác.
Nhân vật Cyrillic ж hoàn toàn không được hiểu theo tiếng Latin1. Vì Tomcat được hướng dẫn xử lý các tham số yêu cầu dưới dạng UTF-8, nó mã hóa ký tự đó chính xác là % D0% B6 .
Nếu và khi các trình duyệt được hướng dẫn đọc các trang ở dạng mã hóa UTF-8 (với tiêu đề yêu cầu và thẻ meta html), thì ít nhất Firefox 2/3 và các trình duyệt khác trong giai đoạn này đều tự mã hóa ký tự là % D0% B6 .
Kết quả cuối cùng là tất cả người dùng có tên "Petteri" đều được tìm thấy và tất cả người dùng có tên "ж" đều được tìm thấy.
Nhưng còn äåö thì sao?
Đặc tả HTTP xác định rằng các URL mặc định được mã hóa thành latin1. Điều này dẫn đến firefox2, firefox3, vv mã hóa như sau
https://localhost:8443/ID/Users?action=search&name=*Päivi*
trong phiên bản được mã hóa
https://localhost:8443/ID/Users?action=search&name=*P%E4ivi*
Trong latin1, ký tự ä được mã hóa thành % E4 . Mặc dù trang / yêu cầu / mọi thứ được xác định để sử dụng UTF-8 . Phiên bản được mã hóa UTF-8 của ä là % C3% A4
Kết quả của việc này là ứng dụng web không thể xử lý chính xác các tham số yêu cầu từ các yêu cầu GET vì một số ký tự được mã hóa bằng latin1 và các ký tự khác trong UTF-8.
Lưu ý: Các yêu cầu POST hoạt động khi trình duyệt mã hóa tất cả các tham số yêu cầu từ các biểu mẫu hoàn toàn trong UTF-8 nếu trang được xác định là UTF-8
Thứ để đọc
Một lời cảm ơn rất lớn cho các nhà văn sau đây đã đưa ra câu trả lời cho vấn đề của tôi:
- 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-parameter-mishandle-utf-8-encoding-td18720039.html
- http://www.utoronto.ca/webdocs/HTMLdocs/NewHTML/iso_table.html
- http://www.utf8-chartable.de/
Lưu ý quan trọng
myshỗ trợ Mặt phẳng đa ngôn ngữ cơ bản sử dụng các ký tự UTF-8 3 byte. Nếu bạn cần đi ra ngoài điều đó (một số bảng chữ cái nhất định cần nhiều hơn 3 byte UTF-8), thì bạn cần phải sử dụng hương vị của VARBINARY
loại cột hoặc sử dụng bộ utf8mb4
ký tự (yêu cầu MySQL 5.5.3 trở lên). Chỉ cần lưu ý rằng việc sử dụng bộ utf8
ký tự trong MySQL sẽ không hoạt động 100%.
Tomcat với Apache
Một điều nữa Nếu bạn đang sử dụng trình kết nối Apache + Tomcat + mod_JK thì bạn cũng cần thực hiện các thay đổi sau:
- Thêm URIEncoding = "UTF-8" vào tệp tomcat server.xml cho trình kết nối 8009, nó được sử dụng bởi trình kết nối mod_JK.
<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" URIEncoding="UTF-8"/>
- Goto thư mục apache của bạn tức là
/etc/httpd/conf
và thêm AddDefaultCharset utf-8
vào httpd.conf file
. Lưu ý: Trước tiên hãy kiểm tra xem nó có tồn tại hay không. Nếu tồn tại bạn có thể cập nhật nó với dòng này. Bạn có thể thêm dòng này ở dưới cùng.