前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >javaWeb核心技术第十篇之Filter

javaWeb核心技术第十篇之Filter

作者头像
海仔
发布2019-08-27 09:42:40
3610
发布2019-08-27 09:42:40
举报
文章被收录于专栏:海仔技术驿站海仔技术驿站

版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。

本文链接:https://blog.csdn.net/zhao1299002788/article/details/100057364

代码语言:javascript
复制
Web中有三大组件(需要配置web.xml)
	servlet:服务器端的小程序.
	Filter(过滤器):运行在服务器,对请求的资源进行过滤,对响应进行包装.
	
经典案例:
	自动登录,网站全局编码,非法文字过滤...
	
	Filter编写流程:
	1.创建一个类,实现一个javax.servlet.Filter接口.
	2.配置web.xml
	
配置解释如下:
	<!-- 
		<filter>通知tomcat需要加载过滤器
			<filter-name>给filter命名,名称任意,web.xml中唯一.
			<filter-class>给filter的全限定类名,底层使用的是反射,实例化对象.
		<filter-mapping>给filter配置的映射.
			<filter-name>找刚才命名的配置
			<url-pattern>filter过滤的路径
	-->
	<filter>
		<filter-name>Demofilter</filter-name>
		<filter-class>com.baidu.a_filter.HelloFilter</filter-class>
	</filter>
	<filter-mapping>
		<filter-name>Demofilter</filter-name>
		<url-pattern>/DemoServlet</url-pattern>
	</filtr-mapping>
	
filter执行流程:
	http://localhost:80/day40/服务器 --> 在web.xml中找filter过滤器 --> 找到filter过滤的路径(拦截相关的服务类) --> 继续向上找找到命名的配置 -->通过配置映射 --> 向上找到filter命名 --> filter的全限定类名
	--> 找到filter实现类并执行doFilter方法 -->在chain.doFilter语句前面有语句体就先执行 --> 执行chain.doFilter(request,response) --> 通过这个方法放行找到对应的所拦截的服务器类 --> 在web.xml找到相对于的服务器类 -->
	执行相关的doGet或者doPost方法(chain.doFilter放行,相当于直接调用调用doGet方法)
	
登录:
	1.准备表单,表单需要:action method;
	2.准备Servlet:
		a:获得
			i. Username,password
		b:处理
			i. Service.findByNameAndPwd(username,password);
		   ii. 返回值User对象
		c.响应
			i:登录成功,要将user对象存入session中.
		   ii:登录失败,请求转发到msg.jsp提示错误.

自动登录分析:
	如果用户没登录,需要将user对象放入session-->自动登录.
	
自动登陆:
	1.页面增加一个复选框.
	2.登陆的Servlet在登陆成功后,获得用户是否勾选自动登陆.
	3.如果勾选,将数据放到cookie中,并响应给浏览器,但切记,持久化cookie
		cookie的目的:下一次,访问时,自动携带用户名和密码
	4.Filter
	5.1.获得Cookie的用户数据,不一定有用户数据,if放行 ,return
	6.2.如果有cookie数据,获得数据,并访问数据库,不一定能获得.
	7.3.如果不能获得,将cookie销毁(覆盖),放行return.
	8.4.如果能获得,自动登陆,将user放到session中,
	9.5.在整个filter最前面,需要获得session的user,因为如果已经登陆,不需要自动登陆.
	
