springmvc处理get/post请求乱码的多种方式【过滤器重新包装HttpServletRequest,配置tomcat的server.xml文件,获取数据时重新编码】

本文介绍了三种处理SpringMVC中GET/POST请求乱码的方法:一是通过装饰者模式包装HttpServletRequest;二是复制SpringMVC源码并自定义过滤器;三是配置Tomcat的server.xml文件。重点探讨了URIEncoding和useBodyEncodingForURI的区别及其在处理GET请求中文乱码中的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

方式一

使用装饰着模式重新包装HttpServletRequest类。只修改Request的getParameter和getParameterValues方法

package com.omp.comm.getEncoding;


import org.springframework.http.client.support.HttpRequestWrapper;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;

public class GetRequestEncoding extends HttpServletRequestWrapper {

    HttpServletRequest request = null;

    public GetRequestEncoding(HttpServletRequest request) {
        super(request);
        this.request = request;
    }

    @Override
    public String getParameter(String name) {

        String method = request.getMethod();
        String value=null;
        try {
            request.setCharacterEncoding("utf-8");

            value = request.getParameter(name);

            if("get".equalsIgnoreCase(method)){
                value = new String(value.getBytes("iso-8859-1"),"utf-8");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        return value;
    }


    @Override
    public String[] getParameterValues(String name) {

        String method = request.getMethod();
        String[] values=null;
        try {
            request.setCharacterEncoding("utf-8");

            values = request.getParameterValues(name);

            if("get".equalsIgnoreCase(method)){
                int i=0;
                for (String str : values) {
                    values[i++] = new String(str.getBytes("iso-8859-1"),"utf-8");
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        return values;
    }

}

编写过滤器GetRequestFilterEncoding用于替换Reuqest

package com.omp.comm.getEncoding;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class GetRequestFilterEncoding implements Filter {
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {

        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;

        GetRequestEncoding myRrequest = new GetRequestEncoding(request);

        filterChain.doFilter(myRrequest, response);

    }

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void destroy() {

    }
}

配置web.xml文件

    <!--配置post请求方式携带中文时的编码格式-->
    <filter>
        <filter-name>characterEncodingFilter</filter-name>
 		<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>UTF-8</param-value>
        </init-param>
        <init-param>
            <param-name>forceEncoding</param-name>
            <param-value>true</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>characterEncodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    
 <!--配置get请求方式携带中文时的编码格式-->
    <filter>
        <filter-name>getEncoding</filter-name>
        <filter-class>com.omp.comm.getEncoding.GetRequestFilterEncoding</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>getEncoding</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

方式二

解决思路,springmvc有自带配置处理post乱码问题,查看源码可以看出也是使用Filter处理的,则可以复制一份源码,通过判断请求类型是get/post来区分编码处理方式。get还是使用装饰着模式来重新包装Request

post提交处理乱码的过滤器源码

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

package org.springframework.web.filter;

import java.io.IOException;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;

public class CharacterEncodingFilter extends OncePerRequestFilter {
    @Nullable
    private String encoding;
    private boolean forceRequestEncoding;
    private boolean forceResponseEncoding;

    public CharacterEncodingFilter() {
        this.forceRequestEncoding = false;
        this.forceResponseEncoding = false;
    }

    public CharacterEncodingFilter(String encoding) {
        this(encoding, false);
    }

    public CharacterEncodingFilter(String encoding, boolean forceEncoding) {
        this(encoding, forceEncoding, forceEncoding);
    }

    public CharacterEncodingFilter(String encoding, boolean forceRequestEncoding, boolean forceResponseEncoding) {
        this.forceRequestEncoding = false;
        this.forceResponseEncoding = false;
        Assert.hasLength(encoding, "Encoding must not be empty");
        this.encoding = encoding;
        this.forceRequestEncoding = forceRequestEncoding;
        this.forceResponseEncoding = forceResponseEncoding;
    }

    public void setEncoding(@Nullable String encoding) {
        this.encoding = encoding;
    }

    @Nullable
    public String getEncoding() {
        return this.encoding;
    }

    public void setForceEncoding(boolean forceEncoding) {
        this.forceRequestEncoding = forceEncoding;
        this.forceResponseEncoding = forceEncoding;
    }

    public void setForceRequestEncoding(boolean forceRequestEncoding) {
        this.forceRequestEncoding = forceRequestEncoding;
    }

    public boolean isForceRequestEncoding() {
        return this.forceRequestEncoding;
    }

    public void setForceResponseEncoding(boolean forceResponseEncoding) {
        this.forceResponseEncoding = forceResponseEncoding;
    }

    public boolean isForceResponseEncoding() {
        return this.forceResponseEncoding;
    }

    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        String encoding = this.getEncoding();
        if (encoding != null) {
            if (this.isForceRequestEncoding() || request.getCharacterEncoding() == null) {
                request.setCharacterEncoding(encoding);
            }

            if (this.isForceResponseEncoding()) {
                response.setCharacterEncoding(encoding);
            }
        }

        filterChain.doFilter(request, response);
    }
}

仿写一份MyRequestEncodingFilter

package com.omp.comm.getEncoding;

import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class MyRequestEncodingFilter extends OncePerRequestFilter {

    @Nullable
    private String encoding;
    private boolean forceRequestEncoding;
    private boolean forceResponseEncoding;

    public MyRequestEncodingFilter() {
        this.forceRequestEncoding = false;
        this.forceResponseEncoding = false;
    }

    public MyRequestEncodingFilter(String encoding) {
        this(encoding, false);
    }

    public MyRequestEncodingFilter(String encoding, boolean forceEncoding) {
        this(encoding, forceEncoding, forceEncoding);
    }

    public MyRequestEncodingFilter(String encoding, boolean forceRequestEncoding, boolean forceResponseEncoding) {
        this.forceRequestEncoding = false;
        this.forceResponseEncoding = false;
        Assert.hasLength(encoding, "Encoding must not be empty");
        this.encoding = encoding;
        this.forceRequestEncoding = forceRequestEncoding;
        this.forceResponseEncoding = forceResponseEncoding;
    }

    public void setEncoding(@Nullable String encoding) {
        this.encoding = encoding;
    }

    @Nullable
    public String getEncoding() {
        return this.encoding;
    }

    public void setForceEncoding(boolean forceEncoding) {
        this.forceRequestEncoding = forceEncoding;
        this.forceResponseEncoding = forceEncoding;
    }

    public void setForceRequestEncoding(boolean forceRequestEncoding) {
        this.forceRequestEncoding = forceRequestEncoding;
    }

    public boolean isForceRequestEncoding() {
        return this.forceRequestEncoding;
    }

    public void setForceResponseEncoding(boolean forceResponseEncoding) {
        this.forceResponseEncoding = forceResponseEncoding;
    }

    public boolean isForceResponseEncoding() {
        return this.forceResponseEncoding;
    }

    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        String encoding = this.getEncoding();
        String method = request.getMethod();

        if (encoding != null) {

            if (this.isForceResponseEncoding()) {
                response.setCharacterEncoding(encoding);
            }

            if("get".equalsIgnoreCase(method)){
                GetRequestEncoding myRrequest = new GetRequestEncoding(request);
                filterChain.doFilter(myRrequest, response);
            }else{
                if (this.isForceRequestEncoding() || request.getCharacterEncoding() == null) {
                    request.setCharacterEncoding(encoding);
                }
                filterChain.doFilter(request, response);
            }
        }
    }
}

web.xml配置

    <filter>
        <filter-name>characterEncodingFilter</filter-name>
        <filter-class>com.omp.comm.getEncoding.MyRequestEncodingFilter</filter-class>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>UTF-8</param-value>
        </init-param>
        <init-param>
            <param-name>forceEncoding</param-name>
            <param-value>true</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>characterEncodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

方式三:

处理post请求还是和方式一的一样,但是处理get请求有两个方式

一, 我们需要把request.getParameter(“参数名”)获取到的字符串先用ISO-8859-1编码成字节流,然后再将其用utf-8解码成字符流,代码如下:

String str = new String(request.getParameter("参数名").getBytes("iso-8859-1"), "utf-8");

二, 我们也可以通过Tomcat配置文件,设置URL编码集(URIEncoding)设置编码.

在tomcat的server.xml配置文件中,添加 URIEncoding=“UTF-8”

在这里要特别注意:当你用eclipse运行项目文件时,如果改了tomcat安装目录下的server.xml文件依旧不起作用,就要改eclipse自身配置的servers底下的server.xml文件.因为eclipse运行项目时用的是这个server.

如下图所示:
在这里插入图片描述
添加 URIEncoding=“UTF-8”

<Connector  connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443"/>

修改为:

<Connector URIEncoding="UTF-8" connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443"/>

备注:

下面来解释一下这两个属性的意义:
useBodyEncodingForURI参数表示是否用request.setCharacterEncoding参数对URL提交的数据和表单中GET方式提交的数据进行重新编码,在默认情况下,该参数为false。
URIEncoding参数指定对所有GET方式请求进行统一的重新编码(解码)的编码。

URIEncoding和useBodyEncodingForURI区别是:

URIEncoding是对所有GET方式的请求的数据进行统一的重新编码,
而useBodyEncodingForURI则是根据响应该请求的页面的request.setCharacterEncoding参数对数据进行的重新编码,不同的页面可以有不同的重新编码的编码
配置useBodyEncodingForURI="true"后,可以解决普通get请求的中文乱码问题,但是对于通过ajax发起的get请求中文依然会乱码,把useBodyEncodingForURI="true"改为URIEncoding="UTF-8"即可。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值