Servlet入门

Servlet是JavaWeb三大组件(Servlet,Filter,Listener)之一,是SUN公司提供的一门动态资源开发的技术,下面简单记录一下如何在IDEA下建立一个自定义Servlet、如何修改Servlet模板、Servlet运行过程简单分析等。html

IDEA建立自定义Servlet

Servlet是顶级接口,下面是GenericServlet抽象类,这个抽象类实现了Servlet的大部分方法,只有一个抽象方法service。若是要作web应用,须要扩展为httpServlet,它实现了Http协议。上一篇Tomcat入门已经介绍了手写一个简单Servlet并放到tomcat目录下,这里使用IDEA来建立并完成部署。java

(1)新建一个新项目,选择Java Enterprise,Application Server中找到本身安装的tomcat,选择Web Application,点击next。web

(2)Project name输入本身的项目名,这点相似eclipse,能够看到它的位置在D盘的IDEAproject目录下,IDEAproject相似eclipse中的workspace工做空间,点击finish。浏览器

(3) IDEA新建的项目,WEB-INF下是没有classes和lib的,须要手动创建文件夹并关联项目。tomcat

 

进入project structure设置界面(IDEA在eclipse使用习惯下使用ctrl+shift+alt+S),需设置java编译后输出的class路径和外部导入jar包的路径lib,就是刚才建立的目录。服务器

class输出文件夹关联设置:app

lib文件夹关联设置,选择Jar Directory:eclipse

勾选lib后确认。webapp

(4) 设置项目部署的位置,这里修改成部署到tomcat的webapp目录下。测试

(5)配置Tomcat服务器,选择Server选项,能够修改服务器名,After lauch不勾选,选择就是使用默认打开地址,这里使用咱们本身的打开路径,所以不勾选。On frame deactivation设置为Update classes and resources,表明鼠标离开IDEA界面也能够实现类和资源的更新。最后将Deploy application configured in Tomcat instance勾选上,表明支持热部署?

继续选择Deployment,Application Context名字设置和工程名字同样的名字,点击OK就完成前期基本配置。

自定义一个Servlet 

如图,IDEA中能够方便的建立servlet(选择Create New Servlet),只须要咱们重写doGet方法和doPost方法。

自动生成代码以下,在Servlet3.0版本中,除了配置web.xml来配置servlet,还可使用注解的方式,二者均可以实现,可是不能共存,不然启动tomcat就会报错。

 1 package com.boe.servlet;
 2 
 3 import javax.servlet.ServletException;
 4 import javax.servlet.annotation.WebServlet;
 5 import javax.servlet.http.HttpServlet;
 6 import javax.servlet.http.HttpServletRequest;
 7 import javax.servlet.http.HttpServletResponse;
 8 import java.io.IOException;
 9 
10 //@WebServlet("/MyFirstServlet")
11 public class MyFirstServlet extends HttpServlet {
12     protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
13         //测试向浏览器发送一段文字
14         response.getWriter().write("<a style='color:blue;font-family:微软雅黑;font-size:20px'>this is my first servlet</a>");
15     }
16 
17     protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
18         doPost(request, response);
19     }
20 }

等效web.xml中的以下配置

1     <!--配置servlet-->
2     <servlet>
3         <servlet-name>myservlet</servlet-name>
4         <servlet-class>com.boe.servlet.MyFirstServlet</servlet-class>
5     </servlet>
6     <servlet-mapping>
7         <servlet-name>myservlet</servlet-name>
8         <url-pattern>/MyFirstServlet</url-pattern>
9     </servlet-mapping>

部署完成后启动tomcat,访问servlet能够正常向页面返回信息(暂时不考虑中文乱码问题,后续考虑),如下是部署到tomcat的webapp下的目录结构。

测试结果。

