前后端交互乱码问题处理

第一.服务器接收客户端请求乱码

1.先用request.getParameter(xxx)获取参数值,然后对此参数值用ISO-8859-1解码再用UTF-8编码,对GET请求和POST请求都有效

2.在用request.getParameter(xxx)方法获取参数值前,用request.setCharacterEncoding(encoding)方法设置字符集。但是这种方式只对POST请求(enctype="application/x-www-form-urlencoded")有效,对GET请求无效,GET请求数据还需要用ISO-8859-1解码再用UTF-8编码。

第二.客户端解析服务器响应乱码

使用request.setContentType("text/html;charset=UTF-8")即可解决。

在spring-web-xxx.RELEASE.jar包中有一个专门处理请求、响应字符编码的Filter,CharacterEncodingFilter。这个Filter内部封装了request.setCharacterEncoding(encoding)和response.setCharacterEncoding(encoding)方法,这个Filter可以处理POST请求的乱码问题,但是处理不了GET请求的乱码问题,也处理不了客户端解析服务器响应时的乱码问题。鉴于此,我们可以自己写一个Filter来处理编码问题,核心方法doFilter()如下:

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
			throws IOException, ServletException {
	request.setCharacterEncoding("UTF-8");
	response.setContentType("text/html;charset=UTF-8");
	chain.doFilter(request, response);
}
这样我们就能处理POST请求的乱码问题和客户端解析服务器响应时的乱码问题,但还是解决不了GET请求时的乱码问题。所以还是得在对应的控制器中对参数值先用ISO-8859-1解码再用UTF-8编码。
request、response的get/setCharacterEncoding()方法源码注释:

/**
     * Returns the name of the character encoding used in the body of this
     * request. This method returns <code>null</code> if the request
     * does not specify a character encoding
     * 
     * @return a <code>String</code> containing the name of the character
     * encoding, or <code>null</code> if the request does not specify a
     * character encoding
     */
    public String getCharacterEncoding();

request.getCharacterEncoding():如果没有调用request.setCharacterEncoding(xxx)方法的话就会返回null。

/**
     * Overrides the name of the character encoding used in the body of this
     * request. This method must be called prior to reading request parameters
     * or reading input using getReader(). Otherwise, it has no effect.
     * 
     * @param env <code>String</code> containing the name of
     * the character encoding.
     *
     * @throws UnsupportedEncodingException if this ServletRequest is still
     * in a state where a character encoding may be set,
     * but the specified encoding is invalid
     */
    public void setCharacterEncoding(String env) throws UnsupportedEncodingException;

request.setCharacterEncoding():需在request.getParameter(xxx)之前调用,否则无效,对get请求也无效。

/**
     * Returns the name of the character encoding (MIME charset)
     * used for the body sent in this response.
     * The character encoding may have been specified explicitly
     * using the {@link #setCharacterEncoding} or
     * {@link #setContentType} methods, or implicitly using the
     * {@link #setLocale} method. Explicit specifications take
     * precedence over implicit specifications. Calls made
     * to these methods after <code>getWriter</code> has been
     * called or after the response has been committed have no
     * effect on the character encoding. If no character encoding
     * has been specified, <code>ISO-8859-1</code> is returned.
     * <p>See RFC 2047 (http://www.ietf.org/rfc/rfc2047.txt)
     * for more information about character encoding and MIME.
     *
     * @return a <code>String</code> specifying the name of
     * the character encoding, for example, <code>UTF-8</code>
     */
    public String getCharacterEncoding();

response.getCharacterEncoding():如果之前没有调用response.setCharacterEncoding(xxx)或者response.setContentType(xxx)的话,会返回ISO-8859-1。

/**
     * Sets the character encoding (MIME charset) of the response
     * being sent to the client, for example, to UTF-8.
     * If the character encoding has already been set by
     * {@link #setContentType} or {@link #setLocale},
     * this method overrides it.
     * Calling {@link #setContentType} with the <code>String</code>
     * of <code>text/html</code> and calling
     * this method with the <code>String</code> of <code>UTF-8</code>
     * is equivalent with calling
     * <code>setContentType</code> with the <code>String</code> of
     * <code>text/html; charset=UTF-8</code>.
     * <p>This method can be called repeatedly to change the character
     * encoding.
     * This method has no effect if it is called after
     * <code>getWriter</code> has been
     * called or after the response has been committed.
     * <p>Containers must communicate the character encoding used for
     * the servlet response's writer to the client if the protocol
     * provides a way for doing so. In the case of HTTP, the character
     * encoding is communicated as part of the <code>Content-Type</code>
     * header for text media types. Note that the character encoding
     * cannot be communicated via HTTP headers if the servlet does not
     * specify a content type; however, it is still used to encode text
     * written via the servlet response's writer.
     *
     * @param charset a String specifying only the character set
     * defined by IANA Character Sets
     * (http://www.iana.org/assignments/character-sets)
     *
     * @see #setContentType
     * @see #setLocale
     *
     * @since Servlet 2.4
     */
    public void setCharacterEncoding(String charset);

response.setCharacterEncoding(xxx):

可以覆盖response.setContentType(xxx)设置的字符集;

response.setContentType("text/html")与response.setCharacterEncoding("UTF-8")一起使用的效果,等同于response.setContentType("text/html;charset=UTF-8");

若要客户端正确解析服务器响应不乱吗,必须明确指定ContentType的值;

需在response.getWriter()之前调用,否则无效。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值