Servlet是JavaWeb三大组件(Servlet,Filter,Listener)之一,是SUN公司提供的一门动态资源开发的技术,下面简单记录一下如何在IDEA下建立一个自定义Servlet、如何修改Servlet模板、Servlet运行过程简单分析等。html
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就完成前期基本配置。
如图,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默认的模板是包含name属性和value属性的,对应就是web.xml中的servlet-name和url-pattern,而且doGet方法和doPost须要单独实现,这里能够修改。
这样修改后的,就只有省略value属性后的地址,若是有多个参数,value就不能省略了。
运行过程:
参考博文:
(1)http://www.javashuo.com/article/p-rehityym-a.html servlet