Web工程和Servlet

news2024/11/14 5:21:09

使用idea创建web项目

第一种方式:使用原型创建web项目,

Archetype的选择如下图:

创建完成:

第二种方式:不使用原型创建web工程

点击new,选择tomcat的bin的上一级目录 

创建完毕

使用:
 

再webapp目录下创建静态资源(html文件) 

这是demo2.html的代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <h1>哈哈</h1>
</body>
</html>

设置:

选择edit configurations

把Application context的内容修改成"/"

运行

运行成功


 

为什么开始的页面是Hello World!

 再tomcat的conf文件夹中

有web.xml文件

里面的内容

是按照这个三个文件的顺序来执行开始页面的,所以我们可以创建一个index.html文件,看看会发生什么

可以发现开始页面已经发生变化

Servlet

之前我们使用的都是使用浏览器访问的静态资源即html,web资源除了静态资源还有动态资源,即数据可以实现变化,并且前端浏览器通过动态资源可以实现数据的交互。那么如果想实现客户端访问服务器的动态资源,需要我们在后端中直接定义类或者间接实现Servlet接口

实现Servlet

第一步创建web项目

第二步在pom.xml文件中导入servlet依赖

 <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.0.1</version>
        </dependency>

第三步在创建的web项目中自定义类实现Servlet接口

第四步:重写Servlet接口的所有方法

注意:导入 的是javax.servlet,而不是变成了tomcat10的jakarta.servlet,不然会出现HTTP状态 500 - 内部服务器错误

import javax.servlet.*;

import java.io.IOException;
//在创建的web项目中的自定义类实现Servlet
public class FirstServlet implements Servlet {

    @Override
    public void init(ServletConfig servletConfig) throws ServletException {

    }

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

    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
        System.out.println("servlet入门");
    }

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

    @Override
    public void destroy() {

    }
}

第五步:在Servlet接口的service的方法书写代码处理业务逻辑

第六步:在web.xml中配置访问Servlet的路径

代码

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="https://jakarta.ee/xml/ns/jakartaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-app_5_0.xsd"
         version="5.0">
<!--    配置访问的servlet路径-->
<!--
    1.<servlet>标签配置浏览器要访问的servlet类
    2.<servlet-class>com.hhh.servlet.FirstServlet</servlet-class>
        通过该标签配置要访问的servlet类的全路径(包名.类名)tomcat底层通过反射技术创建FirstServlet类的对象
        class c=Class.forName("com.hhh.servlet.FirstServlet");
        FirstServlet fs=c.newInstance();//调用FirstServlet类的无参构造方法
        最后通过对象调用service方法
     3.<servlet-name>FirstServlet</servlet-name>
        给FirstServlet类起别名FirstServlet
-->
    <servlet>
        <servlet-name>FirstServlet</servlet-name>
        <servlet-class>com.hhh.servlet.FirstServlet</servlet-class>
    </servlet>

<!--
        4.<servlet-mapping>表示配置的映射路径,映射到com.hhh.servlet.FirstServlet
        5.<servlet-name>FirstServlet</servlet-name>的文本值必须与<servlet>的子标签
        <servlet-name></servlet-name>文本值一样
        6. <url-pattern>/hello</url-pattern>浏览器通过该标签文本访问FirstServlet类
        http://localhost:8080/hello
-->
    <servlet-mapping>
        <servlet-name>FirstServlet</servlet-name>
        <url-pattern>/hello</url-pattern>
    </servlet-mapping>

</web-app>

注意:     <url-pattern>/hello</url-pattern>的文本值一定要加"/"

第七步:启动tomact

第八步:在浏览器访问servlet类

没有内容则成功 

接着回到idea中的终端中

发现输出了我们servlet入门,这样我们就算成功了 

Servlet的执行原理

 1.<servlet>标签配置浏览器要访问的servlet类
 2.<servlet-class>com.hhh.servlet.FirstServlet</servlet-class>
        通过该标签配置要访问的servlet类的全路径(包名.类名)tomcat底层通过反射技术创建FirstServlet类的对象
        class c=Class.forName("com.hhh.servlet.FirstServlet");
        FirstServlet fs=c.newInstance();//调用FirstServlet类的无参构造方法
        最后通过对象调用service方法

service方法的代码作用

        1.接收浏览器客户端请求

        2.处理业务逻辑(与后端交互)

        3.响应数据给浏览器

相当于service层
3.<servlet-name>FirstServlet</servlet-name>
        给FirstServlet类起别名FirstServlet

  4.<servlet-mapping>表示配置的映射路径,映射到com.hhh.servlet.FirstServlet
