使用Filter实现统一编码

【任务目标】
在web开发中,经常会遇到中文乱码问题,按照我们前面所学的知识,解决乱码的通常做法都是在Servlet程序中设置编码方式,但是如果多个Servlet程序都需要设置编码方式,势必会书写大量的代码。为了解决上面的问题,可以在Filter中获取到的请求和响应消息进行编码,从而统一全站的编码方式。
【实现步骤】
1.编写form.jsp页面
在chapter08项目的WebContent目录中,编写一个form.jsp页面,该页面用于提交用户登陆的表单信息,代码如下:

<%@ page language="java" contentType="text/html; charset=utf-8"
	pageEncoding="utf-8" import="java.util.*"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<center>
	<h3>用户登录</h3>
</center>
<body style="text-align: center;">
	<a href="<%=request.getContextPath()%>/CharacterServlet?name=传智播客&password=123456">单击超链接登录</a>
	<form action="<%=request.getContextPath()%>/CharacterServlet"
		method="post">
		<table border="1" width="600px" cellpadding="0" cellspacing="0"
			align="center">
			<tr>
				<td height="30" align="center">用户名:</td>
				<td>&nbsp;<input type="text" name="name" />
				</td>
			</tr>
			<tr>
				<td height="30" align="center">&nbsp; 码:</td>
				<td>&nbsp;<input type="password" name="password" />
				</td>
			</tr>
			<tr>
				<td height="30" colspan="2" align="center">
				<input type="submit" value="登录" />
				 &nbsp;&nbsp;&nbsp;&nbsp;
				<input type="reset" value="重置" />
			    </td>
			</tr>
		</table>
	</form>
</body>

在上述代码中,第10~11行是一个超链接,请求方式为GET方式;第12—32行代码是一个Form表单,它的提交方式被设置为POST方式。
2.创建Servlet
在chapter08项目的cn.itcast.chapter08.filter包中,编写一个CharacterServlet类,该类用于获取用户输入的请求参数,并将参数输出到控制台,代码如下:

package cn.itcast.chapter08.filter;
import java.io.IOException;
import javax.servlet.*;
import javax.servlet.http.*;
public class CharacterServlet extends HttpServlet {
	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		System.out.println(request.getParameter("name"));
		System.out.println(request.getParameter("password"));
	}
	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		doGet(request, response);
	}
}

3.创建过滤器
在chapter08 项目的cn.itcast.chapter08.filter包中,编写一个ChapterFifer该类用于拦截用户的请求访问,实现统一全站编码的功能。 只是针对请求的方式不同,解决乱码的方式也不同。其中,POST方式的请求参数存放在消息体中,,可以通过,setCharaterEncoding()方法进行设置:而GET方式的请求参数存放在消息头中,必须得通过获取URI参数才能进行设置。如果每次单独对GET请求方式进行处理,势必会很麻烦。为此,可以通过HttpServletRequestWrapper类对HttpServletRequest进行包装,通过重写getParameter()的方式来设置GET方式提交参数的编码,CharacterFilter类的实现代码如下所示:

package cn.itcast.chapter08.filter;
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class CharacterFilter implements Filter {
	public void init(FilterConfig filterConfig) throws ServletException {
	}
	public void doFilter(ServletRequest req, ServletResponse resp,
			FilterChain chain) throws IOException, ServletException {
		HttpServletRequest request = (HttpServletRequest) req;
		HttpServletResponse response = (HttpServletResponse) resp;
		// 拦截所有的请求 解决全站中文乱码
		// 指定 request 和 response 的编码
		request.setCharacterEncoding("utf-8"); // 只对消息体有效
		response.setContentType("text/html;charset=utf-8");
		// 对request进行包装
		CharacterRequest characterRequest = new CharacterRequest(request);
		chain.doFilter(characterRequest, response);
	}
	public void destroy() {
	}
}
// 继承 默认包装类HttpServletRequestWrapper
class CharacterRequest extends HttpServletRequestWrapper {
	private HttpServletRequest request;
	public CharacterRequest(HttpServletRequest request) {
		super(request);
		this.request = request;
	}
	// 子类继承父类一定会覆写一些方法,此处用于重写getParamter()方法
	public String getParameter(String name) {
		// 调用被包装对象的getParameter()方法,获得请求参数
		String value = super.getParameter(name);
		if (value == null)
			return null;
		// 判断请求方式
		String method = super.getMethod();
		if ("get".equalsIgnoreCase(method)) {
			try {
					value = new String(value.getBytes("iso-8859-1"), "utf-8");
			} catch (UnsupportedEncodingException e) {
				throw new RuntimeException(e);
			}
		}
		// 解决乱码后返回结果
		return value;
	}
}

