Servlet详解(一)
什么是Servlet
Servlet(Server Applet),全称Java Servlet。一个Java Servlet就是一个小型Java应用程序,它可以继承HttpServlet实现,运行在Web服务器中。Servlet 会接收并响应来自浏览器的请求,通常是基于Http协议的请求。
如下图:

创建Servlet
实现Servlet或者继承Servlet的实现类:
方法一:实现Servlet接口
1> 实现接口Servlet并实现以下几个 生命周期 方法:
init(ServletConfig config):当Servlet被创建时,将会使用此方法对自己初始化service(ServletRequest req,ServletResponse res):当浏览器对服务器发出请求后,servlet会使用该方法处理请求destory():当Servlet处理完请求后,在销毁前会调用此方法,然后GC会将它回收掉
生命周期:
当client访问Servlet时,创建并初始化Servlet, 在服务器中只有一个Servlet实例,当服务器被关闭时,Servlet才会被销毁。
2> 在 web.xml 中注册Servlet,告诉服务器有这么一个Servlet
什么?太麻烦了?还好我们有注解 @WebServlet
使用java注解注册Servlet
启动服务器,访问此Servlet:

在tomcat中的项目结构:

我们可以看到,Java编译的class文件全部被eclipse放置到WEB-INF—> classes目录下了。
输出:

生命周期时序图:

服务器是如何查找Servlet的?

我们看到,通过 <url-pattern> 访问servlet,最后访问到他的class文件。
首先根据 <url-pattern> 找到它的name,然后根据name找到 <servlet> <name> 相同的servlet标签,根据name找到 <servlet-class> class路径,使用找到的class生成servlet实例到服务器内存中。
ServletConfig接口:
servlet容器使用servlet配置对象,该对象在初始化期间将信息传递给ServletConfig。
String getInitParamter(String name):根据初始化参数名称获取初始化参数的值,如果没有此参数,返回nullEnumeration getInitParamterNames():获取所有初始化参数名称,以枚举方式返回,如果没有参数,返回一个空的枚举
在 web.xml 中初始化参数:
在Servlet service()中对初始化参数进行处理:
请求结果如下:

getServletName():获取Servlet的名称<servlet-name>getServletContext():获取ServletContext上下文对象
点击form表单提交,跳转servlet
方法二、继承GenericServlet
所谓的GenericServlet只是一个Servlet的实现类,因为用户每次使用Servlet接口自定义一个Servlet都会进行许多不必要的操作,所以就封装了一个GenericServlet以方便程序员使用,
使用方法:在方法service()中进行请求的处理,具体请查看源码。
下面是它的源码:
方法三、继承HttpServlet
HttpServlet继承自GenericServlet,是针对Http协议的Servlet,是进一步的封装,
使用只需要继承HttpServlet,重写doGet或doPost方法即可,doGet用来处理get请求,而doPost方法用来进行post请求处理。
源码如下:
Servlet线程安全问题:
Servlet存在这线程安全的问题,
假设在Servlet中放置一个成员变量name,用来接受用户的表单信息。当多个用户访问Servlet时,会对name进行多次赋值,那么用户得到的结果就很有可能出错,因为多个用户共用一块内存。
解决办法也很简单,让每个用户都有一块内存保存自己的name值,只需要将name值保存在方法中,建立一个局部变量即可。因为java方法在被调用时,每次被调用,都会开辟一个新的方法区。
修改Servlet创建时机
通常情况下,servlet在被用户第一次调用时创建,如果servlet要进行非常耗时的创建操作,用户就会等待很久,影响用户体验,所以,我们可以将servlet设置在服务器启动之后,解决这类问题:
在 web.xml 中,添加加载时间标签:
Servlet访问路径配置
相对路径:
/ 代表 项目路径
/AServlet => http://localhost:8080/ServletDemo/Aservlet
/File/* => /File/ => http://localhost:8080/ServletDemo/File/sfsdfdsfsdfe 匹配任意
匹配范围越大,优先级越低:
两个配置 /File/AServlet 与 /File/*
访问: http://localhost:8080/ServletDemo/File/AServlet
则会访问AServlet,而不会访问第二个路径,因为第一个优先级高。
后缀名匹配:
*.do: http://localhost:8080/ServletDemo/sfdsfds.do
该方式不常用,Filter过滤器常用
注意:不能同时使用 后缀名 匹配和 相对路径。例如: /File/*.do
ServletContext
项目级别的对象,一个Web项目,有且只有一个ServletContext对象,在项目启动时创建,到项目关闭时销毁,可以理解为这个类集合了项目所有的功能方法,代表了项目,所以这个类非常强大。
我们使用 ServletConfig.getServletContext() 获得这个对象。
功能如下:
获取项目参数
配置项目初始化参数:
获取项目初始化参数:
getServletContext().getInitParamter(String name)
getServletContext().getInitParamterNames()
ServletContext 域
域是服务器两个组件之间的通讯,比如两个Servlet之间通讯。
Application域
在ServletContext中,有一个 Map<String,Object> 集合,用来保存信息,这个Map集合就是ServletContext的域。
AServlet获取ServletContext对象,向域中添加信息,BServlet也可以获取Servlet,然后从ServletContext域中获取AServlet填入的信息。
这样,每个Servlet之间就可以共享信息了。
同样存在线程不安全的问题。
ServletContext获取项目内的资源
获取WebRoot/WebContent下的 user.xml 文件:
获取class资源:
最后更新于
这有帮助吗?