Javaweb之Filter案例练习-项目全局编码过滤器

Filter全局编码过滤器


这篇来做一个Filter在全局编码过滤器练习,这篇新建一个web项目来做练习。

web项目创建

先创建一个叫GlobalFilter的web动态项目,把前面文章出现过的login.jsp复制过来,改成如下代码。

<%@ page language="java" contentType="text/html; charset=UTF-8"

   pageEncoding="UTF-8"%>

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "https://www.w3.org/TR/html4/loose.dtd">

<html>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

<title>Insert title here</title>

</head>

<body>

<form action="${pageContext.request.contextPath}/web/loginServlet" method="post">

用户名:<input type="text" name="username" /><br/>

<input type="submit" value="登录" /><br/>

</form>

</body>

</html>

因为我们这里做全局编码的练习,到时候登录页面输入用户名,我们会采用中文字符输入。

Servlet创建

因为这里我们是模拟全局,实际中应该有许多servlet和许多前端页面,例如注册,登录,首页搜索等。我们就来创建一个servlet来模拟下就好。创建一个LoginServlet.java。 url-pattern是/web/loginServlet。

package com.kaigejava.web.servlet;

import java.io.IOException;

import javax.servlet.ServletException;

import javax.servlet.annotation.WebServlet;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

@WebServlet("/loginServlet")

public class LoginServlet extends HttpServlet {

public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

//request.setCharacterEncoding("UTF-8");

String name = request.getParameter("username");

System.out.println(name);

}

public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

doGet(request, response);

}

}

以前,我们是通过这个红圈代码来设置编码,这样拿到中文的username就不会是乱码。

现实开发中有很多个servlet,如果都这样写这行代码来设置编码,这行代码就冗余,我们可以把这行代码放到Filter过滤器中去。

Filter类创建

创建一个MyFilter.java 实现Filter接口,代码如下。

package com.kaigejava.web.filter;

import java.io.IOException;

import javax.servlet.Filter;

import javax.servlet.FilterChain;

import javax.servlet.FilterConfig;

import javax.servlet.ServletException;

import javax.servlet.ServletRequest;

import javax.servlet.ServletResponse;

import javax.servlet.annotation.WebFilter;

import javax.servlet.http.HttpServletRequest;

public class MyFilter implements Filter {

public void destroy() {

// TODO Auto-generated method stub

}

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {

// 转换对象

HttpServletRequest req = (HttpServletRequest) request;

// 设置编码

req.setCharacterEncoding("UTF-8");

// 放行

chain.doFilter(request, response);

}

public void init(FilterConfig fConfig) throws ServletException {

// TODO Auto-generated method stub

}

}

web.xml内容如下

<?xml version="1.0" encoding="UTF-8"?>

<web-app xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xmlns="https://java.sun.com/xml/ns/javaee" xsi:schemaLocation="https://java.sun.com/xml/ns/javaee https://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">

 <display-name>GlobalFilter</display-name>

 <welcome-file-list>

   <welcome-file>index.html</welcome-file>

   <welcome-file>index.htm</welcome-file>

   <welcome-file>index.jsp</welcome-file>

   <welcome-file>default.html</welcome-file>

   <welcome-file>default.htm</welcome-file>

   <welcome-file>default.jsp</welcome-file>

 </welcome-file-list>


 <filter>

 <filter-name>MyFilter</filter-name>

 <filter-class>com.kaigejava.web.filter.MyFilter</filter-class>

 </filter>


 <filter-mapping>

 <filter-name>MyFilter</filter-name>

 <url-pattern>/*</url-pattern>

 </filter-mapping>


 <servlet>

   <servlet-name>LoginServlet</servlet-name>

   <servlet-class>com.anthony.web.servlet.LoginServlet</servlet-class>

 </servlet>

 <servlet-mapping>

   <servlet-name>LoginServlet</servlet-name>

   <url-pattern>/web/loginServlet</url-pattern>

 </servlet-mapping>


</web-app>

部署测试

现在部署到tomcat然后测试以下,前台页面用户名输入框输入“张三”看看。

在Eclipse控制台可以看到“张三”打印出来不乱码,说明我们Filter中编码设置起效果了。

Get方式提交表单问题

在login.jsp中我们表单提交是post方法,如果改成get呢,会出问题。

重新部署,再来测试下

如果是get方式传过来,中文就很有可能显示乱码。这个问题怎么解决了,有两种方式解决,第一种不要写get,就是post表单提交。现在我们来看看第二种方式如何解决。在MyFilter类中写一个通用的方法,既能解决get也能解决post的编码问题。

装饰模式解决get和post编码问题

我们在MyFilter.java代码中添加一个MyRequest class,里面写我们的装饰器代码,只重写了getParameter(String text)方法。

package com.kaigejava.web.filter;

import java.io.IOException;

import java.io.UnsupportedEncodingException;

import javax.servlet.Filter;

import javax.servlet.FilterChain;

import javax.servlet.FilterConfig;

import javax.servlet.ServletException;

import javax.servlet.ServletRequest;

import javax.servlet.ServletResponse;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletRequestWrapper;

public class MyFilter implements Filter {

public void destroy() {

// TODO Auto-generated method stub

}

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {

// 转换对象

HttpServletRequest req = (HttpServletRequest) request;

// 设置编码

//req.setCharacterEncoding("UTF-8");

// 放行

req = new MyRequest(req);

// req这个对象是包装之后的对象,把这个传到servlet中的request

chain.doFilter(req, response);

}

public void init(FilterConfig fConfig) throws ServletException {

// TODO Auto-generated method stub

}

}

/**

*  继承HttpServlet的包装类,实现装饰模式,解决get和post乱码问题

*

*/