4.配置映射信息
在web.xml文件中,配置CharacterServlet和CharacterFilter的映射信息。由于要拦截用户访问资源的所有请求,因此,将ChapterFilter的映射信息。由于要拦截用户访问资源的所有请求,因此,将ChapterFilter映射信息中“filter-mapping”元素拦截的路径设置为“/*”代码如下:

<servlet>
		<description></description>
		<display-name>CharacterServlet</display-name>
		<servlet-name>CharacterServlet</servlet-name>
		<servlet-class>cn.itcast.chapter08.filter.CharacterServlet</servlet-class>
	</servlet>
	<servlet-mapping>
		<servlet-name>CharacterServlet</servlet-name>
		<url-pattern>/CharacterServlet</url-pattern>
	</servlet-mapping>
	<filter>
		<filter-name>CharacterFilter</filter-name>
		<filter-class>cn.itcast.chapter08.filter.CharacterFilter</filter-class>
	</filter>
	<filter-mapping>
		<filter-name>CharacterFilter</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>

5.项目启动,测试结果
启动Tomact服务器,打开浏览器,在地址栏输入地址“http://localhost:10081/chapter/form.jsp”此时,浏览器窗口会显示一个用户登陆的表单,在这个表单中输入用户名“张荣博”,密码“123456”如下图所示:
在这里插入图片描述
单击上图中的【登录】按钮来提交表单,此时,控制台窗口显示的结果如下图所示:
在这里插入图片描述

从上图可以看出,在form.jsp表单中输入的用户名和密码都正确的显示在控制台窗口,而且中文的用户名也没有出现乱码问题,需要注意的是,form.jsp表单的提交方式是POST。因此,可以说明使用POST提交表单可以解决中文乱码的问题。表单的提交方式还有一种是GET,接下来验证GET方式提交表单的乱码问题能否解决。
单击第一幅图中的“单击超链接登陆”链接来提交表单,这种提交方式相当于GET方式提交表单,此时,控制台窗口显示的结果如下图所示:
在这里插入图片描述
从上图我们可以看出,GET方式提交表单与POST方式提交表单的效果是一致的,同样不会出现乱码问题,因此,可以说明使用Filter过滤器可以方便地完成统一全站编码的功能。

  • 3
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
很遗憾,因为篇幅限制和涉及知识面广泛,无法在此回答全部代码。但是,我可以为您提供以下参考和指导: 1. Servlet/GenericServlet/HttpServlet/ServletRequest/ServletResponse接口机制详解 这里需要详细讲解Servlet API中各个接口的作用和用法,包括Servlet、GenericServlet、HttpServlet、ServletRequest和ServletResponse等。需要掌握Servlet生命周期、Servlet容器、Servlet配置等相关内容。 2. Servlet注解增强、Servlet3.0异步新特性、Servlet文件上传下载机制Part接口机制详解web服务器容器动态注册Servlet 这里需要详细讲解Servlet 3.0中新增的注解、异步处理、文件上传下载机制、Part接口等内容,同时还需要理解Web服务器容器动态注册Servlet的原理和实现。 3. Filter过滤器HttpFilter增强实现全站编码统一 这里需要详细讲解Filter的作用以及HttpFilter的增强功能,同时还需要掌握如何通过Filter实现全站编码统一。 4. web组件9大监听器使用及原理、Session纯化活化机制、及企业生产环境使用场景 这里需要详细讲解Web组件中9大监听器的作用原理、Session纯化活化机制的实现使用场景,同时还需要掌握在企业生产环境中如何使用这些组件。 5. 完成用户登录功能模块的开发 这里需要实现一个用户登录功能模块,包括前端登录界面、LoginServlet程序和LoginFilter程序。需要掌握如何通过Servlet和Filter实现用户登录功能,同时还需要掌握前端页面的实现和数据传输的方法。 总之,对于Web开发中的这些基础概念和技术,需要掌握其作用原理、用法和实现方法,才能够熟练地进行开发和调试。建议多查阅相关文档和教程,不断学习和实践,才能够提高自己的技能水平。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值