javaweb开发中,java监听器对象导致中文乱码过滤器不起作用和失效!

今天遇到一个很奇怪的问题,所以花时间研究了下!

csdn的文章编辑确实有点体验不太好,自己截的图明明是大图,发表文章后就变成了小图,小图就看不太清除了,大家凑合着看吧!截图在下面!

首先,大家先看下效果吧,先知道我要做什么?我项目中有一个jsp页面中,jsp页面中有个form表单,这个表单主要是用来收集数据的,然后提交(post提交)到服务器端上的一个servlet类处理,表单的文本框中会输入中文,所以为了处理中文乱码的问题,我专门写了一个处理中文乱码的过滤器,在中文乱码过滤器类中设置了编码格式是utf-8,web.xml文件中配置了这个中文乱码过滤器!web.xml文件中还配置了request监听器对象和request的Attribute属性的监听器对象。大家都知道,过滤器类中有一个init方法,在web容器启动的时候,比如tomcat启动的时候,过滤器类中的init方法就会执行,而request监听器对象也有一个方法,叫requestInitialized方法,但是requestInitialized方法不会在tomcat启动的时候执行,而是会在request对象创建的时候执行requestInitialized方法。

代码如下:

RequestListener类

package com.jiongmeng.listener;

import java.util.Enumeration;

import javax.servlet.ServletRequest;
import javax.servlet.ServletRequestEvent;
import javax.servlet.ServletRequestListener;

