10、Filter常见应用

)统一全站字符编码的过滤器

通过配置参数encoding指明使用何种字符编码,以处理Html Form请求参数的中文问题

案例:编写jsp 输入用户名,在Servlet中获取用户名,将用户名输出到浏览器上

处理请求post乱码代码

request.setCharacterEncoding("utf-8");

设置响应编码集代码

response.setContentType("text/html;charset=utf-8");

经常会使用,而过滤器可以在目标资源之前执行,将很多程序中处理乱码公共代码,提取到过滤器中 ,以后程序中不需要处理编码问题了

package com.itheima.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 EncodingFilter implements Filter {

private FilterConfig config = null;

public void destroy() {

}

/**

* 全站乱码解决

*/

public void doFilter(ServletRequest request, ServletResponse response,

FilterChain chain) throws IOException, ServletException {

HttpServletRequest req = (HttpServletRequest) request;

chain.doFilter(new MyRequest(req), response);

}

class MyRequest extends HttpServletRequestWrapper {

private HttpServletRequest request = null;

private boolean isEncode = false;

public MyRequest(HttpServletRequest request) {

super(request);

this.request = request;

}

@Override

public Map getParameterMap() {

if (request.getMethod().equalsIgnoreCase("post")) {

try {

request.setCharacterEncoding(config.getInitParameter("encode"));

return request.getParameterMap();

} catch (UnsupportedEncodingException e) {

e.printStackTrace();

}

} else if (request.getMethod().equalsIgnoreCase("get")) {

try {

Map<String, String[]> map = request.getParameterMap();

if(!isEncode){

for (String key : map.keySet()) {

String [] vs = map.get(key);

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

String v = vs[i];

v = new String(v.getBytes("iso8859-1"), config.getInitParameter("encode"));

vs[i] = v;

}

}

isEncode = true;

}

return map;

} catch (Exception e) {

e.printStackTrace();

}

}

return super.getParameterMap();

}

@Override

public String[] getParameterValues(String name) {

if(getParameterMap().get(name)==null)return null;

return (String[])getParameterMap().get(name);

}

@Override

public String getParameter(String name) {

if(getParameterMap().get(name)==null)return null;

return ((String[])getParameterMap().get(name))[0];

}

}

public void init(FilterConfig filterConfig) throws ServletException {

this.config = filterConfig;

}

}

package com.itheima.web;

import java.io.IOException;

import java.util.Map;

import javax.servlet.ServletException;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

public class EncodeTestServlet extends HttpServlet {

public void doGet(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException {

String vs = request.getParameterValues("username")[0];

System.out.println(vs);

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

System.out.println(value);

}

public void doPost(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException {

doGet(request, response);

}

}

<filter>

<filter-name>encode</filter-name>

<filter-class>com.itheima.filter.EncodingFilter</filter-class>

<init-param>

<param-name>encode</param-name>

<param-value>utf-8</param-value>

</init-param>

</filter>

<filter-mapping>

<filter-name>encode</filter-name>

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

</filter-mapping>

)禁止浏览器缓存所有动态页面的过滤器:

有 3 个 HTTP 响应头字段都可以禁止浏览器缓存当前页面,它们在 Servlet 中的示例代码如下:

response.setDateHeader("Expires",-1);

response.setHeader("Cache-Control","no-cache");

response.setHeader("Pragma","no-cache");

并不是所有的浏览器都能完全支持上面的三个响应头,因此最好是同时使用上面的三个响应头。

Expires数据头:值为GMT时间值,为-1指浏览器不要缓存页面

Cache-Control响应头有两个常用值:

no-cache指浏览器不要缓存当前页面。

max-age:xxx指浏览器缓存页面xxx秒。

package com.itheima.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.http.HttpServletResponse;

public class NoChachFilter implements Filter {

public void destroy() {

// TODO Auto-generated method stub

}

public void doFilter(ServletRequest request, ServletResponse response,

FilterChain chain) throws IOException, ServletException {

HttpServletResponse resp = (HttpServletResponse) response;

resp.setDateHeader("Expires",-1);

resp.setHeader("Cache-Control","no-cache");

resp.setHeader("Pragma","no-cache");

chain.doFilter(request, response);

}

public void init(FilterConfig filterConfig) throws ServletException {

// TODO Auto-generated method stub

}

}

<filter>

<filter-name>nocach</filter-name>

<filter-class>com.itheima.filter.NoChachFilter</filter-class>

</filter>

<filter-mapping>

<filter-name>nocach</filter-name>

<url-pattern>*.jsp</url-pattern>

</filter-mapping>

)控制浏览器缓存页面中的静态资源的过滤器:

场景:有些动态页面中引用了一些图片或css文件以修饰页面效果,这些图片和css文件经常是不变化的,所以为减轻服务器的压力,可以使用filter控制浏览器缓存这些文件,以提升服务器的性能。

