listener:
监听器:
作用:监听web中的域对象ServletContext、ServletRequest、HttpSession
监听内容:
三个对象的创建与销毁
ServletContextListener
ServletRequestListener
HttpSessionListener
三个对象属性的变化
ServletContextAttributeListener
........
监听session中JavaBean的状态
注意:以下两个接口需要JavaBean去实现,让JavaBean自己感知自己的状态
HttpSessionActivationListener(监听钝化活化)
钝化:JavaBean从session中序列化到磁盘上(服务器正常关闭时发生,且因为是序列化到磁盘,需要JavaBean实现序列化接口Serializable)
活化:JavaBean从磁盘上加载到了session中(服务器再次启动时session活化)
注意:可以通过配置文件来修改session中的JavaBean什么时候钝化
方式一:直接修改tomcat的context.xml(作用于tomcat的所有项目)
方式二:在项目目录下找到meta-info目录,在该目录下新建一个context.xml,书写内容网上搜索
cookie和session:一个将数据存储在客户端浏览器,一个存储在服务器端(访问人次过多会开辟过多内存,因此需要钝化/活化技术)
HttpSessionBindingListener(对象与session绑定/解绑)
检测Javabean是否添加到session中,或者是否从session中移除
使用步骤:
1.编写一个类,实现接口
2.重写方法
3.编写配置文件
注意:listener全部是接口
filter:过滤器 过滤请求和响应
作用:
自动登陆
统一编码
过滤关键字
压缩响应信息
....
自动登陆
技术分析:
filter、cookie
1.用户表单提交,接收用户名和密码
2.调用service完成登录操作,返回值为user
3.判断user是否为空
若不为空,将user放入session中
判断用户是否勾选了自动登陆
若勾选了:
将用户名和密码写回浏览器
4.下次访问网站的时候
过滤器拦截任意请求
判断有无指定的cookie
有cookie,获取用户名和密码
调用service完成登录操作,返回user
当user不为空时,将user放入session中
注意:上述方式有一个问题,因为有请求时,会自动登陆,导致其它用户无法登陆,并且与登陆和注册相关的操作也不需要自动登陆
解决办法:判断session中有无user,有user时不使用自动登陆;判断请求资源是否和登陆、注册相关,如果相关也不使用自动登陆。
cookie写入中文:Java后台将中文utf-8编码,取出时用js再解码
Filter是一个接口
编写filter的步骤:
1.编写一个类
a.实现filter接口
b.重写方法
2.编写配置文件
a.注册filter
b.绑定路径
3.测试
Filter接口的方法:
init
doFilter
destroy
filter的生命周期
filter单实例多线程
filter在服务器启动的时候创建,调用init方法
请求来的时候创建一个线程,根据路径调用dofilter执行业务逻辑
当filter被移除或者服务器正常关闭的时候调用destroy方法,执行销毁操作
FilterChain:过滤链
过滤器拦截到响应url的请求后会先执行doFilter()方法中chain.doFilter()之前的代码,然后执行下一个过滤器或者servelt。紧接着执行chain.doFilter()之后的代码。
注:一个资源可能被多个过滤器匹配成功,多个过滤器的执行顺序是按照web.xml中filter-mapping的顺序执行的
<filter-mapping><dispatcher>:匹配哪种请求,默认是request
有几个固定值FORWARD、REQUEST,前者只作用于请求转发,且在两个请求中间执行,后者作用于请求,还有
ERROR:用服务器错误而发送过来的请求
<error-page>
<error-code>404</error-code>
<location>404.jsp</location>
////////////////////////////////////////////////////////////////
统一编码:
技术分析:在filter中对request进行加强,重写getParameter等方法
方法加强:
1.继承(要获取构造器)
2.装饰者模式(静态代理)
实现步骤:
1.要求装饰者和被装饰者实现同一个接口,或者继承同一个类(保证可以强转)
2.装饰者要有被装饰者的引用
3.对需要的方法进行加强
4.对不需要加强的方法调用原来的方法即可
注意:在实际使用装饰者模式时,大多数情况可能会出现被装饰者方法过多,如果直接修饰会导致书写很多无聊的调用原来方法的代码,针对这种情况,第三方提供的工具一般都有适配器模式,即提供一个xxxxWrapper类,装饰者直接继承该类,然后重写需要加强的方法即可。
3.动态代理
////////////////////////////////////////////
注解底层:
jdk5之后提供了一个特性,和类、接口同级
格式:@interface 注解名{}
作用:
1.编译检查
2.替代配置文件
3.定义注解(元注解)
4.分析代码(用到反射)
////////////////////////////////////////////////////////
Java中的三个注解
@Override:声明该方法是从父类上继承过来的,执行编译检查
@SuppressWarnings(value):抑制警告
@Deprecated:声明该方法不赞成使用
自定义注解:@interface 注解名{}
注解属性:
注解本质上是一个接口,接口中可以有常量和抽象方法,抽象方法在注解中称之为注解属性
注解属性类型;
基本类型
String
Class
Annotation
枚举
元注解:
定义在注解上的注解
@Retention:规定注解保留到什么阶段,有三个可选值,默认是SOURCE
SOURCE:只在代码中保留,在字节码文件中删掉
ClASS:在代码和字节码文件中都保留,会被VM丢弃
RUNTIME:所有阶段保留,可以通过反射读取注解信息
@Target规定注解作用在什么地方
TYPE:作用在类、接口等
METHOD:作用在方法
FIELD:作用在字段
文件上传:
servlet3.0
commons-fileupload
框架
/////////////////////////////////////////////////////////////////
servlet3.0
tomcat7开始支持3.0规范
3.0文件上传的前提条件:
浏览器端要求:
1.表单的提交方式必须是post
2.表单中必须有一个文件上传组件<input type="file" name=""/>
3.必须设置表单的entype=multipart/form-data
服务器端的要求:
servlet3.0中:
1.需要在servlet中添加注解@MultipartConfig
2.接口普通上传组件(除了文件上传组件):通过request.getParmerter接受
3.接收文件上传组件 request.getPart(name属性值)
getName();获取的name的属性值
4.获取文件名:
part.getHeader("Content-Disposition"):获取头信息,然后截取
////////////////////////////////
上传注意的问题:
1.名字重复:可以用时间戳或者UUID起一个随机名称然后在数据库中提供两个字段,一个字段用来存放文件真实名称,另一个字段用来存放文件存放的路径(随机名称所在路径)
2.文件安全:重要的文件可以存放在WEB-INFO或者是META-INFO或者是服务器创建的一个路径,不重要的文件直接放在项目路径下即可
3.文件存放的目录:如果都存放在一个目录下,当文件增多的时候会出现查询缓慢
方式一:按日期创建目录存放
方式二:按用户存放文件
方式三:规定目录存放的文件个数
方式四:随即目录
!注意:重新部署项目时,项目下的文件都没有了,记得备份
类加载器:
类加载:
编写的.java文件,jvm将其转换为.class文件放入内存中运行,生成.Class对象
类加载器的层次:
引导类加载器:加载rt.jar包
扩展类加载器:ext/*.jar
应用类加载器:自己编写的类
类加载器委托机制:
当一个类运行的时候,有可能有其它的类,应用类加载器询问扩展类加载器:你加载过这些类吗?
扩展类加载器询问引导类加载器:你加载过这些类吗?
引导类加载器:我查查,有一个是我负责的,我加载
扩展类加载:那我来查,有几个是我负责的,我加载,还有几个我之前加载完成了
应用类加载器:收到,剩余没有加载的我来加载
////////////////////////////////////////////////////////////////////////////////////////////
装饰者模式(静态代理)
实现步骤:
1.要求装饰者和被装饰者实现同一个接口,或者继承同一个类(保证可以强转)
2.装饰者要有被装饰者的引用
3.对需要的方法进行加强
4.对不需要加强的方法调用原来的方法即可
注意:在实际使用装饰者模式时,大多数情况可能会出现被装饰者方法过多,如果直接修饰会导致书写很多无聊的调用原来方法的代码,针对这种情况,第三方提供的工具一般都有适配器模式,即提供一个xxxxWrapper类,装饰者直接继承该类,然后重写需要加强的方法即可。
动态代理:
在项目运行时才创建一个代理对象,对方法进行增强(控制)
动态代理实现方式:
方式一:
jdk中的Proxy类,前提:必须实现接口
Object Proxy.newProxyInstance(ClassLoader loader,Class[] interfaces,InvocationHandler h)
参数说明:
ClassLoader:代理对象类加载器,一般我们使用的是被代理对象的类加载器
Class[]:代理对象需要实现的接口,一般我们使用的是被代理对象所实现的所有接口
InvocationHandler:执行处理类,在这里面对方法进行加强
InvocationHandler中只有一个方法Object invoke(object proxy,Method method,Object[] args)
参数说明:
proxy:代理对象
method:当前执行的方法
args:当前方法执行的时候需要的参数
返回值:当前method对象执行的返回值
方式二:
Spring中cglib,前提:继承类