• Servlet入门


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

    IDEA创建自定义Servlet

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

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

    (2)Project name输入自己的项目名,这点类似eclipse,可以看到它的位置在D盘的IDEAproject目录下,IDEAproject类似eclipse中的workspace工作空间,点击finish。

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

     

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

    class输出文件夹关联设置:

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

    勾选lib后确认。

    (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)https://www.cnblogs.com/zyx110/p/10771172.html servlet

  • 相关阅读:
    SpringBoot使用过滤器、拦截器、切面(AOP),及其之间的区别和执行顺序
    发送POST请求,包含文件MultipartFile参数,普通字符串参数,请求头参数
    Linux安装Mongodb(附带SpringBoot整合MongoDB项目Demo)
    博客目录
    Ubuntu+Hexo+Github搭建个人博客
    Hexo+Github搭建个人博客
    Linux设备驱动程序学习----3.模块的编译和装载
    Linux设备驱动程序学习----2.内核模块与应用程序的对比
    Linux设备驱动程序学习----1.设备驱动程序简介
    Linux设备驱动程序学习----目录
  • 原文地址:https://www.cnblogs.com/youngchaolin/p/11502655.html
Copyright © 2020-2023  润新知