Tomcat缓存策略

对于服务器端经常不变化文件,设置客户端缓存时间,在客户端资源缓存时间到期之前,就不会去访问服务器获取该资源 -------- 比tomcat内置缓存策略更优手段

* 减少服务器请求次数,提升性能

设置静态资源缓存时间,需要设置 Expires 过期时间 ,在客户端资源没有过期之前,不会产生对该资源的请求的

* 设置Expires 通常使用 response.setDateHeader 进行设置 设置毫秒值

package com.itheima.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.http.HttpServletResponse;

public class CacheFilter implements Filter {

public void destroy() {

// TODO Auto-generated method stub

}

public void doFilter(ServletRequest request, ServletResponse response,

FilterChain chain) throws IOException, ServletException {

HttpServletResponse resp = (HttpServletResponse) response;

resp.setDateHeader("Expires", System.currentTimeMillis()+3600l*24*30*1000);

chain.doFilter(request, response);

}

public void init(FilterConfig filterConfig) throws ServletException {

// TODO Auto-generated method stub

}

}

<filter>

<filter-name>cache</filter-name>

<filter-class>com.itheima.filter.CacheFilter</filter-class>

</filter>

<filter-mapping>

<filter-name>cache</filter-name>

<url-pattern>*.jpg</url-pattern>

<url-pattern>*.gif</url-pattern>

<url-pattern>*.png</url-pattern>

<dispatcher>REQUEST</dispatcher>

</filter-mapping>

)实现用户自动登陆的过滤器

在用户登陆成功后,以cookis形式发送用户名、密码给客户端

编写一个过滤器,filter方法中检查cookie中是否带有用户名、密码信息,如果存在则调用业务层登陆方法,登陆成功后则向session中存入user对象(即用户登陆标记),以实现程序完成自动登陆。

在访问一个站点,登陆时勾选自动登陆(三个月内不用登陆),操作系统后,关闭浏览器;过几天再次访问该站点时,直接进行登陆后状态

在数据库中创建 user表

create table user (

id int primary key auto_increment,

username varchar(20),

password varchar(40),

role varchar(10)

);

insert into user values(null,'admin','123','admin');

insert into user values(null,'aaa','123','user');

insert into user values(null,'bbb','123','user');

自动登陆 :未登录、存在自动登陆信息、自动登陆信息正确

在用户完成登陆后,勾选自动登陆复选框,服务器端将用户名和密码 以Cookie形式,保存在客户端 。当用户下次访问该站点,AutoLoginFilter 过滤器从Cookie中获取 自动登陆信息

1、判断用户是否已经登陆,如果已经登陆,没有自动登陆的必要

2、判断Cookie中是否含有自动登陆信息 ,如果没有,无法完成自动登陆

3、使用cookie用户名和密码 完成自动登陆

<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

<html>

<head>

</head>

<body>

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

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

密码<input type="text" name="password"/>

<input type="checkbox" name="autoLogin" value="true" />一个月内自动登录

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

</form>

</body>

</html>

package com.itheima.autologin;

import java.io.IOException;

import javax.servlet.ServletException;

import javax.servlet.http.Cookie;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import org.apache.commons.dbutils.QueryRunner;

import org.apache.commons.dbutils.handlers.BeanHandler;

import com.itheima.domain.User;

import com.itheima.util.DaoUtil;

import com.itheima.util.MD5Util;

