Java Web(八)--Servlet(一)

介绍

官网:Servlet 3.1 API Documentation - Apache Tomcat 8.0.53

为什么需要?

提出需求: 请用你现有的html css javascript,开发网站,比如可以让用户留言/购物/支付?

引入我们动态网页(能和用户交互)技术===>Servlet

是什么?

处理请求和发送响应的过程是由一种叫做Servlet的程序来完成的,并且Servlet是为了解决实现动态页面而衍生的东西。

Tomcat 是Web应用服务器,是一个Servlet/JSP容器。 Tomcat 作为Servlet容器,负责处理客户请求,把请求传送给Servlet,并将Servlet的响应传送回给客户。而Servlet是一种运行在支持Java语言的服务器上的组件。 Servlet最常见的用途是扩展Java Web服务器功能,提供非常安全的,可移植的,易于使用的CGI替代品。【Tomcat部分详见Java Web(七)__Tomcat(二)-CSDN博客和Java Web(七)__Tomcat(一)-CSDN博客 】

 Java Servlet API 是Servlet容器(tomcat)和servlet之间的接口,它定义了serlvet的各种方法,还定义了Servlet容器传送给Servlet的对象类,其中最重要的就是ServletRequest和ServletResponse。所以说我们在编写servlet时,需要实现Servlet接口,按照其规范进行操作。

注:

 Servlet 类没有 main() 函数,不能独立运行,只能作为一个模块被载入到 Servlet 容器,然后由 Servlet 容器来实例化,并调用其中的方法;

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

浏览器访问 Servlet 流程分析 

注:

servlet3.0 前使用 web.xml 
servlet3.0 版本以后(包括 3.0)支持注解, 同时支持 web.xml。


手动编写Servlet

实现Servlet接口

需求:
1、开发一个 HelloServlet
2、当浏览器 访问 http://localhost:8080/web 应用名/helloServlet 时,后台输出 "hiHelloServelt"

实现:

1、编写类HelloServlet,实现  Servlet 接口

  •     1.创建javaweb工程,并配置好Tomcat
  •     2.添加servlet.jar(在Tomcat/lib)到工程web/WEB-INF/lib中
  •     3.在src 下 包 com.hspedu.servlet.HelloServlet.java ,并实现Servlet接口

2、实现  service 方法,处理请求,并响应数据

package com.lhyedu.servlet;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;

/**
 * 1. 开发一个Servlet 需要 实现Servlet接口
 * 2. 实现Servlet接口的方法5个
 */
public class HelloServlet02 implements Servlet {

    /**
     * 1.初始化 servlet
     * 2.当创建HelloServlet 实例时,会调用init方法
     * 3. 该方法只会被调用一次
     */
    @Override
    public void init(ServletConfig servletConfig) throws ServletException {
    }

    /**
     * 返回ServletConfig 也就是返回Servlet的配置
     */
    @Override
    public ServletConfig getServletConfig() {
        return null;
    }

    /**
     * 1. service方法处理浏览器的请求(包括get/post)
     * 2. 当浏览器每次请求Servlet时,就会调用一次service
     * 3. 当tomcat调用该方法时,会把http请求的数据封装成实现ServletRequest接口的request对象
     * 4. 通过servletRequest 对象,可以得到用户提交的数据
     * 5. servletResponse 对象可以用于返回数据给tomcat->浏览器
     */
    @Override
    public void service(ServletRequest servletRequest,
                        ServletResponse servletResponse) throws ServletException, IOException {
        HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
        String method = httpServletRequest.getMethod();
        if("GET".equals(method)) {
            doGet(); //用doGet() 处理GET请求
        } else if("POST".equals(method)) {
            doPost(); //用doPost() 处理POST请求
        }
    }

    /**
     * 用于响应get请求的
     */
    public void doGet() {
        System.out.println("doGet() 被调用..");
    }

    /**
     * 用于响应post请求的
     */
    public void doPost() {
        System.out.println("doPost() 被调用..");
    }

