Servlet 详解

一、概念

1. Servlet

Servlet是server applet的缩写,译为:运行在服务器端的小程序

servlet就是一个接口,定义了java类被浏览器访问到[tomcat识别]的规则

我们可以自定义一个类,实现servlet接口,重写方法,实现逻辑

Servlet比较特殊,不需要new,自动就可以运行。也有创建、垃圾回收和销毁过程。

Servlet是JavaWeb的三大组件之一(Servlet、Filter、Listener),它属于动态资源。

Servlet的作用是处理请求,服务器会把接收到的请求交给Servlet来处理,在Servlet中通常需要:

接收请求数据
处理请求
完成响应

例如客户端发出登录请求,或者输出注册请求,这些请求都应该由Servlet来完成处理

Servlet需要我们自己来编写,每个Servlet必须实现javax.servlet.Servlet接口。Servlet对象驻留在服务器内存中。

2. servlet与servlet容器

Java Servlet(Java服务器小程序)是一个基于Java技术的Web组件,运行在服务器端,它由Servlet容器所管理,用于生成动态的内容。 Servlet是平台独立的Java类,编写一个Servlet,实际上就是按照Servlet规范编写一个Java类。Servlet被编译为平台独立 的字节码,可以被动态地加载到支持Java技术的Web服务器中运行。

Servlet容器(如 Tomcat)也叫做Servlet引擎,是Web服务器或应用程序服务器的一部分,用于在发送的请求和响应之上提供网络服务,解码基于 MIME的请求,格式化基于MIME的响应。Servlet没有main方法,不能独立运行,它必须被部署到Servlet容器中,由容器来实例化和调用 Servlet的方法(如doGet()和doPost()),Servlet容器在Servlet的生命周期内包容和管理Servlet。在JSP技术 推出后,管理和运行Servlet/JSP的容器也称为Web容器。

(注:常用的MIME类型:text/html,application/pdf,video/quicktime,application /java,image/jpeg,application/jar,application/octet-stream,application/x- zip)

有了servlet之后,用户通过单击某个链接或者直接在浏览器的地址栏中输入URL来访问Servlet,Web服务器接收到该请求后,并不是将 请求直接交给Servlet,而是交给Servlet容器。Servlet容器实例化Servlet,调用Servlet的一个特定方法对请求进行处理, 并产生一个响应。这个响应由Servlet容器返回给Web服务器,Web服务器包装这个响应,以HTTP响应的形式发送给Web浏览器。

二、简单示例

1、创建 java 工程

File >> New Project >>  Java Enterprise,工程命名为 ServletTest

2、在项目根目录创建目录: web/WEB-INF 

WEB-INF 下创建目录 classeslib

点击file菜单,选择project Structure (ctrl+alt+shift+s), 把当前项目的 Paths  输出路径(Output path)改成 WEB-INF 下的 classes 

3、在 src 中创建 Package  : com.crs811

在包中创建类文件:HelloServlet.java,内容如下:

package com.crs811;

import java.io.IOException;

import javax.servlet.Servlet;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

public class HelloServlet implements Servlet {
    @Override
    public void init(ServletConfig config) throws ServletException {
    }

    @Override
    public ServletConfig getServletConfig() {
        return null;
    }

    @Override
    public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
        //IDEA控制台输出: Hello World!!!
        System.out.println("Hello World!!!");

        PrintWriter out = servletResponse.getWriter();
        out.println("<h1>hello world</h1>");
    }

    @Override
    public String getServletInfo() {
        return null;
    }

    @Override
    public void destroy() {
    }
}

4、在 WEB-INF 中新建 web.xml 文件,web.xml文件是用来初始化配置信息:比如Welcome页面、servlet、servlet-mapping、filter、listener、启动加载级别等。内容如下:

<?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_4_0.xsd"
         version="4.0">

    <servlet>
        <servlet-name>HelloServlet</servlet-name>
        <servlet-class>com.crs811.HelloServlet</servlet-class>
    </servlet>

    <servlet-mapping>
        <servlet-name>HelloServlet</servlet-name>
        <url-pattern>/hello</url-pattern>
    </servlet-mapping>

</web-app>

5、配置 artifacts