public class LoginServlet2 extends HttpServlet {

public void doGet(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException {

try{

//1.校验用户名密码是否正确

QueryRunner runner = new QueryRunner(DaoUtil.getSource());

User user = runner.query("select * from user where username=? and password=?", new BeanHandler<User>(User.class),request.getParameter("username"),MD5Util.md5(request.getParameter("password")));

if(user == null){

request.setAttribute("msg", "用户名密码不正确!!");

request.getRequestDispatcher("/login.jsp").forward(request, response);

return;

}else{

//用户名密码都正确,在session域中保存用户的登录状态

request.getSession().setAttribute("user", user);

//如果勾选过一个月内自动登录,发送cookie信息给浏览器,使浏览器保存用户名密码一个月

if(request.getParameter("autoLogin")!=null){

Cookie cookie = new Cookie("autologin",user.getUsername()+":"+user.getPassword());

cookie.setMaxAge(3600*24*30);

cookie.setPath(request.getContextPath());

response.addCookie(cookie);

}

response.sendRedirect(request.getContextPath()+"/autologin/homepage.jsp");

}

}catch (Exception e) {

e.printStackTrace();

}

}

public void doPost(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException {

doGet(request, response);

}

}

<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

<html>

<head>

</head>

<body>

<c:if test="${sessionScope.user == null}">

欢迎光临游客!<a href="${pageContext.request.contextPath }/autologin/login.jsp">登录</a>

</c:if>

<c:if test="${sessionScope.user != null}">

欢迎回来

</c:if>

</body>

</html>

package com.itheima.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.http.Cookie;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.dbutils.QueryRunner;

import org.apache.commons.dbutils.handlers.BeanHandler;

import com.itheima.domain.User;

import com.itheima.util.DaoUtil;

public class AutoLoginFilter implements Filter {

public void destroy() {

}

public void doFilter(ServletRequest request, ServletResponse response,

FilterChain chain) throws IOException, ServletException {

HttpServletRequest req = (HttpServletRequest) request;

//1.检查用户是否已经登录

if(req.getSession(false) == null || req.getSession().getAttribute("user")==null){

//2.如果用户没有登录过,则检查是否带了autologincookie

Cookie [] cs = req.getCookies();

Cookie findc = null;

if(cs!=null){

for(Cookie c : cs){

if(c.getName().equals("autologin")){

findc = c;

break;

}

}

}

if(findc != null){

//3.如果有autologin cookie,获取cookie的值,检查用户名密码是否正确

String username = findc.getValue().split(":")[0];

String password = findc.getValue().split(":")[1];

//4.如果用户名密码都正确,则自动登录一把

try{

QueryRunner runner = new QueryRunner(DaoUtil.getSource());

User user = runner.query("select * from user where username=? and password=?", new BeanHandler<User>(User.class),username,password);

if(user!=null){

req.getSession().setAttribute("user", user);

}

}catch (Exception e) {

e.printStackTrace();

}

}

}

//5.放行资源

chain.doFilter(request, response);

}

public void init(FilterConfig filterConfig) throws ServletException {

// TODO Auto-generated method stub

}

}

<filter>

<filter-name>autologinFilter</filter-name>

<filter-class>com.itheima.filter.AutoLoginFilter</filter-class>

</filter>

<filter-mapping>

<filter-name>autologinFilter</filter-name>

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

</filter-mapping>

)使用Filter实现URL级别的权限认证

)情景:在实际开发中我们经常把一些执行敏感操作的servlet映射到一些特殊目录中,并用filter把这些特殊目录保护起来,限制只能拥有相应访问权限的用户才能访问这些目录下的资源。从而在我们系统中实现一种URL级别的权限功能。

要求:为使Filter具有通用性,Filter保护的资源和相应的访问权限通过filter参数的形式予以配置。

)系统中存在很多资源,将需要进行权限控制的资源,放入特殊路径中,编写过滤器管理访问特殊路径的请求,如果没有相应身份和权限,控制无法访问

认证:who are you ? 用户身份的识别 ------------ 登陆功能

权限:以认证为基础 what can you do ? 您能做什么? 必须先登陆,才有身份,有了身份,才能确定可以执行哪些操作

package com.itheima.filter;

import java.io.IOException;

import java.util.Enumeration;

import java.util.HashMap;

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.HttpSession;

import com.itheima.domain.User;

public class PrivilegeFilter implements Filter {

private FilterConfig config = null;

private Map<String, String> map = new HashMap<String, String>();

public void destroy() {

// TODO Auto-generated method stub

}

public void doFilter(ServletRequest request, ServletResponse response,

FilterChain chain) throws IOException, ServletException {

//1.当前访问的资源是否需要权限(当前访问资源路径是否是map中具有的需要权限控制的路径的子路径)

HttpServletRequest req = (HttpServletRequest) request;

String uri = req.getRequestURI();

uri = uri.substring(config.getServletContext().getContextPath().length());

String privilege = null;

for(String name : map.keySet()){

if(uri.startsWith(name)){

privilege = map.get(name);

}

}

if(privilege == null){

//2.如果不需要权限,直接放行

chain.doFilter(request, response);

return;

}else{//3.如果需要权限,判断当前用户具有的权限和访问该资源需要的权限是否相匹配,如果匹配就放行,如果不匹配则提示

HttpSession  session = req.getSession(false);

if(session == null || session.getAttribute("user")==null){

throw new RuntimeException("请先登录");

}

User user = (User) session.getAttribute("user");

if(user.getRole().equals(privilege)){

chain.doFilter(request, response);

return;

}else{

throw new RuntimeException("没有对应的权限!!!!");

}

}

}

public void init(FilterConfig filterConfig) throws ServletException {

this.config = filterConfig;

Enumeration enumeration = config.getInitParameterNames();

while(enumeration.hasMoreElements()){

String name = (String) enumeration.nextElement();

String value = config.getInitParameter(name);

map.put(name, value);

}

}

}

<filter>

<filter-name>PrivilegeFilter</filter-name>

<filter-class>com.itheima.filter.PrivilegeFilter</filter-class>

<init-param>

<param-name>/admin</param-name>

