Springmvc学习日记-乱码处理

        乱码问题是伴随整个web开发项目,任何人都会遇到,所以这里将处理乱码方式详细记录一下。无论是get请求还是post请求都会产生乱码,对于get请求,可以通过修改tomcat配置文件一次性解决,但是post请求不行,具体可以参考如下内容。

一、GET请求的乱码

        在tomcat7中在默认配置server.xml下,GET请求会出现乱码,在tomcat8中不会出现乱码。这个地方有一点点区别。

解决tomcat7 GET请求乱码,修改tomcat7中conf/server.xml文件,增加URIEncoding="UTF-8"配置项,具体如下:

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

二、原生Servlet处理POST请求乱码

2.1、通过Servlet Request/Response接口

public class HelloServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("doPost....");
        req.setCharacterEncoding("UTF-8");
        resp.setCharacterEncoding("UTF-8");
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        Integer age = Integer.valueOf(req.getParameter("age"));

        req.setAttribute("username", username);
        req.setAttribute("password", password);
        req.setAttribute("age", age);
        req.getRequestDispatcher("/WEB-INF/jsp/test.jsp").forward(req, resp);
    }
}

2.2、通过Filter过滤器

首先,实现Filter接口

//实现Filter接口
public class EncodingFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        request.setCharacterEncoding("UTF-8");
        response.setCharacterEncoding("UTF-8");
        chain.doFilter(request, response);
    }

    @Override
    public void destroy() {

    }
}

其次,配置过滤器 

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
    <!-- 配置Servlet -->
    <servlet>
        <servlet-name>HelloServlet</servlet-name>
        <servlet-class>com.example.servlet.HelloServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>HelloServlet</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

    <!-- 配置过滤器 -->
    <filter>
        <filter-name>EncodingFilter</filter-name>
        <filter-class>com.example.filter.EncodingFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>EncodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
</web-app>

最后,处理请求,可见是直接获取参数

public class HelloServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        Integer age = Integer.valueOf(req.getParameter("age"));

        req.setAttribute("username", username);
        req.setAttribute("password", password);
        req.setAttribute("age", age);
        req.getRequestDispatcher("/WEB-INF/jsp/test.jsp").forward(req, resp);
    }
}

2.3、通过ServletRequestListener监听器

首先,实现ServletRequestListener接口 

public class RequestListenerHandler implements ServletRequestListener {
    @Override
    public void requestDestroyed(ServletRequestEvent sre) {

    }

    @Override
    public void requestInitialized(ServletRequestEvent sre) {
        try {
            sre.getServletRequest().setCharacterEncoding("UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
    }
}

其次,在web.xml中注册listener(这里没有过滤器配置)

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
    <!-- 配置Servlet -->
    <servlet>
        <servlet-name>HelloServlet</servlet-name>
        <servlet-class>com.example.servlet.HelloServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>HelloServlet</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

    <listener>
        <listener-class>com.example.listener.RequestListenerHandler</listener-class>
    </listener>
</web-app>

最后,Servlet处理

public class HelloServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        Integer age = Integer.valueOf(req.getParameter("age"));

        req.setAttribute("username", username);
        req.setAttribute("password", password);
        req.setAttribute("age", age);
        req.getRequestDispatcher("/WEB-INF/jsp/test.jsp").forward(req, resp);
    }
}

其中前两种比较常见,这里简单说一下第三种,第三种方式不常用,了解即可。

1)第三种方式,主要利用Servlet提供Listener接口,每次创建请求的时候都会被调用,而且Listen接口要早于Filter接口线支持。Servlet执行顺序:监听器,过滤器,Servlet

2)通过listener接口可知,我们没有办法获取到response对象,也就没有办法设置response编码格式,需要在处理的时候单独处理一下

3)对于response乱码,我们需要通常需要设置这两个

resp.setCharacterEncoding("UTF-8");  //告诉Servlet,按照utf-8编码字节流
resp.setContentType("text/html;charset=utf-8");  //告诉浏览器,按照utf-8编码显示

三、SpringMvc处理POST请求乱码

        Servlet解决乱码有一个前提:设置编码之前一定要在获取参数之前设置,否则是无效的。例如下面代码对是无效的:

    @RequestMapping("/hello")
    public String hello(String username, HttpServletRequest request) throws UnsupportedEncodingException {
        request.setCharacterEncoding("UTF-8"); //形参username是从request中获取的,此处在设置编码也是无效的,除非删除形参username
        String uname = request.getParameter("username");
        String password = request.getParameter("password");
        Integer age = Integer.valueOf(request.getParameter("age"));
        request.setAttribute("username", uname);
        request.setAttribute("password", password);
        request.setAttribute("age", age);
        return "test";
    }

        这里设置编码是在获取username参数之后,所以不能生效,除非删掉形参username,但是删掉了username之后,就又变成原生的Servlet方式,不能充分发挥SpringMvc能力。

3.1、过滤器Filter

在web.xml中配置SpringMvc提供的过滤器

    <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>forceResponseEncoding</param-name>
            <param-value>true</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>CharacterEncodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    @RequestMapping("/hello")
    public String hello(String username, String password, Integer age, Model model) throws UnsupportedEncodingException {
        model.addAttribute("username", username);
        model.addAttribute("password", password);
        model.addAttribute("age", age);
        return "test";
    }

3.2、拦截器HandlerInterceptor

        拦截器是SpringMvc提供的,并不是Servlet的东西,拦截器与过滤器功能类似,但拦截器功能更强大一些,下面拦截器工作原理:

        所以我们实现HandlerInterceptor接口后,也是可以处理乱码问题,具体如下:

public class EncodingInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        request.setCharacterEncoding("UTF-8");
        response.setCharacterEncoding("UTF-8");
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {

    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {

    }
}

 在springmvc.xml文件配置一下拦截器,具体如下:

    <mvc:interceptors>
        <mvc:interceptor>
            <mvc:mapping path="/**"/>
            <bean id="EncodingInterceptor" class="com.example.interceptor.EncodingInterceptor"/>
        </mvc:interceptor>
    </mvc:interceptors>

四、Springboot处理POST请求乱码

后面补充

五、JSON中乱码

        参考之前我写的博客:https://blog.csdn.net/xxb249/article/details/122271835https://blog.csdn.net/xxb249/article/details/122271835

六、总结

        解决乱码问题根本思想:在获取参数值,之前先设置一下编码,只要符合这个规则通过什么方式解决乱码都是无所谓的,不过通常都是通过过滤器。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值