Answers:
回答自己作为本网站的常见问题解答会鼓励您这样做。这对我有用:
通常,字符äåö没问题,因为浏览器和Web应用程序的tomcat / java使用的默认字符集为latin1即。“理解”这些字符的ISO-8859-1。
要使UTF-8在Java + Tomcat + Linux / Windows + Mysql下工作,需要满足以下条件:
必须配置连接器使用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 /所使用的编码。另一种方法是在应用程序的每个控制器中设置响应编码等。
该过滤器必须添加到web.xml或webapp的部署描述符中:
<!--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页面的编码方式了:
这是通过在webapp生成的每个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 serveri。通常,这是在Windows中通过修改my.ini -file和在Linux中通过配置my.cnf -file来完成的。在这些文件中,应该定义所有连接到服务器的客户端都使用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=ж
由于latin1和UTF-8均以相同的方式编码ASCII字符,因此正确处理了字符串“ Petteri”。
拉丁语1完全不了解西里尔字母ж。由于指示Tomcat将请求参数处理为UTF-8,因此它将该字符正确编码为%D0%B6。
如果并且当指示浏览器读取UTF-8编码的页面(带有请求标头和html meta-tag)时,至少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
结果是,由于某些字符在latin1中编码,而另一些字符在UTF-8中编码,因此webapp完全不可能正确地处理GET请求中的请求参数。 注意:如果页面被定义为UTF-8,则POST请求确实可以工作,因为浏览器完全以UTF-8格式编码来自表单的所有请求参数。
非常感谢以下作者为我的问题提供了答案:
MySQL的支持使用3字节UTF-8字符的基本多语言平面。如果您不希望这样做(某些字母需要超过3个字节的UTF-8字节),则需要使用一种VARBINARY
列类型的样式或使用utf8mb4
字符集(这需要MySQL 5.5.3或更高版本)。请注意,使用utf8
MySQL中的字符集无法100%地工作。
还有一件事情,如果您使用的是Apache + Tomcat + mod_JK连接器,则还需要进行以下更改:
<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" URIEncoding="UTF-8"/>
/etc/httpd/conf
添加AddDefaultCharset utf-8
在httpd.conf file
。注意:首先检查它是否存在。如果存在,您可以使用此行对其进行更新。您也可以在底部添加此行。pageEncoding
,因此您甚至可以将其保留。2)在您使用的MySQL数据库和表中utf8_swedish_si
,应该是utf8_unicode_ci
。您甚至可以不使用排序规则,仅此而已CHARACTER SET utf8
。
<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" URIEncoding="UTF-8"/>
2.转到您的apache文件夹,即/etc/httpd/conf
并添加AddDefaultCharset utf-8
“ httpd.conf”文件。注意:首先检查它是否存在。如果存在,您可以使用此行对其进行更新。您也可以在底部添加此行。
要添加到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 defaultCharset(默认安装中为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)
导出LC_ALL = en_US.UTF-8
导出LANG = en_US.UTF-8导出LANGUAGE = zh_CN.UTF-8
尚未提及的另一点涉及与Ajax一起使用的Java Servlet。我遇到这样的情况,网页正在从用户那里获取utf-8文本,并将该文本发送到JavaScript文件,该文件包含在发送给Servlet的URI中。Servlet查询数据库,捕获结果并将其作为XML返回给JavaScript文件,然后对其进行格式化,并将格式化后的响应插入原始Web页面。
在一个Web应用程序中,我遵循了Ajax早期书籍中有关包装JavaScript构造URI的说明。书中的示例使用了escape()方法,但我发现(困难的方式)是错误的。对于utf-8,您必须使用encodeURIComponent()。
这些天似乎很少有人推出他们自己的Ajax,但我想我也可以添加它。
关于CharsetFilter
@kosoant答案中提到的....
Filter
Tomcat中有一个内置组件web.xml
(位于conf/web.xml
)。过滤器已命名setCharacterEncodingFilter
并默认带有注释。您可以取消评论(也请记住也取消评论filter-mapping
)
另外jsp-config
,您也不需要进行设置web.xml
(我已经为Tomcat 7+进行了测试)
在Spring MVC 5 + Tomcat 9 + JSP上面临相同的问题。
在经过长期的研究,来到了一个优雅的解决方案(没有必要的过滤器,并没有必要改变在Tomcat 的server.xml(从8.0.0-RC3版本开始))
在WebMvcConfigurer实现中,为messageSource设置默认编码(用于从消息源文件中以UTF-8编码读取数据。
@Configuration
@EnableWebMvc
@ComponentScan("{package.with.components}")
public class WebApplicationContextConfig implements WebMvcConfigurer {
@Bean
public MessageSource messageSource() {
final ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
messageSource.setBasenames("messages");
messageSource.setDefaultEncoding("UTF-8");
return messageSource;
}
/* other beans and methods */
}
在DispatcherServletInitializer实现中,@Override onStartup方法并在其中设置请求和资源字符编码。
public class DispatcherServletInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
@Override
public void onStartup(final ServletContext servletContext) throws ServletException {
// https://wiki.apache.org/tomcat/FAQ/CharacterEncoding
servletContext.setRequestCharacterEncoding("UTF-8");
servletContext.setResponseCharacterEncoding("UTF-8");
super.onStartup(servletContext);
}
/* servlet mappings, root and web application configs, other methods */
}
保存所有消息源并以UTF-8编码查看文件。
在每个* .jsp文件中添加<%@页面contentType =“ text / html; charset = UTF-8”%> 或 <%@ page pageEncoding =“ UTF-8”%> 或将jsp-config描述符添加到web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
id="WebApp_ID" version="3.0">
<display-name>AppName</display-name>
<jsp-config>
<jsp-property-group>
<url-pattern>*.jsp</url-pattern>
<page-encoding>UTF-8</page-encoding>
</jsp-property-group>
</jsp-config>
</web-app>
如果已在连接池(mysql-ds.xml)中指定,则可以在Java代码中按如下所示打开连接:
DriverManager.registerDriver(new com.mysql.jdbc.Driver());
Connection conn = DriverManager.getConnection(
"jdbc:mysql://192.168.1.12:3308/mydb?characterEncoding=greek",
"Myuser", "mypass");