2010-09-17 31 views
12

Servlet của tôi sẽ không sử dụng UTF-8 cho các câu trả lời JSON.Tại sao Servlet của tôi không đáp ứng các yêu cầu JSON trong UTF-8?

MyServlet.java:

public class MyServlet extends HttpServlet { 

    protected void doPost(HttpServletRequest req, HttpServletResponse res) throws Exception { 

    PrintWriter writer = res.getWriter(); 

    res.setCharacterEncoding("UTF-8"); 
    res.setContentType("application/json; charset=UTF-8"); 

    writer.print(getSomeJson()); 
    } 
} 

Nhưng nhân vật đặc biệt không được hiển thị, và khi tôi kiểm tra các tiêu đề mà tôi nhận được trở lại trong Firebug, tôi thấy Content-Type: application/json;charset=ISO-8859-1.

Tôi đã thực hiện một grep -ri iso . trong thư mục Servlet của mình và không có gì cả, vì vậy không nơi nào tôi đặt rõ ràng loại thành ISO-8859-1. Tôi cũng nên chỉ rõ rằng tôi đang chạy trên Tomcat 7 trong Eclipse với mục tiêu J2EE như một môi trường phát triển, với Solaris 10 và bất cứ điều gì họ gọi là môi trường máy chủ web của họ (ai đó quản trị điều này) như môi trường sản xuất, và hành vi là như nhau.

Tôi cũng xác nhận rằng yêu cầu được gửi là UTF-8 và chỉ phản hồi là ISO-8859-1.

Cập nhật

Tôi đã sửa đổi mã để phản ánh rằng tôi đang gọi PrintWriter trước khi tôi đặt mã hóa ký tự. Tôi đã bỏ qua điều này từ ví dụ ban đầu của mình, và bây giờ tôi nhận ra rằng đây là nguồn gốc của vấn đề của tôi. Tôi đọc here mà bạn phải đặt mã hóa ký tự trước khi gọi HttpServletResponse.getWriter() hoặc getWriter sẽ đặt mã đó thành ISO-8859-1 cho bạn.

Đây là vấn đề của tôi. Vì vậy, ví dụ trên phải được điều chỉnh thành

public class MyServlet extends HttpServlet { 

    protected void doPost(HttpServletRequest req, HttpServletResponse res) throws Exception { 

    res.setCharacterEncoding("UTF-8"); 
    res.setContentType("application/json"); 

    PrintWriter writer = res.getWriter(); 
    writer.print(getSomeJson()); 
    } 
} 
+1

Cảm ơn bạn đã "Cập nhật", đó chính xác là những gì tôi đang tìm kiếm: Đặt mã hóa ký tự đầu tiên, Thứ hai là người viết. –

Trả lời

4

Sau khi mã hóa được đặt cho một phản hồi, nó không thể thay đổi.

Cách dễ nhất để buộc UTF-8 là tạo bộ lọc của riêng bạn, là bộ lọc đầu tiên xem trước phản hồi và đặt mã hóa.

Hãy xem how Spring 3.0 does this. Ngay cả khi bạn không thể sử dụng Spring trong dự án của mình, có thể bạn sẽ có được cảm hứng (đảm bảo chính sách công ty của bạn cho phép bạn lấy cảm hứng từ giấy phép nguồn mở).

+0

Bạn đúng về việc không thể thay đổi mã hóa. Tôi đã đặt nó hai lần, nhưng không rõ ràng. Tôi đã làm nó hoàn toàn với getWriter. Xem câu hỏi được cập nhật của tôi. Cảm ơn anwer của bạn và +1. –

1

Mã này có vẻ tốt. Hoặc bạn không chạy mã mà bạn cho rằng mình đang chạy hoặc có một số Filter hoặc proxy ở đâu đó trong chuỗi yêu cầu-phản hồi để sửa đổi loại nội dung như vậy.

+0

Tôi không biết điều này có thể xảy ra ở đâu trừ khi đó là hành vi mặc định của môi trường của tôi. Có một tệp nguồn và tôi đã viết nó từ đầu. Nhưng đây cũng là Servlet đầu tiên của tôi, vì vậy tôi không biết 'Filter' là gì. –

+0

Không có gì khác trong '/ WEB-INF/web.xml' của webapp? Phiên bản Tomcat chính xác là gì? Bạn đã sửa đổi bất cứ điều gì trong tập tin '/ conf/web.xml' sau khi tải xuống/cài đặt nó chưa? – BalusC

+0

Không có gì khác ở đó. Xem câu hỏi được cập nhật của tôi. –

0

Ngoài vấn đề cụ thể, bạn thực sự nên xem xét việc nhận luồng đầu ra, sử dụng thư viện JSON để viết nội dung trực tiếp dưới dạng JSON được mã hóa UTF-8; không có lợi ích gì khi sử dụng các nhà văn. Một số gói JSON chỉ hoạt động với chuỗi, điều này không may, nhưng hầu hết cho phép sử dụng các luồng hiệu quả hơn (an toàn hơn và hiệu quả hơn khi trình phân tích cú pháp/máy phát có thể xử lý các khía cạnh thoát và mã hóa cùng nhau).

+0

Cảm ơn bạn đã đề xuất. Tôi sẽ xem xét điều này. Đây là servlet đầu tiên của tôi, vì vậy tôi không quá quen thuộc với các thư viện có sẵn. Tôi nhất định sử dụng mọi thứ có sẵn trên môi trường Solaris 10 mặc định của chúng tôi. –

Các vấn đề liên quan