<param-value>admin</param-value>

</init-param>

<init-param>

<param-name>/user</param-name>

<param-value>user</param-value>

</init-param>

</filter>

<filter-mapping>

<filter-name>PrivilegeFilter</filter-name>

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

</filter-mapping>

Servlet Filter 2的更多相关文章

  1. servlet/filter/listener/interceptor区别与联系

    转自:http://www.cnblogs.com/doit8791/p/4209442.html servlet.filter.listener是配置到web.xml中(web.xml 的加载顺序是 ...

  2. java Servlet Filter 拦截Ajax请求

    /** * 版权:Copyright 2016-2016 AudaqueTech. Co. Ltd. All Rights Reserved. * 描述: * 创建人:赵巍 * 创建时间:2016年1 ...

  3. Java-maven异常-cannot be cast to javax.servlet.Filter 报错, 原因servlet-api.jar冲突

    使用maven开发web应用程序, 启动的时候报错: jar not loaded. See Servlet Spec . Offending class: javax/servlet/Servlet ...

  4. 理解Servlet过滤器 (javax.servlet.Filter)

    过滤器(Filter)的概念 过滤器位于客户端和web应用程序之间,用于检查和修改两者之间流过的请求和响应. 在请求到达Servlet/JSP之前,过滤器截获请求. 在响应送给客户端之前,过滤器截获响 ...

  5. 使用Servlet Filter做Login checking

    1) 建一个Login Servlet: Login.java package com.my; import java.io.*; import javax.servlet.*; import jav ...

  6. Servlet Filter 1

    1.Filter简介 )Filter也称之为过滤器,它是Servlet技术中最实用的技术,WEB开发人员通过Filter技术,对web服务器管理的所有web资源:例如Jsp, Servlet, 静态图 ...

  7. Java Servlet Filter(转)

    做web开发的人对于Filter应该不会陌生,一直在很简单的使用,但是一直没有系统的总结一下,随着年纪的慢慢长大,喜欢总结一些事情,下面说说我对Filter的理解,官方给出的Filter的定义是在请求 ...

  8. JavaWeb三大组件(Servlet,Filter,Listener 自己整理,初学者可以借鉴一下)

    JavaWeb三大组件(Servlet,Filter,Listener 自己整理,初学者可以借鉴一下) Reference

  9. java.lang.ClassCastException: org.springframework.web.filter.CharacterEncodingFilter cannot be cast to javax.servlet.Filter

    java.lang.ClassCastException: org.springframework.web.filter.CharacterEncodingFilter cannot be cast ...

随机推荐

  1. c++ 字符窜切割

    std::vector<std::string> Tools::SplitStr(const char* baseStr, const char* rule) { log("ba ...

  2. Generic Netlink详解

    netlink socket是一种用于用户态进程和内核态进程之间的通信机制.它通过为内核模块提供一组特殊的API,并为用户程序提供了一组标准的socket接口的方式,实现了全双工的通讯连接. Netl ...

  3. 260. Single Number III

    Given an array of numbers nums, in which exactly two elements appear only once and all the other ele ...

  4. ZOJ 1078 Palindrom Numbers

    原题链接 题目大意:判断一个数是不是palindrom.不限于十进制,可以在任何进制下判断. 解法:还好,数字的范围不大,int类型足够搞定.方法就是从2进制开始,先把数字转换成2进制,判断是否对称, ...

  5. activiti 任务授权,把流程中当前任务授权个其他用户代为办理

    / * 授权代办 * @param serDoc / @Transactional(readOnly = false) public void authAgent(SerDoc serDoc) { S ...

  6. leetcode 150. Evaluate Reverse Polish Notation ------ java

    Evaluate the value of an arithmetic expression in Reverse Polish Notation. Valid operators are +, -, ...

  7. Apache的虚拟主机配置

    使用虚拟主机要先取消中心主机,注释掉DocumentRoot #DocumentRoot "/www/htdoc" 虚拟主机的单独配置: 用户认证 访问日志 错误日志 别名 脚本别 ...

  8. qt 获取当前主机的信息

    随着科技的发展,嵌入式技术在生活中越来越扮演者重要的角色,小到智能手环.手机,大到智能家居.汽车,都和嵌入式技术息息相关.在嵌入式系统中,拥有良好的用户界面会使产品更具市场优势.最近正好有机会用qt做 ...

  9. freeswitch 挂断前执行脚本

    通道变量名 api_hangup_hook 介绍在挂断时执行指定API命令 示例 <action application="set" data="api_hangu ...

  10. 10046事件跟踪会话sql

    背景知识: 10046 事件按照收集信息内容,可以分成4个级别: Level 1: 等同于SQL_TRACE 的功能 Level 4: 在Level 1的基础上增加收集绑定变量的信息 Level 8: ...