Servlet开发总结(一)
一.Servlet简介
- Servlet是sun公司提供的一门用于开发动态web资源的技术。
- Sun公司在其API中提供了一个servlet接口。
- 用户若想用发一个动态web资源(即开发一个Java程序向浏览器输出数据),需要完成以下2个步骤:
1、编写一个Java类,实现servlet接口。
2、把开发好的Java类部署到web服务器中。
- 按照一种约定俗成的称呼习惯,通常我们也把实现了servlet接口的java程序,称之为Servlet。
二.Servlet的运行流程以及图解:
- Servlet程序是由WEB服务器调用,web服务器收到客户端的Servlet访问请求后:
①Web服务器首先检查是否已经装载并创建了该Servlet的实例对象。如果是,则直接执行第④步,否则,执行第②步。
②装载并创建该Servlet的一个实例对象。
③调用Servlet实例对象的init()方,public void init(ServletConfig config):ServletConfig是封装web.xml初始化参数。
④创建一个用于封装HTTP请求消息的HttpServletRequest对象和一个代表HTTP响应消息的HttpServletResponse对象,然后调用Servlet的service()方法并将请求和响应对象作为参数传递进去。
⑤WEB应用程序被停止或重新启动之前,Servlet引擎将卸载Servlet,并在卸载之前调用Servlet的destroy()方法。
三.Servlet调用图解:
四.在Eclipse中开发Servlet
4.1、Servlet接口实现类
- Servlet接口SUN公司定义了两个默认实现类,分别为:GenericServlet、HttpServlet。
- HttpServlet指能够处理HTTP请求的servlet,它在原有Servlet接口上添加了一些与HTTP协议处理方法,它比Servlet接口的功能更为强大。因此开发人员在编写Servlet时,通常应继承这个类,而避免直接去实现Servlet接口。
- HttpServlet在实现Servlet接口时,覆写了service方法,该方法体内的代码会自动判断用户的请求方式,如为GET请求,则调用HttpServlet的doGet方法,如为Post请求,则调用doPost方法。因此,开发人员在编写Servlet时,通常只需要覆写doGet或doPost方法,而不要去覆写service方法。
4.2、Http中的get和post区别
- Http定义了与服务器交互的不同方法,最基本的方法有4种,分别是GET,POST,PUT,DELETE。URL全称是资源描述符,我们可以这样认为:一个URL地址,它用于描述一个网络上的资源,而HTTP中的GET,POST,PUT,DELETE就对应着对这个资源的查,改,增,删4个操作。到这里,大家应该有个大概的了解了,GET一般用于获取/查询资源信息,而POST一般用于更新资源信息。
- GET请求一般不应产生副作用。就是说,它仅仅是获取资源信息,就像数据库查询一样,不会修改,增加数据,不会影响资源的状态。比如,新闻站点的头版不断更新。虽然第二次请求会返回不同的一批新闻,该操作仍然被认为是安全的和幂等的,因为它总是返回当前的新闻。从根本上说,如果目标是当用户打开一个链接时,他可以确信从自身的角度来看没有改变资源即可。get发送数据显示在url地址栏中,不安全。
- POST表示可能修改变服务器上的资源的请求。继续引用上面的例子:还是新闻以网站为例,读者对新闻发表自己的评论应该通过POST实现,因为在评论提交后站点的资源已经不同了,或者说资源被修改了。post发送数据是直接由服务器操作,安全性高。
- 总结一下,Get是向服务器发索取数据的一种请求,而Post是向服务器提交数据的一种请求,在FORM(表单)中,Method默认为"GET",实质上,GET和POST只是发送机制不同,并不是一个取一个发!
4.3、通过Eclipse创建和编写Servlet:
代码如下:
package xu.sha.servletDemo;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Servlet implementation class Servlet03
*/
@WebServlet(description = "ServletDemo03", urlPatterns = { "/Servlet03" })
public class Servlet03 extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
public Servlet03() {
super();
// TODO Auto-generated constructor stub
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
response.getWriter().append("Served at: ").append(request.getContextPath());
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(request, response);
}
}
注意web部署的两种方法:
1.@WebServlet(description = "ServletDemo03", urlPatterns = { "/Servlet03" })
- Servlet3.0提供了注解(annotation),使得不再需要在web.xml文件中进行Servlet的部署描述。
- 在Servlet3.0中,可以使用@WebServlet注解将一个继承于javax.servlet.http.HttpServlet的类标注为可以处理用户请求的Servlet。
@WebServlet注解的相关属性 | ||
NO. | 属性名 | 描述 |
1 | asyncSupported | 声明Servlet是否支持异步操作模式 |
2 | description | Servlet的描述信息 |
3 | displayName | Servlet的显示名称 |
3 | initParams | Servlet的初始化参数 |
5 | name | Servlet的名称 |
6 | urlPatterns | Servlet的访问URL |
7 | value | Servlet的访问URL |
- Servlet的访问URL是Servlet的必选属性,可以选择使用urlPatterns或者value定义。
- 像上面的Servlet3Demo可以描述成@WebServlet(name="Servlet3Demo",value="/Servlet3Demo")。
- 也定义多个URL访问:
1.如@WebServlet(name="Servlet3Demo",urlPatterns={"/Servlet3Demo","/Servlet3Demo2"})
2.或者@WebServlet(name="AnnotationServlet",value={"/Servlet3Demo","/Servlet3Demo2"})
2.web.xml文件中也多了<servlet></servlet>和<servlet-mapping></servlet-mapping>两对标签,这两对标签是配置Servlet03的,代码如下:
<servlet> <servlet-name>ServletDemo02</servlet-name> <servlet-class>xu.sha.servletDemo.Servlet02</servlet-class> </servlet> <servlet-mapping> <servlet-name>ServletDemo02</servlet-name> <url-pattern>/Servlet02</url-pattern> </servlet-mapping>
五.Servlet开发注意细节
5.1、Servlet访问URL映射配置
- 由于客户端是通过URL地址访问web服务器中的资源,所以Servlet程序若想被外界访问,必须把servlet程序映射到一个URL地址上,这个工作在web.xml文件中使用<servlet>元素和<servlet-mapping>元素完成。
- <servlet>元素用于注册Servlet,它包含有两个主要的子元素:<servlet-name>和<servlet-class>,分别用于设置Servlet的注册名称和Servlet的完整类名。
- 一个<servlet-mapping>元素用于映射一个已注册的Servlet的一个对外访问路径,它包含有两个子元素:<servlet-name>和<url-pattern>,分别用于指定Servlet的注册名称和Servlet的对外访问路径。
代码如下:
<servlet> <servlet-name>ServletDemo02</servlet-name> <servlet-class>xu.sha.servletDemo.Servlet02</servlet-class> </servlet> <servlet-mapping> <servlet-name>ServletDemo02</servlet-name> <url-pattern>/Servlet02</url-pattern> </servlet-mapping>
- 同一个Servlet可以被映射到多个URL上,即多个<servlet-mapping>元素的<servlet-name>子元素的设置值可以是同一个Servlet的注册名。
代码如下:
<servlet> <servlet-name>ServletDemo03</servlet-name> <servlet-class>xu.sha.servletDemo.Servlet03</servlet-class> </servlet> <servlet-mapping> <servlet-name>ServletDemo03</servlet-name> <url-pattern>/Servlet03</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>ServletDemo03</servlet-name> <url-pattern>/C.php</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>ServletDemo03</servlet-name> <url-pattern>/A.jsp</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>ServletDemo03</servlet-name> <url-pattern>/B.html</url-pattern> </servlet-mapping>
通过上面的配置,当我们想访问名称是Servlet03的Servlet,可以使用如下的几个地址去访问:
http://localhost:8080/web.project/Servlet03
http://localhost:8080/web.project/A.jsp
http://localhost:8080/web.project/B.html
http://localhost:8080/web.project/C.php
Servlet03被映射到了多个URL上。
5.2、Servlet访问URL使用*通配符映射
在Servlet映射到的URL中也可以使用*通配符,但是只能有两种固定的格式:一种格式是"*.扩展名",另一种格式是以正斜杠(/)开头并以"/*"结尾。例如:
*可以匹配任意的字符,所以此时可以用任意的URL去访问ServletDemo1这个Servlet。
对于如下的一些映射关系:
Servlet1 映射到 /abc/*
Servlet2 映射到 /*
Servlet3 映射到 /abc
Servlet4 映射到 *.do
问题:
当请求URL为“/abc/a.html”,“/abc/*”和“/*”都匹配,哪个servlet响应
Servlet引擎将调用Servlet1。
当请求URL为“/abc”时,“/abc/*”和“/abc”都匹配,哪个servlet响应
Servlet引擎将调用Servlet3。
当请求URL为“/abc/a.do”时,“/abc/*”和“*.do”都匹配,哪个servlet响应
Servlet引擎将调用Servlet1。
当请求URL为“/a.do”时,“/*”和“*.do”都匹配,哪个servlet响应
Servlet引擎将调用Servlet2。
当请求URL为“/xxx/yyy/a.do”时,“/*”和“*.do”都匹配,哪个servlet响应
Servlet引擎将调用Servlet2。
匹配的原则就是"谁长得更像就找谁"
5.3、Servlet与普通Java类的区别
- Servlet是一个供其他Java程序(Servlet引擎)调用的Java类,它不能独立运行,它的运行完全由Servlet引擎来控制和调度。
- 针对客户端的多次Servlet请求,通常情况下,服务器只会创建一个Servlet实例对象,也就是说Servlet实例对象一旦创建,它就会驻留在内存中,为后续的其它请求服务,直至web容器退出,servlet实例对象才会销毁。
- 在Servlet的整个生命周期内,Servlet的init方法只被调用一次。而对一个Servlet的每次访问请求都导致Servlet引擎调用一次servlet的service方法。对于每次访问请求,Servlet引擎都会创建一个新的HttpServletRequest请求对象和一个新的HttpServletResponse响应对象,然后将这两个对象作为参数传递给它调用的Servlet的service()方法,service方法再根据请求方式分别调用doXXX方法。
- 如果在<servlet>元素中配置了一个<load-on-startup>元素,那么WEB应用程序在启动时,就会装载并创建Servlet的实例对象、以及调用Servlet实例对象的init()方法。
举例:
<servlet>
<servlet-name>invoker</servlet-name>
<servlet-class>
org.apache.catalina.servlets.InvokerServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
用途:为web应用写一个InitServlet,这个servlet配置为启动时装载,为整个web应用创建必要的数据库表和数据。
5.4、缺省Servlet
如果某个Servlet的映射路径仅仅为一个正斜杠(/),那么这个Servlet就成为当前Web应用程序的缺省Servlet。
凡是在web.xml文件中找不到匹配的<servlet-mapping>元素的URL,它们的访问请求都将交给缺省Servlet处理,也就是说,缺省Servlet用于处理所有其他Servlet都不处理的访问请求。
代码如下:
<servlet>
<servlet-name>ServletDemo03</servlet-name>
<servlet-class>xu.sha.servletDemo.Servlet03</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ServletDemo03</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
在<tomcat的安装目录>\conf\web.xml文件中,注册了一个名称为org.apache.catalina.servlets.DefaultServlet的Servlet,并将这个Servlet设置为了缺省Servlet。
代码如下:
<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> <servlet-mapping> <servlet-name>default</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping>
当访问Tomcat服务器中的某个静态HTML文件和图片时,实际上是在访问这个缺省Servlet。