【Java】Servlet基础及应用

Servlet(Server Applet)是Java Servlet的简称,是为小服务程序或服务连接器,用Java编写的服务器端程序,主要功能在于交互式地浏览和修改数据,生成动态Web内容。嘿嘿嘿,以上解释来自百度百科,感觉听了并没有什么屁用。一般类似如此的解释,看完上个厕所回来基本就忘掉了。容我以自己的方式来解释一下Servlet,联系到更多日常开发用到的东西,希望能比较容易记住。


一.Servlet及Servlet容器

什么是Servlet?
1.Servlet是一个特殊的Java类,它没有类方法。
2.它不能运行在JVM上,它需要在特殊的容器上装载运行,由容器管理其生成和销毁。(这个容器当然就是Servlet容器,紧接着就会提到)
3.在编写Servlet的时候要遵循Servlet规范。
4.Servlet几乎能处理所有的http请求,并能够给客户端作出相应的http响应。
所以,总结以上四点,一个Servlet类就是一个Java类,并提供基于请求-响应模式的Web服务。

而Servlet容器又是什么呢?
Servlet容器是一个服务端程序,这个程序负责把请求转发给Servlet,交由Servlet处理,当Servlet处理完之后,
交由给Servlet容器,让Servlet容器将结果返回给客户端。
这也是为什么Servlet需要在特殊的容器上运行的原因。再将原因概括来讲就是:Servlet容器要装载和管理Servlet,包括它的创建、执行、销毁等,因此Servlet只有在Servlet容器中才能发挥其功能。


二.Servlet之Hello World

既然前面说明Servlet类就是一个Java类,并提供基于请求-响应模式的Web服务。为了解释起来不那么抽象,我们自然可以用hello world为例来做一个请求-响应的过程。
首先建立一个空白模板的maven的项目,然后为其添加一个web服务组件,使得该项目变为一个web项目,并为该项目部署服务器即可。
【Java】Servlet基础及应用_第1张图片
(如何用maven构建web项目并部署到Tomcat服务器,并非该篇文章要讲述的东西,如果不会可以自行查阅资料,我这边也推荐一篇博客供大家参考:http://www.cnblogs.com/wql025/p/5215570.html#autoid-1-0-0)
注意:在项目部署的时候请一定要在Modules中添加web组件,而Artifacts描述了当前项目发布的信息,就可以从Modules中选择进行添加。然后很多初学者在部署tomcat的时候找不到Artifacts,就是因为部署项目时Modules的配置中没有为项目配置web服务组件。如果没有为项目配置Web服务组件,那么就没有Artifact。(当前项目连Web项目都不是,哪儿来的Artifact,又部署什么呢?)
public class TestServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("doGet method");
        PrintWriter pw = resp.getWriter();
        pw.print("hello world");
        pw.close();
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        super.doPost(req, resp);
    }

    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("service method");
        super.service(req, resp);
    }
}
然后就新建一个类TestServlet来准备做一个hello world,既然要用Servlet来做,就让这个新建的类去继承HttpServlet。这样,我们新建的类就可以去实现HttpServlet的方法,这里我们先实现三个方法:service(), doGet(), doPost()。
service()方法是Servlet的核心,每当客户端请求时,Servlet容器将请求转发给Servlet对象,它的service()方法就会调用,而且传递给这个方法一个HttpServletRequest对象和HttpServletResponse对象作为参数。然后,当请求是以GET的方式发出的,那么service()方式就会把相应的请求转发给doGet()方法。
紧接着,Servlet容器又是如何接受到http请求的url呢?又是如何精准的转发给某个Servlet对象呢?这就要在web.xml文件中去进行配置。


    
    
        TestServlet
        TestServlet
    

    
        TestServlet
        /hello
    
首先,我在标签中去建立一个标签,为我要配置的Servlet取一个名字,再建立一个标签来定位目标Servlet类(这里用类的全限定名)。然后,在标签中去建立一个标签,将其联系到标签中的servlet-name,再建立一个标签来响应http请求。不难理解,通过这样的一个配置,Servlet容器就将http请求和Servlet对象精准的联系起来。
然后我们将tomcat启起来。
【Java】Servlet基础及应用_第2张图片
在浏览器中去访问本地服务器地址并接上/hello以发送一个http请求,得到了我们试图打印的hello world。
【Java】Servlet基础及应用_第3张图片
在控制台,我们发现了之前写在各Servlet方法中的打印语句。"service method"说明,当Http请求发送到servlet时,首先被调用的就是service()方法。而我们的http请求以默认的形式发送,即是GET请求,打印出来的"doGet method"语句也印证了servlet此时将请求转发到doGet()方法这个说法。
【Java】Servlet基础及应用_第4张图片
细心的你可能已经发现,servlet的处理流程恰好与上面描述的流程相反,不如让我们来总结一遍servlet处理流程:首先,发出http://localhost:8080/hello这个请求,servlet容器根据开发者在web.xml的配置,找到相应的servlet对象,并将请求转发给该servlet;然后,servlet开始处理请求,先调用自己的service()方法,开发者可以在这里初始化参数等;最后service()方法根据请求的方式,将请求又转发给doGet()方法,开发者在此可以进行业务逻辑的编写。


三.Servlet生命周期

Servlet生命周期分为三个阶段:初始化阶段,请求处理阶段,销毁阶段。分别对应init(), service(), destory()方法。
a)Servlet初始化对应Servlet的init方法:默认情况下只有当某客户端第一次请求某Servlet的时候,
Servlet容器 才会创建这个Servlet对象的实例,这个时候Servlet容 器才会 毁掉Servlet的init方法。
(有特殊情况如:通过配置元素更改)
b)Servlet的请求处理对应Servlet的Service方法:Servlet根据http的请求类型将不同的http请求转发给
不同的Servlet方法进行处理。
c)Servlet的销毁阶段对应的Servlet的destroy方法:在Servlet销毁之前,由Servlet容器进行回调,
主要是做一些资源的回收和清理的操作。
注:在Servlet中有两个init方法,一般情况下会选择无参数的哪一个。因为,如果选择有参数的init方法
就需要调用父类的init方法从而需要向中注入ServletConfig这个参数。 当你并不需要该参数的时,自然就不
需要具备该参数的方法。
依然以前面的例子来说明,在TestServlet类中重写init(), destory()方法如下:
public class TestServlet extends HttpServlet {
    @Override
    public void destroy() {
        System.out.println("destroy method");
    }

    @Override
    public void init() throws ServletException {
        System.out.println("init method");
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("doGet method");
        PrintWriter pw = resp.getWriter();
        pw.print("hello world");
        pw.close();
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        super.doPost(req, resp);
    }

    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("service method");
        super.service(req, resp);
    }
}
启动Tomcat并用浏览器发送一个本地的请求,间隔几秒钟再刷新一次,然后看控制台。
【Java】Servlet基础及应用_第5张图片
首先可以看到,在调用service()方法之前,首先调用了init()方法。其次,当我们重写刷新浏览器发出请求时,init()方法并没有再次被调用,就应征了前面提到的 默认情况下它在Servlet的生命周期中只会被调用一次。
然后我们将Tomcat停掉,就可以看见destory()方法被调用了。
【Java】Servlet基础及应用_第6张图片
当通过F:\apache-tomcat-8.5.14\bin\catalina.bat stop来停止服务器的时候,紧接着 Servlet容器进行回调destory()方法,最后才Disconnected from server。




至此,Servlet基础就介绍完了,欢迎大家留言或联系我,相互学习、共同进步。

你可能感兴趣的:(Java基础)