    /**
     * 返回servlet信息,使用较少
     */
    @Override
    public String getServletInfo() {
        return null;
    }

    /**
     * 1. 该方法是在servlet销毁时,被调用
     * 2. 只会调用一次
     */
    @Override
    public void destroy() {
        System.out.println("destroy() 被调用...");
    }
}

3、在  web.xml  中去配置  servlet 程序的访问地址,即:给hello.servlet提供对外访问的地址。  

<?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">

    <!--web.xml主要用来配置该web应用使用到的Servlet-->
    <!-- 配置HelloServlet -->
    <!--servlet标签: 给tomcat配置Servlet程序-->

    <servlet>
        <!--servlet-name标签: 给Servlet程序取一个别名(程序员决定), 该名字唯一;一般跟写的Servlet类名相同-->
        <!--servlet-class标签:Servlet的全限定类名,即Servlet类的位置: Tomcat在反射生成该Servlet需要使用。-->
        <servlet-name>HelloServlet</servlet-name>
        <servlet-class>HelloServlet</servlet-class>

        <!--load-on-startup 表示在tomcat 启动时,会自动的加载servlet实例-->
        <!--<load-on-startup>1</load-on-startup>-->
    </servlet>

    <!--servlet-mapping标签: 给Servlet程序配置方位地址-->

    <servlet-mapping>
        <!--servlet-name标签:告诉服务器,当前配置的地址给哪个Servlet使用-->
        <!--url-pattern标签:对外提供访问Servlet的url地址:http://ip[域名]:port/工程路径/helloServlet
            取名是程序员决定的,相当于项目名。【/符号一定要加上】-->

        <servlet-name>HelloServlet</servlet-name>
        <url-pattern>/helloServlet</url-pattern>

    </servlet-mapping>

执行步骤:

【1】首先浏览器通过http://localhost:8080/servletDemo/helloServlet来找到web.xml中的url-pattern;

【2】匹配到url-pattern后,就会找到servlet的名字helloServlet;

【3】通过servlet-name找到servlet-class【即servlet的位置】,然后到其中找到对应的处理方式进行处理。

 4、通过浏览器访问HelloServlet ,进行验证;

  • 浏览器输入:http://localhost:8080/web/HelloServlet
  • 服务后台输出:  hi,helloservlet......  

实现HttpServlet类__推荐方式

示意图:

package com.hspedu.servlet;

import javax.servlet.*;
import javax.servlet.http.*;
import java.io.IOException;

public class OKServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//可以写自己的业务处理代码
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//可以写自己的业务处理代码
    }
}

【1】热加载选项说明

on update action

  •     表示当我们更新操作时, Tomcat 会自动更新类和资源 
  •    当jsp/html 文件修改时,可以生效;但是如果你修改的 java 文件,需要 Redepoly 才会生效。

on frame deactivation

  •     表示 IDEA 失去焦点(比如最小化),也会导致  jsp/html 发生更新
  •    但是 java 修改了,还是需要 redeploy

【2】端口修改

只会影响到当前的项目,而不是去修改 server.xml。


DOS部署

在默认情况下,Tomcat 会自动加载 webapps 目录下的 JavaWeb 应用,并把它发布到名为 localhost 的虚拟主机中。

部署 JavaWeb 应用最快捷的方式:直接将 JavaWeb 应用的所有文件复制到 Tomcat 的 /webapps 目录下

运行方式:

  1.     开放式目录结构(只编译不打包);在开发阶段采用,方便调试
  2.     打包文件(WAR 文件):产品发布阶段时,应该将整个应用打包成 WAR 文件,再进行部署。Tomcat 启动时也会将 WAR 文件自动展开为开放式的目录结构。

 开放式目录结构__部署步骤

1. 进入 Windows DOS 命令行窗口

  •     使用快捷键 “Windows + R”,打开运行对话框
  •     在对话框输入cmd,点击“确定”,进入 Windows 系统命令行窗口

