一: servlet简介:
就是一个运行在web服务器上的小的java程序,用来接受和响应从客户端发送来的请求,通常使用HTTP协议;
servlet的生命周期; 何时创建: ,只要任何一次客户端向服务器发送请求,就会执行servlet;
servlet被构造的时候,init方法就会执行. 只被创建一次,在客户的第一次请求的时候,说明servlet是单例的
service刷新一次就请求一次,可执行多次
servlet被销毁的时候,destroy方法就会执行. 在服务器关闭的时候或项目移除的时候,才会执行
二: servlet执行过程:
用户第一次访问servlet的时候,服务器会创建一个servlet的实例,那么servlet的init方法就会执行,任何一次请求服务器都会创建
一个新的线程访问servlet中的service方法,在service方法内部根据不同的请求方式调用不同的doXXX的方法,
在服务器关闭的时候或项目移除的时候,destroy才会执行
三: servlet的相关配置
1. 服务一启动就创建servlet,在web.xml中<servlet></servlet>配置
<load-on-startup>2<load-on-startup>传入正整数,整数越小,被创建优先级越高,不要用1;服务器默认1
四: 相对路径和绝对路径的区别:
1.相对路径: 都是需要找位置相对关系, ../ 上一级 , ../../上两级 依次推理;(不好找)
2.绝对路径: 不需要找相对关系, 以/开始, 需要其他服务器的时候, 带协议的 "http://localhost/servle6,
访问自己服务器可以不带协议: /servlet6
①客户端路径: 一定要加工程名 例如:上面例子;
②服务器路径: 不需要加工程名 例如:从servlet5中找servlet6 直接写 /servlet6;
五.servletContext的功能:
servletContext; 是一个域对象. 作用范围: 整个web工程;
1.创建: 服务器启动时候,Tomcat服务器为每个web项目创建一个单独的servletContext对象;
2.销毁: 服务器关闭或项目移除时候,进行销毁;
3.作用:
①.获得全局的初始化参数, 全局参数的配置,任何一个servlet都可得到;
<context-param>
<param-name>username
<param-value>
然后读取用getInitparameter("username");或 getInitparameterNames();
②. 用来获得文件的MIME的类型,可以用来文件上传和下载的时候限制用户上传头像类型
getMimetype(文件名); 获得文件的类型
③. 作为域对象存储数据,用来读取web项目下的文件.
④.读取web工程下的文件
六 request的中文乱码问题:
1.get提交方式: 地址栏中会乱码,然后放在request缓存区;
1.修改Tomcat的字符集的编码;
2.使用URLEncoder和URLDecoder进行编码和解码的操作
3.使用String的构造方法:new String(参数.getBytes("ISO-8859-1"),"UTF-8");
2.post提交方式:post的参数实在请求体中,直接到达后台的servlet中的request中,
request也有缓存区request的缓存区也是ISO-8859-1编码
解决: request.setCharacterEncoding("UTF-8");
3. Request作为域对象存取数据;
作用范围就是一次请求的范围,这样只能用转发了
创建:客户端向服务器发送了一次请求后,就会创建一个request对象
销毁: 当服务器对这次请求做出了响应之后;
setAtrribute(); getAttribute();
七: response输出和乱码问题
1. 响应内容的方法; print其实调用了writer方法然后获得值变为字符串;
response.getwriter().print();
response.getoutputstream().writer(byte); 以上两个输出方法只能用一个;
2..字节流getoutputstream().writer(中文.bytes("UTF-8"));
乱码的问题: 不一定;主要是你服务器编码要和浏览器编码相同
解决: 设置中文转出字节数组取出的时候的编码 , 设置浏览器默认打开的编码
.response.setHeader(“Content-Type”,”text/html;charset=UTF-8”);
.response.getoutputstream().writer(中文.bytes("UTF-8"));
3.字符流 getwriter().print();
乱码的问题: 一定会乱码; 因为字符流有缓存区 , response的字符流缓存区默认编码ISO-8859-1;
解决: 设置response的字符流的缓存区的编码; 在输出之前
设置浏览器默认打开的时候采用的编码; 和1相同;
response.setContentType(“text/html;charset=UTF-8”);
八: session的使用:
1..使用session技术; 使用cookie本身是有大小和个数的限制. 但是session没有限制;cookie的数据保存在客户端,
session保存在服务器端.
2.session的执行原理: 基于cookie.
3.使用session: 全称httpsession; 是一个域对象,request.getsession();就会在服务器端开辟空间,利用set-cookie
带回sessionid , 不同的浏览器访问,都会开辟不同的空间.
4.session 是一个域对象,session什么创建, 服务器第一次调用getsession,什么时候销毁,关闭浏览器,就会销毁
保存sessionid的cookie销毁, 下次打开浏览器,就会创建一个新的session .
5. 销毁: 三种情况销毁session
①session过期,默认过期时间为30分钟
②非正常关闭服务器,如果正常关闭session序列化到硬盘
③手动调用session.invalidate();
作用范围: 多次请求(一次会话);
九:.servlet3.0技术:
没有web.xml
注解开发: @webServlet(urlPatterns="路径")
文件上传,
异步请求功能. 注解上面加上asyncsupported=true;
在servlet中加注解@Multipartconfig.作用是:可以使用 servlet3.0中的新方法
十: filter介绍:
1. filter过滤器的概述: 可以过滤从客户端向服务器发送的请求. 进行IP过滤,脏话过滤
2.编写一个类,实现filter接口,重写三个方法.在web.xml配置过滤器filter和filter-mapping和servlet类似,
在url-pattern中写拦截谁,从而实现拦截,在chain.dofilter(request,response)来放行
3.filter 创建和销毁: 服务器启动就会创建, 服务器关闭就会销毁.
4.Filterconfig:获取过滤器配置的名称,初始化参数,方法和servletconfig的方法相同.
5.filterchain: 过滤器链,拦截两遍.执行顺序: 与<filter-mapping>有关; 就一个放行方法.
6.在拦截器中,先判断session中是否有用户信息,有就放行,
如果没有,从cookie中获取, 到数据库查询,有,将用户信息存入到session,放行.
1.把request强转成httpservletrequest,先判断session里面,因为session里面也有信息,来显示昵称.
2.session中没有,针对浏览器没有关闭的情况,因为session依赖会话级别的cookie.查询cookie中,
有的cookie的值,切割字符串,封装数据,查询数据库.有,把信息放到session 中,放行.
3.配置过滤器, 7.过滤器相关的配置:两种拦截方式
<url-pattern>的配置: 完全路径匹配 :以/开始 如: /demo4/dmoe.jsp;
目录匹配, 扩展名匹配和servlet相同.
在filterMapping标签里面, <servlet-name>根据servlet的名称来拦截servlet.
< dispatcher> 可配置多个拦截,request:默认值 forward 转发 include 包含
.error (全局)错误页面跳转 注意:路径不要写固定的某一个路径
8.通用字符集编码的过滤器.
在filter中,增强request的getparameter方法.模板类httpservletrequestwrapper .class
实现了httpservletrequest 所有方法. 1.建立一个类继承模板类, 重写getParameter(){获得请求方式,然后判断.处理编码} 2.在filter中,先把request强转,然后新建自己类.
9.编写通用性处理乱码问题;
编写一个过滤器, (request.getclass.getclasLoader)
在invoke方法内,判断增强的方法是否是getparameter();然后得到请求方式request.getmethod();
判断请求方式,运行处理的方法,得到值进行处理, m.invoke(对象引用,);
十一: 读取web工程下的文件 :
java项目可以直接用绝对路径读取, 但web项目是在服务器上;主要问题就是文件路径问题
1.传统的java项项目的读取方法,相对路径是相对的Tomcat中bin路径
2. 在src下创建一个文件 ,然后在包下新建一个servlet
3.使用servletContext来读取web项目下的文件
public Inputstream getresourceAsStream(); 根据提供的路径读取文件
public string getRealPath(); 返回一个路径的磁盘的绝对路径
①.获得servletcontext对象,然后调用getresourceAsStream("/WEB-INF/classes/文件名");
然后用Properties读取文件内容
②.获得servletcontext对象,然后调用getRealPath("/WEB-INF/classes/文件名");得到绝对
路径,然后用传统的的读取方法,路径就写绝对路径/
4.自定义工具类读取文件;是一个java类, 用类的加载器来加载class文件,将class文件加载内存
自定义工具类.class.getClassLoader().getresourceAsStream();
5. 加载器的执行流程:
应用类加载器----->扩展类加载器----->系统类加载器
6.类加载器: 将class文件加载到JVM中执行文件.
1.引导类加载器: 加载是JDK中JRE的rt.jar,就是现有的java类
2.扩展类加载器: 加载*.jar,ExclassLoader
3.应用类加载器: 加载自定义类
这些类加载器如何保证类只会加载一次且不会重复加载. 有一个类加载器的全盘委托机制,3-2-1;
先委托到1加载器中,然后把自己负责的java类加载完成,然后再次依次执行.1-2-3;
十二. 完成文件的下载
1.Response 代表的响应对象, 从服务器向浏览器输出内容;
2.常用的API: 响应行: setstatus(int) 设置响应码,
响应头: addHeader();
addDateHeader(); addIntHeader(); 一个key对应多个value的响应头
setHeader(string name,string value);
setDateHeader(string name , long date),setIntHeader(); 一个key对应一个value的响应头
响应体:getoutputstream(); getwriter();
3.文件下载方式:
1. 超链接下载,直接将文件的路径写到超链接的href中, ---前提:文件类型,浏览器不支持,如果支持,直接就打开了;
2. 手写代码方式完成文件下载;设置两个头和一个流:
content-type :文件的MIME的类型
content-disposition: 以下载中的方式打开文件
inputstream :文件输入流
3.在业务层重定向到一个登陆.jsp页面,然后在跳转到文件下载页面
4.文件下载:
①.超链接下载:<a href="/day10/文件路径">直接下载
②.编码下载: <a href="/day10/servlet ? filename=hello.zip">
③.在servlet中 设置两个头和一个流:接收参数的时候要解码 第一个头: 告知浏览器文件的类型//下载的文件名要解码;
第二个头: 浏览器已下载的方式打开
输入流的路径:this.getServletContext().getRealPath("/download/"+parameter);
type= getMimetype(文件名); 得到类型
response.setHeader("Content-Type",type);
处理中文问题;
response.setHeader("Content-Disposition","attachment;参数名="+参数值);
④. 服务器输入流,(getRealPath("/文件夹/文件名");)读取文件,然后通过字节输出流下载;response.getoutputstream();
关闭输入流
5.中文文件下载
①.request 接受参数是中文的时候: new String(参数.getBytes("ISO-8859-1"),"UTF-8");
②. 在设置头信息下载的时候,下载文件名会乱码
IE浏览器下载中文文件时,采用URL的编码
Firefox浏览器................Base64的编码;
获得头信息String agent = request.getHeader("User-Agent");
十三: web监听器
1.web中的监听器: web中listener和filter是属于servlet规范中的高级的技术;
1. 监听器共分为三类八种(监听三个域对象)
2.事件源: servlet中三个域对象: servletcontext,httpsession ,servletRequest.
监听器: 自定义类实现八个接口事件源和监听器的绑定: 配置;
2.web中的监听器的分类
1.监听三个域对象的创建和销毁的监听器.servletcontextlistener httpsessionListener servletrequestlistener
2:监听三个域对象的属性变更的监听器(属性添加,移除,替换)
servletContextattributelistener httpsessionattributeListener servletrequestattributelistener
3.监听httpsession中的javaBean的状态改变(绑定,解除绑定,钝化,活化);
httpsessionBindingListener httpsessionactivationListener
3.web中的监听器的使用
编写一个类实现监听器的接口: 通过配置文件配置监听器
一类:监听三个域对象的创建和销毁的监听器.
1.实现 servletcontextlistener,重写初始化和销毁方法
2.在web.xml配置监听器: <listener> <listener-class>类的全路径
3.企业中的应用: 加载框架的配置文件,服务器一启动就加载 ,定时任务的调度; timer类, schedule(定时方法), timertask
4 .实现httpsessionListener, 重写两个方法;
在web.xml配置监听器: <listener> <listener-class>类的全路径
二类:监听三个域对象的属性变更的监听器(属性添加,移除,替换)
1.servletcontextattributelistener监听servletcontext对象属性变更
attributeAdded(); attributeremoved() attributereplaced();
自定义实现上面接口,重写方法,配置监听器 <listener> <listener-class>类的全路径
在jsp页面session.setattribute(); 添加 替换,删除
2. httpsessionattributeListener 监听httpsession对象属性变更 ,方法和1相同
3.servletrequestattributelistener 监听httpsession对象属性变更, 方法同上
三类: 监听httpsession中的javaBean的对象的状态改变(绑定,解除绑定,钝化,活化);
不用配置,作用在JavaBean上,javaBean可以自己感知
1. httpsessionBindingListener: 监听Httpsession中javaBean的绑定和解除绑
自定义类实现接口,重写两个方法,然后只要存在session域中,就绑定,然后从session域 中删除就是解除绑定
2. httpsessionactivationListener: 监听Httpsession中javaBean的钝化,活化
sessionDidactivate 反序列化从硬盘删除(活化) sessionwillactivate 序列化到硬盘上(钝化)
自定义类实现序列化接口,实现接口,重写方法.正常关闭服务器,就序列化到硬盘了
启动服务器,然后活化;
3.可以优化session: 使用session,如果每次30分钟,浪费服务器内存,这时候就可以把长时间
序列化到硬盘上.
通过配置<context>标签配置时session序列化.
1.配置在Tomcat的context.xml中配置一个<context>在Tomcat中所有的虚拟主机和虚拟路径都会按照这个配置执行
2.配置在Tomcat的locathost/context.xml中配置一个<context>只有localhost虚拟主机中的所有虚拟路径按照这个配置执行
3.配置在当前项目下的META-INF/context.xml中配置一个<context>只有这个工程才会被影响;
4.在META-INF新建context.xml 粘贴配置文件,配置文件中的maxidieswap:1
1分钟session会自动序列化到硬盘, directory: 序列化后存放的位置
使用sessionid作为文件名字.这个文件不会消失;
<Context>
<Manager className="org.apache.catalina.session.PersistentManager" maxIdleSwap="1">
<Store className="org.apache.catalina.session.FileStore" directory="it315"/>
</Manager>
</Context>