64

My servlet code looks like that:

response.setContentType("text/html; charset=UTF-8");
response.setCharacterEncoding("UTF-8");
ServletOutputStream out = response.getOutputStream();
out.println(...MY-UTF-8 CODE...);

...

then I get the error:

java.io.CharConversionException: Not an ISO 8859-1 character: ש
 javax.servlet.ServletOutputStream.print(ServletOutputStream.java:89)
 javax.servlet.ServletOutputStream.println(ServletOutputStream.java:242)
 rtm.servlets.CampaignLogicServlet.doPost(CampaignLogicServlet.java:68)
 javax.servlet.http.HttpServlet.service(HttpServlet.java:637)
 javax.servlet.http.HttpServlet.service(HttpServlet.java:717)

How can I switch the charset of Servlet's outputstream ???

Brian Agnew
  • 268,207
  • 37
  • 334
  • 440
GyRo
  • 2,586
  • 5
  • 30
  • 38

6 Answers6

132

I think you want to use getWriter() instead. That will accept a string and encode it, whereas the output stream is for handling binary data.

From the doc:

Returns a PrintWriter object that can send character text to the client. The character encoding used is the one specified in the charset= property of the setContentType(java.lang.String) method, which must be called before calling this method for the charset to take effect.

Either this method or getOutputStream() may be called to write the body, not both.

Here's the change of the code:

response.setContentType("text/html; charset=UTF-8");
response.setCharacterEncoding("UTF-8");
PrintWriter out = response.getWriter();
out.println(...MY-UTF-8 CODE...);
sorifiend
  • 5,927
  • 1
  • 28
  • 45
Brian Agnew
  • 268,207
  • 37
  • 334
  • 440
13

This also works:

ServletOutputStream out = response.getOutputStream();
out.write("MY-UTF-8 CODE".getBytes("UTF-8")); 
quagmired
  • 131
  • 1
  • 2
  • 1
    working for me too, but why does it work with `write` but not with `print`/`println`? – moeTi Sep 19 '14 at 07:21
  • @moeTi This is weird for me as well. Any explanations? – Zouzias Sep 24 '14 at 13:09
  • @moeTi The `print` function will encode the data in the format that is specified in the characterEncoding of the `response` object. If you didn't set a characterEncoding header, the default is to use ISO-8859-1 https://github.com/eclipse/jetty.project/blob/jetty-9.4.x/jetty-server/src/main/java/org/eclipse/jetty/server/Response.java#L902 – harshpatel991 Mar 21 '18 at 20:21
4

The same case happen to me before and i tried to add-on one line on top of the PrintWriter and it is work.

response.setContentType("text/html; charset=GBK");
PrintWriter out = response.getWriter();

Kim
  • 980
  • 1
  • 15
  • 29
2

In the case where you have to Request Dispatcher from a doFilter to @WebServlet("/anywebpage") which should only contain the PrintWriter out = response.getWriter();

        String erpg = "anywebpage";
        response.setContentType("text/html; charset=UTF-8");
        RequestDispatcher rd = request.getRequestDispatcher(erpg);
        rd.include(request, response);

You should NOT require to declare the following line: response.setCharacterEncoding("UTF-8");

Instead, make sure to include the following before the PrintWriter out = response.getWriter(); instruction:

response.setContentType("text/html; charset=UTF-8");
Supercoder
  • 1,066
  • 1
  • 10
  • 16
0
public void output(String jsonStr, HttpServletResponse response) throws IOException {
    response.setContentType("text/html;charset=UTF-8;");
    response.setCharacterEncoding("UTF-8");
    ServletOutputStream out = response.getOutputStream();
    out.write(jsonStr.getBytes("UTF-8"));
    out.flush();
    out.close();
}
Allen
  • 130
  • 7
0
// HTML Output code list
StringBuffer select_code = new StringBuffer();
List<con_element> ccc = codeService.code_select(code);

for(int i=0;i<ccc.size();i++){
    select_code.append("<option value='" + ccc.get(i).getCce_num() + "'>" + ccc.get(i).getCce_hname() + "</option>" );
}

response.setContentType("text/html; charset=UTF-8");
response.setCharacterEncoding("UTF-8");
response.getWriter().print( select_code );
gudok
  • 4,029
  • 2
  • 20
  • 30
이대범
  • 11
  • 1