I often see people asking me in discussion forums what to do if the Chinese characters displayed in JSP are garbled, why the Chinese input by the user I get through request is garbled, why the Chinese characters I write to the database are garbled, and other questions about Chinese characters being garbled.
In fact, this problem is very simple. Regardless of whether it is Chinese characters, Japanese, or some other double-byte language, we will treat it as UTF-8.
(1) The double-byte text in the request is good. Now we will use UTF-8 encoding in the entire application. The reason why UTF-8 is chosen is not only for the above reasons. We know that Java is based on UTF-8. 8 or above, so we should be right to choose UTF-8^_^
We first save our .java and .jsp files in UTF-8 encoding. It doesn’t matter if the previous files were not saved in UTF-8, but it is recommended that all future files be saved in UTF-8.
And write in .jsp: < %@page contentType="text/html; charset=UTF-8"%> instead of < %@page contentType="text/html; charset=UTF-8"%>
Then add the following paragraph to web.xml:
<web-app>
...
<filter>
<filter-name>Set Character Encoding</filter-name>
<filter-class>com.redv.projects.eduadmin.util.filters.SetCharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>Set Character Encoding</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
...
</web-app>
The code of com.redv.projects.eduadmin.util.filters.SetCharacterEncodingFilter is as follows:
package com.redv.projects.eduadmin.util.filters;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.UnavailableException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class SetCharacterEncodingFilter
implements Filter {
protected String encoding = null;
protected FilterConfig filterConfig = null;
protected boolean ignore = true;
public void destroy() {
this.encoding = null;
this.filterConfig = null;
}
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
// Conditionally select and set the character encoding to be used
if (ignore || (request.getCharacterEncoding() == null)) {
String encoding = selectEncoding(request);
if (encoding != null) {
request.setCharacterEncoding(encoding); //This is what is working, haha, it: Overrides the name of the character encoding used in the body of this request. This method must be called prior to reading request parameters or reading input using getReader().
}
}
// Pass control on to the next filter
chain.doFilter(request, response);
}
public void init(FilterConfig filterConfig) throws ServletException {
this.filterConfig = filterConfig;
this.encoding = filterConfig.getInitParameter("encoding");
String value = filterConfig.getInitParameter("ignore");
if (value == null) {
this.ignore = true;
}
else if (value.equalsIgnoreCase("true")) {
this.ignore = true;
}
else if (value.equalsIgnoreCase("yes")) {
this.ignore = true;
}
else {
this.ignore = false;
}
}
protected String selectEncoding(ServletRequest request) {
return (this.encoding);
}
}
In this way, our request request is encoded in UTT-8, and we can use it in the JSP program: request.getParameter("myKey") You can directly get the UTF-8 encoded string, instead of like this: new String(request.getParameter("myKey").getBytes("ISO-8859-1"), "GBK") to solve those garbled characters. http://www.devdao.com/
(2) Double-byte text processed by database http://www.upas.org/java/DatabaseEncodingProblemSolution/
Another one is the problem of writing to the database. We know that when using mysql, we can use this URL to deal with the Chinese character encoding problem: jdbc:mysql://localhost:3306/upas?useUnicode=true&characterEncoding=gb2312,
So what should we do about those things that we can't solve like mysql? Should we write like this every time:
import java.sql.*;
Class.forName("org.gjt.mm.mysql.Driver");
Connection con = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
try {
con = DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "root", "");
pstmt = con.prepareStatement("SELECT f3, f4 FROM tbl1 WHERE f1 = ? AND f2 = ?");
pstmt.setString(1, new String(f1.getBytes("GBK"), "ISO-8859-1");
pstmt.setString(2, new String(f2.getBytes("GBK"), "ISO-8859-1");
rs = pstmt.executeQuery();
String f3, f4;
while(rs.next()) {
f3 = new String(rs.getString(1).getBytes("ISO-8859-1"), "GBK");
f4 = new String(rs.getString(2).getBytes("ISO-8859-1"), "GBK");
}
}
finally {
//close resources
...
}
In fact, we can write it like this:
import java.sql.*;
import com.redv.sql.encoding.*;
Class.forName("org.gjt.mm.mysql.Driver");
Connection con = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
try {
con = DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "root", "");
//Take over the database connection instance
boolean coding = true;
EncodingConnection codingConnection = new EncodingConnection(con, coding, "ISO-8859-1", "GBK");
//Get the database connection instance after taking over. Use con directly in the future, which is already an instance repackaged by EncodingConnection.
con = codingConnection.getConnection();
pstmt = con.prepareStatement("SELECT f3, f4 FROM tbl1 WHERE f1 = ? AND f2 = ?");
pstmt.setString(1, f1);
pstmt.setString(2, f2);
rs = pstmt.executeQuery();
String f3, f4;
while(rs.next()) {
f3 = rs.getString(1);
f4 = rs.getString(2);
}
}
finally {
//close resources
...
}
Let's see, how about it, we only need to modify it slightly where we get the database connection. We can even save it as a parameter in the properties and change the Boolean value of coding to set whether to use automatic encoding conversion. Often we can use a Database class to encapsulate the getConnection that obtains the database connection, so that we can obtain the database connection from javax.sql.DataSource. At this time, we only need to modify our Database class, instead of searching for all places where rs.setString() and rs.getString() are used to add our encoding conversion code. Even when we use the con.createStatment() statement, there is no problem even if our sql statement contains Chinese characters or other double-byte characters:
SELECT name, gender FROM student table WHERE class LIKE '%computer%'