2. 引入 javax.servlet 包

先在命令行中输入set classpath=,然后将 servlet-api.jar 文件拖进命令行内,回车执行 。

  •     命令:set classpath = path
    •         path 表示引入 jar 包的路径
    •         set classpath命令用来为当前窗口设置临时环境变量,只在当前窗口下有效。

3. 编译 Servlet

  •     1)在命令提示符中使用 cd命令进入 MyServlet.java 所在的目录
  •     2)使用 javac -encoding UTF-8 -d . MyServlet.java 命令进行编译
  •     3)进入 MyServlet.java 文件所在的目录,可发现新增了编译后的目录和 .classes 字节码文件,即完成对 Servlet 的编译工作

4. 创建目录结构

    依照 JavaWeb 应用的固定目录结构,在 Tomcat 中为该 Servlet 创建目录。

  •     目录
    •         在 Tomcat 的 webapps 目录中创建 servletDemo(web 应用的名字,由自己定义)文件夹;
    •         在 servletDemo 文件夹内创建 WEB-INF 文件夹;
    •         在 WEB-INF 内创建 classes 文件夹;
    •         在 WEB-INF 内创建配置文件 web.xml(可以复制 \webapps\ROOT\WEB-INF 中的 web.xml 使用)

5. 将 Servlet 移动到 Tomcat 目录中

  •     编译好的字节码和目录移动到 Tomcat\webapps\servletDemo\WEB-INF\classes 目录下

6. 配置 web.xml

  •     对 webapps\servletDemo\WEB-INF 目录的 web.xml 中进行配置

7、访问

  •     进入 Tomcat\bin 目录下双击 startup.bat,启动 Tomcat。
  •     浏览器的地址栏中输入“http://localhost:8080/servletDemo/MyServlet”,访问 MyServlet

Servlet的生命周期

 Servlet 的生命周期由 Servlet 容器管理;在 javax.servlet.Servlet 接口中定义3 个方法:init()、service()、destory(),它们分别在 Servlet 生命周期的不同阶段被 Servlet 容器调用。

【1】初始化阶段

Servlet 容器(比如: Tomcat)加载 Servlet,加载完成后,Servlet 容器会创建一个 Servlet 实例并调用init()方法,init()方法只会调用一次。

    (1)加载和实例化Servlet

        加载成功后,容器会通过反射对 Servlet 进行实例化【编写 Servlet 类时,需要一个无参构造方法】;

        Servlet 容器装载 Servlet的情形:

  •             当容器启动或首次请求某个 Servlet 时,容器会读取 web.xml 或 @WebServlet 中的配置信息,对指定的 Servlet 进行加载;
  •             Servlet 重新装载时,浏览器再向 Servlet 发送请求的第 1 次;比如 tomcat 进行 redeploy;【redeploy 会销毁所有的Servlet 实例】。
通过在 web.xml 文件中添加<load-on-startup>1</load-on-startup>
 1 表示装载的顺序,默认值为0;

load-on-startup 是 web.xml 中的一个节点,是 servlet 元素的子元素,用来标记 Servlet 容器启动时是否初始化当前 Servlet,以及当前 Servlet 的初始化顺序

    (2)调用init()方法初始化Servlet实例

        在 Servlet 的整个生命周期内,init() 方法只能被调用一次。

        初始化期间,Servlet 实例可以通过 ServletConfig 对象获取在 web.xml 或者 @WebServlet 中配置的初始化参数。

【2】处理浏览器请求阶段(service 方法)

当初始化完成后,Servlet 容器会将该实例保存在内存中,通过调用它的 service() 方法,为接收到的请求服务。    

