Passing request parameters as UTF-8 encoded string

2019-01-13 08:15发布

This question already has an answer here:

I am creating a simple login page and I want to pass login and password parameters as UTF-8 encoded strings. As you can see in the code below, the first line is where I set encoding to UTF-8, but it seems this is pointless because it doesn't work. When I use login and password parameters with accents the result page receives strange characters.

How to set character encoding correctly in a way that works in all browsers?

<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>My Page</title>
    </head>

    <body>
        <h1>Welcome to My Page</h1>

        <form name="login" action="login.jsp" method="POST">
            Login:<br/>
            <input type="text" name="login" value="" /><br/>
            Password:<br/>
            <input type="password" name="password" value="" /><br/>
            <br/>
            <input type="submit" value="Login" /><br/>
        </form>

    </body>
</html>

5条回答
贼婆χ
2楼-- · 2019-01-13 08:48

Calling ServletRequest#setCharacterEncoding() will still fail in some cases.

If your container follows the servlet spec carefully (as does tomcat) it will be interpreting post parameters as ISO-8859-1 by default. This may garble UTF-8 characters (such as Japanese in the recent case I worked through) before they ever get to your code, especially if you have a servlet filter that inspects the request parameters with getParameter() or getParameters(). Those two methods force decoding of the parameters, and decoding is only ever done once.

Here's a link for how to get around this in Tomcat if you have filters that look at the request parameters. Folks will want to check the docs for their particular container.

http://wiki.apache.org/tomcat/FAQ/CharacterEncoding#Q1

The key bit from that is:

Add

useBodyEncodingForURI="true" URIEncoding="UTF-8"

to the Context element in Tomcat's server.xml and add

  <filter>
    <filter-name>Character Encoding Filter</filter-name>
    <filter-class>org.apache.catalina.filters.SetCharacterEncodingFilter</filter-class>
    <init-param>
      <param-name>encoding</param-name>
      <param-value>UTF-8</param-value>
    </init-param>
  </filter>
  <filter-mapping>
    <filter-name>Character Encoding Filter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>

as before any filter that calls getParameter() or getParameters() in web.xml. I found that although the link above makes the two attributes to the context element seem like alternatives, the useBodyEncodingForURI one is absolutely necessary or tomcat won't set the encoding for the querystring. From Request.java in tomcat 7.0.42:

boolean useBodyEncodingForURI = connector.getUseBodyEncodingForURI();
if (enc != null) {
    parameters.setEncoding(enc);
    if (useBodyEncodingForURI) {
        parameters.setQueryStringEncoding(enc);
    }
} else {
    parameters.setEncoding
        (org.apache.coyote.Constants.DEFAULT_CHARACTER_ENCODING);
    if (useBodyEncodingForURI) {
        parameters.setQueryStringEncoding
            (org.apache.coyote.Constants.DEFAULT_CHARACTER_ENCODING);
    }
}
查看更多
我命由我不由天
3楼-- · 2019-01-13 08:49

The pageEncoding only sets the response character encoding and the charset attribute of the HTTP Content-Type header. Basically, it tells the server to decode the characters produced by JSP as UTF-8 before sending it to the client and the header tells the client to encode them using UTF-8 and also to use it when any forms in the very same page is to be submitted back to the server. The contentType already defaults to text/html, so below is sufficient:

<%@page pageEncoding="UTF-8"%>

The HTML meta tag is ignored when the page is served over HTTP. It's only been used when the page is by the client saved as a HTML file on local disk system and then opened by a file:// URI in browser.

In your particular case, the HTTP request body encoding is apparently not been set to UTF-8. The request body encoding needs to be set by ServletRequest#setCharacterEncoding() in the servlet or a filter before the first call on request.getXxx() is ever made in any servlet or filter involved in the request.

request.setCharacterEncoding("UTF-8");
String login = request.getParameter("login");
String password = request.getParameter("password");
// ...

See also:

查看更多
家丑人穷心不美
4楼-- · 2019-01-13 08:52

Sample character Encoding :

<%@ page language="java" pageEncoding="utf8" contentType="text/html;charset=UTF-8" %>
查看更多
神经病院院长
5楼-- · 2019-01-13 08:57

I came across this problem recently and couldn't find the answer here. I'm using Weblogic and most of the solutions are for Tomcat.

For encoding to work with Weblogic you have to put this to your weblogic.xml

<charset-params> 
    <input-charset> 
        <resource-path>/*</resource-path> 
        <java-charset-name>UTF-8</java-charset-name> 
    </input-charset> 
</charset-params>

Source: weblogic.xml docs

NOTE: I also have these options in my _JAVA_OPTIONS, but don't know if they are necessary.

-Dweblogic.webservice.i18n.charset=utf-8 
-Dfile.encoding=UTF-8
查看更多
\"骚年 ilove
6楼-- · 2019-01-13 09:03

The problem is dependent on that, which application server is used. Even the pages are correcty setted e.g. to UTF8, the attempt to obtain parameter in correct form (according expected language) don't gives good results i.e. request.getParameter(...) returns not expected characters, because default code page for parameters is mostly 8859-1. It means, that the codepage for parameters is independent on codepage of JSP page and default codepage for parameters influences the result. The best description, which i found is here: [1]: http://docs.cksource.com/CKFinder_2.x/Developers_Guide/Java/Configuration/URI_Encoding. In some application servers the "request.setCharacterEncoding(...)" has no effect. You must set parameter encoding in descriptor. The most complicated are JBoss, Apache Tomcat, in middle is Glassfish. Better is WebLogic, the best is Jetty (UTF-8 is default setting). In my case i must create glassfish-web.xml descriptor and put there parameter-encoding tag. In my case (GlassFish):

<glassfish-web-app error-url="">
  <!-- request.setCharacterEncoding("UTF-8") not functioning -->
  <parameter-encoding default-charset="UTF-8" />
</glassfish-web-app>
查看更多
登录 后发表回答