5.<servlet-name>FirstServlet</servlet-name>的文本值必须与<servlet>的子标签
        <servlet-name></servlet-name>文本值一样
6. <url-pattern>/hello</url-pattern>浏览器通过该标签文本访问FirstServlet类
        http://localhost:8080/hello

Servlet的生命周期

1.谁创建Servlet对象

         tomcat使用反射技术创建对象

2. 何时创建Servlet对象

        第一次访问Servlet类的时候创建Servlet对象,调用无参构造方法创建对象,使用对象立刻调用init方法进行初始化,init方法只执行一次。然后调用service方法处理业务逻辑

3.创建对象之后再次访问Servlet类的时候只会执行service方法

4.关闭tomcat服务器的时候,关闭之前使用Servlet类的对象调用destroy方法销毁资源

实现服务器启动就创建Servlet对象

现在是访问映射路径时才创建Servlet对象(http//localhost:8080/hello) 

我们要实现实现服务器启动就创建Servlet对象

方法: 使用<servlet>的子标签<load-on-startup>

    <servlet>
        <servlet-name>FirstServlet</servlet-name>
        <servlet-class>com.hhh.servlet.FirstServlet</servlet-class>
<!--
    服务器启动创建Servlet对象,文本默认值是-1表示第一次访问时才创建Servlet对象,如果文本值>0,表示tomcat启动时创建对象
    如果多个servlet都配置了该标签,那么文本值越小创建Servelt对象的优先级越高。        
-->
        <load-on-startup>1</load-on-startup>
    </servlet>

         服务器启动创建Servlet对象,文本默认值是-1表示第一次访问时才创建Servlet对象,如果文本值>0,表示tomcat启动时创建对象
    如果多个servlet都配置了该标签,那么文本值越小创建Servelt对象的优先级越高。 

 实现Servlet方式二:自定义类继承GenericServlet

好处:只需要开发者重写service方法

public class SecondServlet extends GenericServlet {
    //</editor-fold>
    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
        System.out.println("利用GenericServlet实现Servlet");
    }
}

使用快捷键ctrl + alt + u查看一个类的继承关系图

GenericServlet是一个抽象类

接着在web.xml中部署映射关系

 <servlet>
        <servlet-name>SecondServlet</servlet-name>
        <servlet-class>com.hhh.servlet.SecondServlet</servlet-class>
    </servlet>

    <servlet-mapping>
        <servlet-name>SecondServlet</servlet-name>
        <url-pattern>/second</url-pattern>
    </servlet-mapping>

实现Servlet方式三:自定义类继承抽象类HttpServlet

好处:处理http协议的(请求和响应),根据不同的请求方式做出不同的处理

重写父类的方法:ctrl+o

public class ThirdServlet extends HttpServlet {
    //post请求执行的方法
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("利用HttpServlet实现Servlet...post");
    }
    //get请求执行的方法
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("利用HttpServlet实现Servlet...get");
    }
}
<servlet>
        <servlet-name>ThirdServlet</servlet-name>
        <servlet-class>com.hhh.servlet.ThirdServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>ThirdServlet</servlet-name>
        <url-pattern>/Third</url-pattern>
    </servlet-mapping>

结果:
利用HttpServlet实现Servlet...get

继承关系:

Servlet的常见问题

1.HTTP 500异常

服务器代码异常

根据报错找代码问题

2.404 not found 找不到服务器资源

原因:自己的操作问题

是我们访问的资源在服务器中不存在

解决:
1.修改访问地址

2.在服务器中创建资源

3.访问的资源必须在target中,如果没有就执行clean命令,然后重新部署web项目

3.405

原因:调用父类HttpServlet中的doGet,doPost方法(如super.doGet())

4.启动服务器报错

注意:只要启动服务器报错基本都是路径问题

路径没有写 /

一个Servlet类映射多个路径

  <servlet>
        <servlet-name>ThirdServlet</servlet-name>
        <servlet-class>com.hhh.servlet.ThirdServlet</servlet-class>
    </servlet>

    <servlet-mapping>
        <servlet-name>ThirdServlet</servlet-name>
        <url-pattern>/Third</url-pattern>
    </servlet-mapping>

    <servlet-mapping>
        <servlet-name>ThirdServlet</servlet-name>
        <url-pattern>/third</url-pattern>
    </servlet-mapping>

Servlet映射路径配置规范

1.完全路径匹配

