1.Servlet简介
Servlet:用java语言开发网页动态资源的技术。
特点:
1)servlet就是一个普通的java类,继承HttpServlet类 GenClassServlet类
2)一个普通的java类实现了Servlet接口,也叫Servlet程序。我们通常继承HttpServlet是为了创建一个基于http协议的servlet程序。
3)servlet程序交给tomcat服务器运行!!!
4)先要导入tomact中lib中导入servlet的jar包,不然不能调用
2.Servlet开发的过程
1)编写java类,继承HttpServlet
2)servlet程序交给tomcat服务器运行
2.1 把servlet的class字节码拷贝到WEB-INF/classes目录下
2.2 在web.xml文件中配置
HelloServlet
gz.itcast.a_servlet.HelloServlet
HelloServlet
/hello
3.Servlet的执行过程
前提:tomact启动之时会把全部的网站的web.xml加入进入到内存中
1.在浏览器中输入:http://localhost:8080/day01/hello (先去本地找hotes然后在找到对应的ip,没有在去寻找dns服务器)
2.获取url字符串,得到了需要访问的资源名称:/hello
3.在day01网址下的web.xml文件中搜索是否存在/hello匹配的url-pattern
4.匹配到url-pattern之后,再取出servlet-name的名称,再去web.xml信息中搜索一个和servlet-name的名称相同的servlet的配置信息
5.找打对应的servlet配置信息的servlet-class的,取出servlet-class的内容
6.创建helloservlet对象,调用HellServlet类的方法
4.Servlet的路径映射
url-pattern: 表示servlet的路径映射,也叫servlet访问名称。
url-patttern 浏览器输入URL
精确匹配 /demo1 http://localhost:8080/day10/demo1
/itcast/demo1 http://localhost:8080/day10/itcast/demo1
模糊匹配 /* http://localhost:8080/day10/任意路径
/itcast/* http://localhost:8080/day10/itcast/任意路径
*.后缀 http://localhost:8080/day10/任意路径.后缀
*.do
*.action
*.jsf
*.html)
注意:
1)url-pattern要么以/开头,要么以*开头 例如: itcast/demo1错误写法。
2)不能同时使用两种模糊匹配。例如: /itcast/*.html 错误写法
3)当多个url-pattern同时符合匹配规则,那么
3.1 精确匹配的url-pattern会优先被执行。(长的最像的url-pattern优先)
3.2 后缀名结尾的模糊匹配的url-pattern优先级最低!!!
5.Sevlet缺省路径
/ : 表示servlet的缺省路径。
在tomcat服务器中配置了一个DefaultServlet,叫默认Servlet,该默认Servlet的url-pattern就是/ 。默认Servlet的作用,用于解析web应用下的静态资源。
问题: 浏览器输入一个资源名称时,查找资源的顺序是如何?
1)首先,在当前web应用下的web.xml文件中查找是否有匹配的url-pattern
2)如果匹配到,执行对应的servlet(动态资源)
3)如果没有匹配到,就交给tomcat服务器的默认Servlet去处理
4)默认Servlet会到当前web应用下读取对应名称的静态资源文件。
5)如果读到对应的静态资源文件,那么就把内容返回给浏览器
6)如果读不到对应的静态资源文件,那么就返回404的错误页面。
结论: 先找动态资源,再找静态资源!!!!
6.Servlet的生命周期(重点)
4.1 生命周期
以前:以前的程序,java类,自己去new对象,自己去使用对象调用。
现在: sevlet程序。servlet的生命周期由tomcat服务器控制的。
servlet什么时候对象创建,什么销毁,什么时候调用什么方法???
4.2 Servlet的四个生命周期
构造方法: 在创建servlet对象时调用。只调用1次。证明servlet对象在tomcat服务器中是单实例的。
init方法:在创建完servlet对象后调用。只调用1次。
service方法: 在每次请求servlet时调用。调用n次。
destroy方法: servlet对象销毁时调用。只调用1次。tomcat服务器停止或web应用重新部署时调用
4.3 用伪代码模拟tomcat服务器如何调用servlet生命周期
浏览器输入: http://localhost:8080/day10/hello
得到字符串: gz.itcast.a_servlet.HelloServlet
1)tomcat服务器通过反射构造对象
1.1 得到字节码对象
Class clazz = Class.forName("gz.itcast.a_servlet.HelloServlet ");
1.2 构造对象
Object hello = clazz.newInstance(); --1) servlet的构造方法被调用
2)tomcat服务器调用init方法
2.1 得到init方法对象
Method m = clazz.getDeclareMethod("init",ServeletConfig.class);
2.2 执行方法
m.invoke(hello,config); --2)servlet的init方法被调用
3)tomcat服务器创建request和response对象,调用service方法
3.1 得到service方法对象
Method m = clazz.getDeclareMethod("service",HttpServletRequest.class,HttpServletRespnose.class);
3.2 执行方法
m.invoke(hello,request,response); --3)servlet的service方法被调
4)tomcat服务器停止或web应用重新部署时,tomcat服务器调用destroy方法
4.1 得到destroy方法对象
Method m = clazz.getDeclareMethod("destroy",null)
4.2 执行方法
m.invoke(hello,null); --4)servlet的destroy方法被调用
7.线程安全问题
servlet对象特点: 在tomcat服务器中是单实例多线程的!!!
5.1 引发Servlet多线程问题
多个线程同时操作了Servlet的成员变量(共享数据)。
5.2 避免Servlet并发问题建议
1)尽量不要在servlet类中使用成员变量。
2)如果要使用成员变量,那么就要给使用到成员变量的代码块加上代码锁,尽量缩小同步锁的范围,以避免因为同步产生代码并发执行效率降低的问题
8.Servlet自动加载
默认情况下,第一次访问servlet时创建servlet对象。创建对象的过程中会调用构造方法和inti方法。如果init方法的业务逻辑需要消耗比较长的时间,用户的第一次访问servlet时需要等待较长的时间。
改变servlet对象创建的时机: tomcat服务器启动的时候创建servlet对象。
LoadDemo2
gz.itcast.e_load.LoadDemo2
1
注意: 值写正整数。数值越大,创建对象的优先级越低
9.Servlet中的Init方法问题
在GenericServlet中,有两个init方法。
#有参数的init方法:该方法是servlet的四个生命周期方法中的一个。由tomcat服务器默认调用的初始化方法。在GenericServet的实现中,该方法会调用无参数的init方法。
#无参数的init方法:该方法的是Sun公司设计出来用于给开发者去覆盖,用于实现初始化逻辑的方法。
结论: 如果要编写servlet的初始化逻辑,只需要覆盖无参数的init方法即可!!!!
Servlet中重要对象:
1)HttpServletRequest对象:封装请求信息
2)HttpServletResponse对象:封装响应信息
3)ServletConfig对象: 封装一个servlet配置参数信息
4)ServletContext对象: 封装web应用环境信息
10. ServletConfig对象
10.1ServletConfig创建
ServletConfig对象是在创建完servlet对象之后,被创建出来。然后通过有参数的init方法传递到servlet中。
ServetConfig对象主要用于加载servlet配置参数信息。
10.2ServletConfig的API
java.lang.String getInitParameter(java.lang.String name) --得到参数
java.util.Enumeration getInitParameterNames()
ServletContext getServletContext() 得到servlet上下文对象
java.lang.String getServletName() 得到servlet名称
web.xml配置
ConfigDemo
gz.itcast.g_config.ConfigDemo
path
e:/bbs.txt
BBB
BBB's value
注意: servlet的配置参数只对当前servlet有效的!!对其他servlet是无效的!!
11 ServletContext对象(重点)
11.1ServletContext简介
ServletContext叫Servlet上下文对象,该对象表示当前的web应用环境信息。一个web应用只会创建一个ServletContext对象。
11.2ServletContext创建时机
ServletContext对象是在tomcat服务器加载完当前web应用后创建出来。ServletContext对象是作为ServletConfig对象成员变量传入servlet中。通过ServletConfig的getServletContext()方法得到ServletContext对象。
class ServletConfig{
ServletContext context;
getInitParameter()
getInitParameterNames();
getServletContext(){
return contex;
}
}
init(ServletConfig config){
context.getServletContext()
}
11.3ServletContext对象的API
得到web应用的上下文路径
java.lang.String getContextPath()
得到web应用的全局参数(所有servlet有效的!!)
java.lang.String getInitParameter(java.lang.String name)
java.util.Enumeration getInitParameterNames()
域对象相关的方法
void setAttribute(java.lang.String name, java.lang.Object object) 保存数据
java.lang.Object getAttribute(java.lang.String name) 得到数据
void removeAttribute(java.lang.String name) 清除数据
转发相关的
RequestDispatcher getRequestDispatcher(java.lang.String path)
web应用读取资源文件
java.lang.String getRealPath(java.lang.String path)
java.io.InputStream getResourceAsStream(java.lang.String path)
11.4得到web应用的上下文路径
java.lang.String getContextPath() 得到web应用上下路径。也就是部署到tomcat服务器上运行的web应用名称。
!11.4得到web应用的全局参数
java.lang.String getInitParameter(java.lang.String name)
java.util.Enumeration getInitParameterNames()
#web.xml
AAA
AAA's value
BBB
BBB's value
CCC
CCC's value
注意:全局参数对当前web应用下的所有servlet都有效的!!!
11.5域对象相关的方法
ServetContext对象是一个域对象!!!
域对象的作用: 主要用于保存数据和获取数据,用于在web应用中不同资源之间共享数据。
Servlet1 Servlet2
name=eric response.sendRedirect("/Servlet2?name=eric"); request.getParameter("name");
1)参数形式: 只能传递字符串数据
2)使用域对象形式:
在Servlet1中保存数据
在Servlet2中获取数据
域对象相关的方法:
void setAttribute(java.lang.String name, java.lang.Object object) 保存数据
java.lang.Object getAttribute(java.lang.String name) 得到数据
void removeAttribute(java.lang.String name) 清除数据
ServletContext域作用范围:
在当前的web应用中有效!!!
Servlet中所有域对象:
HttpServletRequest对象: request域
ServletContext对象: context域
HttpSession对象: session域
Jsp中域对象:
PageContext对象: page域
11.6转发相关的
RequestDispatcher getRequestDispatcher(java.lang.String path)
在servlet中实现页面跳转
请求重定向: response.sendRedirect(路径);
请求转发: request.getRequestDispacher(路径).forward(request,respone);
=======请求重定向 vs 请求转发 区别====
请求重定向:
1)地址栏改变,改变为重定向到地址
2)可以重定向到当前web应用,其他web应用,甚至是其他站点资源。
3)处于两次不同的请求。不可以使用request域对象来共享数据。
请求转发:
1)地址栏不会改变。
2)只能转发到当前web应用内部资源。
3)处于同一次请求。可以使用request域对象来共享数据
不同类型资源:
1)web应用内部资源。在当前web应用中的资源
2)其他web应用资源。在同一个站点下的其他web应用的资源。
3)站点外的资源。其他站点下的资源。
在web应用中写路径的方法:
1)先给路径加上 斜杠 /
2)思考: 写的路径给谁使用
给服务器使用 / 代表当前web应用的根目录下
给浏览器使用 / 代表当前的站点的根目录下
11.7web应用读取资源文件
路径:
绝对路径:e:/
相对路径: . 表示当前路径。表示java命令运行的目录。
注意:
1)在java项目中,ecplise工具,把java命令的运行根目录设置到项目根目录下。
2)在web项目中,. 表示从tomcat的bin开始,因为java命令从bin目录开始执行。
在web应用下读取资源文件方式:
java.lang.String getRealPath(java.lang.String path) 得到资源文件的绝对路径
java.io.InputStream getResourceAsStream(java.lang.String path)