äöå
等和特殊情况下像ЦжФ
这样的西里尔字母都能够被支持。
我的设置如下:
- 开发环境:Windows XP
- 生产环境:Debian
äöå
等和特殊情况下像ЦжФ
这样的西里尔字母都能够被支持。
我的设置如下:
作为该网站FAQ的回答者,鼓励这样做。以下方法对我有效:
大多数字符(如äåö)通常不会有问题,因为浏览器和Tomcat/Java用于Web应用程序的默认字符集是Latin1即ISO-8859-1,可以“理解”这些字符。
要在Java+Tomcat+Linux/Windows+Mysql环境下使用UTF-8,需要进行以下配置:
必须配置连接器使用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请求不受此影响。
然后就需要强制java web应用程序将所有请求和响应都视为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 /其他内容的编码方式。另一种方法是在应用程序的每个控制器中设置响应编码等。
必须将此过滤器添加到webapp的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)中找到。
在您的web.xml中添加以下内容:
<jsp-config>
<jsp-property-group>
<url-pattern>*.jsp</url-pattern>
<page-encoding>UTF-8</page-encoding>
</jsp-property-group>
</jsp-config>
或者,Web应用程序的所有JSP页面都需要在顶部具有以下内容:
<%@page pageEncoding="UTF-8" contentType="text/html; charset=UTF-8"%>
如果使用了不同的JSP片段来进行布局,则需要在所有片段中使用此功能。
JSP页面编码告诉JVM以正确的编码处理JSP页面中的字符。然后,需要告诉浏览器html页面所使用的编码:
这可以通过在Web应用程序生成的每个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' />
...
在使用数据库时,必须定义连接使用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&characterEncoding=UTF-8"
/>
使用的数据库必须使用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服务器也需要进行配置。通常在Windows中,这是通过修改my.ini文件,在Linux中则是通过配置my.cnf文件来完成的。 在这些文件中,应该定义所有连接到服务器的客户端使用utf8作为默认字符集,并且服务器使用的默认字符集也是utf8。
[client]
port=3306
default-character-set=utf8
[mysql]
default-character-set=utf8
这些也需要定义字符集。例如:
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 ;
如果在Tomcat的server.xml中定义了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”被正确处理。
拉丁字母表中根本无法理解西里尔字母“ж”。由于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。
结果是,Web应用程序几乎无法正确处理GET请求中的请求参数,因为一些字符以latin1编码,而另一些字符以UTF-8编码。
注意:如果页面被定义为UTF-8,则POST请求可以正常工作,因为浏览器会完全以UTF-8编码表单中的所有请求参数
非常感谢以下作者为我的问题提供答案:
mysql支持使用3字节UTF-8字符来支持基本多语言平面。如果您需要使用超出此范围的字符(某些字母需要使用超过3字节的UTF-8),那么您需要使用VARBINARY
列类型或使用utf8mb4
字符集(需要MySQL 5.5.3或更高版本)。只需注意,在MySQL中使用utf8
字符集并不总是有效。
还有一件事,如果您正在使用Apache + Tomcat + mod_JK连接器,则还需要进行以下更改:
<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" URIEncoding="UTF-8"/>
/etc/httpd/conf
,并在httpd.conf文件
中添加AddDefaultCharset utf-8
。 注意:首先检查它是否存在。如果存在,您可以使用此行更新它。您也可以在底部添加此行。pageEncoding
已经隐含地完成了HTML元标记,所以你甚至可以将其省略。2)在MySQL数据库和表中,你使用了utf8_swedish_si
,应该使用utf8_unicode_ci
。你甚至可以省略排序规则(collation),只需使用CHARACTER SET utf8
即可。 - BalusC<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" URIEncoding="UTF-8"/>
/etc/httpd/conf
,并在' httpd.conf '文件中添加 AddDefaultCharset utf-8
。注意: 首先检查它是否存在。如果存在,则可以使用此行进行更新。您也可以将此行添加到底部。<Connector>
上的默认URIEncoding
现在是UTF-8
。 - Christopher Schultz我认为你在自己的回答中已经很好地总结了它。
在从端到端进行UTF-8转换的过程中,您可能还想确保java本身正在使用UTF-8。将-Dfile.encoding=utf-8用作JVM的参数(可以在catalina.bat中配置)。
除了kosoant的答案,如果你使用的是Spring,而不是编写自己的Servlet过滤器,你可以使用他们提供的org.springframework.web.filter.CharacterEncodingFilter
类,在web.xml中进行如下配置:
<filter>
<filter-name>encoding-filter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>FALSE</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encoding-filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
这是关于在使用Java访问MySql表时,需要进行希腊编码的设置:
请在您的JBoss连接池(mysql-ds.xml)中使用以下连接设置:
<connection-url>jdbc:mysql://192.168.10.123:3308/mydatabase</connection-url>
<driver-class>com.mysql.jdbc.Driver</driver-class>
<user-name>nts</user-name>
<password>xaxaxa!</password>
<connection-property name="useUnicode">true</connection-property>
<connection-property name="characterEncoding">greek</connection-property>
如果您不想将其放入JNDI连接池中,可以像下一行所示那样将其配置为JDBC-url:
jdbc:mysql://192.168.10.123:3308/mydatabase?characterEncoding=greek
对于我和尼克来说,这样我们就不会再忘记它并浪费时间了.....
之前的回答对我的问题没有帮助。问题只出现在生产环境中,使用tomcat和apache mod_proxy_ajp。发帖内容会因为什么原因丢失非ASCII字符。 最终问题出在JVM默认字符集(默认安装为US-ASCII:Charset dfset = Charset.defaultCharset();) 因此,解决方案是通过修改器运行tomcat服务器,以UTF-8作为默认字符集来运行JVM:
JAVA_OPTS="$JAVA_OPTS -Dfile.encoding=UTF-8"
(在catalina.sh中添加此行并重新启动tomcat服务)
也许您还需要更改Linux系统变量(编辑~/.bashrc和~/.profile以进行永久更改,请参见https://perlgeek.de/en/article/set-up-a-clean-utf8-environment)
export LC_ALL=en_US.UTF-8
export LANG=en_US.UTF-8export LANGUAGE=en_US.UTF-8
我遇到了类似的问题,但是这是在我使用Apache Commons压缩文件时出现在文件名中的。 所以,我用这个命令解决了它:
convmv --notest -f cp1252 -t utf8 * -r
对我来说它非常有效。希望能帮到任何人 ;)
关于@kosoant答案中提到的CharsetFilter
...
在Tomcat的web.xml
(位于conf/web.xml
)中有一个内置的Filter
。该过滤器的名称为setCharacterEncodingFilter
,默认情况下被注释掉了。您可以取消注释它(请记得同时取消注释其filter-mapping
)。
此外,在您的web.xml
中不需要设置jsp-config
(我已经为Tomcat 7+测试过了)。