HttpServlet类的认识
HttpServlet的API
//伪类图
+ HttpServlet();
# doGet(req:HttpServletRequest, resp:HttpServletResponse):void
# getLastModified(req:HttpServletRequest):long
# doHead(req:HttpServletRequest, resp:HttpServletResponse):void
# doPost(req:HttpServletRequest, resp:HttpServletResponse):void
# doPut(req:HttpServletRequest, resp:HttpServletResponse):void
# doDelete(req:HttpServletRequest, resp:HttpServletResponse):void
# doOptions(req:HttpServletRequest, resp:HttpServletResponse):void
# doTrace(req:HttpServletRequest, resp:HttpServletResponse):void
# service(req:HttpServletRequest, resp:HttpServletResponse):void
+ service(req:ServletRequest, resp:ServletResponse):void
HttpServlet继承自GenericServlet类,两者都为抽象类,GenericServlet类实现了Servlet, ServletConfig, Serializable接口。当容器调用init()方法时,将传入的ServletConfig对象封装起来。GenericServlet并没有实现任何有关HTTP的方法。最初定义Servlet时并不限于它只能用于HTTP,所以HTTP的相关服务流程定义在HttpServlet的service()方法中。
设计模式认识:在这里使用了设计模式中的模板方法模式(模板方法模式在一个方法中定义了一个算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以在不改变算法结构的情况下,重新定义算法中的某些步骤)。这里的service()方法就是一个算法的骨架。
Tomcat中service()方法的流程
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String method = req.getMethod();//取得请求的方法
if (method.equals("GET")) {
//如果方法为GET
//...
doGet(req, resp);
} else if (method.equals("HEAD")) {
//如果方法为HEAD
//...
doHead(req, resp);
} else if (method.equals("POST")) {
//如果方法为POST
//...
doPost(req, resp);
} //...其他请求方式类似
}
当请求到来时,容器就会调用Servlet的service()方法,判断请求方式,在调用doGet(), doPost()等方法。所以要想对GET,POST请求进行处理,只需继承HttpServlet类后,重写对应的doGet(), doPost()方法。
部署Servlet文件web.xml
写好Servlet后,就要告诉Web容器关于这个Servlet的信息。Web容器会读取名为web.xml的部署描述文件。
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1">
<servlet>
<servlet-name>HelloWorld</servlet-name>
<servlet-class>cn.xhcoding.servlet.HelloWorld</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>HelloWorld</servlet-name>
<url-pattern>/hello.do</url-pattern>
</servlet-mapping>
</web-app>
<web-app>
开头标签中的东西,主要是Servlet版本,XML有关的信息。
<servlet>
标签中的<servlet-class>
告诉容器要加载那个类文件,注意要使用完全符合名称。<servlet-name>
告诉容器,为该类创建一个实例,并注册为HelloWorld这个名字(可以任意命名)。
接下来<servlet-mapping>
告诉容器,请求那个URL时,用哪个Servlet处理。<servlet-name>
告诉容器要使用的Servlet名字,<url-pattern>
告诉容器在请求这个URL时使用对应的Servlet。
Web容器的作用
当浏览器的请求来到HTTP服务器,而HTTP服务器转交给容器时,容器会创建一个代表当次请求的HttpServletRequest对象,并将请求相关信息设置给该对象。同时,容器创建一个HttpServletResponse对象,作为对客户端进行响应的Java对象。
接着,容器会根据web.xml的设置,找出处理该请求的Servlet,调用他的service()方法,将两个对象作为参数传入,接着就可以在对应的处理方法中使用这两个对象,如doGet()方法中。