SpringMVC08-乱码问题

本文介绍了一种解决Web应用程序中出现的乱码问题的方法,包括使用Spring MVC提供的过滤器、自定义过滤器以及通过修改Tomcat配置等方式来确保表单提交的数据能够正确地被解析。

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

首先我们尝试构造一个乱码

第1步 我们可以在首页编写一个提交的表单,在web目录下创建form.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<form action="${pageContext.request.contextPath}/e/t1" method="post">
    <input type="text" name="username">
    <input type="submit">
</form>
</body>
</html>

第2步 后台编写对应的处理类

@Controller
public class EncodingController {
    @RequestMapping(value ="/e/t1",method = RequestMethod.POST)
    public String test(Model model, @RequestParam("username")String name){
        System.out.println("===============/e/t1=========");
        model.addAttribute("msg", name); //获取表单的输入
        return "test"; //跳转到test页面显示输入的值
    }
}

第3步 到网址http://localhost:8080/test11_war_exploded/form.jsp,先到输入中文测试,发现乱码百福

不得不说,乱码问题是在我们开发中十分常见的问题,也是让我们程序猿比较头大的问题!

解决方法:

​ 注意过滤器的参数 url-pattern 为 /*,过滤所有请求(包括 jsp );如果设置为 /,访问 jsp 就不会经过过滤器了!

1.pringMVC过滤器

以前乱码问题,我们通过过滤器解决,在SpringMVC给我们提供了一个过滤器,可以在web.xml中配置

修改xml文件需要重启服务器

    <filter>
        <filter-name>encoding</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>
    </filter>
    <!--  注意 url-pattern 为 /*,过滤所有请求(包括 jsp );如果设置为 /,访问 jsp 就不会经过过滤器了!  -->
    <filter-mapping>
        <filter-name>encoding</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

有些极端情况下,这个过滤器对get的支持不好

修改Tomcat乱码处理方法:

1、修改Tomcat配置,设置编码!

    <Connector URIEncoding="utf-8" port="8080" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="8443"/>
2、自定义过滤器

先编写自定义的过滤器

public class EncodingFilter implements Filter {
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("========执行字符过滤器");
        servletRequest.setCharacterEncoding("utf-8");
        servletResponse.setCharacterEncoding("utf-8");
        servletResponse.setContentType("text/html; charset=utf-8");
        filterChain.doFilter(servletRequest,servletResponse);
    }

    public void destroy() {

    }
}

在编辑我们的web.xml注册

    <!--注册filter-->
    <filter>
        <filter-name>encodingFilter</filter-name>
        <filter-class>com.kuang.filter.EncodingFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>encodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
3、绝招-大神的自定义办法
package com.kuang.filter;


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

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.util.Map;

/*
* 解决get和post的请求,全部乱码的过滤器
* */
public class GenericEncodingFilter implements Filter {
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException {
        //处理response的字符串
        System.out.println("===================doFilter============");
        HttpServletResponse myResp = (HttpServletResponse) resp;
        myResp.setContentType("text/html; charset=UTF-8");

        //转换为与协议相关对象
        HttpServletRequest myReq = (HttpServletRequest) req;
        //对request包装增强
        MyRequest myRequest = new MyRequest(myReq);

        chain.doFilter(myRequest,resp);
    }

    public void destroy() {

    }
}
//自定义request对象,HttpServletRequest的包装类


class MyRequest extends HttpServletRequestWrapper{
    private HttpServletRequest request;
    private boolean flag=true;


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

    @Override
    public String getParameter(String name) {
        if(name==null || name.trim().length()==0){
            return null;
        }
        String[] values = getParameterValues(name);
        if(values==null || values.length==0){
            return null;
        }

        return values[0];
    }

    @Override
    /**
     * hobby=[eat,drink]
     */
    public String[] getParameterValues(String name) {
        if(name==null || name.trim().length()==0){
            return null;
        }
        Map<String, String[]> map = getParameterMap();
        if(map==null || map.size()==0){
            return null;
        }

        return map.get(name);
    }

    @Override
    /**
     * map{ username=[tom],password=[123],hobby=[eat,drink]}
     */
    public Map<String,String[]> getParameterMap() {

        /**
         * 首先判断请求方式
         * 若为post  request.setchar...(utf-8)
         * 若为get 将map中的值遍历编码就可以了
         */
        String method = request.getMethod();
        if("post".equalsIgnoreCase(method)){
            try {
                request.setCharacterEncoding("utf-8");
                return request.getParameterMap();
            } catch (UnsupportedEncodingException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }else if("get".equalsIgnoreCase(method)){
            Map<String,String[]> map = request.getParameterMap();
            //需要遍历map 修改value的每一个数据的编码
            if(flag){
                for (String key:map.keySet()) {
                    String[] arr = map.get(key);
                    //继续遍历数组
                    for(int i=0;i<arr.length;i++){
                        //编码
                        try {
                            arr[i]=new String(arr[i].getBytes("iso8859-1"),"utf-8");
                        } catch (UnsupportedEncodingException e) {
                            e.printStackTrace();
                        }
                    }
                }
                flag=false;
            }
            return map;
        }

        return super.getParameterMap();
    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值