回顾重点内容:
http协议:对浏览器与服务器之间数据传输内容格式规定!
1)http请求:
请求行
请求头
空行
实体内容
HttpServletRequest对象:获取请求信息
请求行:
请求方式:request.getMethod() get和post
请求资源:request.getRequestURI() / request.getRequestURL()
http协议: request.getProtocol();
请求头:
request.getHeader("name");
request.getHeaderNames();
实体内容:
requet.getInputStream();
通用的获取参数内容:
request.getParaemter("name") 一个值的参数
request.getParameterValues("name") 多个值的参数
request.getParameterNames() 参数名称列表
request.getParameterMap();
2)响应信息:
响应行
响应头
空行
实体内容
HttpServletResponse对象:修改响应信息
响应行:
response.setStatuts() 修改状态码
响应头:
response.setHeader("name","value")
response.setContentType("") 发送content-type响应头
实体内容:
response.getWriter().write(“字符内容”)
response.getOutputStream().write("字节内容");
servlet编程(原理)
大纲
1. servlet概念及相关接口简介
2. servet 执行过程
3. servlet路径映射
4. 缺省servlet —应用层面
5. servlet生命周期(重点) –理解层面
6. Servlet自动加载 –知识点
7. Servlet线程安全
8. servletConfig对象
9. Servlet相关接口详解
10. ServletContext对象
servlet的特点
1)sevlet是一个普通的java类,继承HttpServlet类。
2)其实实现了Servlet接口的java类,才是一个Servlet类。
3)servlet程序需要交给tomcat服务器运行!
浏览器: http://localhost:8080/day09/hello
步骤
前提: tomcat服务器启动时会把每个网站的web.xml文件加载进内存。
1)在浏览器输入;http://localhost:8080/day09/hello
2) 截取URL的字符串,得到需要访问的资源名称: /hello
3)在day09网站下的web.xml信息中搜索是否存在 /hello 匹配的url-pattern。
4)匹配到对应的url-pattern之后,取出当前映射信息中的servlet-name的名称,然后在web.xml信息中搜索是否存在一个相同名称的servlet-name的servlet配置信息。
5)找到对应的servlet配置信息之后,取出当前配置信息的servlet-class的内容
字符串: gz.itcast.a_servlet.HelloServlet
6)创建HelloServlet对象,然后调用HelloServlet类中的方法。
7)Servlet就把内容返回给浏览器用户。
<servlet-mapping>
<servlet-name>HelloServletservlet-name>
<url-pattern>/hellourl-pattern>
servlet-mapping>
url-pattern 浏览器访问
精确匹配 /hello http://localhost:8080/day09/hello
/itcast/hello http://localhost:8080/day09/itcast/hello
模糊匹配
/* http://localhost:8080/day09/任意路径
/itcast/* http://localhost:8080/day09/itcast/任意路径
*.后缀名 http://localhost:8080/day09/任意路径.后缀名
(*.action
*.do
*.html
。。。
)
注意:
1)要么以斜杠开头,要么*号开头 itcast>
非法的url-pattern: /itcast/*.html
2) 当多个url-pattern同时被匹配的情况下
2.1 精确匹配优先(长的最像的那个优先被匹配)
2.2 以后缀名结尾的url-pattern的优先级最低的
什么是缺省路径
在tomcat服务器内部配置了一个缺省路径 / , 这个缺省路径在tomcat服务器内部被一个缺省Servlet(DefaultServlet)匹配。缺省的这个Servlet的作用是专门用于处理所有网站中的静态网页。
浏览器: http://localhost:8080/day09/hello.html
一个路径在tomcat服务器的执行过程:
1)搜索day09下面的web.xml文件信息。搜索是否存在匹配的
2)匹配到对应的url-pattern,执行对应的Servlet程序。
3)如果没有匹配的url-pattern,就把这个请求交给tomcat服务器的DefaultServlet处理。
4)DefaultServlet会在day09的根目录下搜索是否存在一个名称叫hello.html的文件。
5)如果找到次文件, 那么DefaultServlet读取该文件内容返回给用户。
6)如果找不到次文件, 那么就给用户返回一个404状态码+404错误页面。
结论: 先找动态网页,再找静态网页。
研究servlet的生命周期,就是研究servlet这个在什么时候创建对象,在什么时候调用什么方法,在什么时候销毁对象。
以前: new Student();
现在: servlet是由tomcat服务器执行的生命周期。
构造方法: 创建servlet对象时调用,只调用1次,证明了sevlet是单例的。
init方法: 创建完对象之后调用。只调用1次。该方法用于初始化对象。
service方法: 在每次请求时调用,调用n次。该方法入口方法,我们的逻辑代码在这里被调用。
destory方法:在servlet对象销毁之后调用。只调用1次。重新部署网站或者停止服务器,servlet对象就会销毁了。
字符串: gz.itcast.a_servlet.HelloServlet
1)通过反射,创建HelloServlet的对象
1.1 得到HelloServlet的CLass对象
Class clazz = Class.forName("gz.itcast.a_servlet.HelloServlet ")
1.2 通过class对象调用构造方法
Object obj = clazz.newInstance(); 调用无参的构造方法。 --1)构造方法被调用
2)通过反射,调用init方法
2.1 得到init方法对象
Method m = clazz.getDeclaraeMethod("init",ServletConfig.class);
2.2 调用方法
m.invoke(obj,config); --2)init方法被调用
3)通过反射,调用service方法
3.1 得到service方法对象
Method m =
clazz.getDeclareMethod("service",HttpServletRequest.class,HttpServletResponse.class);
3.2 调用方法
m.invoke(obj,request,response); --3)service方法被调用
4)通过反射,调用destroy方法
4.1 得到destroy方法对象
Method m= clazz.getDeclareMethod('destroy",null);
4.2调用方法
m.invoke(obj,null); --4)destroy方法被调用
servlet在tomcat服务器中,是单实例多线程的
1)尽量不要使用成员变量,或者静态成员变量。
2)必须要使用成员变量,要么给使用了成员变量的代码块加同步锁,加锁的代码块的范围尽量缩小,因为有可能影响程序并发效率。
默认情况servlet对象是在第一次访问的时候创建。如果在这个servlet的构造方法或者init方法执行比较多的逻辑,那么第一次访问servlet的用户体验就不好!
那么能不能改变创建servlet的机制? 可以的,可以让servlet在服务器启动的时候自动加载。
<servlet>
<servlet-name>LifeDemoservlet-name>
<servlet-class>gz.itcast.c_life.LifeDemoservlet-class>
<load-on-startup>1load-on-startup>
servlet>
注意:load-on-startup中的整数值越大,创建的优先级越低!!!
init(ServletConfig) 这个有参数的init方法的作用就是Servlet的其中一个重要的生命周期方法。这个方法一定会被tomcat服务器调用。
init(): 这个无参的init方法的作用就是为了提供给开发者方便去覆盖,覆盖这个方法,可以在此方法编写初始化的逻辑。这个方法才是真的给开发者做初始化逻辑的方法。
小结:
Servlet开发中涉及的对象:
HttpservletRequest对象: 请求对象
HttpServletResponse对象: 响应对象
ServletConfig对象: servlet配置对象
ServletContext对象: servlet的上下文对象
servletconfig是配置对象,主要把servlet的初始化参数封装到这个对象中。一个网站中可能会存在多个ServletConfig对象,一个ServletConfig对象就封装了一个servlet的配置信息。
<servlet>
<servlet-name>ConfigDemoservlet-name>
<servlet-class>gz.itcast.f_config.ConfigDemoservlet-class>
<init-param>
<param-name>pathparam-name>
<param-value>e:/aaa.txtparam-value>
init-param>
servlet>
在servlet中获取初始化参数
config.getInitParameter("name"); 根据参数名称获取参数值
config.getInitParameterNames(); 获取所有参数名称
ServletConfig对象叫servlet上下文对象。 一个网站只会创建一个ServletContext对象。代表的是整个网站的环境信息。
this.getServletConfig().getServletContext(); 通过ServletConfig对象来获取到ServletContext对象的!!
伪代码:
ServletContext对象:启动的时候创建
ServletConfig对象:调用init方法之前创建的,在ServletContext对象创建之前
public ServletCofig{
ServletContext context;
public ServletConfig(context){
this.context=context;
}
public ServetContxt getServletContext(){
return;
}
}
ServletConfig config = new ServletConfig(context);
public MyServlet extends HttpSevlet{
publlic init(ServletConfig config){
SevletContext context= config. getServletContext();
}
}
1)获取web的上下文路径
java.lang.String getContextPath()
2)获取全局参数
java.lang.String getInitParameter(java.lang.String name)
java.util.Enumeration getInitParameterNames()
3)和域对象相关的
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就是我们学习的第一个域对象。
Servlet三个域对象:
ServletContext
HttpServletRequest
HttpSession
4)请求转发的
RquestDispatcher getRequestDispatcher(java.lang.String path)
在servlet跳转页面:
请求重定向:
1)地址栏会发送改变,变成重定向到的地址。
2)可以跳转到项目内的资源,也可以跳转项目外的资源
3)浏览器向服务器发出两次请求,那么就不能使用请求来作为域对象来共享数据。
请求转发:
1)地址栏不会改变。
2)只能跳转到项目内的资源,不能跳转到项目外的资源
3)浏览器向服务器发出一次请求,那么可以使用请求作为域对象共享数据。
5)读取web项目的资源文件
java.lang.String getRealPath(java.lang.String path)
java.io.InputStream getResourceAsStream(java.lang.String path)
java.net.URL getResource(java.lang.String path)
总结:
Servlet编程:
1)servlet编写
2)servlet的映射路径(精确匹配 模糊匹配 缺省路径???)
3)servlet的生命周期(构造方法,init方法,service方法,destroy方法)
4)多线程并发问题(单实例多线程,servlet使用成员变量,同步锁解决)
5)自动加载(load-on-startup) + 两个init方法的区别
6)ServletConfig对象:读取初始化参数
7)ServetContext对象(重点)
5大作用:
1)读取web上下文路径(1)
2)读取全局参数(2)
3)作为域对象使用(3)
4)可以转发页面(1)
5)读取web资源文件(3)