Servlet
Posted 阿Hai
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Servlet相关的知识,希望对你有一定的参考价值。
Servlet
Servlet概述
Servlet是Sun提供的动态web资源开发技术。其本质是一个java类,要求这个类必须实现Servlet接口,以便服务器能够调用。
开发Servlet的两个步骤:
(1) 写一个java程序实现Servlet接口(或继承其实现类GenericServlet或HttpServlet)
public class FirstServlet extends GenericServlet{
public void service(ServletRequest req, ServletResponse res) throws ServletException, java.io.IOException{
}
}
(2) 将编译好的带包的.class放到WEB-INF/classes下,配置web应用的 web.xml注册Servlet
<servlet>
<servlet-name>FirstServlet</servlet-name>
<servlet-class>com.diysoul.FirstServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>FirstServlet</servlet-name>
<url-pattern>/FirstServlet</url-pattern>
</servlet-mapping>
Servlet生命周期
servlet第一次被访问的时候在内存中创建对象,在创建后立即调用init()方法进行初始化。对于每一次请求都会调用service(Request req, Response resp)方法处理请求,此时Request对象封装请求信息,Response对象(最初是空的)代表响应消息,传入到service方法里供使用。当service方法处理完成后,返回服务器,服务器根据Response中的信息组织成响应消息返回给浏览器。响应结束后servlet并不销毁,一直驻留在内存中等待下一次请求。直到服务器关闭或web应用被移除出虚拟主机,servlet对象销毁并在销毁前调用destroy()方法做一些善后的工作。
Servlet接口的继承结构
Servlet接口:定义了一个servlet应该具有的方法,所有的Servlet都应该直接或间接实现此接口。
GenericServlet:对Servlet接口的默认实现,通用Servlet,这是一个抽象类,其中的大部分方法都做了默认实现,只有service方法是一个抽象方法需要继承者自己实现。
HttpServlet: 对HTTP协议进行了优化的Servlet,继承自GenericServlet类,并且实现了其中的service抽象方法,默认的实现中判断了请求的请求方式,并根据请求方式的不同分别调用不同的doXXX()方法。通常直接继承HttpServlet即可。
Servlet配置
Servlet配置是通过在web.xml中添加servlet及servlet-mapping来实现的,其放置位置为: /WebRoot/WEB-INF/web.xml
在web.xml中利用<servlet><servlet-mapping>标签注册一个Servlet,一个<servlet>可以对应多个<servlet-mapping>。
<servlet>
<servlet-name>FirstServlet</servlet-name>
<!--注意:此处要的是一个Servlet的完整类名,不是包含.java或.class扩展的文件路径--!>
<servlet-class>com.diysoul.FirstServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>FirstServlet</servlet-name>
<url-pattern>/FirstServlet</url-pattern>
</servlet-mapping>
1.Servlet的配置包括两部分
(1)<servlet>配置Servlet的名字和完整类路径:
servlet-name是自定义的,就是给Servlet取个名字。
servlet-class是Servlet完整的类,就是从一开始的包一直“.”到该Servlet。
(2)<servlet-mapping>是用来截获请求的,包括servlet-name和url-pattern。
servlet-name跟<servlet>中的servlet-name是对应的,两个servlet-name一定要一致,否则会找不到对应的Servlet。
url-pattern是截获请求的规则,当表单提交的时候,会根据特定的规则调用相应的Servlet。下面会具体阐述。
2.url-pattern匹配规则
(1).完全匹配
如:<url-pattern>/servlet/MyServlet.do</url-pattern>
(2).目录匹配
如:<url-pattern>/servlet/*</url-pattern>
(3).扩展名匹配
如:<url-pattern>*.do</url-pattern>
以”/"开头和以”/*”结尾的是用来做路径映射的。
以前缀”*.”开头的是用来做扩展映射的。
“/” 是用来定义default servlet映射的。即缺省servlet。
剩下的都是用来定义详细映射的。比如: /aa/bb/cc.action
容器查找规则:
a、容器会首先查找完全匹配,如果找不到,再查找目录匹配,如果也找不到,就查找扩展名匹配。
b、如果一个请求匹配多个“目录匹配”,容器会选择最长的匹配。
c、“*.”匹配级别最低。
如:servletA的url-pattern为/test/*,而servletB的url-pattern为/test/b/*,此 时访问http://localhost/test/b时,容器会选择路径最长的servlet来匹配,也就是这里的servletB。
缺省servlet:如果一个servlet的对外访问路径被设置为/,则该servlet就是一个缺省servlet,其他servlet不处理的请求都由它来处理。注意:在conf/web.xml中配置了缺省servlet,对静态资源的访问和错误页面的输出都是由这个缺省servlet来处理。如果在web应用中配置了一个缺省servlet,此时conf/web.xml中的缺省servlet会被覆盖,会导致静态web资源无法访问。因此不推荐配置。
注意:”/*.action”这样一个看起来很正常的匹配是错误的。因为这个匹配既属于路径映射,也属于扩展映射,会导致容器无法判断。
3.可以为<servlet>配置<load-on-startup>子标签,指定servlet随着服务器的启动而加载,其中配置的数值指定启动的顺序
<servlet>
<servlet-name>invoker</servlet-name>
<servlet-class>
org.apache.catalina.servlets.InvokerServlet
</servlet-class>
<load-on-startup>2</load-on-startup>
</servlet>
Servlet的线程安全问题
一个servlet在内存只有一个实例处理请求,当多个请求发送过来的时候就会有多个线程操作该servlet对象,此时可能导致线程安全问题。
解决方法:
首先尽量不要在servlet中出现成员变量。
其次利用同步代码块解决问题,由于同一时间同步代码块只能处理一个请求,效率低下,因此同步代码块中尽量只包含核心的导致线程安全问题的代码。
以上是关于Servlet的主要内容,如果未能解决你的问题,请参考以下文章