Saya sering melihat orang-orang bertanya kepada saya di forum diskusi apa yang harus saya lakukan jika karakter Cina yang ditampilkan di JSP kacau, mengapa masukan bahasa Cina oleh pengguna yang saya terima melalui permintaan kacau, mengapa karakter Cina yang saya tulis ke database kacau, dan lainnya pertanyaan tentang karakter Cina yang kacau.
Sebenarnya, masalah ini sangat sederhana. Terlepas dari apakah itu karakter Cina, Jepang, atau bahasa double-byte lainnya, kami akan memperlakukannya sebagai UTF-8.
(1) Teks byte ganda dalam permintaan itu bagus. Sekarang kita akan menggunakan pengkodean UTF-8 di seluruh aplikasi. Alasan mengapa UTF-8 dipilih bukan hanya karena alasan di atas UTF-8.8 atau lebih tinggi, jadi kita sebaiknya memilih UTF-8^_^
Kami pertama-tama menyimpan file .java dan .jsp dalam pengkodean UTF-8. Tidak masalah jika file sebelumnya tidak disimpan dalam UTF-8, tetapi disarankan agar semua file berikutnya disimpan dalam UTF-8.
Dan tulis dalam .jsp: < %@page contentType="text/html; charset=UTF-8"%> alih-alih < %@page contentType="text/html; charset=UTF-8"%>
Kemudian tambahkan paragraf berikut ke web.xml:
<aplikasi web>
...
<filter>
<filter-name>Setel Pengkodean Karakter</filter-name>
<filter-class>com.redv.projects.eduadmin.util.filters.SetCharacterEncodingFilter</filter-class>
<init-param>
<nama-param>pengkodean</nama-param>
<nilai-param>UTF-8</nilai-param>
</init-param>
</filter>
<pemetaan filter>
<filter-name>Setel Pengkodean Karakter</filter-name>
<url-pattern>/*</url-pattern>
</pemetaan filter>
...
</web-app>
Kode com.redv.projects.eduadmin.util.filters.SetCharacterEncodingFilter adalah sebagai berikut:
paket com.redv.projects.eduadmin.util.filters
;
impor javax.servlet.Filter;
impor javax.servlet.FilterChain;
impor javax.servlet.FilterConfig;
impor javax.servlet.ServletException;
impor javax.servlet.ServletRequest;
impor javax.servlet.ServletResponse;
impor javax.servlet.UnavailableException;
impor javax.servlet.http.HttpServletRequest;
impor javax.servlet.http.HttpServletResponse;
SetCharacterEncodingFilter kelas publik
mengimplementasikan Filter {
pengkodean String yang dilindungi = null;
FilterConfig yang dilindungi filterConfig = null;
boolean yang dilindungi abaikan =
true
;
this.filterConfig = null;
}
public void doFilter(Permintaan ServletRequest, respons ServletResponse,
FilterChain chain) menampilkan IOException, ServletException {
// Pilih dan atur pengkodean karakter yang akan digunakan secara kondisional
if (abaikan || (request.getCharacterEncoding() == null)) {
Pengkodean string = selectEncoding(permintaan);
jika (pengkodean != null) {
request.setCharacterEncoding(encoding); //Ini yang berfungsi, haha, itu: Mengganti nama pengkodean karakter yang digunakan dalam isi permintaan ini harus dipanggil sebelum membaca parameter permintaan atau membaca input menggunakan getReader( ).
}
}
// Meneruskan kontrol ke filter berikutnya
chain.doFilter(permintaan, respons);
}
public void init(FilterConfig filterConfig) melempar ServletException {
this.filterConfig = filterConfig;
this.encoding = filterConfig.getInitParameter("encoding");
Nilai string = filterConfig.getInitParameter("abaikan");
jika (nilai == nol) {
this.abaikan = benar;
}
else if (nilai.equalsIgnoreCase("benar")) {
this.abaikan = benar;
}
else if (nilai.equalsIgnoreCase("ya")) {
this.abaikan = benar;
}
kalau tidak {
this.abaikan = salah;
}
}
protected String selectEncoding(ServletRequest request) {
return
(this.encoding
)
;
) Anda bisa langsung mendapatkan string yang dikodekan UTF-8, alih-alih seperti ini: new String(request.getParameter("myKey").getBytes("ISO-8859-1"), "GBK") untuk menyelesaikan karakter yang kacau tersebut. http://www.devdao.com/
(2) Teks byte ganda yang diproses oleh database http://www.upas.org/java/DatabaseEncodingProblemSolution/
Masalah lainnya adalah masalah penulisan ke database. Kita tahu bahwa saat menggunakan mysql, kita dapat menggunakan URL ini untuk menangani masalah pengkodean karakter Cina: jdbc:mysql://localhost:3306/upas?useUnicode=true&characterEncoding=gb2312,
Jadi apa yang harus kita lakukan terhadap hal-hal yang tidak dapat kita selesaikan seperti mysql? Haruskah kita menulis seperti ini setiap saat:
impor java.sql.*;
Kelas.forName("org.gjt.mm.mysql.Driver");
Koneksi con = null;
Pernyataan Disiapkan pstmt = null;
HasilSet rs = null;
mencoba {
con = DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "root", "");
pstmt = con.prepareStatement("PILIH f3, f4 DARI tbl1 DI MANA f1 = ? DAN f2 = ?");
pstmt.setString(1, String baru(f1.getBytes("GBK"), "ISO-8859-1");
pstmt.setString(2, String baru(f2.getBytes("GBK"), "ISO-8859-1");
rs = pstmt.executeQuery();
Tali f3, f4;
while(rs.next()) {
f3 = String baru(rs.getString(1).getBytes("ISO-8859-1"), "GBK");
f4 = String baru(rs.getString(2).getBytes("ISO-8859-1"), "GBK");
}
}
Akhirnya {
//menutup sumber daya
...
}
Sebenarnya kita bisa menulisnya seperti ini:
impor java.sql.*;
import com.redv.sql.encoding.*;
Class.forName("org.gjt.mm.mysql.Driver");
Koneksi con = null;
Pernyataan Disiapkan pstmt = null;
HasilSet rs = null;
mencoba {
con = DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "root", "");
//Ambil alih instance koneksi database
pengkodean boolean = benar;
EncodingConnection codingConnection = new EncodingConnection(con, coding, "ISO-8859-1", "GBK");
//Dapatkan instance koneksi database setelah mengambil alih. Gunakan con secara langsung di masa mendatang, yang sudah merupakan instance yang dikemas ulang oleh EncodingConnection.
con = codingConnection.getConnection();
pstmt = con.prepareStatement("PILIH f3, f4 DARI tbl1 DI MANA f1 = ? DAN f2 = ?");
pstmt.setString(1, f1);
pstmt.setString(2, f2);
rs = pstmt.executeQuery();
Tali f3, f4;
while(rs.next()) {
f3 = rs.getString(1);
f4 = rs.getString(2);
}
}
Akhirnya {
//menutup sumber daya
...
}
Mari kita lihat, bagaimana, kita hanya perlu memodifikasinya sedikit di mana kita mendapatkan koneksi database. Kita bahkan dapat menyimpannya sebagai parameter di properti dan mengubah nilai pengkodean Boolean untuk mengatur apakah akan menggunakan konversi pengkodean otomatis. Seringkali kita bisa menggunakan kelas Database untuk merangkum getConnection yang memperoleh koneksi database, sehingga kita bisa mendapatkan koneksi database dari javax.sql.DataSource. Saat ini, kita hanya perlu memodifikasi kelas Database, daripada mencari semua tempat di mana rs.setString() dan rs.getString() digunakan untuk menambahkan kode konversi pengkodean. Bahkan ketika kita menggunakan pernyataan con.createStatment(), tidak ada masalah meskipun pernyataan sql kita berisi karakter Cina atau karakter byte ganda lainnya:
PILIH nama, jenis kelamin DARI tabel siswa DIMANA kelas SEPERTI '%komputer%'