【案例分析】如何解决jsp页面乱码问题?

       方法一:

       单独配置jsp页面:

       在jsp页面开头的地方设置charset=GB1803目的是response的时候,返回界面显示时候中文不乱码,如下代码所示:


<%@ page language="java" contentType="text/html; charset=GB18030" pageEncoding="GB18030"%>


除此之外,在jsp中java代码部分设置request的编码方式 :

<%
	//设置request过程的Charset
	request.setCharacterEncoding("GB18030");
	//从jsp页面中获取用户输入的值
	String command = request.getParameter("command");
	if("add".equals(command)) {
		User user = new User();
		user.setUserId(request.getParameter("userId"));
		user.setUserName(request.getParameter("userName"));
		user.setPassword(request.getParameter("password"));
		user.setEmail(request.getParameter("email"));
		
		UserManager.getInstance().addUser(user);
		out.println("添加用户成功!");
	}

%>

  UML图解析:

                           

java拦截器 下排除 java的拦截器_xml

    如上所示,可知每个页面对于request过程和response过程都需要设置编码方式,不仅仅每个jsp页面需要加CharsetEncoding代码,执行过程中也消耗较大内存。

方法二:

通过filter拦截器来实现对所有页面的CharsetEncoding设置:

(1)新建一个filter的package包,写一个设置编码的filter类,未在web.xml中配置之前,该类就是普通的java类。

//定义字符集的类
public class CharsetEncodingFilter implements Filter {
	//设定成员变量
	String encoding;
	
	public void destory() {
	
	}
	
	public void doFilter(ServletRequest request, ServletResponse response,FilterChain chain) throws IOException, ServletException {
		//设置字符集
		request.setCharacterEncoding("GB18030");
		//继续执行
		chain.doFilter(request,response);
	}
	
	public void init(FilterConfig filterConfig) throws ServletException {
		//从web.xml中取出--编码方式
		this.endCoding = filterConfig.getInitParameter("encoding");
	}
}


(2)在web.xml中进行filter配置

<web-app version="2.4">
	<filter>
		<filter-name>CharsetEncodingFilter</filter-name>
		<filter-class>com.bjpowernode.drp.util.filter.CharsetEncodingFilter</filter-class>
		<init-param>
			<param-name>encoding</param-name>
			<param-value>GBK</param-value>
		</init-param>
	</filter>

	<filter-mapping>
		<filter-name>CharsetEncodingFilter</filter-name>
		<url-pattern>*.jsp</url-pattern>
	</filter-mapping>
</web-app>

             

通过web.xml和filter类的结合,此时的CharsetEncodingFilter已经不是一个普通的java类,作为介乎于TomCat和JSP之间的一个屏障,统一对所有的jsp界面进行字符集配置(<url-pattern>*.jsp</url-pattern>)。

        UML图解析:

        

java拦截器 下排除 java的拦截器_java拦截器 下排除_02

   通过在xml中doFilter的设置,使得不同的多个Filter也可以执行,而且init方法在tomcat启动到关闭过程中仅仅执行一次,这样每次打开新的页面,都不用重复设置jsp的编码方式。

【理解Filter机制】

几点注意:

(1)CharsetEncodingFilter实现javax.servlet.Filter,重写了三个方法:

public void destroy(){
		//销毁,目前还没有用到
	}
        public void doFilter(){
	       //执行filter的工作,该类可以实现权限控制
	}
        public void init(){
		//初始化方法,只执行一次。
	}


对于filter,随着TomCat开启,调用init方法,从配置文件中取参数放到成员变量,任务完成;对于doFilter,每次执行拦截器都会调用该方法,至于何时调用拦截器,在<filter-mapping>中的<url-pattern>有配置。待关闭TomCat,执行调用destroy()方法。

      (2)doFilter( )实现权限控制,对于登录用户的权限,通过从session中读取的信息,在其中判断,如果权限允许,执行chain.doFilter方法, 相关的jsp页面予以显示。


public void doFilter(ServletRequest request, ServletResponse response,FilterChain chain) throws IOException, ServletException {
		//设置字符集
		request.setCharacterEncoding("GB18030");

		//加以权限判断是否允许继续执行
		
		//继续执行
		chain.doFilter(request,response);
	}

     

(3)<url-pattern>中的几种写法

      1.精确匹配


<filter-mapping>  
    <filter-name>CharseEncodingFilter</filter-name>  
    <url-pattern>/servlet/TestServlet</url-pattern>  
</filter-mapping>


       2.扩展匹配


<filter-mapping>  
    <filter-name>CharseEncodingFilter</filter-name>  
    <url-pattern>*.jsp</url-pattern>  
 </filter-mapping>


        3.路径前缀匹配


<filter-mapping>  
    <filter-name>CharseEncodingFilter</filter-name>  
    <url-pattern>/sysmgr/*</url-pattern>  
</filter-mapping>


        4.全部匹配 


<filter-mapping>  
    <filter-name>CharseEncodingFilter</filter-name>  
    <url-pattern>/*</url-pattern>  
</filter-mapping>



      总结:DRP学到filter的时候,回头看了下项目中的filter配置,对于权限控制这块,有了浅显的理解,有点“拦截”的意思,我的这个CharSet例子,仅仅是拦截器中的一个小小应用,后续还会继续更新filter的知识。