JavaEE核心API--Servlet
来源:互联网 发布:淘宝网借贷 编辑:程序博客网 时间:2024/05/18 21:40
一.Servlet简介
Servlet是serverapplet的简写,意为服务器端程序。用来处理客户端浏览器发来的请求,并相应给浏览器动态资源
Servlet是JavaWeb三大组件(Servlet,Filter,Listener)
1.1 Servlet的功能
Servlet用来处理动态资源,其根本任务是,处理请求,生成响应。
1.2 Servlet的工作方式
Servlet是一个供其他Java程序(Servlet引擎)调用的Java类,它不能独立运行,它的运行完全由Servlet引擎(即服务器,如:Tomcat)来控制和调度。
1.3 Servlet的生命周期
如果客户端的多次发出Servlet请求,通常情况下,服务器只会创建一个Servlet实例对象,也就是说Servlet实例对象一旦创建,它就会驻留在内存中,为后续的其它请求服务,直至web容器退出,Servlet实例对象才会销毁。
Servlet的生命周期方法的执行:
1)第一次调用Servlet时,将执行初始化方法,init(ServletConfig),创建Serlvet的实例,以单实例的形式创建(Struts2的动作类则是多实例的)。
2)每一次调用都执行service(ServletResquest , ServletResponse)方法。
3)服务器关闭(或项目移除),调用destroy( )方法销毁Servlet的实例。
二.Servlet的基本使用
2.1 Servlet的创建
方式一:实现servlet接口.
方式二:继承javax.servlet.GenericServlet
方式三:继承javax.servlet.http.HttpServlet
2.2 Servlet的生命周期方法
生命周期方法指的是调用之后必须要执行的方法。对于servlet来讲,有3个生命周期方法。
2.3 Servlet中的其他方法
Servlet对象一共有5个方法,除了3个和生命周期有关的方法外,还有2个不常用的方法:
getServletInfo()方法,获得servlet的信息(版本,作者,版权..),基本不用
getServletConfig()方法,返回servletConfig对象
2.4 Servlet技术中各对象的作用范围
三.ServletConfig接口
功能:封装了servlet在web.xml中的配置,ServletConfig的API:
1.getServletName 获得配置文件中< servlet-name >元素的内容
2.getInitParameter 根据< init-param >中的 < param-name > 获得 < /param-value >
<init-param> <param-name>name</param-name> <param-value>tom</param-value></init-param>
getInitParameterNames返回所有< param-name >
getServletContext返回ServletContext对象
四.ServletContext接口
服务器启动的时候会为每一个WEB应用创建一个单独的ServletContext对象,ServletContext对象中的数据可以在整个WEB应用中获取(需要使用ServletContext对象的获取值的方法)
4.1 ServletContext封装了web.xml中的配置
<context-param> <param-name>name</param-name> <param-value>jerry</param-value></context-param><context-param> <param-name>password</param-name> <param-value>1234</param-value></context-param>
可以使用ServletContext中的方法获得web.xml中的配置内容:
getInitParameterNames(); 获得所有键
getInitParameter(key); 根据键获得对应的值
4.2 Servlet技术中三大域对象(application域,session域,request域)之一
“域”即存储数据的区域,Request,Session和ServletContext对象都有存取数据的功能,所以又被称为“域”。ServletContext对应着application域。application域中的数据可以再整个项目范围内存取。(注:JSP中为四大域,多了一个页面域—-page域)
关于域的操作:
ServletContext的常用功能:
ServletContext中的数据可以在整个项目中存取,所以可以用来做Servlet对象之间的通信
4.3 获得项目中资源
所有servletContext中关于路径的获得,相对路径都是相对的 WebRoot(项目根)下
getRealPath 通过相对路径获得绝对路径
getResourceAsStream 根据相对路径获得指定资源流
五.实现了Servlet接口的类
在Servlet的API中有2个实现了Servlet接口的类,对Servlet进行了封装和优化,方便开发人员的使用
5.1 GenericServlet
实现了ServletConfig接口,方便调用(在init方法中做的优化)
GenericServlet有两个init方法,使用时调用空参的init方法,含参的init方法做了优化
public void init(ServletConfig config) throws ServletException { this.config = config; this.init(); }
public void init() throws ServletException { }
GenericServlet源码
public abstract class GenericServlet implements Servlet, ServletConfig, Serializable { private static final long serialVersionUID = 1L; private transient ServletConfig config; public GenericServlet() { } public void destroy() { } public String getInitParameter(String name) { return this.getServletConfig().getInitParameter(name); } public ServletConfig getServletConfig() { return this.config; } public ServletContext getServletContext() { return this.getServletConfig().getServletContext(); } public void init(ServletConfig config) throws ServletException { this.config = config; this.init(); } public abstract void service(ServletRequest var1, ServletResponse var2) throws ServletException, IOException; .......}
5.2 HTTPServlet
1.HTTPServlet是在GenericServelt的基础上做的进一步的优化,是一个抽象类。
2.因为我们WEB项目都是基于HTTP协议,所以Service方法中的request,response对象都是基于HTTP协议的。也就是HttpServletReueqst和HttpServletResponse。它帮我们进行了强转.
3.根据不同的请求采取不同的方法进行处理。有专门处理GET和POST请求的方法。
HTTPServlet部分源码
public abstract class HttpServlet extends GenericServlet { private static final long serialVersionUID = 1L; private static final String METHOD_GET = "GET"; private static final String METHOD_POST = "POST"; private static final String METHOD_PUT = "PUT"; private static final String HEADER_IFMODSINCE = "If-Modified-Since"; private static final String HEADER_LASTMOD = "Last-Modified"; private static final String LSTRING_FILE = "javax.servlet.http.LocalStrings"; private static ResourceBundle lStrings = ResourceBundle.getBundle("javax.servlet.http.LocalStrings"); public HttpServlet() { } protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String protocol = req.getProtocol(); String msg = lStrings.getString("http.method_get_not_supported"); if (protocol.endsWith("1.1")) { resp.sendError(405, msg); } else { resp.sendError(400, msg); } } protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String protocol = req.getProtocol(); String msg = lStrings.getString("http.method_post_not_supported"); if (protocol.endsWith("1.1")) { resp.sendError(405, msg); } else { resp.sendError(400, msg); } }
六.Servlet线程安全问题
因为在servlet运行期间只有一个servlet实例存在.可能会同时处理多个请求.那么我们在servlet中声明成员变量来存储用户数据是有线程安全问题的.
解决方法:
6.1 实现SigleThreadModel (不推荐)
SigleThreadModel本质上是一个标记接口,类似Serializable,标记接口的主要作用就是给某个对象打上一个标志,告诉JVM,这个对象可以做什么,比如实现了”Serializable”接口的类的对象就可以被序列化,而实现” SigleThreadModel ” 接口的类的对象则可以创建多个实例,所以这种方法解决线程安全的原理是创建多个Servlet实例,每个线程分配一个Servlet的实例对象,会使占用很多内存,所以这种解决办法不好,很少用
6.2 使用局部变量保存用户数据(推荐)
若service()方法里有一个局部变量n,当有多个线程并发访问service()方法时,Servlet不会创建新的实例,而是每次访问都调用一次service()方法,所以每一个线程里面都有自己的n变量,各个线程操作的都是自己的n变量,所以不存在线程安全问题。
多线程并发访问某一个方法的时候,如果在方法内部定义了一些资源(变量,集合等),那么每一个线程都有这些东西,所以就不存在线程安全问题了。
七.Servlet随着服务器的启动而创建
Servlet实例默认是在第一次访问时创建,在web.xml文件中可以设置更改Servlet实例的创建时机,改为服务器启动后直接创建Servlet的实例
使用< load-on-startup >配置来实现.
例如:
<servlet> <servlet-name>AServlet</servlet-name> <servlet-class>cn.itcast.servlet.hello.AServlet</servlet-class> <load-on-startup>3</load-on-startup></servlet>
< load-on-startup >标签内填写一个整数,每个Servlet都可以独立设置一个启动常数,这个常数数值越小代表优先级越高,创建时优先创建。如果优先级一样,启动顺序按照配置顺序。
八.关于Servlet路径配置问题详解
web.xml文件中的< url-pattern > 标签配置目标资源路径
完全路径匹配:
特点:路径完整,指定Servlet对象
目录匹配:
特点:以 * 结束,代表匹配一定范围内的资源
后缀名匹配:
特点:匹配后缀名
注意:
1.关于路径,配置的路径匹配范围越大优先级越低
优先级排序:完全路径匹配>目录匹配>后缀名匹配
2.两种匹配模式不能混用.例如错误的例子: /*.do
缺省Servlet
缺省Servlet的映射路径为“/”,若一个请求在web.xml文件中匹配不到Servlet,那么这个请求就会交给缺省Servlet处理
在Tomcat默认的配置文件/conf/web.xml中就配置有缺省Servlet
当访问Tomcat服务器中的静态文件时,底层就是调用这个默认的缺省Servelt进行处理的
<servlet> <servlet-name>default</servlet-name> <servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class> <init-param> <param-name>debug</param-name> <param-value>0</param-value> </init-param> <init-param> <param-name>listings</param-name> <param-value>false</param-value> </init-param> <load-on-startup>1</load-on-startup></servlet>
- JavaEE核心API--Servlet
- 【JavaEE—Hibernate】Hibernate核心api
- javaee.jar与servlet-api.jar
- javaee.jar与servlet-api.jar
- JavaEE struts2 Action访问Servlet API
- Servlet之核心API/UML
- Servlet系列(三)----Servlet核心API
- javaEE servlet
- JavaEE----------Servlet
- JavaEE-Servlet
- javaee(servlet)
- servlet核心API的UML图
- 初识Servlet生命周期及核心API
- javaee-api会引入javax-servlet-api,与服务器中的tomcat的jar包重复
- JavaEE Servlet Session详解
- javaEE servlet-01
- javaEE servlet-02
- javaEE servlet入门
- 分布式自增 id 的高阶
- 【西南交通大学第十三届ACM决赛-重现赛】 A B E F H K
- ssh在myeclipse中的
- kubernetes initcontainer <=1.5 yaml 例子
- 欢迎使用CSDN-markdown编辑器 (1)
- JavaEE核心API--Servlet
- ElasticSearch5.6.1索引、类型、文档的增删查改--利用RESTful接口和Kibana可视化工具
- Java 9正式发布
- VirtualBox配置相关
- 面试问题
- C语言比较两个数的大小使用if-else语句和条件运算符
- Linux下mongodb部署
- 【数据结构笔记】三、树与二叉树
- 清除浮动的方法及优缺点