JSF/Facelets sử dụng theo mặc định UTF-8 để giải mã các tham số yêu cầu HTTP. GlassFish tự sử dụng theo mặc định ISO-8859-1 làm các tham số yêu cầu giải mã HTTP. Các tham số yêu cầu HTTP có thể được phân tích cú pháp và giải mã chỉ một lần và điều này xảy ra bất cứ khi nào một tham số yêu cầu được mã yêu cầu lần đầu tiên như vậy request.getParameter("name")
. Vì vậy, nếu tham số yêu cầu được yêu cầu lần đầu tiên trước JSF đã đặt mã hóa thông số yêu cầu thành UTF-8, thì thông số này sẽ được phân tích cú pháp (không chính xác) bằng ISO-8859-1.
Khi JSF cần phải thiết lập mã hóa tham số yêu cầu trong quá trình khôi phục quan điểm giai đoạn như sau,
request.setCharacterEncoding("UTF-8");
trong khi các thông số yêu cầu đã được phân tích, sau đó GlassFish sẽ hiển thị chính xác cảnh báo này.
Hậu quả không mong muốn là tất cả các tham số yêu cầu HTTP đó có thể kết thúc trong Mojibake. Dữ liệu biểu mẫu ban đầu được gửi và mã hóa bằng UTF-8. Nếu bạn giải mã dữ liệu UTF-8 bằng bộ ký tự khác như ISO-8859-1, thì các ký tự trong phạm vi 8 bit trở lên (thường là các "ký tự đặc biệt" như é
, à
, ö
, v.v ... sẽ bị hỏng và kết thúc trong é
, Ã
, ö
vv
về mặt kỹ thuật, giải pháp đúng là không yêu cầu một tham số yêu cầu HTTP trước JSF đã thiết lập mã hóa ngay. Bạn về cơ bản cần phải kiểm tra tất cả các mã mà chạy trước giai đoạn xem khôi phục của JSF, chẳng hạn như bộ lọc servlet, trình lắng nghe pha, v.v. nếu chúng không thực hiện điều đó.
Nếu bạn không thể tìm thấy nó, hoặc mã nằm ngoài tầm kiểm soát của bạn, bạn có thể yêu cầu GlassFish sử dụng UTF-8 để giải mã các tham số yêu cầu HTTP, vì vậy nó không cần phải thay đổi khi JSF muốn để có được chúng. Bạn có thể làm điều đó bằng cách thêm các mục sau đây để các <glassfish-web-app>
của /WEB-INF/glassfish-web.xml
tập tin của bạn:
<parameter-encoding default-charset="UTF-8"/>
(lưu ý: các tập tin và mục gốc được trước đây gọi là sun-web.xml
và <sun-web-app>
tương ứng)
Ghi nhận nên được rằng điều này là cụ thể cho GlassFish và tất cả điều này sẽ không hoạt động khi bạn triển khai webapp đến một máy chủ khác.Cách tiếp cận máy chủ độc lập kinh điển là để tạo ra một servlet filter mà làm về cơ bản công việc sau đây trong doFilter()
phương pháp:
request.setCharacterEncoding("UTF-8");
chain.doFilter(request, response);
và chắc chắn rằng nó được ánh xạ trước khi bất kỳ bộ lọc khác mà cần phải thu thập bất kỳ thông số yêu cầu HTTP.
Cập nhật: là tại sao GlassFish đã thiết lập nó trước, nó có thể gây ra bởi PrimeFaces. Xem thêm câu hỏi liên quan: Unicode input retrieved via PrimeFaces input components become corrupted.
Từ kinh nghiệm của tôi nhắn nổi tiếng này bị mất sau khi nâng cấp phiên bản cá móm . Cái nào bạn đang dùng? – Osw
@Osw: thực ra đã có một lỗi liên quan trong một trong những phiên bản Mojarra 2.0.x sớm nhất, nhưng điều đó đã được gây ra bởi một vấn đề khác nhỏ và chỉ bị ảnh hưởng bởi các yêu cầu Ajax. Tuy nhiên, OP sử dụng GF 3.1 có gói JSF 2.1. – BalusC
@osw: cụ thể là tôi đang sử dụng GF 3.1.1 Build 12. Tôi có lẽ không nên nhưng tôi cho phép cả Netbeans và GF tải xuống tất cả các bản cập nhật ngay sau khi chúng có sẵn. Tôi nhớ lại vấn đề này ở gần như mọi cấp độ phiên bản, tuy nhiên. Nó chỉ đến mức mà tôi đã thử nghiệm rất nhiều trang, tạo ra đủ các thông báo lỗi trong quá trình, rằng tôi đã được kích thích để thực hiện hành động trên đó. BTW phiên bản Mojarra trong gói này là 2.1.3 (FCS b02). – AlanObject