动态网页的开发:Servlet和JSP
Servlet其实就一个运行在web服务器上的小的Java程序,用于处理从web客户端发送的请求,并且对请求作出响应。
静态页面不能写循环,判断,SQL等语句。而Servlet就可以写。
使用Servlet:编写一个Java类实现Servlet的接口;配置Servlet
相关内容可以查JAVAEE的API中的Servlet
1.创建一个项目,在中建包建类
其他方法保持不变
2.配置这个类,在WEB-INF下的web.xml中配置
双击类名,右击copy全路径
前后的servlet-name必须要一致
启动服务器,打开浏览器:http://localhost:8080/web_test/hello
http://localhost:8080/web_test/+访问路径
执行流程:
Servlet的实现关系:
Servlet接口
|
|
GenericServlet类 通用的Servlet,是一个与协议无关的Servlet
|
|
HttpServlet类 Http专用的Servlet
SUN设计之初,是有野心,以后的互联网不仅仅只使用http协议,其他协议就可以通过GenericServlet实现。HttpServlet是一个与协议相关的Servlet是专门用来处理HTTP协议的请求。通常编写一个Servlet一般都会让这个Servlet*继承HttpServlet重写service方法*****(**不用再实现Servlet接口,因为会有很多用不到的方法也要重写**)*****。*
*查看源码可以知道,*****在service方法内部根据请求方式不同执行不同的doXXX的方法(get请求执行doGet方法,如果是post请求就会执行doPost方法)。****
*所以*****一般**继承了HttpServlet之后不需要重写service方法,只需要重写doGet和doPost方法即可。往往请求要处理的内容的代码都是一致的,所以需要让doGet和doPost相互调用可以简化编程**(**编码一次,另一个方法调用这个方法即可**)*****。*
Eclipse中使用Servlet模版:(不用在web.xml中修改完成配置,这样是自动完成了Servlet的配置)
右击new的时候选择新建Servlet;输入name(默认继承了HttpServlet)后,点击next;对Servlet进行配置:name和前面一致(一般不用改),URL mapping就是访问名字(右边edit可以修改),点击next;构造方法可以不用选,重写方法选择doGet和doPost方法。点击finish
生命周期:一个对象从创建到销毁过程
Servlet生命周期:Servlet对象从创建到销毁的过程
Servlet中有****init,service,destroy****方法,这几个方法称为是Servlet生命周期相关的方法
Servlet是在第一次被访问的时候会被实例化,只要Servlet一被实例化那么Servlet中的init方法就会执行(init只会执行一次,Servlet是单例的)。
任何一次从客户端发送来的请求,那么Servlet中的service方法就会执行(在service方法的内部根据请求的方式不同调用不同doXXX方法)。
当Servlet从服务器中移除或者服务器关闭的时候Servlet对象被销毁,里面的destroy方法就会执行,然后垃圾回收就会将其回收掉(在servers下点红色方框关闭服务器,在控制台下的红色方框是强制退出,不是服务器)
Servlet的启动时加载:Servlet对象是第一次被访问的时候会被创建的,init方法就会执行。假设在init方法中做了一些比较耗时的操作(比如:加载了一些配置文件并且解析可能需要花费3秒钟)。第一个用户第一次访问这个Servlet的时候,需要等待3秒钟,这样会使体验感很差,所以要改为启动时加载。
Servlet默认是在第一次访问的时候创建的对象,现在通过一个配置将Servlet的实例化的过程放在服务器启动的时候(****让服务器启动的时候创建Servlet的对象****)。如果现在这样做那么之前花费的时间就会在服务器启动的时候一起花费掉了。对于用户来讲就不需要额外花费这个时间。
在web.xml中配置。值越小,优先级越高。有一个默认的Servlet启动优先级为1,所以配置的最高为2。(可以在Tomcat的conf下的web.xml中查看文档)
Servlet的访问路径的配置:
1.完全路径匹配:以 / 开始 比如:/ServletDemo1 /aaa/ServletDemo2
2.目录匹配:以 / 开始,以 /结束 比如:/ /aaa/* /aaa/bbb/*
3.扩展名匹配:不能以 / 开始,以开始 比如:.action *.do *.jsp
(*代表的是任意字符)
访问的优先级:完全路径匹配 > 目录匹配 > 扩展名匹配
如果输入的三个都匹配,比如:/aaa/ServletDemo2.do 实际会先进行完全路径的匹配,再进行目录匹配,最后是扩展名匹配。
ServletConfig对象:
ServletConfig用来获得Servlet的相关的配置的对象。(init方法中可以传递这个对象)
获得ServletConfig对象:
ServletConfig对象的API:
获得Servlet的初始化参数(值和名字)
获得ServletContext对象
获得Servlet的名称
配置初始化参数的例子:在web.xml中添加配置:
实现:
ServletContext对象:
ServletContext:Servlet的上下文对象。ServletContext对象对Servlet之前和之后的内容都知道。这个对象一个web项目只有一个。在服务器启动的时候为每个web项目创建一个单独的ServletContext对象。
作用:
1.用来获取web项目信息:因为一个web项目只有一个ServletContext对象,所以这个对象对整个项目的相关内容都是了解的
获取文件的MIME类型:文件上传和下载的时候会用到这个方法(这些类型都可以在conf下的web.xml中找到)
获取web项目请求工程名:
获取web项目的初始化参数:全局的参数
可以在前面配置全局的初始化参数(原来的局部配置参数是在Servlet标签内部配置的,现在配置全局的话在最前面配置)
2.读取web项目下的文件:之前使用IO流就可以读取文件(java项目中)。现在是一个web项目,web项目需要发布到tomcat下才能访问的。获取web项目下的文件如果使用传统的IO就会出现问题(原因:路径中使用的是相对路径,相对的是JRE环境,是Tomcat的bin路径)。
使用getServletContext的getResourceAsStream方法或者getServletContext的getRealPath方法
以/开头的都是相对路径。
3.作为域对象存取数据:
域对象:指的是将数据存入到域对象中,这个数据就会有一定的作用范围。域指的是一定的作用范围。
作为域对象的API:
存入数据的方法:
获取数据的方法:
移除数据的方法:
作用范围:
ServletContext是在服务器启动的时候为每个web项目单独创建一个ServletContext对象。当web项目从服务器中移除,或者是关闭服务器的时候ServletContext对象会被销毁。向ServletContext中保存的数据一直存在(当服务器关闭的时候ServletContext对象被销毁,然后里面数据才会失效)。*范围:整个web应用。*
例子:
在demo7中初始化的时候存入数据,发现访问demo7和8的时候都能访问到name的值,所以ServletContext的域对象是整个web应用。
开发的软件是B/S结构的软件,可以通过浏览器访问服务器的软件。
从浏览器输入一个地址访问服务器(将这个过程称为是请求:将浏览器向服务器发送的数据的封装)。服务器接收到请求,需要进行处理,处理以后需要将处理结果显示回浏览器端(将这个过程称为是响应:将服务器向浏览器发送数据的封装)。
Response对象:
Response关于响应行的方法:
设置响应的状态码:
200 正确
302 重定向
304 查找本地缓存
404 请求资源不存在
500 服务器内部错误
Response关于响应头的方法:
set开头的方法:针对一个key对应一个value的情况
举例:比如有一个头
content-Type:text/html setHeader(“content-Type”,”text/plain”);
最终得到头的结果:content-Type:text/plain
add开头的方法:针对一个key对应多个value的情况
举例:比如有一个
content-Type:text/html addHeader(“content-Type”,”text/plain”);
最终得到头的结果:content-Type:text/html,text/plain
Response关于响应体的方法:
向页面输出内容:字节和字符
Response其他的API:
重定向的方法:
设置浏览器打开页面时候采用的字符集:
设置响应字符流的缓冲区字符集:
服务器向浏览器回写Cookie的方法:
// 一般由服务器向浏览器的方法都能在response中找到
完成重定向:302状态码和Location响应头结合使用的效果
Demo1跳转到了Demo2
也可以使用response.sendRedirect(“/web01/ResponseDemo2”);替换重定向两句写法(实际开发中常用)
定时刷新效果:
在HTML中完成页面跳转:使用
这里的n秒后跳转的n是我们人为输入的定值,不能变化,所以我们可以用JS来完成读秒的效果:
需要n变化,先要对这个n加标签:i,再对
加方法onload=“load()”,然后编写scrip语句:
Response向页面响应中文(可能会出现乱码)
1.使用字节流响应中文
这里的“中文”这两个字可能会产生乱码:因为这个乱码的产生与中文转成字节数组及浏览器打开方式(打开的时候采用的默认字符集)有关
解决办法:将中文转成字节数组的时候和浏览器默认打开的时候采用的字符集一致即可
*2.使用字符流相应中文*
这里一定会产生乱码:字符流是有缓冲区的,response获得字符流,response设计默认的缓冲区编码是ISO-8859-1。这个字符集不支持中文的。
解决办法:设置response获得字符流缓冲区的编码和设置浏览器默认打开时候采用的字符集一致即可
字符流向页面响应中文,有一种简化的方式:
Request对象:开发的软件都是B/S结构软件,从浏览器向服务器提交一些数据,将这些内容进行封装就封装成了一个请求对象(Request对象)
1.获得客户机信息:
****获得请求的方式****:get还是post
获得请求路径后的提交参数的字符串:?xx=xxx&xxx=xxxxx
获得请求路径的URL和URI:URI范围比URL大(URI,统一资源标识符。URL,统一资源定位符。URI包括URL和URN。URL是全写,URI是名字)
****获得客户机的ip地址****:
2.获得请求头的方法:
获得一个key对应一个value的请求头:
获得一个key对应多个value的请求头:
3****.获得请求参数的方法****:
获得提交的参数(一个name对应一个value):
获得提交的参数(一个name对应多个value):
获得提交的参数,将提交的参数的名称和对应的值存入到一个Map集合中:
4.****作为域对象存取数据的方法****:
向request域中存数据:
从request域中获取数据:
从request域中移除数据:
Request对象其实就是从客户端浏览器向服务器发送的一次请求信息的封装。那么实质上向Request中所保存的数据有效期也是*一次请求范围。*
*一次请求范围:从客户端浏览器向服务器发送一次请求,服务器针对这次请求对浏览器作出响应。当服务器作出响应之后,请求对象就销毁了,保存在其中的数据就无效了。*
代码演示:
Request对象获取客户机信息:
Request对象接收表单请求参数:
编写一个静态页面:
在RequestDemo2中接收参数:
(数组无法直接输出,需要调用Arrays.toString()方法输出)
Request对象接收表单请求参数的中文乱码处理:
POST方式接收中文:
GET方式接收中文:(基本不用,因为一般表单提交都是用post方法)
从Servlet向JSP中跳转的方法:请求转发和重定向
1.请求转发:
通过ServletRequest对象获得RequestDispatcher对象
再根据RequestDispatcher中的方法进行请求转发
代码实现:
请求转发后访问Servlet的页面:
重定向:
通过HttpServletResponse对象中的以下方法实现重定向
代码实现:
重定向后访问Servlet的效果:
请求转发和重定向的区别:
请求转发是一次请求一次响应,而重定向是两次请求两次响应。
请求转发地址栏不会变化的,重定向地址栏发生变化。
请求转发路径不带工程名,重定向需要带工程名路径。
请求转发只能在本网站内部,重定向可以定向到任何网站。
*如果需要使用request进行值传递,需要通过请求转发完成。如果页面需要跳转到其他网站上必须使用重定向。*
因为request对象作为域对象的范围是一次请求,所以如果JSP需要获取request中的数据的话,只能用请求转发;如果用重定向的话,存入的值会获取不到,为null。