servlet详解

servlet的冰山一角

Servlet 是 Sun 公司推出的一种基于 Java 的动态网站开发技术, 是 Server Applet 的缩写,译为“服务器端小程序”,是一种使用 Java 语言来开发动态网站的技术
Java 是一种功能强大的通用型编程语言,可以处理 HTTP 请求,可以访问数据库,可以生成 HTML 代码,您完全可以使用原生 Java 来开发动态网站。但是,使用原生 Java 开发动态网站非常麻烦,需要自己解析 HTTP 请求的报头,需要自己分析用户的请求参数,需要自己加载数据库组件……种种原因导致使用原生 Java 开发动态网站几乎是一件不能被接受的事情。正是基于这种原因,Java 官方后来推出了 Servlet 技术,它对开发动态网站需要使用的原生 Java API 进行了封装,形成了一套新的 API,称为 Servlet API。
Servlet 基于 Java,可以使用几乎全部的 Java API,所以它的功能异常强大,完全可以胜任企业级开发,能够处理那些高并发、大吞吐量、业务逻辑复杂的应用场景。

运行原理

Web 服务器是整个动态网站的“大门”,用户的 HTTP 请求首先到达 Web 服务器,Web 服务器判断该请求是静态资源还是动态资源:如果是静态资源就直接返回,此时相当于用户下载了一个服务器上的文件;如果是动态资源将无法处理,必须将该请求转发给 Servlet 容器

Servlet 容器接收到请求以后,会根据配置文件(web.xml)找到对应的 Servlet 类,将它加载并实例化,然后调用其中的方法来处理用户请求;处理结束后,Servlet 容器将处理结果再转交给 Web 服务器,由 Web 服务器将处理结果进行封装,以 HTTP 响应的形式发送给最终的用户

servlet创建方式

在 Servlet 中,一个动态网页对应一个 Servlet 类,我们可以通过 web.xml 配置文件将 URL 路径和 Servlet 类对应起来。访问一个动态网页的过程,实际上是将对应的 Servlet 类加载、实例化并调用相关方法的过程;网页上显示的内容,就是通过 Servlet 类中的某些方法向浏览器输出的 HTML 语句,所以,使用 Servlet 创建动态网页的第一步,就是创建 Servlet 类。

HttpServlet 就是专为 HTTP 协议而量身打造的 Servlet 类。

一个动态页面对应一个 Servlet 类,开发一个动态页面就是编写一个 Servlet 类,当用户请求到达时,Servlet 容器会根据配置文件(web.xml)来决定调用哪个类。

web.xml 中各元素含义及用法如下

<web-app>: 根元素。

<servlet> :用于注册 Servlet

<servlet> 包含两个主要的子元素 <servlet-name> 和 <servlet-class>,分别用于指定 Servlet 的名称和 Servlet 的完整限定名(包名+类名)。

<servlet-mapping> :用于定义 Servlet 与 URL 之间的映射。

<servlet-mapping> 包含两个子元素 <servlet-name> 和 <url-pattern>,分别用于指定 Servlet 的名称和虚拟路径。

web.xml 的顶层标签 <web-app> 中有一个属性:metadata-complete,该属性用于指定当前 web.xml 是否是完全的。若该属性设置为 true,则容器在部署时将只依赖 web.xml,忽略所有的注解。若不配置该属性,或者将其设置为 false,则表示启用注解支持。

web.xml映射

客户端通过 URL 地址来访问 Web 服务器中的资源,Servlet 程序若想被外界访问,就必须被映射到一个 URL 地址上。很多时候,该 URL 地址和 Servlet 程序的物理路径(在硬盘上的存储位置)并不一致,因此它被称为虚拟路径。Servlet 与虚拟路径的对应关系就叫做 Servlet 虚拟路径映射

Servlet 虚拟路径映射可以被分为 2 类:

  • 单一映射 使用 web.xml、@WebServlet 实现单一映射,其中用<servlet> 和 <servlet-mapping> 元素实现

  • 多重映射 通过配置多个 <servlet-mapping> 元素、 <url-pattern>子元素,以字符串数组的形式@WebServlet 注解实现

Servlet匹配测试

package net.biancheng.www;

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

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

public class VirtualPathServlet extends HttpServlet {