每收到一个 http 请求,服务器就会产生一个新的线程去处理;对于 Servlet 的每一次请求,Servlet 容器都会调用一次 service() 方法,并创建新的 ServletRequest 和 ServletResponse 对象;即 service() 方法在 Servlet 的整个生命周期中会被调用多次。

    Servlet 容器接收到来自客户端请求时,容器会针对该请求分别创建一个 ServletRequst 对象和 ServletResponse 对象,将它们以参数的形式传入 service() 方法内,并调用该方法对请求进行处理;

  •          ServletRequst 对象获取客户端的相关信息和请求信息;
  •         ServletResponse 对象将响应信息进行包装,返回给客户端;
  •         当 Servlet 容器将响应信息返回给客户端后,ServletRequst 对象与 ServletResponse 对象就会被销毁。
    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
        //count值,在不断的累计,说明HelloServlet是单例的
         count++;
       //tomcat每处理一次http请求,就生成一个新的线程
        System.out.println("hi,helloservlet......" + count + Thread.currentThread().getId());
    }

   注:执行 service() 方法前,init() 方法必须已成功执行;

【3】终止阶段 destory 方法(体现 Servlet 完整的生命周期)

    当web 应用被终止,或者Servlet 容器终止运行,或者Servlet 类重新装载时,会调用destroy()方法,释放该实例使用的资源;

比如重启tomcat ,或者  redeploy web 应用;例如:关闭数据库连接,关闭文件的输入流和输出流等,随后该实例被 Java 的垃圾收集器所回收。

    对于每个 Servlet 实例来说,destory() 方法只能被调用一次;

    注:要看到 destory 效果,需要保证 servlet 实例被创建过或者 Servlet 重新装载时(比如 redeploy)。


其他

部署动态网站

一般至少需要三个组件,分别是 Web 服务器、脚本语言运行时和数据库。例如,部署 PHP 网站一般选择「Apache + PHP 运行时 + MySQL」的组合。

【1】web服务器 

一种对外提供 Web 服务的软件,可以接收浏览器的 HTTP 请求,并将处理结果返回给浏览器。

  •             运行 PHP 网站一般选择 Apache 或者 Nginx;
  •             运行 ASP/ASP.NET 网站一般选择 IIS;
  •             运行 Python 网站一般选择内置的 WSGI 服务器模块——wsgiref

    通常所说的 Web 服务器,功能往往都比较单一,一般只能提供 http(s) 服务,让用户访问静态资源(HTML 文档、图片、CSS 文件、JavaScript 文件等)。它们不能执行任何编程语言,也不能访问数据库,更不能让用户注册和登录。

   若只有 Web 服务器,那您只能部署静态网站,不能部署动态网站。

【2】运行环境(运行时)

    习惯将以上各种支持脚本语言运行的部件统称为运行环境,或者运行时(Runtime)。开发网站使用的编程语言一般都是脚本语言(比如 PHP、ASP、Python)。

    部署网站时都是将源代码直接扔到服务器上,然而源代码自己并不能运行,必须要有解释器的支持。当用户访问动态页面时,解释器负责分析、编译和执行源代码,然后得到处理结果。

    解释器:执行脚本语言的核心部件。包含如下辅助性的部件:

  •             垃圾回收器:负责及时释放不需要的内存,腾出资源供其它页面使用
  •             标准库:任何编程语言都会附带标准库;它们提供了很多通用性的功能,极大地提高了开发效率,避免重复造轮子

【3】数据库

    Web 服务器不带数据库,编程语言也不带数据库。数据库是一款独立的软件,若要实现用户注册、发布文章、提交评论等功能,就必须安装一款数据库。

  •         比如 MySQL、Oracle、SQL Server 等。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/406864.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Linux权限的理解

一、Linux权限的概念 1.1Linux的两种用户 Linux下有两种用户&#xff1a;超级用户(root)和普通用户。 超级用户&#xff1a;可以再linux系统下做任何事情&#xff0c;不受限制 普通用户&#xff1a;在linux下做有限的事情。 超级用户的命令提示符是“#”&#xff0c;普通用户的…

深入了解Java泛型的底层原理