就是在  <url-pattern>/Third</url-pattern>标签文本中配置什么,那么浏览器地址栏就访问什么

如 http://localhost:8080/Third

2.目录匹配

/xx/*

在浏览器地址栏输入的路径只要以xx开头都会访问对于的Servlet类

   <servlet-mapping>
        <servlet-name>ThirdServlet</servlet-name>
        <url-pattern>/user/*</url-pattern>
    </servlet-mapping>

后缀名匹配

*.xx    注意:在web.xml文件中开头不能写  /

那么在浏览器地址栏只要以xx结尾的路径都会访问对应的Servlet类

 <servlet-mapping>
        <servlet-name>ThirdServlet</servlet-name>
        <url-pattern>*.do</url-pattern>
    </servlet-mapping>

Servlet路径优先级由高到低:
 完全路径匹配>目录匹配>后缀名匹配

如果又是以/user开头,又以.do结尾,会执行/user的Servlet类

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

重新思考:Netflix 的边缘负载均衡

声明 本文是对Netflix 博客的翻译 前言 ​ 在先前关于Zuul 2开源的文章中&#xff0c;我们简要概述了近期在负载均衡方面的一些工作。在这篇文章中&#xff0c;我们将更详细地介绍这项工作的原因、方法和结果。 ​ 因此&#xff0c;我们开始从Zuul和其他团队那里学习&#…

【限免】杂波环境下线性调频脉冲、巴克码、频率步进脉冲雷达MTI、脉冲压缩【附MATLAB代码】

来源&#xff1a;微信公众号&#xff1a;EW Frontier 本代码主要模拟杂波环境&#xff08;飞机、地杂波、鸟类信号&#xff09;下&#xff0c;Chirp脉冲、巴克码脉冲、频率步进脉冲雷达信号的脉冲压缩及MTI、​匹配滤波。 MATLAB主代码 % 定义参数 fs 1000; % 采样率 T 1; …

C语言 | Leetcode C语言题解之第106题从中序与后序遍历序列构造二叉树

题目&#xff1a; 题解&#xff1a; int post_idx;typedef struct {int key;int val;UT_hash_handle hh; } hashTable;hashTable* idx_map;void insertHashTable(int x, int y) {hashTable* rec malloc(sizeof(hashTable));rec->key x;rec->val y;HASH_ADD_INT(idx_m…

九、图形化脚本

多年来&#xff0c; shell脚本一直都被认为是枯燥乏味的。但如果你准备在图形化环境中运行脚本时&#xff0c;就未必如此了。有很多与脚本用户交互的方式并不依赖read和echo语句。 9.1 创建文本菜单 创建交互式shell脚本最常用的方法是使用菜单。提供各种选项可以帮助脚本用户…

牛客NC295 连续子链表最大和【simple 动态规划 Java/Go/PHP/C++】

题目 题目链接&#xff1a; https://www.nowcoder.com/practice/650b68dfa69d492d92645aecd7da9b21 思路 动态规划动态规划算法通过迭代遍历输入数组&#xff0c;维护一个额外的数组 dp 来记录截止到每个位置的最大连续子数组和&#xff0c;并利用一个变量 max_num 实时更新全…

面向可复用性和可维护性的设计模式 课程学习总结

什么是设计模式 设计模式&#xff1a;在软件设计中给定上下文中常见问题的通用的、可重用的解决方案。 设计模式分类 1. 创建型模式——Creational patterns 关注对象创建的过程 1.1 工厂方法模式 定义用于创建对象的接口&#xff0c;但让子类决定要实例化哪个类。工厂方…

swift中json和字典Dict或者数组相互转换,JSONSerialization的强大使用

在Swift中&#xff0c;你可以使用JSONSerialization类将JSON字符串转换为字典。要将 Swift 字典转换为 JSON 字符串&#xff0c;我们可以使用JSONSerialization类的data(withJSONObject:options:)方法。这个方法将字典转换为二进制数据&#xff0c;然后我们可以使用String(data…

Leetcode 环形链表|| 快慢指针解法

但是我们不知道 aaa 的值&#xff0c;该怎么办&#xff1f;依然是使用双指针法。考虑构建一个指针&#xff0c;此指针需要有以下性质&#xff1a;此指针和 slow 一起向前走 a 步后&#xff0c;两者在入口节点重合。那么从哪里走到入口节点需要 aaa 步&#xff1f;答案是链表头节…

SAP-CO成本控制概念之标准成本

“ 本篇介绍&#xff1a;标准成本的会计概念&#xff0c;标准成本的制定标准&#xff1b;通过结合会计标准成本的概念与SAP CO标准成本估算功能&#xff0c;更具象化的了解SAP如何实现标准成本管理&#xff0c;为后续学习SAP实际成本核算打下基础。” 01 — 背景需求 SAP实施…

【C++】深入解析C++智能指针:从auto_ptr到unique_ptr与shared_ptr

文章目录 前言&#xff1a;1. 智能指针的使用及原理2. C 98 标准库中的 auto_ptr:3. C 11 中的智能指针循环引用&#xff1a;shared_ptr 定制删除器 4. 内存泄漏总结&#xff1a; 前言&#xff1a; 随着C语言的发展&#xff0c;智能指针作为现代C编程中管理动态分配内存的一种…

infoq读书笔记-云原生时代,如何建设稳定性可观测体系?

而可观测性则是把Log、Trace、Metric拧成了一股绳&#xff0c;让三大支柱互相之间建立亲密的“血缘关系”&#xff0c;通过这种关系我们可以结构化的从整体到局部再到具体细节的观测业务&#xff1a; 图片来自网络如果把业务系统比作一座海上的冰山&#xff0c;监控仅能看到的…

02_前端三大件HTML

文章目录 HTML用于网页结构搭建1. 标签2. 客户端服务器交互流程3. 专业词汇4. html语法细节5. 安装VSCODE安装插件6. Live Server插件使用7. 标题&段落&换行&列表8. 超链接标签使用9. 图片10. 表格的写法11. 表单标签*(重点)12. 下拉框13. 页面布局标签14. 块元素和…

机器学习大模型驱动:未来的趋势与应用

文章目录 &#x1f4d1;前言一、什么是机器学习大模型&#xff1f;1.1 大模型的特点1.2 大模型的技术基础 二、大模型的技术实现2.1 Transformer 架构2.2 预训练和微调2.3 模型并行和数据并行 三、大模型的应用场景3.1 自然语言处理&#xff08;NLP&#xff09;3.2 计算机视觉&…

02324 自学考试 离散数学屈婉玲教材 目录

02324 自学考试 离散数学屈婉玲教材 目录 02324 自学考试 离散数学屈婉玲教材 02324离散数学全程班历年真题资料

21.2zabbix低级自动发现-mysql多实例

配置mysql多实例 注释&#xff1a;自动发现&#xff1a;创建监控主机&#xff1b;低级自动发现&#xff1a;创建监控项 mysql单实例是直接yum安装&#xff0c;开启mysql多实例 准备配置文件 #mysql3307实例 cp /etc/my.cnf /etc/my3307.cnf vim /etc/my3307.cnf [mysqld] dat…

Maven多环境打包配置

一、启动时指定环境配置文件 在启动springboot应用的jar包时&#xff0c;我们可以指定配置文件&#xff0c;通常把配置文件上传到linux服务器对应jar包的同级目录&#xff0c;或者统一的配置文件存放目录 java -jar your-app.jar --spring.config.location/opt/softs/applicat…

4.Redis之Redis的通用命令

0.Redis 实战操作 通过 redis-cli 客户端和 redis 服务器交互 涉及到很多的 redis 的命令 【redis 的命令非常非常多!!! 1.掌握常用命令(多操作多练习) 2.学会使用 redis 的文档-> 阅读文档, 是程序猿的基操!! redis 的命令非常非常多!!! 1.掌握常用命令(多操作多练习…

Golang文件操作

文章目录 文件操作基本介绍普通的文件操作方式&#xff08;os包&#xff09;带缓冲的文件操作方式&#xff08;bufio包&#xff09;文件拷贝操作&#xff08;io包&#xff09; 命令行参数基本介绍解析命令行参数&#xff08;flag包&#xff09; JSON基本介绍JSON序列化JSON反序…

【手把手带你搓组件库】从零开始实现Element Plus

从零开始实现Element Plus 前言亮点项目搭建1、创建项目初始化monorepo创建 .gitignore目录结构安装基础依赖配置文件创建各个分包入口utilscomponentscoreplaytheme 2、创建VitePress文档3、部署到Github Actions生成 GH_TOKENGitHub Page 演示 4、总结 前言 在本文中&#xf…

vim操作手册

vim分为插入模式、命令模式、底行模式。 插入模式&#xff1a;编辑模式 命令模式&#xff1a;允许使用者通过命令&#xff0c;来进行文本的编辑控制 底行模式&#xff1a;用来进行让vim进行包括但不限于shell进行交互 w&#xff1a;保存 wq&am…