Run >> Edit Configurations >> Deployment , 右方加号,如果没有 artifacts ,则需要添加,步骤如下

(1) 点击file菜单,选择project Structure (ctrl+alt+shift+s)

(2) 选择Modules, 找到需要部署的项目(ServletTest),右键,点击add,  找到web,点击web

(3) 选择Artifacts,然后点击+号,选择Web Application:exploded,然后选择from Modules, 选择对应的项目,点击ok即可,  添加好后,想要部署的项目就可以deployment中添加了

6、测试:

点击“运行”按钮运行项目,或在浏览器输入:http://localhost:8080/ServletTest_war_exploded/hello

则浏览器和控制台会输出 servlet 的内容:

浏览器:

控制台:

三、生命周期

首先加载servlet的class,实例化servlet,然后初始化servlet调用init()的方法,接着调用服务的service的方法,最后容器关闭时候调用destroy 销毁方法。

1.被创建:执行init方法,只执行一次

Servlet什么时候被创建?

--默认情况下,第一次被访问时,Servlet被创建,然后执行init方法;

--可以配置执行Servlet的创建时机;

2.提供服务:每个客户端请求都会执行service方法,执行多次,处理doGet和doPost方法

3.被销毁:当Servlet服务器正常关闭时,执行destroy方法,只执行一次

Servlet 调用过程详解,请点击下图看大图:

四、servlet 输出网页

在项目的包 com.crs811 中新建  WebpageServlet.java,内容如下:

package com.crs811;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet("/webpage")
public class WebpageServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        //设置response查询的码表
        //response.setCharacterEncoding("UTF-8");
        //通过一个头 Content-Type 告知客户端使用何种码表
        //response.setHeader("Content-Type", "text/html;charset=UTF-8");

        response.setContentType("text/html;charset=UTF-8");
        PrintWriter out=response.getWriter();
        out.println("<html>");
        out.println("<body>");
        out.println("<h1>要输入的内容.........</h1><p><font color='red'>我是红色文字</font></p>");
        out.println("</body>");
        out.println("</html>");
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doGet(request, response);
    }
}

浏览器端输入:http://localhost:8080/ServletTest_war_exploded/webpage

可以看到,这种输出HTML页面的方式很麻烦,HTML代码和java代码混杂在一起,不便于维护

因此才使用 jsp 来将 HTML 页面和java 事务逻辑分离,因此形成了 javaweb 的 MVC结构

涉及的知识点

1、HttpServlet

广义上,Servlet 即实现了 Servlet 接口 的类,当我们创建一个自定义类,实现 Servlet 接口 的时候,会发现有 5 个方法需要重写,有init【初始化】,destroy【销毁】,service【服务】,ServletConfig【Servlet配置】,getServletInfo【Serlvet信息】。
这样做的话每次都需要实现 5 个方法,太麻烦了!

因此改进的方法是继承 HttpServlet 类,该类已经默认实现了 Servlet 接口中的所有方法,在编写 Servlet 的时候,只需要重写需要的方法就好了,并且该类还在原有 Servlet 接口上添加了一些与 HTTP 协议处理相关的方法,比 Servlet 接口的功能更强大。

Servlet 处理请求的方法一共有三种:

实现 service() 方法
重写 doGet() 和 doPost() 方法,并在 doGet() 中添加一句this.doPost(req, resp);(因为无论是get或post请求提交的数据,处理方式都基本相同,下同)
重写 doGet() 和 doPost() 方法,并在 doPost() 中添加一句this.doGet()(req, resp)

2、注解

注解是 Servlet 3.0 提出的新特性,支持注解配置,这大大简化了我们的工作。

在之前的开发工作中,我们总是去 web.xml 文件中配置servlet,至少会出现8行:

而当一个项目中存在很多 Servlet ,那么配置文件就会变得非常臃肿,不便于后期的维护

在 Servlet 3.0 推出之后,我们可以使用注解来配置 Servlet,上面 8 行的配置可以简化为一行简单的注解:@WebServlet(name="WebpageServlet", urlPatterns="/webpage")

使用urlPatterns 或 value 定义访问的 URL,只有这个属性是必要的,name 是可以缺省的值,所以可以简写成:

@WebServlet("/foreServlet")


Comments are closed.