    private static final long serialVersionUID = 1L;

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setContentType("text/html;charset=UTF-8");
        PrintWriter writer = resp.getWriter();
        // 向页面输出
        writer.write("本次访问的Servlet是:" + this.getServletName());
        writer.close();
    }

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

}
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://xmlns.jcp.org/xml/ns/javaee"
    xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
    id="WebApp_ID" metadata-complete="false" version="4.0">

    <servlet>
        <servlet-name>MyServlet1</servlet-name>
        <servlet-class>net.biancheng.www.VirtualPathServlet</servlet-class>
    </servlet>
    <servlet>
        <servlet-name>MyServlet2</servlet-name>
        <servlet-class>net.biancheng.www.VirtualPathServlet</servlet-class>
    </servlet>
    <servlet>
        <servlet-name>MyServlet3</servlet-name>
        <servlet-class>net.biancheng.www.VirtualPathServlet</servlet-class>
    </servlet>
    <servlet>
        <servlet-name>MyServlet4</servlet-name>
        <servlet-class>net.biancheng.www.VirtualPathServlet</servlet-class>
    </servlet>
    <servlet>
        <servlet-name>MyServlet5</servlet-name>
        <servlet-class>net.biancheng.www.VirtualPathServlet</servlet-class>
    </servlet>

    <!-- 完全路径匹配 -->
    <servlet-mapping>
        <servlet-name>MyServlet1</servlet-name>
        <url-pattern>/hello</url-pattern>
    </servlet-mapping>
    <!-- 目录匹配 -->
    <servlet-mapping>
        <servlet-name>MyServlet2</servlet-name>
        <url-pattern>/abc/my/*</url-pattern>
    </servlet-mapping>
    <!-- 目录匹配 -->
    <servlet-mapping>
        <servlet-name>MyServlet3</servlet-name>
        <url-pattern>/abc/*</url-pattern>
    </servlet-mapping>
    <!-- 扩展名匹配 -->
    <servlet-mapping>
        <servlet-name>MyServlet4</servlet-name>
        <url-pattern>*.do</url-pattern>
    </servlet-mapping>
    <!--缺省匹配 -->
    <servlet-mapping>
        <servlet-name>MyServlet5</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
</web-app>

启动 Tomcat 服务器,在地址栏中输入“http://localhost:8080/servletDemo/hello”,结果如下图。

注意

url网址访问 , 比如http:localhost:8080/虚拟项目路径/项目资源路径

项目的虚拟目录在webapps下面找

tomcat文件目录含义

  • conf 目录主要是用来存放 Tomcat 的配置文件

  • bin 目录用来存放 Tomcat 命令,主要分为两大类,一类是以.sh结尾的 Linux 命令,另一类是以.bat结尾的 Windows 命令。很多环境变量都在此处设置,例如 JDK 路径、Tomcat 路径等

  • lib 目录主要用来存放 Tomcat 运行需要加载的 jar 包。

  • logs 目录用来存放 Tomcat 在运行过程中产生的日志文件,清空该目录中的文件不会对 Tomcat 的运行带来影响。

  • temp 目录用来存放 Tomcat 在运行过程中产生的临时文件,清空该目录中的文件不会对 Tomcat 的运行带来影响

  • webapps 目录用来存放应用程序(也就是通常所说的网站),当 Tomcat 启动时会去加载 webapps 目录下的应用程序,我们编写的 Servlet 程序就可以放在这里。Tomcat 允许以文件夹、war 包、jar 包的形式发布应用。

  • work 目录用来存放 Tomcat 在运行时的编译文件(也即 class 字节码文件),例如 JSP 编译后的文件。清空 work 目录,然后重启 Tomcat,可以达到清除缓存的作用。

@WebServlet 注解 和 web.xml 的优缺点

在 Servlet 中,web.xml 扮演的角色十分的重要,它可以将所有的 Servlet 的配置集中进行管理,但是若项目中 Servelt 数量较多时,web.xml 的配置会变得十分的冗长。这种情况下,注解(Annotation)就是一种更好的选择。

@WebServlet 注解配置 Servlet

优点:@WebServlet 直接在 Servlet 类中使用,代码量少,配置简单。每个类只关注自身业务逻辑,与其他 Servlet 类互不干扰,适合多人同时开发。

缺点:Servlet 较多时,每个 Servlet 的配置分布在各自的类中,不便于查找和修改。

web.xml 配置文件配置 Servlet

优点:集中管理 Servlet 的配置,便于查找和修改。

缺点:代码较繁琐,可读性不强,不易于理解。

doGet和doPost

Servlet 没有 main() 方法,不能独立运行,但它可以作为 JavaWeb 应用的一个组件被部署到 Servlet 容器(tomcat)中,由容器来实例化和调用 Servlet 的方法,例如:doGet() 、doPost() 等。

doGet方法提交表单的时候会在url后边显示提交的内容,所以不安全,安全性差。因为是直接将数据显示在地址栏中,浏览器有缓冲,可记录用户信息。所以安全性低(杂糅)

doGet方法处理中文问题很困难,要写过滤器之类的

POST方式:适合大规模的数据传送。因为是以实体的方式传送的

在用户刷新时,GET方式:不会有任何提示,POST方式:会弹出提示框,问用户是否重新提交

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值