深入了解Java泛型的底层原理 在Java编程中&#xff0c;泛型是一项强大的特性&#xff0c;它允许我们编写更加通用和类型安全的代码。然而&#xff0c;对于许多开发者来说&#xff0c;泛型的底层原理可能并不清晰。本文将深入探讨Java泛型的底层实现原理&#xff0c;帮助您更好…

深入探索Linux:ACL权限、特殊位与隐藏属性的奥秘

前言&#xff1a; 在Linux系统中&#xff0c;文件和目录的权限管理是一项至关重要的任务。它决定了哪些用户或用户组可以对文件或目录执行读、写或执行等操作。传统的Linux权限模型基于用户、组和其他的概念&#xff0c;但随着时间的推移&#xff0c;这种模型在某些情况下显得…

Bean的声明周期

1.创建Bean对象&#xff08;调用无参数构造&#xff09; 2.给bean对象设置相关属性&#xff08;依赖注入&#xff09; 3.bean后置处理器&#xff08;初始化前执行&#xff0c;类似于过滤器和拦截器&#xff09; 首先要定义一个类MyBeanPost&#xff0c;实现BeanPostProcessor…

解锁业务灵活性:RuleGo规则引擎的高效解耦与实时响应秘籍

文章目录 入门指南&#xff1a;RuleGo规则引擎&#x1f389; 概述&#x1f3c6; RuleGo的优势&#x1f680; 特性&#x1fa81; 架构图使用场景&#x1f3af; 典型使用场景规则链概述RuleGo规则链优势规则链配置示例 入门指南&#xff1a;RuleGo规则引擎 &#x1f389; 概述 …

嵌入式中十大经典排序算法(代码实现),建议收藏

前言 兜兜转转&#xff0c;时间如白驹过隙。时间证明了一个道理&#xff0c;学啥忘啥&#xff0c;学的越快忘得越快&#xff0c;还不如踏踏实实写点笔记心得来的实在。 编程初学期间&#xff0c;排序算法是让人抓头最多的一块。为什么我连最简单的冒泡排序都理解不了&#xff…

【动态规划】【状态压缩】LCP04 覆盖

作者推荐 【广度优先搜索】【网格】【割点】【 推荐】1263. 推箱子 本文涉及知识点 动态规划汇总 LCP04 覆盖 你有一块棋盘&#xff0c;棋盘上有一些格子已经坏掉了。你还有无穷块大小为1 * 2的多米诺骨牌&#xff0c;你想把这些骨牌不重叠地覆盖在完好的格子上&#xff0…

C#学习总结

1、访问权限 方法默认访问修饰符&#xff1a;private 类默认访问修饰符&#xff1a;internal 类的成员默认访问修饰符&#xff1a;private 2、UserControl的使用 首先添加用户控件 使用时一种是通过代码添加&#xff0c;一种是通过拖动组件到xaml中

音频的“隐形保镖”——音频数字水印

在互联网时代&#xff0c;多媒体数字资源可以快捷地传播和获取&#xff0c;但同时也导致了数字音频产品的非法扩散、非法拷贝和非法篡改猖獗&#xff0c;数字音频产品的完整性和版权保护问题越来越凸显。文档和图像可以添加水印&#xff0c;音频同样可以添加水印&#xff0c;让…

【递归版】归并排序算法(1)

目录 MergeSort归并排序 整体思想 图解分析 代码实现 时间复杂度 递归&归并排序VS快速排序 MergeSort归并排序 归并排序&#xff08;MERGE-SORT&#xff09;是建立在归并操作上的一种有效的排序算法&#xff0c;该算法是采用分治法&#xff08;Divide and Conquer&a…

堆排序法的名字由来,排序步骤是什么,最坏情况下的排序次数如何计算得来的呢?

问题描述&#xff1a;堆排序法的名字由来&#xff0c;排序步骤是什么&#xff0c;最坏情况下的排序次数如何计算得来的呢&#xff1f; 问题解答&#xff1a; 堆排序法的名字来源于它使用了堆这种数据结构。堆是一种特殊的树形数据结构&#xff0c;具有以下特点&#xff1a;在…