总结:
	Filter 生命周期:
		生命周期:从一个类创建到销毁的过程.
		创建:服务器启动创建,只会被创建一次.
		销毁:服务器关闭销毁.
		FilterConfig:当前Filter的配置对象(没用)
	Filter过滤器链(FilterChain)
		多个过滤器组成过过滤器链.
		多个过滤器执行的顺序是web.xml中的配置顺序.
	Filter过滤器配置:
		Url-patter 表示过滤器拦截的路径.
		Servlet访问路径:
			1.完全匹配:/a/b/c/AServlet.
			2.不完全匹配(目录匹配) /a/b/c/*
			3.后缀名匹配  *.do  *.action  *.jsp
			4.缺省匹配 : / 以上三个没用匹配执行缺省匹配
			匹配顺序是:1>2>3>4.
		
		Filter的url-patter拦截路径,执行doFilter(request,response,filterChain)方法:
			1.完全匹配 : /a/b/c/AServlet
			2.不完全匹配(目录匹配) /a/b/c/*
			3.后缀名匹配  *.do  *.action  *.jsp
	Filter 的拦截方式dispatcher
	默认情况下,filter在jsp或者servlet之前执行.
	可以通过修改dispatcher的值,改变拦截的实际,一般默认即可.
	dispatcher的值有ERROR,FORWARD,INCLUDE,REQUEST.
	
处理网站字符集编码问题:
	每一个Servlet都需要处理乱码get和post都需要处理.
	
补充:动态代理:
	动态代理对方法进行增强,在程序运行时进行增强,动态:程序运行时动态创建  被创建的这个类称为代理类.
	代理:代理类.
	你 ==>> 供货商(增强,代理类) ==>> 厂商(目标类).
	public static Object newProxyInstance(ClassLoader loader,Class<?>[] interfaces,InvocationHandLer h);
	
	参数1:类加载器,动态创建的类,没有在内存中,需要类加载器,将类加载到内存形成Class对象.语法:当前类.class.getClassLoader() 固定.
	参数2:因为动态创建的类,但里面没用方法,代理需要的方法,从目标类中找语法: 目标类实例.getClass.getInterfaces() 固定.
	参数3:执行处理类,因为代理类是动态创建出来,通过参数2可以获得方法,但需要有实现方法的位置,增强的方法,写在执行处理类中.
		在执行处理中有invoke(Object proxy,Method method,Object[] args)方法,目标类每调用一次方法,执行处理类的invoke方法将会被执行一次.
		参数1:代理类的实例(没用)
		参数2:执行的方法
		参数3:执行方法的参数 
	
	动态代理:
	1.动态代理(在程序运行时,动态创建的类)的目的是为了增强方法.
	2.继承  必须明确  父类
	3.实现  必须明确  接口 
	4.装饰者设计模式  (静态代理:包装类是提前定义好的)
	5.字节码增强
	
	DoPost处理乱码:
	将request.setCharacterEncoding("utf-8")放到过滤器中,处理成功.
	doGet处理乱码:
	因为每一个参数都必须处理乱码,没有办法全部放在filter,因为不知道后续要获得什么参数.
	
处理乱码的工具类:

/**
 * 处理乱码的工具类
 *
 */
public class EncodingFilter implements Filter {


	public void destroy() {
		// TODO Auto-generated method stub
	}

	public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException {
		final HttpServletRequest request = (HttpServletRequest)req;
		HttpServletResponse response = (HttpServletResponse)resp;
		try {
			
			//处理post乱码
			request.setCharacterEncoding("utf-8");
			
			//处理响应
			response.setHeader("content-type", "text/html;charset=utf-8");
			
			//处理get乱码
			HttpServletRequest myRequest = (HttpServletRequest)Proxy.newProxyInstance(
					EncodingFilter.class.getClassLoader(), 
					request.getClass().getInterfaces(), 
					new InvocationHandler() {
						@Override
						public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
							
							//可以对getParameter进行增强   get提交方式
							
							//1.判断是get请求方式
							String requestMethod= request.getMethod();
							if("GET".equalsIgnoreCase(requestMethod)){
								//get提交  只对getParameter方法进行拦截
								String methodName = method.getName();
								if("getParameter".equals(methodName)){
									//get方式 并且 调用的getParameter方法
									//获得以前乱码 return 不乱码
									String tempValue = request.getParameter(args[0].toString());
									//如果没有获得数据 防止空指针
									if(tempValue == null){
										return null;
									}
									return new String(tempValue.getBytes("iso-8859-1"),"utf-8");
									
								}
							}
							
							//不需要增强
							return method.invoke(request, args);
						}
					});
			
			//放行
			chain.doFilter(myRequest, response);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	public void init(FilterConfig fConfig) throws ServletException {
		// TODO Auto-generated method stub
	}

}


@WebServlet注解用于标注在一个继承了HttpServlet类之上,属于类级别的注解。
用法形如:
@WebServlet("/DisplayHeader1")


// 扩展 HttpServlet 类
public class DisplayHeader extends HttpServlet {


// 处理 GET 方法请求的方法
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

其中 /DisplayHeader1 表示访问该servlet的 url 映射(地址)(此处为相对路径,即 “项目名称/DisplayHeader1” )。

该注解的作用等价于 在web.xml中配置的该servlet的<servlet-mapping>元素中<url-pattern>的配置,比如:
<servlet>
<!-- 类名 -->
<servlet-name>DisplayHeader</servlet-name>
<!-- 所在的包 -->
<servlet-class>test.DisplayHeader</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>DisplayHeader</servlet-name>
<!-- 访问的网址 -->
<url-pattern>/DisplayHeader2</url-pattern>
</servlet-mapping>
此时,访问如下两个路径的效果是一样的,不互斥:
http://localhost:8080/test/DisplayHeader1
和
http://localhost:8080/test/DisplayHeader2
此为在本机上进行的测试,其中test为项目名称。


WebServlet注解什么意思?
相当于在web.xml注册一个servlet.
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019年08月24日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
云开发 CloudBase
云开发(Tencent CloudBase,TCB)是腾讯云提供的云原生一体化开发环境和工具平台,为200万+企业和开发者提供高可用、自动弹性扩缩的后端云服务,可用于云端一体化开发多种端应用(小程序、公众号、Web 应用等),避免了应用开发过程中繁琐的服务器搭建及运维,开发者可以专注于业务逻辑的实现,开发门槛更低,效率更高。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档