一、servlet概述
1.什么是servlet
servlet就是用java编写的服务器端程序(Server Applet),
它需要交给服务器来运行.
广义上讲,Servlet是指任何实现了Servlet这个接口的类别.
*servlet是单例的.
2.Servlet的优缺点
(1)优点
*可移植性.
*功能强大:可以使用javaAPI核心的所有功能.
*模块化:每一个servlet可以执行一个特定的任务,并且可以将它们并在一起工作,servlet之间可以通信.
*高效持久:servlet一旦载入,就驻留在内存中.用线程的方式加快了响应的速度(单实例、多线程).
(2)缺点
servlet利用输出HTML语句来实现动态网页.如果用来开发整个网站,太麻烦.
因此sun退出jsp.
3.servlet技术的实现
servlet技术是基于Request-Response编程模型
实现过程:
*客户端发送请求至服务器
*服务器启动并调用Servlet,Servlet根据客户端请求生成响应内容并将其传给服务器.
*服务器将响应返回客户端.
二、如何使用servlet
1.写一个servlet并注册
*创建web项目
*创建一个类,并实现servlet接口
*由于客户端通过url地址访问web服务器中的资源,所以servlet程序若想被外界访问,
必须把servlet程序映射到一个url地址上,这就需要在/WEB-INF/web.xml中
使用<servlet>元素和<servlet-mapping>元素来完成.
<servlet>
<servlet-name>为servlet起一个别名,项目内必须唯一</servlet-name>
<servlet-class>servlet类的完整路径名</servlet-class>
<!-- 如果有初始化参数可以配置,没有则不写 -->
<init-param>
<param-name>初始化参数名</param-name>
<param-value>初始化参数值</param-value>
</init-param>
<!-- 如果需要服务器已启动就加载servlet,则要配置如下,取值0-6,值越小越优先加载 -->
<load-on-startup>0</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>名字和上面要保持一致</servlet-name>
<url-pattern>自定义浏览器访问路径,必须"/"开头,名称唯一</url-pattern>
</servlet-mapping>
示例:
<servlet>
<servlet-name>HelloWorld</servlet-name>
<servlet-class>cn.itcast.HelloWorld</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>HelloWorld</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>
如果在本地测试,浏览器输入:http://localhost:8080/day05/hello
2.Servlet虚拟路径举例
对于如下的映射关系:
* Servlet1 映射到 /abc/*
* Servlet2 映射到 /*
* Servlet3 映射到 /abc
* Servlet4 映射到 *.do
(1)当请求URL为"/abc/a.html",Servlet1和Servlet2都匹配,
Servlet引擎将调用Servlet1.
(2)当请求URL为"/abc"时,Servlet1和Servlet3都匹配
Servlet引擎将调用Servlet3.
(3)当请求URL为"/abc/a.do"时,Servlet1和Servlet4都匹配
Servlet引擎将调用Servlet1.
(4)当请求URL为"/a.do"时,Servlet2和Servlet4都匹配
Servlet引擎将调用Servlet2.
(5)当请求URL为"/xxx/yyy/a.do"时,Servlet2和Servlet4都匹配
Servlet引擎将调用Servlet2.
3.缺省Servlet
*如果某个Servlet的映射路径仅仅为一个正斜杠(/),那么这个Servlet就成为当前Web应用程序的缺省Servlet.
*如果在web.xml文件中找不到匹配的<servlet-mapping>元素的URL,其访问请求都交给缺省Servlet处理.
*在%tomcat%\conf\web.xml文件中,已经注册了一个名称为org.apache.catalina.servlets.DefaultServlet的缺省Servlet.
*当访问Tomcat服务器中的某个静态HTML文件和图片时,实际是在访问这个缺省的Servlet.
三、Servlet生命周期
1.Servlet生命周期概述
javax.servlet.Servlet接口定义了Servlet的生命周期
*init()方法
服务器调用该方法初始化Servlet.
*service()方法
初始化完毕,服务器调用该方法响应客户的请求.
*destroy()方法
服务器调用该方法消灭servlet对象.
需要注意的事项:
*init()方法只在Servlet第一次被请求加载的时候被调用一次,当有客户再请求Servlet服务时,
Web服务器将启动一个新的线程,在该线程中,调用service方法响应客户的请求.对于每次访问
请求,Servlet引擎都会创建一个新的HttpServletRequest请求对象和一个新的
HttpServletResponse响应对象,然后将这两个对象作为参数传递给它调用的Servlet
的service()方法,service方法再根据请求方式分别调用doXXX方法.
*Servlet是一个供其他java程序(Servlet引擎)调用的java类,它不能独立运行,
它的运行完全由Servlet引擎来控制和调度.
*和init()方法类似,针对客户端的多次Servlet请求,通常情况下,服务器只会创建一个Servlet
实例对象,也就是说Servlet实例对象一旦创建,它就会驻留在内存中,为后续的其它请求服务,直至
web容器退出,servlet实例对象才会销毁.
2.init(ServletConfig)
javax.servlet.ServletConfig是对当前servlet的配置信息的描述.
(1)当servlet配置了初始化参数后(即用<init-param>标签),web容器在创建servlet实例对象时,会自动将这些
初始化参数封装到ServletConfig对象中,并在调用servlet的init方法时,将ServletConfig对象传递给
servlet.如此,程序员就可以通过ServletConfig对象得到当前servlet的初始化参数信息.
(2)ServletConfig中的方法
*getInitParameter("paramName"):返回指定初始化参数名称的值.
*getInitParameterNames():返回当前servlet的所有初始化参数的名称.
*getServletName():返回当前servlet的名称.即标签<servlet-name>配置的名称
*getServletContext():ServletConfig保存了当前web项目的ServletContext的引用.
(3)ServletContext
*ServletContext是对当前web项目上下文的描述(即对当前web项目所有内容的描述),在tomcat启动时创建,tomcat关闭时销毁.
*tomcat为每一个web项目单独创建一个区域,用来管理整个项目,此区域称为ServletContext.
*项目中所有的Servlet共享同一个ServletContext对象,可以通过它进行通讯.
例如:servlet1 -->setAttribute
servlet2 -->getAttribute
*可以获取web应用的初始化参数,<context-param>
(4)<context-param>和<init-param>的区别
*<context-param>是web应用范围内的参数,存放在servletcontext中,
可以在servlet通过getServletContext().getInitParameter("context/param")得到.
*<init-param>是servlet范围内的参数,只能在servlet的init()方法通过this.getInitParameter("param1")取得.
3.service(ServletRequest,ServletResponse)
(1)request:
*接口:javax.servlet.ServletRequest
*实现类:org.apache.catalina.connector.RequestFacade
*关系:RequestFacade 实现了 HttpServletRequest
HttpServletRequest 继承了 ServletRequest
*服务器获得浏览器发送的数据
request.getParameter("username"); 获得单个数据.
request.getParameterValues("love");获得一组数据.
request.serCharacterEncoding("UTF-8");只对POST请求有效.
(2)response:
*接口:javax.servlet.ServletResponse
*实现类:org.apache.catalina.connector.ResponseFacade
*关系:ResponseFacade 实现了 HttpServletResponse
HttpServletResponse 继承了 ServletResponse
*服务器对浏览器做出响应,使用流操作,将所需要的数据存放在流中,数据将显示在浏览器上.
字符流:response.getWriter();一般在程序中发送数据内容.
字节流:response.getOutputStream();一般用于带有拷贝功能的程序中.
两个流同时只能使用一个.
字节流中的print()方法不能发送中文.
字节流中的write(data.getBytes("utf-8"));可以发送中文.
字符流均可发送中文.
*解决乱码:response.serContentType("text/html;charset=utf-8");
通知tomcat和浏览器发送数据的编码.
四、Servlet接口实现类
Servlet接口,SUN公司定义了两个默认实现类.
(1)GenericServlet实现类.
* GenericServlet是一个通用的,与协议无关的servlet
* 它是一个抽象类,为了方便用户编写servlet而存在,只具有抽象方法service(ServletRequest,ServletResponse)
* 不仅实现了Servlet接口,也实现了ServletConfig接口,
* 它缓存了init方法的实际参数值,也就是把ServletConfig的实例对象给缓存了.
* 此类存在一个没有参数的init方法,所有的servlet初始化工作,建议覆盖此方法.
否则覆盖带有参数的init方法,需要在方法的第一行添加super.init(config),目的是为了缓存ServletConfig对象.
(2)HttpServlet实现类.(****开发时继承此类*****)
* HttpServlet是能够处理HTTP请求的servlet.
* 由于绝大多数情况下Servlet只用来扩展基于HTTP协议的Web服务器,因此开发人员在编写Servlet时,通常
会继承这个类,而避免直接实现Servlet接口.
* HttpServlet在实现Servlet接口时,覆写了service方法,该方法体内的代码会自动判断用户的请求方式,
如为GET请求,则调用HttpServlet的doGet方法,如为Post请求,则调用doPost方法,因此,开发人员在
编写Servlet时,只需要覆写doGet或doPost方法,而不要去覆写service方法.
* 当继承HttpServlet的总结:
*Servlet初始化时覆盖init(),无需覆盖init(config)
*根据Http请求的方式,覆盖相应的doGet或者doPost方法,无需覆盖Service方法.
*当doGet和doPost代码逻辑相同时,可以相互调用,简化编程.
五、转发与重定向
1.概念:
*一个web资源收到客户端请求后,通知浏览器去访问另外一个web资源(浏览器进行2次请求),称为请求重定向.
*一个web资源收到客户端请求后,通知服务器去调用另外一个web资源进行处理(服务器内部的调用),称为请求转发.
2.实现方式:
*重定向Redirect
HttpServletResponse.sendRedirect(String location);
如果路径的相对URL以"/"开头,他是相对于整个web站点的根目录.
*转发,两种方式得到RequestDispatcher
*ServletContext.getRequestDispatcher(String path);
这里的path必须以"/"开头,即必须是相对于context的root.
*ServletRequest.getRequestDispatcher(String path);
这里的path可以是相对路径,如果以"/"开头,则认为是从context的root开始的.
即相对与web应用程序的.
3.请求次数
*重定向:请求2次,tomcat创建了两个request对象,是两个独立的访问请求与响应过程.request中的值不共享.
*转发:请求1次,tomcat创建了两个request对象,并将第一个request中的内容拷贝到第二个request中,值相同,
属于同一个访问请求和响应过程,request中的值共享.
4.地址栏是否修改
重定向:修改,看到的是跳转后页面的内容.
转发:没有修改,看到的是转发后最后一个servlet响应的内容
5.范围:
*RequestDispatcher.forward方法只能将请求转发给同一个web应用中的组件;
*而HttpServletResponse.sendRedirect方法还可以重定向到同一个站点上的其他应用程序中的资源,甚至使用绝对
URL重定向到其他站点的资源.
6.使用
request中放了内容,则用转发,否则都用重定向.
1.什么是servlet
servlet就是用java编写的服务器端程序(Server Applet),
它需要交给服务器来运行.
广义上讲,Servlet是指任何实现了Servlet这个接口的类别.
*servlet是单例的.
2.Servlet的优缺点
(1)优点
*可移植性.
*功能强大:可以使用javaAPI核心的所有功能.
*模块化:每一个servlet可以执行一个特定的任务,并且可以将它们并在一起工作,servlet之间可以通信.
*高效持久:servlet一旦载入,就驻留在内存中.用线程的方式加快了响应的速度(单实例、多线程).
(2)缺点
servlet利用输出HTML语句来实现动态网页.如果用来开发整个网站,太麻烦.
因此sun退出jsp.
3.servlet技术的实现
servlet技术是基于Request-Response编程模型
实现过程:
*客户端发送请求至服务器
*服务器启动并调用Servlet,Servlet根据客户端请求生成响应内容并将其传给服务器.
*服务器将响应返回客户端.
二、如何使用servlet
1.写一个servlet并注册
*创建web项目
*创建一个类,并实现servlet接口
*由于客户端通过url地址访问web服务器中的资源,所以servlet程序若想被外界访问,
必须把servlet程序映射到一个url地址上,这就需要在/WEB-INF/web.xml中
使用<servlet>元素和<servlet-mapping>元素来完成.
<servlet>
<servlet-name>为servlet起一个别名,项目内必须唯一</servlet-name>
<servlet-class>servlet类的完整路径名</servlet-class>
<!-- 如果有初始化参数可以配置,没有则不写 -->
<init-param>
<param-name>初始化参数名</param-name>
<param-value>初始化参数值</param-value>
</init-param>
<!-- 如果需要服务器已启动就加载servlet,则要配置如下,取值0-6,值越小越优先加载 -->
<load-on-startup>0</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>名字和上面要保持一致</servlet-name>
<url-pattern>自定义浏览器访问路径,必须"/"开头,名称唯一</url-pattern>
</servlet-mapping>
示例:
<servlet>
<servlet-name>HelloWorld</servlet-name>
<servlet-class>cn.itcast.HelloWorld</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>HelloWorld</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>
如果在本地测试,浏览器输入:http://localhost:8080/day05/hello
2.Servlet虚拟路径举例
对于如下的映射关系:
* Servlet1 映射到 /abc/*
* Servlet2 映射到 /*
* Servlet3 映射到 /abc
* Servlet4 映射到 *.do
(1)当请求URL为"/abc/a.html",Servlet1和Servlet2都匹配,
Servlet引擎将调用Servlet1.
(2)当请求URL为"/abc"时,Servlet1和Servlet3都匹配
Servlet引擎将调用Servlet3.
(3)当请求URL为"/abc/a.do"时,Servlet1和Servlet4都匹配
Servlet引擎将调用Servlet1.
(4)当请求URL为"/a.do"时,Servlet2和Servlet4都匹配
Servlet引擎将调用Servlet2.
(5)当请求URL为"/xxx/yyy/a.do"时,Servlet2和Servlet4都匹配
Servlet引擎将调用Servlet2.
3.缺省Servlet
*如果某个Servlet的映射路径仅仅为一个正斜杠(/),那么这个Servlet就成为当前Web应用程序的缺省Servlet.
*如果在web.xml文件中找不到匹配的<servlet-mapping>元素的URL,其访问请求都交给缺省Servlet处理.
*在%tomcat%\conf\web.xml文件中,已经注册了一个名称为org.apache.catalina.servlets.DefaultServlet的缺省Servlet.
*当访问Tomcat服务器中的某个静态HTML文件和图片时,实际是在访问这个缺省的Servlet.
三、Servlet生命周期
1.Servlet生命周期概述
javax.servlet.Servlet接口定义了Servlet的生命周期
*init()方法
服务器调用该方法初始化Servlet.
*service()方法
初始化完毕,服务器调用该方法响应客户的请求.
*destroy()方法
服务器调用该方法消灭servlet对象.
需要注意的事项:
*init()方法只在Servlet第一次被请求加载的时候被调用一次,当有客户再请求Servlet服务时,
Web服务器将启动一个新的线程,在该线程中,调用service方法响应客户的请求.对于每次访问
请求,Servlet引擎都会创建一个新的HttpServletRequest请求对象和一个新的
HttpServletResponse响应对象,然后将这两个对象作为参数传递给它调用的Servlet
的service()方法,service方法再根据请求方式分别调用doXXX方法.
*Servlet是一个供其他java程序(Servlet引擎)调用的java类,它不能独立运行,
它的运行完全由Servlet引擎来控制和调度.
*和init()方法类似,针对客户端的多次Servlet请求,通常情况下,服务器只会创建一个Servlet
实例对象,也就是说Servlet实例对象一旦创建,它就会驻留在内存中,为后续的其它请求服务,直至
web容器退出,servlet实例对象才会销毁.
2.init(ServletConfig)
javax.servlet.ServletConfig是对当前servlet的配置信息的描述.
(1)当servlet配置了初始化参数后(即用<init-param>标签),web容器在创建servlet实例对象时,会自动将这些
初始化参数封装到ServletConfig对象中,并在调用servlet的init方法时,将ServletConfig对象传递给
servlet.如此,程序员就可以通过ServletConfig对象得到当前servlet的初始化参数信息.
(2)ServletConfig中的方法
*getInitParameter("paramName"):返回指定初始化参数名称的值.
*getInitParameterNames():返回当前servlet的所有初始化参数的名称.
*getServletName():返回当前servlet的名称.即标签<servlet-name>配置的名称
*getServletContext():ServletConfig保存了当前web项目的ServletContext的引用.
(3)ServletContext
*ServletContext是对当前web项目上下文的描述(即对当前web项目所有内容的描述),在tomcat启动时创建,tomcat关闭时销毁.
*tomcat为每一个web项目单独创建一个区域,用来管理整个项目,此区域称为ServletContext.
*项目中所有的Servlet共享同一个ServletContext对象,可以通过它进行通讯.
例如:servlet1 -->setAttribute
servlet2 -->getAttribute
*可以获取web应用的初始化参数,<context-param>
(4)<context-param>和<init-param>的区别
*<context-param>是web应用范围内的参数,存放在servletcontext中,
可以在servlet通过getServletContext().getInitParameter("context/param")得到.
*<init-param>是servlet范围内的参数,只能在servlet的init()方法通过this.getInitParameter("param1")取得.
3.service(ServletRequest,ServletResponse)
(1)request:
*接口:javax.servlet.ServletRequest
*实现类:org.apache.catalina.connector.RequestFacade
*关系:RequestFacade 实现了 HttpServletRequest
HttpServletRequest 继承了 ServletRequest
*服务器获得浏览器发送的数据
request.getParameter("username"); 获得单个数据.
request.getParameterValues("love");获得一组数据.
request.serCharacterEncoding("UTF-8");只对POST请求有效.
(2)response:
*接口:javax.servlet.ServletResponse
*实现类:org.apache.catalina.connector.ResponseFacade
*关系:ResponseFacade 实现了 HttpServletResponse
HttpServletResponse 继承了 ServletResponse
*服务器对浏览器做出响应,使用流操作,将所需要的数据存放在流中,数据将显示在浏览器上.
字符流:response.getWriter();一般在程序中发送数据内容.
字节流:response.getOutputStream();一般用于带有拷贝功能的程序中.
两个流同时只能使用一个.
字节流中的print()方法不能发送中文.
字节流中的write(data.getBytes("utf-8"));可以发送中文.
字符流均可发送中文.
*解决乱码:response.serContentType("text/html;charset=utf-8");
通知tomcat和浏览器发送数据的编码.
四、Servlet接口实现类
Servlet接口,SUN公司定义了两个默认实现类.
(1)GenericServlet实现类.
* GenericServlet是一个通用的,与协议无关的servlet
* 它是一个抽象类,为了方便用户编写servlet而存在,只具有抽象方法service(ServletRequest,ServletResponse)
* 不仅实现了Servlet接口,也实现了ServletConfig接口,
* 它缓存了init方法的实际参数值,也就是把ServletConfig的实例对象给缓存了.
* 此类存在一个没有参数的init方法,所有的servlet初始化工作,建议覆盖此方法.
否则覆盖带有参数的init方法,需要在方法的第一行添加super.init(config),目的是为了缓存ServletConfig对象.
(2)HttpServlet实现类.(****开发时继承此类*****)
* HttpServlet是能够处理HTTP请求的servlet.
* 由于绝大多数情况下Servlet只用来扩展基于HTTP协议的Web服务器,因此开发人员在编写Servlet时,通常
会继承这个类,而避免直接实现Servlet接口.
* HttpServlet在实现Servlet接口时,覆写了service方法,该方法体内的代码会自动判断用户的请求方式,
如为GET请求,则调用HttpServlet的doGet方法,如为Post请求,则调用doPost方法,因此,开发人员在
编写Servlet时,只需要覆写doGet或doPost方法,而不要去覆写service方法.
* 当继承HttpServlet的总结:
*Servlet初始化时覆盖init(),无需覆盖init(config)
*根据Http请求的方式,覆盖相应的doGet或者doPost方法,无需覆盖Service方法.
*当doGet和doPost代码逻辑相同时,可以相互调用,简化编程.
五、转发与重定向
1.概念:
*一个web资源收到客户端请求后,通知浏览器去访问另外一个web资源(浏览器进行2次请求),称为请求重定向.
*一个web资源收到客户端请求后,通知服务器去调用另外一个web资源进行处理(服务器内部的调用),称为请求转发.
2.实现方式:
*重定向Redirect
HttpServletResponse.sendRedirect(String location);
如果路径的相对URL以"/"开头,他是相对于整个web站点的根目录.
*转发,两种方式得到RequestDispatcher
*ServletContext.getRequestDispatcher(String path);
这里的path必须以"/"开头,即必须是相对于context的root.
*ServletRequest.getRequestDispatcher(String path);
这里的path可以是相对路径,如果以"/"开头,则认为是从context的root开始的.
即相对与web应用程序的.
3.请求次数
*重定向:请求2次,tomcat创建了两个request对象,是两个独立的访问请求与响应过程.request中的值不共享.
*转发:请求1次,tomcat创建了两个request对象,并将第一个request中的内容拷贝到第二个request中,值相同,
属于同一个访问请求和响应过程,request中的值共享.
4.地址栏是否修改
重定向:修改,看到的是跳转后页面的内容.
转发:没有修改,看到的是转发后最后一个servlet响应的内容
5.范围:
*RequestDispatcher.forward方法只能将请求转发给同一个web应用中的组件;
*而HttpServletResponse.sendRedirect方法还可以重定向到同一个站点上的其他应用程序中的资源,甚至使用绝对
URL重定向到其他站点的资源.
6.使用
request中放了内容,则用转发,否则都用重定向.