基于RK3399 Android11适配OV13850 MIPI摄像头

目录 1、原理图分析2、编写和配置设备树3、调试方法4、遇到的问题与解决5、补丁 1、原理图分析 从上图可看出&#xff0c;我们需要关心的&#xff0c;①MIPI数据和时钟接口使用的是MIPI_TX1/RX1 ②I2C使用的是I2C4总线 ③RST复位引脚使用的是GPIO2_D2 ④PWDN使用的是GPIO1_C7 ⑤…

A星寻路算法详解

A星寻路算法 前言 A星寻路算法是静态路网中求解最短路径最有效的直接搜索方法&#xff0c;也是解决许多搜索问题的有效算法&#xff0c;它可以应对包括复杂地形&#xff0c;各种尺度的障碍物以及不同地形的路径规划问题。掌握A星寻路算法能够提高路径规划效率&#xff0c;应对…

大模型参数高效微调

参数高效微调目的 PEFT技术旨在通过最小化微调参数的数量和计算复杂度&#xff0c;来提高预训练模型在新任务上的性能&#xff0c;从而缓解大型预训练模型的训练成本。这样一来&#xff0c;即使计算资源受限&#xff0c;也可以利用预训练模型的知识来迅速适应新任务&#xff0…

域名 SSL 证书信息解析 API 数据接口

域名 SSL 证书信息解析 API 数据接口 网络工具&#xff0c;提供域名 SSL 证书信息解析&#xff0c;多信息查询&#xff0c;毫秒级响应。 1. 产品功能 提供域名 SSL 证书信息解析&#xff1b;最完整 SSL 属性信息解析&#xff1b;支持多种元素信息抽取&#xff0c;包括主题的可…

【Java程序设计】【C00278】基于Springboot的数码论坛管理系统(有论文)

基于Springboot的数码论坛管理系统&#xff08;有论文&#xff09; 项目简介项目获取开发环境项目技术运行截图 项目简介 这是一个基于Springboot的数码论坛系统 本系统分为系统功能模块、管理员功能模块以及用户功能模块。 系统功能模块&#xff1a;在系统首页可以查看首页、…

Linux:Jenkins:GitLab+Maven+Jenkins的部署

1.环境 我这里准备了三台centos7 1.用于部署gitlab 运行内存&#xff1a;6G 名字&#xff1a;Jenkins-GitLab 192.168.6.1 2.用于部署jenkins 运行内存&#xff1a;2G 名字&#xff1a;Jenkins-server 192.168.6.2 3.用于打包测试…

全面解析企业财务报表系列之五:阅读财报结构、顺序、模块与不同侧重

全面解析企业财务报表系列之五&#xff1a;阅读财报结构、顺序、模块与不同侧重 一、明确本次报表分析的目的二、确定报表分析的重点项目三、重点分析项目之间的联系四、资产负债表的阅读五、利润表的阅读六、现金流量表的阅读七、综合分析 一、明确本次报表分析的目的 报表的…

VBA即用型代码手册:立即保护所有工作表Code及插入多工作表Code

我给VBA下的定义&#xff1a;VBA是个人小型自动化处理的有效工具。可以大大提高自己的劳动效率&#xff0c;而且可以提高数据的准确性。我这里专注VBA,将我多年的经验汇集在VBA系列九套教程中。 作为我的学员要利用我的积木编程思想&#xff0c;积木编程最重要的是积木如何搭建…

【C语言】指针变量未初始化

我们知道&#xff1a;全局变量未赋初值&#xff0c;编译器会直接赋值为0&#xff1b;局部变量如果未赋初值&#xff0c;则会维持上一状态保存在该地址上的值&#xff0c;这个值是随机的。把这个值赋值给局部变量是没有意义的。 但是指针变量是如何解决不赋初值&#xff1f; 指…