文章目录
-
servlet规范来自于JAVAEE规范中的一种
-
作用
- 在servlet规范中,指定[动态资源文件]开发步骤
- 在servlet规范中,制定了Http服务器调用动态资源文件规则
- 在servlet规范中,指定Http服务器管理动态资源文件实例对象规则
-
servlet接口的实现类
- servlet接口来自于servlet规范下的一个接口 ,这个接口存在于http服务器提供的jar包
- tomact服务器下lib文件有一个servlet-api.jar存放servlet接口
- servlet规范中任务,http服务器能调用的[动态资源文件]必须是一个servlet接口实现类
/** * 子类-->父类-->A接口 * 此时子类也是A接口的实现类 * 抽象类的作用:降低接口实现类对接口实现过程的难度 * 将接口中不需要使用的抽象方法交给抽象类进行完成 * 这样我们的接口实现类只需要对接口需要方法进行重写 * Tomcat根据Servlet规范调用servlet接口实现类规则: * 1.Tomcat有权创建Servlet接口实现类实例对象 * Servlet oneServlet = new OneServlet(); * 2.Tomcat根据实例对象调用service方法处理当前请求 * oneServlet.service(); * 继承 继承 实现接口 * OneStrvlet------->(abstract)HttpServlet------>(abstract)GenericServlet-------->servlet接口 * 去掉了init() * destory() * getServletInfo() * getServletConfig() * *通过父类来决定在何种情况下调用子类的方法------[设计模式]------模板设计模式 * HttpServlet :servlet(){ * if(请求方式 == get){ * this.doGet(); * }else if(请求方式 == post){ * this.doPost(); * } * } * * 复习: * 重写规则 * 抽象类的作用 * 子类实现接口的规则 * this指向 * 继承规则 */
-
servlet接口实现类开发的步骤
-
创建一个java类继承Httplet父类,使之成为一个servlet接口的实现类
-
重写HttpServlet父类的两个方法.doGet()或者doPost().
get post
浏览器-------->oneServlet.doGet( ) 浏览器--------->oneServlet.doPost()
-
将Servlet接口实现类信息[注册]到tomcat服务器
【网站】—>【web】---->【WEB-INF】—>web.xml
<!--将Servlet接口实现类路径地址交给Tomcat--> <servlet> <servlet-name>mm</servlet-name> <!--声明一个变量存储servlet接口实现类类路径--> <servlet-class>com.bjpowernode.controller.OneServlet</servlet-class><!--声明servlet接口实现类类路径--> </servlet> Tomcat String mm = "com.bjpowernode.controller.OneServlet"
-
-
网站结构:
-
src:存放作为动态资源文件的java文件
-
web文件夹:存放作为静态资源文件[图片,html,css,js]
存放网站运行时依赖的jar[maysql驱动]
存放网站核心配置文件(web.xml)
-
web-INF:以来的jar[mysql]驱动/核心配置文件(web.xml)
-
lib:依赖的jar[mysql]驱动(需要自己建)
-
web.xml:通知Tomcat当前网站哪些java类是动态资源文件
-
servlet对象生命周期
-
网站中所有的Servlet接口实现类的实例对象,只能由Http服务器负责创建.
开发人员不能手动创建Servlet接口实现类的实现
-
在默认的情况下,Http服务器接受到对于当前Servlet 接口实现类的第一次请求时,自动创建这个Servlet接口实现类的实例对象
在手动配置的情况下,要求Http服务器在启动的时候自动创建某个Servlet接口的实现类的实例对象
-
在Http服务器运行期间,一个Servlet接口实现类只能被创建出一个实例对象
-
在服务器关闭的时候,会自动的将网站中所有的Servlet对象进行销毁
HttpServletResponse接口
- 介绍
- HttpServletRetention接口来自于servlet规范中,在tomcat中存在servlet-api.jar中
- HttpServletRetention接口实现类由Http服务器负责提供
- HttpServletRetention接口负责将doGet/doPost方法执行结果写入到响应体交给浏览器
- 开发人员习惯于将HttpServletRetention接口修饰的对象称为[响应对象]
- 主要功能
- 将执行结果以二进制的形式写入到[响应体]
- 设置响应头中【content-type】属性值,从而控制浏览器使用对应的编译器将响应体二进制数据编译为【文字,图片等】。
- 设置响应头中【localtion】属性,将一个请求地址赋给location从而来控制我们的浏览器想指定服务器发送请求
基础用法
String result = "Hello Wrold";
//---------响应对象将结果写入到响应体------------
//1.通过响应对象,向tomcat索要输出流
PrintWriter out= response.getWriter();
//2.通过输出流,将执行结果以二进制的形式写入到响应体中
out.write(result);
//---------响应对象将结果写入到响应体------------
-
设置响应头
//设置响应头content-type response.setContentType("text/html;charset = utf-8");
-
跳转地址(切换URL)
/* 浏览器在接受到响应包之后,如果发现响应头中含有location属性 , 将会自动通过地址栏向location指定网站发送请求 sendRedirect方法远程控制浏览器请求行为[请求地址,请求方式,请求参数] */ String result = "http://www.baidu.com:"; //通过响应对象,将地址赋值给响应头中的location属性 response.sendRedirect(result);//[响应头中 location= "www.baidu.com"]
HttpServletRequest接口
-
介绍:
- HttpServletRequest接口来自于servlet规范中,在tomcat中存在servlet-api.jar中
- HttpServletRequest接口实现类由Http服务器负责提供
- HttpServletRequest接口负责在doGet/doPost方法运行时读取http请求协议包中信息
- 开发人员习惯于将httpservletrequest接口修饰的对象称为[请求对象]
-
作用:
- 可以读取http请求协议包中[请求行中的信息]
- 可以读取保存在http请求协议包中的[请求头]或者[请求体]中请求参数信息
- 可以代替浏览器向http服务器申请资源文件的调用
基础用法
//1.通过请求对象,读取[请求行]中的[url]请求信息
String url= request.getRequestURL().toString();
//2.通过请求对象读取请求行中[method]信息
String method = request.getMethod();
//3.通过请求对象读取请求行中的uri信息
/*
URI:资源文件精准定位地址,在请求行中并没有URI这个属性
实际上是URL中截取的一个字符串
URI用于让HTTP服务器对被访问的资源文件进行定位
*/
String uri = request.getRequestURI();
System.out.println("URL" +url);
System.out.println("METHOD" +method );
System.out.println("URI" +uri);
读取参数值
//1.通过请求头对象获得[请求头]中所有请求参数名
Enumeration paramNames = request.getParameterNames();//将所有请求参数的名称保存到一个枚举对象来进行返回
while (paramNames.hasMoreElements()){
String paramName =(String)paramNames.nextElement();
//2.通过请求对象读取指定的请求参数的值
String value = request.getParameter(paramName);
System.out.println("请求参数名"+paramName+"请求参数值"+value);
}
POST乱码问题:
-
以get方式发送中文参数内容"你好世界"得到一个正常结果
-
以Post方式发送中文参数内容"你好世界"得到乱
问题的原因:
- 浏览器以get方式发送请求,请求参数保存在[请求头],在http请求协议包到达http服务器后,第一件事就是进行解码,请求头中的二进制的内容由我们TomCat负责解码,TomCat9.0默认使用的是[utf-8]字符集,可以解释一切国家的文字
- 浏览器以Post方式发送请求,请求参数保存在[请求体],在http请求协议包到达http服务器后,第一件事就是进行解码,请求体二进制内容由当前请求对象(request)负责解码,request默认使用[ISO-8859-1]字符集,此时如果请求图参数的内容是中文,将无法解码只能得到乱码
解决方案:
-
在Post请求方式下,在读取请求体内容之前,应该通知请求对象使用utf-8字符集对请求体内容进行一次重新解码
-
//通知请求对象,使用utf-8字符集对当前请求体二进制内容进行一次重新解码 request.setCharacterEncoding("utf-8"); //通过请求对象来读取[请求体]中的参数信息 String value = request.getParameter("username"); System.out.println("从请求体中得到参数值"+value);
请求对象和响应对象生命周期
- 在http服务器接收到浏览器发送的[http请求协议包]之后,自动为当前的[http请求协议包]生成一个[请求对象]和一个[相应对象]
- 在http服务器调用doGet()/doPost()方法时,负责将[请求对象]和[相应对象]作为实参传递到方法,确保doGet/doPost的正确执行
- 在http服务器准备推送http响应协议包之前,负责将本次请求关联的[请求对象]和[相应对象]销毁.
- [请求对象]和[响应对象]生命周期贯穿一次请求的处理过程中
- [请求对象]和[响应对象]相当于用户在服务端的代言人
实战图
用户的查询功能
登录流程图
欢迎资源文件
-
前提:用户可以记住网站名称,但是不会去记住网站的资源文件的
-
默认欢迎资源文件
用户发送了一个针对某个网站的[默认请求]时,此时由http服务器自动从当前网站返回的资源文件
正常请求:http://localhost:8080/myweb/index.html
默认请求:http://localhost/myweb/
-
Tomcat对于默认欢迎资源文件定位规则
- 规则位置:Tomcat安装位置/conf/web.xml
-
设置当前网站的默认欢迎资源文件的规则
-
规则位置:网站/web/WEB-LNF/web.xml
-
规则命令:
<welcome-file-list> <welcome-file>login.html</welcome-file> </welcome-file-list>
-
网站设置自定位默认文件定位规则,此时Tomcat自带的定位规则将失效
-
状态码
-
介绍:
-
由三位数字组成的一个符号
-
Http服务器在推送响应包之前,根据本次请求处理情况,将Http状态码写入到响应包中的[状态行上]
-
作用:如果Http服务器针对本次请求,返回了对应的资源文件
通过Http状态码通知浏览器应该如何处理这个结果
如果Http服务器针对本次请求,无法返回对应的资源文件
通过Http状态码向浏览器解释不能提供服务的原因
-
-
分类:
-
组成:100—599:分为五个大类
-
1XX:最有特征的 100:通知浏览器本次返回的资源文件并不是一个独立的资源文件,需要浏览器在接受响应包之后,继续向Http服务器索要依赖的其他资源文件
-
2xx:最有特征的是200,通知浏览器本次返回的资源文件是一个完整独立的资源文件,浏览器在接收到后不需要索要其他关联文件
-
3xx:最有特征302,通知浏览器,本次返回的不是一个资源文件的内容,而是一个资源文件的地址,需要浏览器根据这个地址自动发起请求来索要这个资源文件
-
4xx:
- 404:通知浏览器,由于在服务端没有定位到被访问的资源文件,因此无法提供帮助
- 405:通知浏览器,在服务端已经定位到被访问的资源文件(servlet)但是这个Servlet对于浏览器采用的请求方式不能处理
-
5xx:
- 500: 这个servlet可以接收浏览器采用的请求方式,但是servlet在处理请求期间,由于java异常导致处理失败
-
多个Servlet之间调用的规则
-
前提条件:某些来自于浏览器发送请求,往往需要多个servlet协同处理,但是浏览器一次只能访问一个servlet,导致用户需要手动通过浏览器发起多次请求才能得到服务.这样增加用户获得服务的难度,导致用户放弃访问当前网站
-
提高用户使用感受规则:
无论本次请求涉及到多少个servlet,用户只需要手动的通知浏览器发起一次请求即可
-
多个servlet之间的调用规则:
- 重新定向解决方案
- 请求转发解决方案
重定向解决方案
原理图:
-
工作原理:用户第一次通过手动方式通知浏览器访问OneServlet.OneServlet工作完毕后,将TwoServlet地址写入到响应头中的location属性中,导致Tomcat将302状态码写入到状态栏中.浏览器接收到响应包后,会读到302状态,此时浏览器自动根据响应头中location属性发起第二次请求,访问TwoServlet去完成请求中剩余的任务
-
实现命令😗*response.sendRedirect(“请求地址”); **
将地址写入到响应包中响应头中location属性
//重定向解决方案 response.sendRedirect("/myweb/two");//地址格式:/网站名/资源文件名
-
特征:
- 请求地址:既可以把当前网站的内部的资源文件地址发送给浏览器,也可以把其他网站资源文件地址发送给浏览器(http://ip地址:端口号/网站名/资源文件名)
- 请求次数:浏览器至少发送两次请求,但是只有第一次请求是用户手动发送.后续请求都是刘看齐自动发送的.
- 请求方式:重新定向解决方案中,通过地址栏通知浏览器发起下一次的请求,因此通过重定向解决方案调用的资源文件接收方式一定是get
- 缺点:重定向解决方案需要在浏览器和服务器之间进行多次的往返,大量的事件消耗在往返次数上,增加用户等待时间
请求转发解决方案
原理图:
-
原理:用户第一次通过手动方式要求浏览器访问oneServlet.oneServlet工作完毕后,通过当前的请求对象代替浏览器,向Tomcat发送请求,申请调用TwoServlet.Tomcat在接受这个请求后,自动调用原来的TwoServlet来来完成剩余的任务
-
实现命令:请求对象代替浏览器向Tomcat发送请求
-
通过当前的请求对象去生成资源文件申请报告对象
RequestDispatcher report = request.getRequestDispatcher("/资源文件名");//一定要以"/"开头
-
将报告发送给Tomcat
report.forward(当前的请求对象,当前的相应对象)
//请求转发的方案 //1.通过当前请求对象生成资源文件申请报告对象 RequestDispatcher report = request.getRequestDispatcher("/two"); //将报告对象发送给tomcat report.forward(request,response);
-
-
优点;
- 无论本次请求涉及到多少个servlet,用户只需要手动通过浏览器发送一次请求
- Servlet之间调用发送在服务端计算机上,节省了服务端与浏览器之间的往返次数,增加处理服务速度
-
特征:
-
请求次数:在请求转发过程中只有一次请求
-
请求地址:只能向tomcat服务器申请调用当前网站站下资源文件地址
request.getRequestDispathcher("/资源文件名");不要写网站名
-
请求方式:在请求转发过程中,浏览器只发送了一个Http请求协议包.参与本次请求的所有的Servlet共享同一个请求协议包,因此这些Servlet接受的请求方式与浏览器所发送的请求方式是一致的
-
多个Servlet之间的数据共享实现方案
- 数据共享:OneServlet工作完之后,将产生的数据交给TwoServlet来使用,这样就叫做数据共享
- Servlet规范中提供了四种数据共享方案
- ServletContext接口
- cookie类
- HttpSession接口
- HttpServletRequest接口
ServletContext接口
-
介绍:
-
来自于servlet规范中的一个接口,在tomcat中存在servlet-api.jar
在tomcat中负责提供这个接口实现类
-
如果两个Servlet来自于同一个网站,彼此之间通过网站的servletcontext实例对象实现数据共享
-
开发人员习惯于将ServletContext对象成为[全局作用域对象]
-
-
工作流程图:
-
工作原理:每一个网站都存在一个全局作用域对象,这个全局作用域对象[相当于]一个map,这个网站中OneServlet可以将一个数据存入到全局作用域对象,当前网站中其他的Servlet此时都可以从全局作用域对象得到这个数据进行使用
-
全局作用域对象生命周期
- 在http服务器启动过程中,自动为当前网站在内存中创建一个全局作用域对象
- 在http服务器运行期间,一个网站只有一个全局作用域对象
- 在Http服务器运行期间,全局作用域对象一直处于存活状态
- 在http服务器准备关闭时,负责将当前网站中全局作用域对象进行销毁
全局作用域对象生命周期贯穿网站整个运行期间
-
命令实现:[同一个网站]OneServlet将数据共享给TwoServlet
OneServlet public void doGet(HttpServletRequest request,HttpServletResponse response){ //1.通过[请求对象]向Tomcat索要当前网站下的[全局对象] ServletContext application = request.getServletContext(); //2.将数据添加到全局作用域对象作为[共享数据] application.setAttribute("key1",数据); //相当于集合的add方法 }
TwoServlet public void doGet(HttpServletRequest request,HttpServletResponse response){ //1.通过[请求对象]向Tomcat索要当前网站下的[全局对象] ServletContext application = request.getServletContext(); //2.从全局作用域对象得到指定关键字对应数据 Object 数据 = application.getAttribute("key1"); }
Cookie
- Cookie来自于Servlet规范中的一个工具类, 存在于Tomcat提供的Servlet-api.jar中
- 如果两个Setvlet来自于同一个网站,并且为同一个浏览器/用户提供服务,此时可以借助于cookie对象进行数据共享
- cookie存储当前用户的私人数据,在共享数据过程中提高我们的服务质量,
- 在现实生活场景中,Cookie相当于用户在服务端得到[会员卡]
工作原理图:
**核心原理:**用户通过浏览器第一次向myweb网站发送请求申请OneServlet.OneServlet在运行期间创建一个Cookie存储与当前用户相关数据.OneServlet工作完毕后,【将Cookie写入到响应头】交还给当前浏览器
浏览器在收到响应包之后,将cookie存储在浏览器缓存一段时间在之后,用户通过【同一个浏览器】再次向【myweb】网站发送请求申请TwoServlet时,【浏览器需要无条件的将myweb网站之前推送过来的Cookie写入到【请求头】中】发送过去。此时TwoServlet在运行时,就可以通过读取请求头中cookie信息,得到OneServlet提供的共享数据
-
实现命令:同一个网站与twoServlet借助于Cookie实现数据共享
OneServlet{ public void doGet(HttpServletRequest request,HttpServletResponse response){ //1.创建一个cookie对象,保存共享数据(当前用户数据) Cookie card = new Cookie("key1","value1"); //cookie也是相当于一个map,一个cookie只能存放一个键值对 //这个键值对中的key和value只能是String,键值对中的key不能是中文 //2.[发卡]将cookie写入到响应头,交给浏览器 resp.addCookie(card); } } 浏览器/用户:<----------响应包 [200] [cookie:key1=abc] [] [处理结果] 浏览器向myweb网站发送请求访问TwoServlet---->请求包[url:/myweb/two method:get] [请求参数:xxxx cookie key1 =abc; ] [] [] TwoServlet{ public void doGet(HttpServletRequest request,HttpServletResponse response){ //1.调用请求对象从请求头中得到浏览器返回的Cookie Cookie[] cookieArray = request.getCookie(); //循环遍历得到每一个cookie的key和value for(Cookie card:cookieArray){ card.getName();//读取key 'key1' String value =card.getValue();//读取value "abc" } } }
cookie的生命周期
-
cookie的销毁时机:
-
在默认的情况下,Cookie对象存放在浏览器的缓存中,因此只要将浏览器关闭 ,那么Cookie对象就被销毁掉
-
在手动设置的情况下,可以要求浏览器将接收到得Cookie存放在客户端计算机上硬盘上,同时需要指定Cookie在硬盘上的存活时间,在存活时间范围内,关闭浏览器,关闭客户端计算机,关闭服务器他都不会导致Cookie被销毁.在存活时间到达时,Cookie自动从硬盘上被删除
cookie.setMaxAge(60);//Cookie从 硬盘上存活1分钟
-
HttpSession接口
-
- HttpServlet接口来自于Servlet规范下得一个接口,存在于Tomcat中Servlet-api.jar,其相关的实现类由http服务器提供.
- 如果两个Servlet来自于同一个网站,并且为同一个浏览器/用户提供服务,此时借助HttpSession对象进行数据共享
- 开发人员习惯于将HttpSession接口修饰为[会话作用域对象]
-
HttpSession与Cookie区别:[面试题]
-
存储位置是不同的:Cookie存储在客户端的计算机中
HttpSession存放在服务端的计算机
-
存储的数据类型也是不同的:
Cookie对象存储的共享数据类型只能是String
httpSession对象可以存储任意类型的共享数据Object
-
数据数量:
一个Cookie对象只能存放一个共享数据
HttpSesstion使用map集合存储共享数据,所以可以存储任意数量的共享数据
-
参照物不同:Cookie相当于客户在服务端的一个会员卡
HttpSession相当于客户在服务端的私人保险柜
-
-
命令实现:同一个网站下Oneservlet将数据传递给TwoServlet
```java
OneServlet{
public void doGet(HttpServletRequest request,HttpServletResponse response){
//1.调用请求对象向Comcat索要当前用户在服务端私人储物柜
HttpSession session = request.getSession();
//2.将数据添加到用户私人储蓄柜
session.setAttribute(“key1”,共享数据);
}
}
浏览器访问/myweb网站TwoServlet
TwoServlet{
public void doGet(HttpServletRequest request,HttpServletResponse response){
//1.调用请求对象向Comcat索要当前用户在服务端私人储物柜
HttpSession session = request.getSession();
//2.从会话作用域对象得到OneServlet提供的共享数据
object 共享数据 = session.getAttribute(“key1”,共享数据);
}
}
监听器接口
-
介绍:一组来自于Servlet规范下的接口,共有八个接口.在TomCat中存在serlvet-api.jar
-
监听器接口需要由开发人员亲自实现,由Http服务器提供jar包并没有对应的实现类
-
监听器接口用于监控[作用域对象生命周期变化时刻]以及[作用域对象共享数据变化时刻]
-
作用域对象:
-
在Servlet规范中,认为在服务端内存中可以在某些条件下为两个Servlert之间提供数据共享方案的对象,被称为[作用域对象]
-
在Servlet规范下的作用域对象:
ServletContext:全局作用域对象
HttpSession:会话作用域对象
HttpServletRequest:请求作用域对象
cookie是存储在客户端的,并不在服务端
-
-
监听器接口实现类开发规范:三步
- 根据我们监听的实际情况,选择对应监听器接口进行实现
- 重写监听器接口声明【监听事件处理方法】
- 在web.xml文件将监听器接口实现类注册到Http服务器
ServletContextListener接口:
-
作用:通过这个接口合法的检测全局作用域对象被初始化时刻以及被销毁使可
-
监听事件处理方法:
public void contentinitlize():在全局作用域对象被http服务器初始化被调用
public void contextDestroy():在全局作用域对象被Http服务器销毁时候触发调用
-
注册监听器
从web.xml中添加:
<!--将监听器接口实现类注册到Tomcat--> <listener> <listener-class>com.bjpowernode.listener.one</listener-class> </listener>
ServletContextAttributeListener接口:
-
作用:通过这个接口合法的检测全局作用域对象共享数据变化时刻
-
监听事件处理方法:
public void contextAdd():在全局作用域对象添加共享数据
public void contextReplaced():在全局作用域对象更新共享数据
public void contextRemove():在全局作用域对象删除共享数据
Servlet规范拓展----Filter接口(过滤器接口)
-
介绍:
- 来自于Servlet规范下的接口,在Tomcat中存在servlet-api.jar包
- Filter接口实现类由开发人员负责提供,Http服务器不再提供
- Filter接口在Http服务器调用Servlet之前,对Http服务器进行拦截
-
具体作用:
- 拦截Http服务器,帮助Http服务器检测当前请求的合法性
- 拦截Http服务器,对应该请求进行增强操作
-
Filter接口实现类开发步骤:三步
- 创建一个Java类实现Filter接口
- 重写Filter接口中doFilter方法
- web.xml将过滤器接口实现注册到Http服务器
2重写:
public class OneFilter implements Filter { @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { //通过拦截请求对象得到参数信息,从而得到来访用户的真实年龄 String age = request.getParameter("age"); if(Integer.valueOf(age)<70){ //将拦截对象和相应对象交换Tomcat,由Tomcat继续调用资源文件 chain.doFilter(request,response);//放行 }else{ //过滤器代替HttpServlet拒绝本次请求 response.setContentType("text/html;charset = utf-8"); PrintWriter out = response.getWriter(); out.print("<font color=red>访问不合法</font>"); } } }
3注册到Tomcat
<!--将我们的类文件的路径交给tomcat处理--> <filter> <filter-name>onefilter</filter-name><!--名字--> <filter-class>com.bjpowernode.filter.OneFilter</filter-class><!--地址--> </filter> <!--通知Tomcat在调用何种资源文件的时候需要被 当前过滤器拦截--> <filter-mapping> <filter-name>onefilter</filter-name> <url-pattern>/资源文件名</url-pattern> <!--哪个文件--> </filter-mapping>
如果要求Tomcat在调用某一个具体文件之前,来调用OneFilter拦截
/img/mm.jpg
如果要求Tomcat在调用某一个文件夹下的所有资源文件之前,来调用OneFilter拦截
/img/*
如果要求Tomcat在调用任意文件夹下的某种类型资源文件之前,来调用OneFilter拦截
*.jpg
如果要求Tomcat在调用任意文件之前,来调用OneFilter拦截
/*