/** 
 * @Description: (request对象在创建和消亡的监听器) 
 * @author 囧囧   E-mail:[email protected] 
 * jerry
 * @date: 2017年11月8日 下午1:06:49 
 * 

Copyright: Copyright (c) 2005-2017版权归囧萌软件科技公司所有

* @version 创建时间:2017年11月8日 下午1:06:49 */ public class RequestListener implements ServletRequestListener{ @Override public void requestDestroyed(ServletRequestEvent requestEvent) { System.out.println("************request对象消亡************"); } @Override public void requestInitialized(ServletRequestEvent requestEvent) { System.out.println("************request对象创建************"); // ServletRequest request = requestEvent.getServletRequest(); // String hobby = request.getParameter("hobby"); // System.out.println("页面传递的参数hobby(爱好) = " + hobby); // Enumeration parameterNames = request.getParameterNames(); // while (parameterNames.hasMoreElements()) { // String parameterName = parameterNames.nextElement(); // System.out.println("参数名 = " + parameterName + " 参数值 = " + request.getParameter(parameterName)); // } } }

RequestAttributeListener类

package com.jiongmeng.listener;

import javax.servlet.ServletRequestAttributeEvent;
import javax.servlet.ServletRequestAttributeListener;

/** 
 * @Description: (request对象在attribute时的监听器) 
 * @author 囧囧   E-mail:[email protected] 
 * jerry
 * @date: 2017年11月8日 下午1:12:47 
 * 

Copyright: Copyright (c) 2005-2017版权归囧萌软件科技公司所有

* @version 创建时间:2017年11月8日 下午1:12:47 */ public class RequestAttributeListener implements ServletRequestAttributeListener{ @Override public void attributeAdded(ServletRequestAttributeEvent requestAttributeEvent) { System.out.println("我是request对象的attributeAdded方法"); System.out.println("request对象中添加属性,名 = " + requestAttributeEvent.getName() + " 值 = " + requestAttributeEvent.getValue()); //System.out.println("请求参数hobby的值 = " + requestAttributeEvent.getServletRequest().getParameter("hobby")); } @Override public void attributeRemoved(ServletRequestAttributeEvent requestAttributeEvent) { System.out.println("我是request对象的attributeRemoved方法"); //打印的是删除前的值 System.out.println("request对象中删除属性,名 = " + requestAttributeEvent.getName() + " 值 = " + requestAttributeEvent.getValue()); // System.out.println("请求参数hobby的值 = " + requestAttributeEvent.getServletRequest().getParameter("hobby")); } @Override public void attributeReplaced(ServletRequestAttributeEvent requestAttributeEvent) { System.out.println("我是request对象的attributeReplaced方法"); //打印的是修改前的值 System.out.println("request对象中修改属性,名 = " + requestAttributeEvent.getName() + " 值 = " + requestAttributeEvent.getValue()); System.out.println("请求参数hobby的值 = " + requestAttributeEvent.getServletRequest().getParameter("hobby")); } }

ChineseMessyCodeFilter类

package com.jiongmeng.filter;

import java.io.IOException;
import java.util.Enumeration;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

/**
 * 
 * 中文乱码过滤器(请求前过滤器)
 * @author czh
 * @time 2017年10月12日 下午10:48:17
 */
public class ChineseMessyCodeFilter implements Filter{
	private String characterEncoding = "utf-8";

	@Override
	public void destroy() {
		System.out.println("*******************中文乱码过滤器destroy()*******************");
	}

	@Override
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain)
			throws IOException, ServletException {
		request.setCharacterEncoding(characterEncoding);
		System.out.println("*********************脱衣服洗澡!(请求前过滤)*********************"); //前过滤
//		System.out.println("请求servlet资源路径 = " + ((HttpServletRequest)request).getServletPath());
//		System.out.println("请求方式(get / post) = " + ((HttpServletRequest)request).getMethod());
		filterChain.doFilter(request, response);
		System.out.println(response.getClass());
		System.out.println("*********************穿衣服准备出门!(请求后过滤)*********************");//后过滤
		
	}

	@Override
	public void init(FilterConfig filterConfig) throws ServletException {
		System.out.println("filterName = " + filterConfig.getFilterName());
		characterEncoding = filterConfig.getInitParameter("characterEncoding");
		Enumeration names = filterConfig.getInitParameterNames();
		while (names.hasMoreElements()) {
			String name = (String) names.nextElement();
			System.out.println(name + " = " + filterConfig.getInitParameter(name));
		}
		System.out.println("*******************中文乱码过滤器init()*******************");
	}

}

web.xml文件



  javaWeb
  
    java.lang.ArithmeticException
    /arithmeticError.jsp
  
  
    500
    /error500.jsp
  
  
    404
    /error404.jsp
  
  
    SystemInit
    com.jiongmeng.system.SystemInit
    0
  
   
  
    com.jiongmeng.listener.ApplicationListener
  
  
    com.jiongmeng.listener.ApplicationAttributeListener
  
  
    com.jiongmeng.listener.SessionListenerImpl
  
  
    com.jiongmeng.listener.SessionAttributeListener
  
  
  
  
  
    com.jiongmeng.listener.RequestListener
  
  
    com.jiongmeng.listener.RequestAttributeListener
  
  
  
    springConfigLocation
    /WEB-INF/applicationContext.xml
  
  
    city
    jiangxiyudu
  
  
  
  
  
  
  
   
  
   
  
  
  
  
   
  
  
  
  
   
  
  
    chineseMessyCodeFilter
    com.jiongmeng.filter.ChineseMessyCodeFilter
    
      characterEncoding
      utf-8
    
    
      logType
      log4j
    
  
  
    chineseMessyCodeFilter
    /thermaServlet
    /hello
    /*
  
  
  
    15
  
  
    testRequestGetParameter
    testIncludeAction.jsp
    tomcatKnowledge.jsp
  
  
    myJspHideObject
    /9jspHideObject.jsp
    
      userName
      令狐冲
    
  
  
    myJspHideObject
    /hello
  
  
    firstServlet
    com.jiongmeng.FirstServlet
    1
  
  
    firstServlet
    /firstServlet
    /myfirstServlet
  
  
    bookInfo
    com.jiongmeng.BookInfo
  
  
    bookInfo
    /bookInfo/*
    /bookInfo/save
    /bookInfo/update
    /bookInfo/findAll
  
  
    testServlet
    com.jiongmeng.TestServlet
    
      color
      blue
    
    
      color
      red
    
    
      userName
      jiongjiong
    
    0
  
  
    testServlet
    /testServlet
  

在浏览器地址栏中输入jsp地址,就会执行request监听器对象的requestInitialized方法和request的Attribute属性的监听器对象的attributeReplaced方法。等jsp加载完了,就会执行request监听器对象的requestDestroyed方法,当然这些都不是我们的重点!

javaweb开发中,java监听器对象导致中文乱码过滤器不起作用和失效!_第1张图片

点击submit按钮提及到服务器端,发现表单中的中文提交到服务器端的时候,服务器端拿到的中文数据是中文乱码,这就很奇怪了,我明明是写了处理中文乱码的过滤器的嘛!

javaweb开发中,java监听器对象导致中文乱码过滤器不起作用和失效!_第2张图片

于是我debug了一下,看看执行的流程和顺序是怎么回事!

debug后,第1步执行的是request监听器对象的requestInitialized方法,所以监听器是优先于过滤器执行的,看下图

javaweb开发中,java监听器对象导致中文乱码过滤器不起作用和失效!_第3张图片

第2步执行的是RequestAttributeListener类中的attributeReplaced方法,看下图

javaweb开发中,java监听器对象导致中文乱码过滤器不起作用和失效!_第4张图片

第3步执行的是ChineseMessyCodeFilter类(中文乱码过滤器类)中的doFilter方法,看下面的截图

javaweb开发中,java监听器对象导致中文乱码过滤器不起作用和失效!_第5张图片

javaweb开发中,java监听器对象导致中文乱码过滤器不起作用和失效!_第6张图片

这个时候小伙伴应该明白了为什么我们写了中文乱码过滤器还是会乱码!

没错,就是在执行ChineseMessyCodeFilter类(中文乱码过滤器类)中的doFilter方法之前,我们的程序先执行了request监听器对象的requestInitialized方法和request的Attribute属性的监听器对象的attributeReplaced方法,而这2个方法中又使用了request.getParameter()方法,我们都知道在request.setCharacterEncoding("utf-8");这句话之前,不能使用request.getParameter()方法,这样会导致服务器端获取到的还是中文乱码,所以必须是request.getParameter()这句话只能放在request.setCharacterEncoding("utf-8");这句话之后,才能解决中文乱码的问题,所以知道原因了的话,我们只要把RequestAttributeListener类中的attributeReplaced方法中的getServletRequest().getParameter()这句话注释掉,把RequestListener类中requestInitialized方法中的request.getParameter()注释掉,就可以解决中文乱码过滤器失效的问题,所以大家记住,javaweb开发中监听器中的一些语句会导致过滤器失效,就像这个例子一样,request监听器对象中的一些语句导致了中文乱码过滤器失效!

javaweb开发中,java监听器对象导致中文乱码过滤器不起作用和失效!_第7张图片

javaweb开发中,java监听器对象导致中文乱码过滤器不起作用和失效!_第8张图片

注释掉后,jsp表单提交,服务器端拿表单数据的时候就不会是中文乱码了!,看下图

javaweb开发中,java监听器对象导致中文乱码过滤器不起作用和失效!_第9张图片


你可能感兴趣的:(java编程)