这样就完成了一个基本的Servlet,查看HttpServlet源码,发现service方法底层会根据method类型,执行不一样的方法,如GET和POST请求,就会执行doGet和doPost方法,所以重写这两个方法,跟重写service方法效果同样,如下为service方法源码。

 1     protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
 2         String method = req.getMethod();
 3         long lastModified;
 4         if (method.equals("GET")) {
 5             lastModified = this.getLastModified(req);
 6             if (lastModified == -1L) {
 7                 this.doGet(req, resp);
 8             } else {
 9                 long ifModifiedSince;
10                 try {
11                     ifModifiedSince = req.getDateHeader("If-Modified-Since");
12                 } catch (IllegalArgumentException var9) {
13                     ifModifiedSince = -1L;
14                 }
15 
16                 if (ifModifiedSince < lastModified / 1000L * 1000L) {
17                     this.maybeSetLastModified(resp, lastModified);
18                     this.doGet(req, resp);
19                 } else {
20                     resp.setStatus(304);
21                 }
22             }
23         } else if (method.equals("HEAD")) {
24             lastModified = this.getLastModified(req);
25             this.maybeSetLastModified(resp, lastModified);
26             this.doHead(req, resp);
27         } else if (method.equals("POST")) {
28             this.doPost(req, resp);
29         } else if (method.equals("PUT")) {
30             this.doPut(req, resp);
31         } else if (method.equals("DELETE")) {
32             this.doDelete(req, resp);
33         } else if (method.equals("OPTIONS")) {
34             this.doOptions(req, resp);
35         } else if (method.equals("TRACE")) {
36             this.doTrace(req, resp);
37         } else {
38             String errMsg = lStrings.getString("http.method_not_implemented");
39             Object[] errArgs = new Object[]{method};
40             errMsg = MessageFormat.format(errMsg, errArgs);
41             resp.sendError(501, errMsg);
42         }
43 
44     }

访问原理分析

以下是request请求头和请求行里的内容,请求行里host为localhost表明访问的虚拟主机,另外默认端口号是80,经过这两个说明访问的是本机的tomcat服务器。若是Host中没写localhost就访问默认虚拟主机,这个在tomcat的server.xml中Engine标签的defaultHost属性指定了。而后请求行里还包括访问的资源路径,如MyServlet就是一个web应用的虚拟路径,经过它能够找到实际web资源的目录,这里使用的是第二种虚拟路径-实际路径映射的配置,能够在IDEA的tomcat目录下,找到同名的xml文件,里面写的就是实际资源的路径。

如下为文件路径和内容。

而后肯定了web资源的位置后,最后需读取web.xml或者@WebServlet中配置的关系,来肯定要访问的真实资源,这里web.xml中就指定了真实资源的位置,即com/boe/servlet/MyFirstServlet,这是一个手写的servlet,访问它后执行doGet方法,最后返回一个字符到页面。

访问静态资源

前面tomcat入门就知道,web目录下,WEB-INF目录外的图片,音频等资源为静态资源,也能够直接访问。本次将一张图片放到了web目录下,从新设置部署后能够直接读取图片内容,以下所示。

放入图片,到web目录下,注意不要放到WEB-INF下,万一放到WEB-INF下也能够,可是须要先建立一个static文件夹,将图片放入,也能够直接访问。

设置资源

从新部署后访问结果,发现能够直接访问。

为何能够访问静态资源呢,首先会读取当前web应用下的web.xml,匹配全部url-pattern发现没有匹配的资源,而后会读取conf/web.xml,调用缺省的servlet来匹配静态资源,若是匹配到就显示,没有就报错404。

servlet模板修改

Servlet默认的模板是包含name属性和value属性的,对应就是web.xml中的servlet-name和url-pattern,而且doGet方法和doPost须要单独实现,这里能够修改。

这样修改后的,就只有省略value属性后的地址,若是有多个参数,value就不能省略了。

Servlet运行过程与生命周期

运行过程:

i. 经过Host标签肯定访问虚拟主机。
ii. 经过资源名称部分肯定访问的是哪个web应用,能够设置缺省web应用。
iii. 经过资源名称部分肯定访问的是哪个web资源,这里就是servlet或者图片。
iv. 肯定是哪个Servlet资源后,会建立对应Servlet对象,执行其中的service方法,这里是执行doGet方法和doPost方法,本质上同样。
v. 在service方法执行完成以后,会将response缓冲区中的内容在服务器组织成必定结构。
vi. 最终将组织好的结果数据响应到浏览器中。
 
生命周期:
在Servlet被初次访问的时候,会在tomcat内存中建立一个当前Servlet的对象,而且会马上调用init方法完成初始化的操做。这个对象会驻留在内存中的,再次访问这个servlet时,都是访问这个对象,当web应用移除后,就会自动调用destroy方法完成销毁,人为调用这个方法无效。 
 

参考博文:

(1)http://www.javashuo.com/article/p-rehityym-a.html servlet

相关文章
相关标签/搜索