大数据正式21
来源:互联网 发布:网络防御技术 编辑:程序博客网 时间:2024/06/05 10:45
大数据正式21
过滤器
- 定义
- Filter--过滤器
- 是Servlet中最实用的技术--JavaEE核心技术之一【Servlet+Filter+Listener】
- 可以拦截对资源的访问,拦截下来后可以是否允许通过时,在之前或之后做一些额外单位操作,所谓的拦截,其实是将代表请求的request对象和代表Response对象拦截下来;责任链模式【依次拦截、检查、和控制】
- 一个资源看可以被多个过滤器拦截
- 一个拦截器也可以拦截多个资源
- 图解
- 常见使用场景
- 基于URL的访问控制权限
- 全站乱码解决过滤器
- 自动登录
- 过滤敏感词
- 压缩响应
- 。。。
实现一个过滤器的步骤
写一个类实现Filter接口
- public void init(FilterConfig arg0) throws ServletException
- 初始化方法
- public void doFilter(final ServletRequest arg0, ServletResponse arg1,FilterChain arg2) throws IOException, ServletException
- 最核心的方法,在存活期间,会造成此方法的执行,在里面写逻辑代码即可
- public void destroy()
- 在过滤器被销毁之前调用,实现善后操作
- api
例
package com.peng.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;public class FilterDemo implements Filter { public void destroy() { System.out.println("destory"); } public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2) throws IOException, ServletException { System.out.println("kernel"); } public void init(FilterConfig arg0) throws ServletException { System.out.println("init"); }}
- public void init(FilterConfig arg0) throws ServletException
在web.xml中配置过滤器
<!-- 过滤器 --><filter> <filter-name>FilterDemo</filter-name> <filter-class>com.peng.filter.FilterDemo</filter-class></filter><filter-mapping> <filter-name>FilterDemo</filter-name> <url-pattern>/*</url-pattern></filter-mapping>
- filter的生命周期
- 在web应用启动的时候,会创建出应用中配置的过滤器对象,init方法进行初始化操作,之后一直存活,直到web应用销毁时,Filter跟着被销毁,再销毁之前执行destory方法的逻辑。在存活期间,进行对资源的拦截处理(doFilter方法),可以增加before和after方法,进行处理,一层一层进,一层一层出。
- 调用过程
- 如果一个资源被多个过滤器拦截,顺序为【mapping】配置的顺序
- 和Filter相关的对象
- FilterConfig过滤器配置对象
- init方法的参数
- 获取filter初始化参数
- 获取ServletContext对象
- 例子
<filter> <filter-name>FilterDemo</filter-name> <filter-class>com.peng.filter.FilterDemo</filter-class> <init-param> <param-name>key1</param-name> <param-value>value1</param-value> </init-param> <init-param> <param-name>key2</param-name> <param-value>value2</param-value> </init-param></filter>
public void init(FilterConfig arg0) throws ServletException { System.out.println("init"); Enumeration initParameterNames = arg0.getInitParameterNames(); while (initParameterNames.hasMoreElements()) { String name = initParameterNames.nextElement().toString(); System.out.println(name + "~" + arg0.getInitParameter(name)); }}
- 执行效果
- 执行效果
- FilterChain
- doFilter函数的参数
- 代表过滤器链
- 提供doFilter方法,执行之后的过滤器
public void doFilter(final ServletRequest arg0, ServletResponse arg1,FilterChain arg2) throws IOException, ServletException { // 过滤具体操作 // 释放资源--责任链模式,进行下一个过滤器执行操作 arg2.doFilter(arg0, arg1);}
- FilterConfig过滤器配置对象
Filter应用
全站乱码解决过滤器
请求乱码
GET方式
- 解决方案一:获取参数,解决乱码,再放回去
- 【有问题:Request方法没setParameter方法】
解决方案二:request中的数据包无法改变,只能改变其原始方法
- 继承【这里不能使用】:对已有对象的改造无效--因为对象是已经生成的,不能new出新的子类对象
可以使用装饰模式装饰request方法【这里能使用】:
- 【getParameter(String key)】
- 【getParameterValues()】
【getParameterMap】
package com.easymall.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.ServletContext;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 String encode = null; // 初始化过滤器 public void init(FilterConfig arg0) throws ServletException { // 获取ServletContext对象 ServletContext sc = arg0.getServletContext(); // 获取全局变量之编码 this.encode = sc.getInitParameter("encode"); } public void doFilter(final ServletRequest arg0, ServletResponse arg1, FilterChain arg2) throws IOException, ServletException { // 请求乱码-get、post一起解决 MyServletRequest msr = new MyServletRequest((HttpServletRequest) arg0); // 响应乱码 arg1.setCharacterEncoding(encode); arg1.setContentType("text/html;charset=" + encode); // 释放资源 arg2.doFilter(msr, arg1); } // 销毁过滤器方法 public void destroy() { } // 内部类装饰 class MyServletRequest extends HttpServletRequestWrapper { private ServletRequest request = null; private boolean hasNoteEncode = true; public MyServletRequest(HttpServletRequest request) { super(request); this.request = request; } // 改造方法 @Override public String getParameter(String name) { return this.getParameterValues(name) == null ? null : this .getParameterValues(name)[0]; } // 改造方法 @Override public Map<String, String[]> getParameterMap() { try { // 注:第一次map之后就对了,得处理--加一个标记 @SuppressWarnings("unchecked") Map<String, String[]> map = request.getParameterMap(); if (hasNoteEncode) { for (Map.Entry<String, String[]> entry : map.entrySet()) { String[] values = entry.getValue(); for (int i = 0; i < values.length; i++) { values[i] = new String( values[i].getBytes("iso8859-1"), encode); } } hasNoteEncode = false; } return map; } catch (UnsupportedEncodingException e) { e.printStackTrace(); throw new RuntimeException(e); } } // 改造方法 @Override public String[] getParameterValues(String name) { return this.getParameterMap().get(name); } }}
动态代理:通过代理对象来改造,并且通过代理对象访问被代理对象【这里能使用】:
package com.easymall.filter;import java.io.IOException;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;import java.lang.reflect.Proxy;import javax.servlet.Filter;import javax.servlet.FilterChain;import javax.servlet.FilterConfig;import javax.servlet.ServletContext;import javax.servlet.ServletException;import javax.servlet.ServletRequest;import javax.servlet.ServletResponse;import javax.servlet.http.HttpServletRequest;public class EncodingFilter implements Filter { private String encode = null; public void destroy() { } public void doFilter(final ServletRequest arg0, ServletResponse arg1, FilterChain arg2) throws IOException, ServletException { // 请求乱码-get-- 动态代理 // 将ServletRequest强转为HttpServletRequest final HttpServletRequest hsr = (HttpServletRequest) arg0; // get转码---动态代理方法 // 2、创建代理对象【固定】 // 参数一:被代理对象的类加载器。 实现方式:被代理对象.getClass().getClassLoader() // 参数二:被代理对象的接口数组。 实现方式:被代理对象.getClass().getInterfaces() // 参数三:处理类【用来增强方法的】 // 增强代码需要写在处理类的 invoke方法中即可 HttpServletRequest obj = (HttpServletRequest) Proxy.newProxyInstance( hsr.getClass().getClassLoader(), // 获取被代理类类加载器 hsr.getClass().getInterfaces(), // 获取被代理类实现类的接口 new InvocationHandler() { // 参数一: Object proxy 代理对象。没用 // 参数二: Method method 被代理对象的对应方法 // 参数三: Object[] args 被代理对象对应方法执行时,传递的实参 public Object invoke(Object arg0, Method method, Object[] arg2) throws Throwable { // 针对getParameter方法进行增强 if ("getParameter".equals(method.getName())) { // 获取提交方式 String m = hsr.getMethod(); if ("GET".equalsIgnoreCase(m)) { // 调用原来的方法 String invoke = (String) method.invoke(hsr, arg2); String re = null; try { // 转码 re = new String(invoke .getBytes("iso8859-1"), encode); } catch (Exception e) { } return re; } } return method.invoke(hsr, arg2); } }); // 请求乱码-post arg0.setCharacterEncoding(encode); // 响应乱码 arg1.setCharacterEncoding(encode); arg1.setContentType("text/html;charset=" + encode); // 释放资源 arg2.doFilter(obj, arg1); } public void init(FilterConfig arg0) throws ServletException { ServletContext sc = arg0.getServletContext(); this.encode = sc.getInitParameter("encode"); }}
- 解决方案一:获取参数,解决乱码,再放回去
POST方式
arg0.setCharacterEncoding(encode);
- 响应乱码
- 解决方案
arg1.setCharacterEncoding(encode);arg1.setContentType("text/html;charset=" + encode);
- 解决方案
自动登录
- 不加过滤器的登录
- 加入过滤器的登录
- 在处理用户登录时
- 首次登录时:判断是否勾选过自动登录
- 否--进入登录页面
- 是--保存到cookie【注意:密码的保密性】
- 再次访问时:
- 用户未登录+cookie信息账号密码正确-->>自动登录
- 已经登录过,判断账号密码是否正确-->>正确则进行登录
- 首次登录时:判断是否勾选过自动登录
代码示例
package com.easymall.filter;import java.io.IOException;import java.net.URLDecoder;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 javax.servlet.http.HttpServletResponse;import javax.servlet.http.HttpSession;import com.easymall.domain.User;import com.easymall.factory.BasicFactory;import com.easymall.service.UserService;public class AautologinFilter implements Filter { public void destroy() { } public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2) throws IOException, ServletException { HttpServletRequest request = (HttpServletRequest) arg0; HttpServletResponse response = (HttpServletResponse) arg1; // 只有未登录的用户 if (request.getSession(false) == null || request.getSession().getAttribute("user") == null) { // 只有携带Cookie才自动登录 Cookie[] cookies = request.getCookies(); Cookie autoCookie = null; for (Cookie cookie : cookies) { if ("autologin".equals(cookie.getName())) { autoCookie = cookie; } } if (autoCookie != null) { // 只有自动登录cookie保存的用户名正确才能自动登录 String username = URLDecoder.decode(autoCookie.getValue() .split("#")[0], "utf-8"); String password = autoCookie.getValue().split("#")[1]; UserService userService = BasicFactory.getFactory().getObj( UserService.class); if (userService.checkUsernameAndPassord(username, password)) { // 获取session HttpSession session = request.getSession(); // 在session中加入相应的标记 session.setAttribute("user", new User(-1, username, null, null, null)); // 回到主页 response.getWriter().write("登录成功!正在跳转。。。"); response.setHeader("refresh", "2;url=" + request.getContextPath() + "/index.jsp"); } } } else {// 已经登录过 // 跳转页面的话,会一直进过滤器哦。。。。 } // 放行资源 arg2.doFilter(arg0, arg1); } public void init(FilterConfig arg0) throws ServletException { }}
加密
- MD5加密算法
- 特点
- 任意大小的二进制经过MD5计算得到一个独一无二的128位二进制
- 相同的数据得到的MD5得到的结果相同
- 不相同的数据得到的MD5得到的结果不同
- 通常转化为16进制的32位数据
- 数据摘要,数据指纹----之后对比
- 应用
- 加密存储数据
- 文件的完整性
- 数字签名
- 。。。
- EasyMall中,应该加密的地方
- Cookie中自动登录的密码的存储
- 数据库中存放密码的记录,不应该铭文记录
- 特点
代码示例
package com.easymall.utils;import java.math.BigInteger;import java.security.MessageDigest;import java.security.NoSuchAlgorithmException;public class MD5Utils { /** * 使用md5的算法进行加密 */ public static String md5(String plainText) { byte[] secretBytes = null; try { secretBytes = MessageDigest.getInstance("md5").digest( plainText.getBytes()); } catch (NoSuchAlgorithmException e) { throw new RuntimeException("没有md5这个算法!"); } String md5code = new BigInteger(1, secretBytes).toString(16); // 为了防止不够32位,比如一些短的密码生成的数据可能不够32位,那么为了解决这的问题,在数据的前面进行补0操作 for (int i = 0; i < 32 - md5code.length(); i++) { md5code = "0" + md5code; } return md5code; }}
补充
阅读全文
1 0
- 大数据正式21
- 大数据正式1
- 大数据正式2
- 大数据正式3
- 大数据正式4
- 大数据正式5
- 大数据正式6
- 大数据正式7
- 大数据正式8
- 大数据正式9
- 大数据正式10
- 大数据正式11
- 大数据正式12
- 大数据正式13
- 大数据正式14
- 大数据正式15
- 大数据正式16
- 大数据正式17
- 欢迎使用CSDN-markdown编辑器
- Hibernate框架快速入门
- 消息摘要算法MAC实现与应用
- Qt在CPP文件中使用 Q_OBJECT宏
- CSS3(三)
- 大数据正式21
- LINUX C++ 按修改时间清理过期文件函数实现
- 小程序开发中踩的坑
- string类函数总结(转载)
- android如何设置一开始先加载LoginActivity(登陆)页面而不是MainActivity主页面
- java对象序列化和反序列化(serializing)
- 二维数组传参做形参
- 返回Json数据浏览器带上<pre></pre>标签解决方法
- 网络应用的Socket API编程的基本调用流程