class MyRequest extends HttpServletRequestWrapper{

HttpServletRequest request;

public MyRequest(HttpServletRequest request) {

super(request);

this.request = request;

}

public String getParameter(String name) {

name = request.getParameter(name); //乱码

try {

return new String(name.getBytes("iso-8859-1"), "UTF-8");

} catch (UnsupportedEncodingException e) {

e.printStackTrace();

}

return null;

}

}

部署到tomcat,login.jsp表单还是get提交,测试可以解决get和post乱码。

重写其他方法

在request对象中,还有其他方法,例如getParameters() 和getParameterMap(),这里我们把这两个方法都重写一下。

package com.kaigejava.web.filter;

import java.io.IOException;

import java.io.UnsupportedEncodingException;

import java.util.Map;

import javax.servlet.Filter;

import javax.servlet.FilterChain;

import javax.servlet.FilterConfig;

import javax.servlet.ServletException;

import javax.servlet.ServletRequest;

import javax.servlet.ServletResponse;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletRequestWrapper;

public class MyFilter implements Filter {

public void destroy() {

}

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {

// 转换对象

HttpServletRequest req = (HttpServletRequest) request;

// 放行

req = new MyRequest(req);

// req变成自己包装的对象,然后传递给servlet中,servlet中的request就是调用包装过的req

chain.doFilter(req, response);

}

public void init(FilterConfig fConfig) throws ServletException {

}

}

/**

* 继承HttpServlet的包装类,实现装饰模式,解决get和post乱码问题

*

*/

class MyRequest extends HttpServletRequestWrapper {

HttpServletRequest request;

public MyRequest(HttpServletRequest request) {

super(request);

this.request = request;

}


/*@Override

public String getParameter(String name) {

name = request.getParameter(name); //乱码

try {

return new String(name.getBytes("iso-8859-1"), "UTF-8");

} catch (UnsupportedEncodingException e) {

e.printStackTrace();

}

return null;

}*/


@Override

public String getParameter(String name) {

Map map = getParameterMap();

return map.get(name)[0];

}


@Override

public String[] getParameterValues(String name) {

Map map = getParameterMap();

return map.get(name);

}


public boolean flag = true;

@Override

public Map

Map map = request.getParameterMap(); // 乱码

if (flag) {

for (Map.Entry m : map.entrySet()) {

String[] values = m.getValue();

for (int i = 0; i < values.length; i++) {

try {

values[i] = new String(values[i].getBytes("iso-8859-1"), "UTF-8");

} catch (UnsupportedEncodingException e) {

e.printStackTrace();

}

}

}

flag = false;

}

return map;

}

}

由于最后三个方法,我们倒数第二个第三个都是调用倒数第一个,为了解决第一个调用乱码好了,第二个再次调用又变成乱码,所以这里在第三个方法添加了一个flag。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,686评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,668评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,160评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,736评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,847评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,043评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,129评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,872评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,318评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,645评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,777评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,470评论 4 333
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,126评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,861评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,095评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,589评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,687评论 2 351

推荐阅读更多精彩内容