3.1_43 JavaSE-WEB核心 P1 【Tomcat、Servlet】

相关链接


目录


P1 【Tomcat、Servlet】


  • 今日要掌握的内容:
    • Tomcat
      • 【应用】tomcat服务器的下载和安装
      • 【应用】tomcat如何部署项目
    • Servlet
      • 【应用】通过Idea创建JavaWeb项目(部署tomcat服务器),并且会添加依赖(classes,lib文件夹)
      • 【应用】通过Servlet接收:浏览器提交到服务器的数据
      • 【理解】Servlet原理、Servlet的生命周期
      • 【应用】doGet()方法和doPost()方法
      • 【掌握】模拟登陆案例

  • 所需资源【tomcat+jar包+servlet_src+jdk】
    • 链接:https://pan.baidu.com/s/1WzEIhZxXl7puaY_GTXEYtg
    • 提取码:dqt2

一、Tomcat


1.1 web开发基本概念


  • web项目框架示意图

JDBC接口: Java代码和数据库之间交互的规则;
Servlet接口: 服务器软件和Java代码之间交互的规则;
Http协议: 浏览器和服务器软件之间交互的规则;
在这里插入图片描述


1.1.1 web应用服务器
  • 可以让他人通过浏览器访问你电脑上 html文件,是因为,java代码等资源的软件

在这里插入图片描述


1.1.2 web资源

  存在于web服务器,供外界访问的资源就是 web资源,如:存在域 web服务器内部 htmljs图片视频等资源。

  静态资源 指web页面中供人们浏览的数据始终是不变的。如:图片视频音频html文件js文件等;场景:优酷上播放的电影

  动态资源 值web页面中供人们浏览的数据是由程序产生的,不同的时间点访问web页面看到的内容各不相同. 如: jsp/ServletASPPhp等;场景:12306买票,不同时刻票数不同

  JavaWeb领域的动态资源 指通过java代码生成html。


1.1.3 常用web服务器

  Tomcat 它是一个开源免费的web服务器,支持servlet规范和jsp规范, 它不支持JavaEE的13种规范。所属公司 apache,是Sun公司开发,为了推动Java语言的发展,免费开源给apache基金会;

  Weblogic: 大型的收费服务器,它完美支持JavaEE的所有规范。所属公司 oracle;

  Websphere: 大型的收费服务器,它完美支持JavaEE的所有规范, 所属公司 IBM;


1.1.4 BS架构、CS架构

  BS(Browser - Server): 客户端 - 服务器。例子: QQ,迅雷,快播,暴风影音,各种网络游戏客户端等等。上面介绍的几种web服务器,如:Tomcat就是BS架构的。

  CS(Client - Server): 浏览器 - 服务器。例子:所有网站(知乎,百度等等,)


1.2 Tomcat入门体验


  • Step1: 下载安装(http://tomcat.apache.org/
    • Tomcat7免费,但新版本会收费(Sun被Oralce收购后,新版本开始收费),且目前市场主流使用Tomcat7版本,新版本可能会导致操作系统(Win7、XP)不兼容

在这里插入图片描述

  • tar.gz 文件 是linux操作系统下的安装版本
  • exe文件是window操作系统下的安装版本
  • zip文件是window操作系统下压缩版本

在这里插入图片描述

  • Step2: 将下载好的tomcat服务器解压到某目录下,即可使用(没有中文名和空格)

在这里插入图片描述

  • Step3: 进入tomcat安装目录,大概了解目录结构

在这里插入图片描述

  • Step4: 找到conf/server.xml,第71行,将端口号(port)改为80

在这里插入图片描述

  • Step5: 【项目(web资源)发布】找到webapps目录,随便新建一个子目录,我这里新建子目录叫csdn

在这里插入图片描述

Step6: 进入子目录,随便放入几个html文件
在这里插入图片描述

  • Step7: 运行bin/startup.bat,启动tomcat服务

在这里插入图片描述

  • Step8: 启动成功后可以看到如下信息 Server startup in xxxx ms,(保持窗口开启,关掉这个窗口Tomcat服务也会一起关闭)

在这里插入图片描述

  • Step9: win+r 输入cmd进入dos窗口,输入ipconfig查看本地ip地址10.36.212.131

在这里插入图片描述

  • Step10: 打开浏览器在,在浏览器的地址栏中输入(浏览器默认端口号为80,可以省略不写):
    • a. http://ip地址:80/csdn/1.html
    • b. http://127.0.0.1:80/1.html
    • c. http://localhost:80/1.html
  • 就会自动找到资源目录下的文件访问,同一局域网其他电脑也可以通方式a访问

在这里插入图片描述


  • Step11: 运行bin/stop.bat,关闭tomcat服务

在这里插入图片描述


1.2.1 ⭐️ Tomcat原理(图解)⭐️

  项目(web资源)发布时,只需要把开发好的项目复制到webapps下面即可。这时不用重启tomcat服务器,tomcat服务器会自动的加载复制到webapps下面的所有项目资源。

在这里插入图片描述


1.2.2 常见问题1:无法启动、闪退

主要原因: 没有配置JAVA_HOME环境变量。JAVA_HOME 环境变量 中配置的是JDK的安装目录,不包含bin目录,不是tomcat的安装目录。

闪退的原因查看: 可以在startup.bat文件末尾添加 pause 命令,让运行的窗口暂停。
在这里插入图片描述
解决方式:

  Tomcat软件运行它需要依赖Java的运行环境。需要在电脑中配置JAVA_HOME环境变量;

  JAVA_HOME环境变量中配置的JDK的安装目录,不能包含bin目录。

在这里插入图片描述


1.2.3 常见问题2:端口被占用

  如果启动的时候,发生异常问题,这时有可能是端口被占用;Tomcat服务器在启动的时候默认占用本地的8080端口,如果这个端口被占用,启动的时候就会报错。


查看日志文件:

  通过查看 logs 目录下的日志文件catalina.date.log,确定异常信息
在这里插入图片描述

查看本地端口使用情况:

  在dos窗口中输入 netstat –nao 就可以查看当前端口的占用情况

在这里插入图片描述

  假如Tomcat配置端口号为65423,启动服务后Tomcat闪退,可以考虑是该端口号被占用导致启动失败而闪退,使用命令 netstat –nao | findstr xxxx 就可以按条件查询端口是被哪个进程(pid)占用了 => 可以看到pid为21132

在这里插入图片描述


1.2.2.1 方式1 根据pid结束该进程

  可以通过任务管理器查看该进程(按pid排序方便查找),从任务管理器结束进程,或 taskkill /pid 进程号 -t -f来结束该进程。

  注意: 如果这个进程是操作系统的任务进程,这时一般是不能停止这个进程。

在这里插入图片描述

  • 结束该进程后再次查看该进程,已经关闭

在这里插入图片描述

  • dos命令窗口结束进程后,从任务管理器也找不到 pid 21132

在这里插入图片描述

  • 备注: 如果看不到pid这一列,右击标题栏,可以手动打开

在这里插入图片描述

在这里插入图片描述


1.2.2.2 方式2 修改tomcat端口号

  • 找到conf/server.xml,第71行,将端口号(port)改为80
  • 依次启动bin/shutdown.bat 和 bin/startup.bat ,修改完server.xml文件必须重启服务器才能有效。

在这里插入图片描述



1.3 ⭐️Tomcat启动与关闭⭐️


  • 开启服务: 运行bin/startup.bat,启动tomcat服务

在这里插入图片描述

  • 关闭服务: 正常情况下,点击关闭按钮即可停止服务

在这里插入图片描述

  • 但有时startup.bat会运行一会之后窗口闪退,但服务还没有停止,网页也可以继续访问;这时候就需要运行bin/shutdown.bat,关闭tomcat服务

在这里插入图片描述


1.4 ⭐️Tomcat目录结构⭐️


在这里插入图片描述

  • bin: 里面记录的是tomcat的一些指令;
    • //掌握:startup.bat,shutdown.bat
  • conf: 配置和文件;
    • //掌握:server.xml,web.xml
  • libs: 引入的jar包;
  • logs: 日志文件;
  • temp: 临时文件;
  • webapps: 里面放的是我们写的Java项目;
  • work: 和JSP相关的;(目前先了解,P4中讲解)

1.4 Idead创建JavaWeb项目


1.4.1 版本选择

  首先JavaSE、JavaEE都是SUN公司自己定义的官方标准,Servlet/JSP是有自己的版本的,每次版本的升级都会带来重大更新;

  而Tomcat则是第三方的实现,由于它自身就是使用Java开发的,所以它的版本也和前面三个标准有密切的关系,而且具有一定的对应关系,详见下表。(来自tom.apache)


  • Apache Tomcat Versions

Servlet Spec | JSP Spec | EL Spec | WebSocket Spec | Authentication (JASIC) Spec | Apache Tomcat Version | Latest Released Version | Supported Java Versions
|:–|:–|:–|:–|:–|:–|:–|:–|:–|:–|
5.1 | TBD | TBD | TBD | TBD | 10.1.x | 10.1.0-M1 (alpha) | 8 and later
5.0 | 3.0 | 4.0 | 2.0 | 2.0 | 10.0.x | 10.0.7 | 8 and later
4.0 | 2.3 | 3.0 | 1.1 | 1.1 | 9.0.x | 9.0.48 | 8 and later
3.1 | 2.3 | 3.0 | 1.1 | 1.1 | 8.5.x | 8.5.68 | 7 and later
3.1 | 2.3 | 3.0 | 1.1 | N/A | 8.0.x (superseded) | 8.0.53 (superseded) | 7 and later
3.0 | 2.2 | 2.2 | 1.1 | N/A | 7.0.x | 7.0.109 | 6 and later(7 and later for WebSocket)
2.5 | 2.1 | 2.1 | N/A | N/A | 6.0.x (archived) | 6.0.53 (archived) | 5 and later
2.4 | 2.0 | N/A | N/A | N/A | 5.5.x (archived) | 5.5.36 (archived) | 1.4 and later
2.3 | 1.2 | N/A | N/A | N/A | 4.1.x (archived) | 4.1.40 (archived) | 1.3 and later
2.2 | 1.1 | N/A | N/A | N/A | 3.3.x (archived) | 3.3.2 (archived) | 1.1 and later

↓↓↓↓↓↓↓ 翻译 ↓↓↓↓↓↓↓

  • Apache Tomcat 版本

Servlet
版本 | JSP版本 | EL 版本 | WebSocket
版本 | 认证 (JASIC) 规范 | Apache Tomcat
版本 | 最新发布版本 | 支持的 Java 版本
|:–|:–|:–|:–|:–|:–|:–|:–|:–|:–|
5.1 | 待定 | 待定 | 待定 | 待定 | 10.1.x | 10.1.0-M1
(阿尔法) | 8 及以后
5.0 | 3.0 | 4.0 | 2.0 | 2.0 | 10.0.x | 10.0.7 | 8 及以后
4.0 | 2.3 | 3.0 | 1.1 | 1.1 | 9.0.x | 9.0.48 | 8 及以后
3.1 | 2.3 | 3.0 | 1.1 | 1.1 | 8.5.x | 8.5.68 | 7 及以后
3.1 | 2.3 | 3.0 | 1.1 | 不适用 | 8.0.x
(已取代) | 8.0.53
(已取代) | 7 及以后
3.0 | 2.2 | 2.2 | 1.1 | 不适用 | 7.0.x | 7.0.109 | 6 及更高版本
(WebSocket 为7及更高版本)
2.5 | 2.1 | 2.1 | 不适用 | 不适用 | 6.0.x
(已归档) | 6.0.53
(存档) | 5 及以后
2.4 | 2.0 | 不适用 | 不适用 | 不适用 | 5.5.x
(已归档) | 5.5.36
(存档) | 1.4 及更高版本
2.3 | 1.2 | 不适用 | 不适用 | 不适用 | 4.1.x
(已归档) | 4.1.40
(存档) | 1.3 及更高版本
2.2 | 1.1 | 不适用 | 不适用 | 不适用 | 3.3.x
(已归档) | 3.3.2
(存档) | 1.1 及更高版本


  • Tocmat、Servlet、JavaEE版本(不完全统计)
Tomcat版本Servlet版本JSP版本JSF版本JAVA EE版本
3.1JavaEE7
7.0.x3.02.2JavaEE6
6.0.x (archived)2.52.11.2、2.0JavaEE5
5.5.x (archived)2.42.01.1J2EE1.4
4.1.x (archived)2.31.2J2EE1.3
3.3.x (archived)2.21.1

  所以一会在构建web项目时,版本为 JavaEE6


1.4.2 ⭐️操作步骤⭐️

1.4.2.a 2020.2 之前的版本

  IntelliJ IDEA 2020.2 这个新版本,不管是在创建项目上,还是在进行一些选项的配置上,与之前的版本相比都有些许的不同。

  • Step1:创建项目

在这里插入图片描述

  • Step2:选择框架支持、JavaEE版本

在这里插入图片描述

  • Step3:项目名称

在这里插入图片描述

  • Step4: 修改index.jsp,编辑配置信息

在这里插入图片描述

  • Step5:配置tomcat

在这里插入图片描述

  • Step6:配置tomca

在这里插入图片描述

  • Step7:配置tomca

在这里插入图片描述

  • Step8:配置tomca

在这里插入图片描述

  • Step9:启动tomcat,查看页面

在这里插入图片描述


1.4.2.b 2020.2 (包括)之后版本

  IntelliJ IDEA 2020.2 这个新版本,不管是在创建项目上,还是在进行一些选项的配置上,与之前的版本相比都有些许的不同。

  • Step1:创建项目

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

  • Step2:添加框架的支持 ,创建完Java项目后,右击项目,选择Add Frameworks Support;

在这里插入图片描述

  • Step3:选择JavaEE版本 根据1.4.1中所讲述映射关系,Tomcat7对应JavaEE6

在这里插入图片描述

  • Step4:选择web项目 选中Web Application,默认create web.xml

在这里插入图片描述

  • 新增目录结构 web

在这里插入图片描述

  • Step6:Run -> Configurations

在这里插入图片描述

  • Step7:add -> Tomcat Server -> Local

在这里插入图片描述

  • Server标签页介绍

在这里插入图片描述

  • Step8:Server标签页(配置Tomcat_HOME) -> Application server -> Tomcat Home(tomcat安装目录)

在这里插入图片描述

在这里插入图片描述

  • Step9:Server标签页(点击update按钮时,IDEA执行什么操作) -> on ‘Update’ action,选择 redeployed,重新部署

在这里插入图片描述

  • Step10:Server标签页(光标失去焦点时,IDEA执行什么操作) -> on freame deactivation,选择 update classes and resources

在这里插入图片描述

  • Step11:Deployment标签页(Tomcat部署到项目) ,设置服务名(Name),添加依赖(artifact

在这里插入图片描述

在这里插入图片描述

  • Step12:工程路径(Application context) 可以对项目的访问地址进行修改,
    如果是/,则默认访问项目路径为localhost:端口号/,后面加上要访问的资源路径;
    如果是/abc,则默认访问项目路径为localhost:端口号/abc,后面加上要访问的资源路径;

在这里插入图片描述

  • 配置完成工具栏出现如下标志,但未启动

在这里插入图片描述

  • Step13:启动Tomcat,启动成功后会自动弹出首页 index.jsp(根据Step7 图2配置);

在这里插入图片描述

  • 启动成功

在这里插入图片描述

  • 浏览器访问

在这里插入图片描述


1.4.3 ⭐️Tomcat热部署配置⭐️

  热部署(失去焦点时的 Update resource 或 Update classes and resources)是Idea自带的一项功能,用于提升开发效率。官方文档说明
  在运行或调试应用程序时,可以直接修改源码并查看更改的结果,而无需重新启动服务器。根据工程的类型和运行配置,可能涉及资源和类的简单更新或重建和重新部署web工程 (artifacts)。共有以下三种触发方式:

在这里插入图片描述

在这里插入图片描述


  方式一: 点击按钮手动update

在这里插入图片描述


  方式二: 失去焦点,当这个光标不闪烁(比如切至其他软件),则自动触发失去焦点的动作

在这里插入图片描述

  • 方式三: 手动选择

在这里插入图片描述


  热部署功能体验

  Step1: 启动tomcat后,查看页面内容;

在这里插入图片描述

  Step2: 修改静态资源内容,;
在这里插入图片描述
  Step3: 刷新浏览器,可以直接显示更新后的代码;

在这里插入图片描述


on ‘Update’ action(点击update按钮时,IDEA执行什么操作):
  ○ update resources: 更新静态资源(*.html,*.jsp,*.css等)
  ○ update classes and resources: 更新静态资源(*.html,*.jsp,*.css等)、和动态资源(*.java) => (java 修改后,会被编译成.class 然后覆盖到target目录下)
  这里需要注意一下:
    在运行模式下,修改java文件时不会立刻生效;
    在debug模式下,修改java文件时可以立刻生效
    两种运行模式下,修改resources资源文件都是可以立刻生效。
  ○ redeployed 重新部署,把原来的war删掉,重新发布到tomcat里,不重启服务器(Tomcat)。更新静态资源(*.html,*.jsp,*.css等)、部分动态资源(*.java)、和配置文件(*.xml,*.properties等)。;
  ○ restart server: 重启服务器(Tomcat)。时间太久,不建议使用。


on freame deactivation(光标失去焦点时,IDEA执行什么操作):
  ○ Do nothing: 什么都不做;
  ○ update resources: 更新静态资源(*.html,*.jsp,*.css等)
  update classes and resources 更新静态资源(*.html,*.jsp,*.css,*.xml等)、和部分动态资源(*.java) => (java 修改后,会被编译成.class 然后覆盖到target目录下)
  这里需要注意一下:
    在运行模式下,修改java文件时不会立刻生效;
    在debug模式下,修改java文件时可以立刻生效
    两种运行模式下,修改resources资源文件都是可以立刻生效。


1.4.3.1 ⭐️小结⭐️

   这次练习中,选择了手动 update => redeployed(重新部署),失去焦点 => update classes and resources(更新资源)的方式;

  1. 热部署的意义在于,不需要鼠标点任何按钮,就能在浏览器看到最新修改后的代码,所以要在失去焦点动作选中(update classes and resource),并且debug启动;
  在这里插入图片描述
  2. 只有部署了war exploded项目时,

  3. 实际开发中,项目会比较大,机器性能不好的话不建议热部署,会比较消耗系统资源,建议手动update => update classes and resource,失去焦点 => Do Nothing

  4. update classes and resource只能更新部分动态和静态资源,不能更新系统配置文件。如果需要更新配置文件(比如pom.xml)和所有动态资源(java代码),就要用到redeployed;

这里groupies相当于1.2.1 Tomcat原理(图解)中的csdn项目路径
在这里插入图片描述

  6. 添加web项目(artifact)时,只有war exploded项目才能使用热部署功能,war项目不可以 => war exploded才会出现 on freame deactivation(失去焦点时动作)选项,默认是没有这一栏的;

在这里插入图片描述

默认没有 on freame deactivation(失去焦点时动作)选项
在这里插入图片描述


1.4.4 war 和 war exploded的区别

  • war模式: 将WEB工程以包的形式上传到服务器 ;
    • war模式这种可以称之为是发布模式,看名字也知道,这是先打成war包,再发布;
    • 获取上下文环境绝对路径,得到Tomcat的位置;
      String contextPath = request.getSession().getServletContext().getRealPath("/");

  • war exploded模式: 将WEB工程以当前文件夹的位置关系上传到服务器;
    • war exploded模式是直接把文件夹、jsp页面 、classes等等移到Tomcat 部署文件夹里面,进行加载部署。因此这种方式支持热部署,一般在开发的时候也是用这种方式。
    • 在平时开发的时候,使用热部署的话,应该对Tomcat进行相应的设置,这样的话修改的jsp界面什么的东西才可以及时的显示出来
    • 获取上下文环境绝对路径时,得到项目target的位置;
      String contextPath = request.getSession().getServletContext().getRealPath("/");

1.4.5 web项目目录结构

在这里插入图片描述

  1. 浏览器只能访问除了WEB-INF以外的目录,是访问不了的,写好的页面要直接放在web下

  2. 首页是JSP格式(Java Server Page:Java服务器页面),jsp可以实现html,css,和for循环等功能,例如:

在这里插入图片描述

    <table border=1>
      <%
        for(int i = 0;i < 2;i++){
      %>
      <tr><td>a</td><td>b</td></tr>
      <%
        }
      %>
    </table>

1.4.6 ⭐️web项目添加依赖(lib)⭐️

  • 添加依赖的目的
    在这里插入图片描述

1.4.6.1 准备工作

  • 准备工作1:web 下新建html页面,测试表单提交

在这里插入图片描述

在这里插入图片描述

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>测试表单数据提交</title>
</head>
<body>
这是一个普通的页面
</body>
</html>
  • 启动tomcat后,访问localhost/form.html

在这里插入图片描述

  • 准备工作2:src下指定路径创建java类
    在这里插入图片描述

1.4.6.2 操作步骤

  • Step1:Project structure(项目结构)

在这里插入图片描述

  • Step2:Libraries(添加依赖) -> New Project Library -> Java

在这里插入图片描述

  • Step3:Libraries(添加依赖)-> 找到lib目录

在这里插入图片描述

  • Step4:Libraries(添加依赖)-> 选择lib目录类型(Jar Directory)

在这里插入图片描述

  • Step5:Libraries(添加依赖)-> 选择lib目录所属模块,我这里只有一个,但实际可能会出现多个

在这里插入图片描述

  • Step6:Modules(配置模块) -> Dependencies(配置lib)

在这里插入图片描述

  • Step6:Modules(配置模块) -> Paths(配置classes路径)

在这里插入图片描述

  • Step7:测试classes路径,运行测试类后,这里出现编译后的.class文件,说明classes依赖配置成功;

在这里插入图片描述

  • Step8:添加DBUtils依赖 -> commons-dbutils-1.6.jar

添加依赖前可以看到是使用不了QueryRunner类的
在这里插入图片描述

把DBUtils依赖放入lib目录下
在这里插入图片描述

我这里导包到lib目录后还是读取不到(不清楚具体原因)
在这里插入图片描述

还是close project,重新进入就ok了
在这里插入图片描述


案例代码一测试jdbc依赖

package com.groupies.test01;

import org.apache.commons.dbutils.QueryRunner;

/**
 * @author GroupiesM
 * @date 2021/07/02
 * @introduction 测试jdbc依赖
 */
public class Test01 {
    public static void main(String[] args) {
        System.out.println("我是Test01测试类!");

        //DBUtils: QueryRunner
        QueryRunner qr = new QueryRunner();
    }
}


  • Step9:继续添加DBUtils依赖 -> mysql-connector-java-5.0.8-bin.jarc3p0-0.9.1.2.jar

在这里插入图片描述


二、Servlet


  • tomcat所依赖的servlet来自 -> Tomcat\lib目录下的servlet-api.jar
    在这里插入图片描述

  • 各知识点的分布(Servlet负责服务器和Java代码之间的交互)
    在这里插入图片描述

2.1 Servlet快速入门(浏览器访问Java代码)


  • Servlet概述: 服务器识别Java代码的规则
  • request: 请求,浏览器给服务器传输的数据
  • response: 响应,服务器给浏览器传输的数据

2.1.1 准备工作

  • Step1:Modules(配置模块) 添加Tomcat的依赖(tomcat/lib目录下的jar,其中就包括下面要使用的Servlet)到项目模块的依赖 ;

Project Structure -> Modules -> Dependencies -> ➕ -> Library
在这里插入图片描述

选择Tomcat(我也不清楚为什么这里出现2个,)
在这里插入图片描述

将Tomcat中的依赖导入项目,并保存
在这里插入图片描述

现在读取到该jar包依赖,并可以使用(Tomcat的Servlet接口)了
在这里插入图片描述


2.1.2 ⭐️操作步骤⭐️

步骤:
  1. 定义类,实现Servlet接口;
   //该类放在com.groupies.test02_Servlet快速入门;(后边讲分层详细讲解)

  2. 重写接口中所有的方法,把响应给浏览器的数据写到:service()方法中;
   //在service()方法中,给浏览器写一句回执信息(先不要写中文)

   response.getWriter().write("This is Demo1Servlet " + new Date().toLocaleString());
  3. 配置web.xml文件,注册映射
  4. 启动Tomcat,使用浏览器访问Servlet接口


  • Step1:定义类,实现Servlet接口

在这里插入图片描述

  • Step2:重写接口中所有的方法alt + insert把响应给浏览器的数据写到:service()方法中;

在这里插入图片描述

在这里插入图片描述


案例代码二Servlet快速入门【Servet类】

package com.groupies.test02_Servlet快速入门;

import javax.servlet.*;
import java.io.IOException;
import java.util.Date;

/**
 * @author GroupiesM
 * @date 2021/07/02
 * @introduction Servlet快速入门
 *
 *  步骤:
 *      1.定义类,实现Servlet接口
 *      2.重写接口中所有的方法,把响应给浏览器的数据写到:service()方法中
 *      3.配置web.xml文件,注册和映射
 * 		4.使用浏览器访问Servlet接口
 */
public class Demo2Servlet implements Servlet {

    @Override
    public void init(ServletConfig servletConfig) throws ServletException {
        //初始化的方法
    }
    @Override
    /**
     * @param request 请求
     * @param response 响应
     */
    public void service(ServletRequest request, ServletResponse response) throws ServletException, IOException {
        //和浏览器交互的代码:接收浏览器提交的数据,给浏览器相应数据
        //可以直接写到浏览器(先不要响应中文,会乱码)
        response.getWriter().write("This is Demo2Servlet   " + new Date().toLocaleString());

    }
    @Override
    public void destroy() {
        //销毁(servlet)的方法
    }

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

  • Step3:配置web.xml文件,注册和映射

在这里插入图片描述


案例代码二Servlet快速入门【web.xml】

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
		  http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
           version="3.0">

    <!--配置Demo2Servlet-->
    <!--确定要访问的Java代码-->
    <servlet>
        <!--起别名,可以随便写-->
        <servlet-name>Demo2Servlet</servlet-name>
        <!--确定唯一的JAva代码,要写全类名-->
        <servlet-class>com.groupies.test02_Servlet快速入门.Demo2Servlet</servlet-class>
    </servlet>
    <!--确定浏览器访问Java代码的路径-->
    <servlet-mapping>
        <!--引用别名,要和上边配置的别名一致-->
        <servlet-name>Demo2Servlet</servlet-name>
        <!--
            第一个"/"不表示           http://ip:端口号/项目名/
            "/Demo2Servlet"表示:   http://ip:端口号/项目名/Demo2Servlet
        -->
        <url-pattern>/Demo2Servlet</url-pattern>
    </servlet-mapping>
</web-app>

  • Step4:使用浏览器访问Servlet接口,响应(response)

在这里插入图片描述


2.1.3 ⭐️Servlet细节(图解)⭐️

在这里插入图片描述

对比于 1.2.1 ⭐️Tomcat原理(图解)⭐️,只是将资源路径配置到了web.xml中
在这里插入图片描述


2.1.4 ⭐️Servlet生命周期⭐️

规律:
  1. 第一次访问,会调用构造和初始化方法,只会调用一次
  2. 每次访问Servlet,都会调用Service方法
  3. 当前Servlet类被销毁时才会调用销毁方法


  • Step1:定义类 (Demo2Servlet),实现Servlet接口;

在这里插入图片描述

  • Step2:重写接口中所有的方法,创建构造方法,在每个方法中都输出到控制台;

案例代码三Servlet的生命周期【Servet类】

package com.groupies.test02_Servlet快速入门;

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

/**
 * @author GroupiesM
 * @date 2021/07/05
 * @introduction Servlet的生命周期
 *
 *  步骤:
 *      1.构造方法
 *      2.初始化方法
 *      3.Service方法
 *      4.销毁方法
 */
public class Demo3Servlet implements Servlet {
    //类比找工作的步骤
    public Demo3Servlet() {
        System.out.println("1.构造方法:提交简历,接收到面试邀约 *1");
    }

    @Override
    public void init(ServletConfig servletConfig) throws ServletException {
        System.out.println("2.初始化方法:面试,携带简历,离职证明,体检证明 *1");
    }

    @Override
    public void service(ServletRequest request, ServletResponse response) throws ServletException, IOException {
        response.getWriter().write("This is Demo3Servlet   " + new Date().toLocaleString());
        System.out.println("3.Service方法:敲代码,还是敲代码 *n");
    }

    @Override
    public void destroy() {
        System.out.println("4.销毁的功能:离职,提交离职报告,交接文档 *1");
    }

    @Override
    public ServletConfig getServletConfig() {
        return null;
    }
    @Override
    public String getServletInfo() {
        return null;
    }
}
  • Step3:配置web.xml文件,注册和映射;

案例代码三Servlet的生命周期【web.xml】

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
		  http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
           version="3.0">

    <!--配置Demo2Servlet-->
    <!--确定要访问的Java代码-->
    <servlet>
        <!--起别名,可以随便写-->
        <servlet-name>Demo2Servlet</servlet-name>
        <!--确定唯一的JAva代码,要写全类名-->
        <servlet-class>com.groupies.test02_Servlet快速入门.Demo2Servlet</servlet-class>
    </servlet>
    <!--确定浏览器访问Java代码的路径-->
    <servlet-mapping>
        <!--引用别名,要和上边配置的别名一致-->
        <servlet-name>Demo2Servlet</servlet-name>
        <!--
            第一个"/"不表示           http://ip:端口号/项目名/
            "/Demo2Servlet"表示:   http://ip:端口号/项目名/Demo2Servlet
        -->
        <url-pattern>/Demo2Servlet</url-pattern>
    </servlet-mapping>

    <!--配置Demo3Servlet-->
    <servlet>
        <servlet-name>Demo3Servlet</servlet-name>
        <servlet-class>com.groupies.test02_Servlet快速入门.Demo3Servlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>Demo3Servlet</servlet-name>
        <url-pattern>/Demo3Servlet</url-pattern>
    </servlet-mapping>
</web-app>
  • Step4:启动Tomcat,多次访问Demo2Servlet,查看控制台,调用该接口以后,会先构造、初始化、Service。之后每次访问都会再调用一次Service方法;

在这里插入图片描述

  • Step5:关闭Tomcat,查看控制台,体验Servet的四个生命周期(构造、初始化、service、销毁)
    在这里插入图片描述

2.2 ⭐️HttpServlet⭐️


  • 自定义HttpServlet
继承关系:
	1interface Servlet
	2abstract GenericServlet implements Servlet
	3abstract  HttpServlet extends GenericServlet
	4级 自定义class extends HttpServlet
==========================================================================
逻辑关系:
	1.Servlet接口:
		//服务器软件和Java代码之间交互的规则;
	2.GenericServlet抽象类
		//一般的servlet,只是实现了接口方法【注意:不针对任何网络协议】
	3.HttpServlet抽象类:
		//针对Http协议做的实现
		//Http有8种提交方式,其中GET和POST最常用
	4.自定义Servlet
		//例如:Demo4Servlet类
		//只需要重写doGet()方法和doPost()方法即可

2.2.1 快速创建HttpServlet

  问题: 每次我们都需要新建一个类,然后去实现Servlet接口,重写接口中所有的方法,最后配置web.xml文件,这样做比较麻烦,如何优化这个步骤?

  回答: 新建一个servlet即可(idea会自动让该类去继承HttpServlet,然后自动配置web.xml)  


  • Step1: 这里右键看不懂Servlet

在这里插入图片描述

  • Step2: 检查src是否设为Sources

在这里插入图片描述

  • Step3: 检查依赖是否导入

在这里插入图片描述

  • Step4: 检查factes是否选中了Source Roots,我这里没选,勾上以后点击ok保存

在这里插入图片描述

  • Step5: 右击目录,可以看到快速创建Servlet

在这里插入图片描述

  • Step6: 输入类名,路径,取消添加注解
    在这里插入图片描述
  • Step7: 创建成功

在这里插入图片描述

  • Step8: 自动配置web.xml中的<servlet>(要访问的Java代码),<servlet-mapping>(浏览器要访问的资源路径)需要手动配置

在这里插入图片描述

  • Step9: 实现doGet和doPost逻辑。这里的意思是无论哪种方式提交,都由doGet()方法统一实现

在这里插入图片描述


2.2.2 HttpServlet响应时乱码问题

  • Step1: 在自定义Servlet中的doGet中实现(响应中文)

在这里插入图片描述

  • Step2: 启动Tomcat,访问自定义Servlet,出现响应乱码问题

在这里插入图片描述

  • Step3: 【乱码原因:编解码不一致】【解决方法:编解码一致】

在这里插入图片描述


案例代码四HttpServlet响应时乱码问题【Servet类】

package com.groupies.test04_快速创建Servlet; /**
 * @author GroupiesM
 * @date 2021/07/05
 * @introduction 快速创建Servlet
 */

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

public class Demo4Servlet extends HttpServlet {
    /*
        你知道的get提交方式有哪些
            <form method="get">
            URL地址栏 xxx.xxx.xxx?username=abc&password=123
            <a></a>
    */
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request,response);
    }

    /*
        你知道的post提交方式有哪些?
        <form method="post">
    */
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //处理的代码逻辑 ...
        /**
         * 响应时乱码原因:编解码不一致
         * 响应时乱码解决方案:编解码一致
         */
        //解决响应时的乱码问题,默认编码规则:(java7=GBK,java8=UTF-8)
        response.setContentType("text/html;charset=utf-8");//告诉浏览器,用文本或页面方式解析
        response.getWriter().write("我是demo4Servlet的 doGet()方法" + new Date().toLocaleString());
    }
}

案例代码四HttpServlet响应时乱码问题【web.xml】

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
		  http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
           version="3.0">

    <!--配置Demo2Servlet-->
    <!--确定要访问的Java代码-->
    <servlet>
        <!--起别名,可以随便写-->
        <servlet-name>Demo2Servlet</servlet-name>
        <!--确定唯一的JAva代码,要写全类名-->
        <servlet-class>com.groupies.test02_Servlet快速入门.Demo2Servlet</servlet-class>
    </servlet>
    <!--确定浏览器访问Java代码的路径-->
    <servlet-mapping>
        <!--引用别名,要和上边配置的别名一致-->
        <servlet-name>Demo2Servlet</servlet-name>
        <!--
            第一个"/"不表示           http://ip:端口号/项目名/
            "/Demo2Servlet"表示:   http://ip:端口号/项目名/Demo2Servlet
        -->
        <url-pattern>/Demo2Servlet</url-pattern>
    </servlet-mapping>

    <!--配置Demo3Servlet-->
    <servlet>
        <servlet-name>Demo3Servlet</servlet-name>
        <servlet-class>com.groupies.test02_Servlet快速入门.Demo3Servlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>Demo3Servlet</servlet-name>
        <url-pattern>/Demo3Servlet</url-pattern>
    </servlet-mapping>

    <!--配置Demo4Servlet-->
    <servlet>
        <servlet-name>Demo4Servlet</servlet-name>
        <servlet-class>com.groupies.test04_快速创建Servlet.Demo4Servlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>Demo4Servlet</servlet-name>
        <url-pattern>/Demo4Servlet</url-pattern>
    </servlet-mapping>
</web-app>

2.2.3 获取浏览器提交的参数

  用户在浏览器可能通过标签提交到服务器一些数据, 我们怎么知道用户提交的是什么标签, 什么值呢?

  这就需要用到: 获取参数


2.2.3.1 创建表单和Servlet

Step1: 编辑form表单数据,用get方式提交, 提交至Demo5Servlet(现在还没有);

在这里插入图片描述

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>测试表单数据提交</title>
</head>
<body>
    <!--get请求是为了方便从url看到返回参数,开发时还是用post请求-->
    <!--action 属性规定当提交表单时,向何处发送表单数据。-->
    <form method="get" action="/demo5Servlet">
        用户名:<input type="text" name="username"><br>
        密码:<input type="password" name="password"><br>
        爱好:
            <input type="checkbox" name="hobby" value="lanqiu">篮球
            <input type="checkbox" name="hobby" value="zuqiu">乒乓球
            <input type="checkbox" name="hobby" value="ppq">足球
        <input type="submit" value="点我提交">
    </form>
</body>
</html>

Step2: 重启Tomcat,访问form表单,填写表单后点击提交;

在这里插入图片描述

Step3: 可以从url看到请求参数username=groupies&password=123&hobby=lanqiu&hobby=zuqiu

在这里插入图片描述

Step5: 快速创建Servlet并配置web.xml(略,详见2.2.1)

在这里插入图片描述


2.2.3.2 接收浏览器提交的数据(两种方式)

  HTTPServletRequest 的,成员方法

 //根据表单项name的属性值, 获取非多选框的值.
 String getPrrameter(String name);

 //根据表单项name的属性值, 获取多选框的值.
 String[] getParameterValues(String name); 

 //由服务器创建的map, 表单项的name属性值作为key, 用户填写或者选择的值作为值.
 Map<String,String[]> getParameterMap();
  • Step1: 自定义Servlet类接收参数

在这里插入图片描述


案例代码五获取浏览器提交的参数【Servet类】

package com.groupies.test05_获取浏览器提交的参数; /**
 * @author GroupiesM
 * @date 2021/07/05
 * @introduction 接收浏览器提交的数据
 * //1.根据表单项name的属性值, 获取非多选框的值.
 * String getPrrameter(String name);
 * <p>
 * //2.根据表单项name的属性值, 获取多选框的值.
 * String[] getParameterValues(String name);
 * <p>
 * //3.由服务器创建的map, 表单项的name属性值作为key, 用户填写或者选择的值作为值.
 * Map<String,String[]> getParameterMap();
 */

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Arrays;
import java.util.Map;

public class Demo5Servlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        /*接收浏览器提交的数据*/

        //方式一:通过参数名获取值
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        String[] hobbies = request.getParameterValues("hobby");

        System.out.println("username = " + username);
        System.out.println("password = " + password);
        System.out.println("hobby = " + Arrays.toString(hobbies));
        System.out.println("=======================================");

        //方式二:程序自动封装参数为:Map集合
        Map<String, String[]> map = request.getParameterMap();
        //遍历双列集合
        for (String key : map.keySet()) {
            System.out.println(key + " === " + Arrays.toString(map.get(key)));
        }
    }
}

案例代码五获取浏览器提交的参数【web.xml】

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
		  http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
           version="3.0">

    <!--配置Demo2Servlet-->
    <!--确定要访问的Java代码-->
    <servlet>
        <!--起别名,可以随便写-->
        <servlet-name>Demo2Servlet</servlet-name>
        <!--确定唯一的JAva代码,要写全类名-->
        <servlet-class>com.groupies.test02_Servlet快速入门.Demo2Servlet</servlet-class>
    </servlet>
    <!--确定浏览器访问Java代码的路径-->
    <servlet-mapping>
        <!--引用别名,要和上边配置的别名一致-->
        <servlet-name>Demo2Servlet</servlet-name>
        <!--
            第一个"/"不表示           http://ip:端口号/项目名/
            "/demo2Servlet"表示:   http://ip:端口号/项目名/demo2Servlet
        -->
        <url-pattern>/demo2Servlet</url-pattern>
    </servlet-mapping>

    <!--配置Demo3Servlet-->
    <servlet>
        <servlet-name>Demo3Servlet</servlet-name>
        <servlet-class>com.groupies.test02_Servlet快速入门.Demo3Servlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>Demo3Servlet</servlet-name>
        <url-pattern>/demo3Servlet</url-pattern>
    </servlet-mapping>

    <!--配置Demo4Servlet-->
    <servlet>
        <servlet-name>Demo4Servlet</servlet-name>
        <servlet-class>com.groupies.test04_快速创建Servlet.Demo4Servlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>Demo4Servlet</servlet-name>
        <url-pattern>/demo4Servlet</url-pattern>
    </servlet-mapping>

    <!--配置Demo5Servlet-->
    <servlet>
        <servlet-name>Demo5Servlet</servlet-name>
        <servlet-class>com.groupies.test05_获取浏览器提交的参数.Demo5Servlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>Demo5Servlet</servlet-name>
        <url-pattern>/demo5Servlet</url-pattern>
    </servlet-mapping>
</web-app>

  • Step2: 提交表单数据,查看控制台(两种方式)

在这里插入图片描述


2.3 web.xml中url-pattern的三种写法


  在访问url时,如何保证不同的url能访问同一个资源路径呢?

在这里插入图片描述

在这里插入图片描述


2.3.1 普通写法

  方式一: 普通写法,修改配置文件后后重启Tomcat

在这里插入图片描述

    <!--配置Demo4Servlet-->
    <servlet>
        <servlet-name>Demo4Servlet</servlet-name>
        <servlet-class>com.groupies.test04_快速创建Servlet.Demo4Servlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>Demo4Servlet</servlet-name>
        <!--方式一:普通写法-->
        <url-pattern>/Demo4Servlet</url-pattern>
        <url-pattern>/Demo4Servlet/aa</url-pattern>
        <url-pattern>/Demo4Servlet/aa/bb</url-pattern>
        <url-pattern>/Demo4Servlet/aa/bb/cc</url-pattern>
    </servlet-mapping>

  访问:http://localhost/Demo4Servlet/aa?id=1

在这里插入图片描述


2.3.2 通配符

  方式二: 通配符,修改配置文件后后重启Tomcat

在这里插入图片描述

    <!--配置Demo4Servlet-->
    <servlet>
        <servlet-name>Demo4Servlet</servlet-name>
        <servlet-class>com.groupies.test04_快速创建Servlet.Demo4Servlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>Demo4Servlet</servlet-name>
        <!--方式二:通配符-->
        <!--*表示后面的内容可以随便写-->
		<url-pattern>/Demo4Servlet/*</url-pattern>
    </servlet-mapping>

  访问:http://localhost/Demo4Servlet/a/b/c/d.efg?id=2

在这里插入图片描述

2.3.3 扩展名匹配

  方式三: 扩展名匹配,修改配置文件后后重启Tomcat

在这里插入图片描述

    <!--配置Demo4Servlet-->
    <servlet>
        <servlet-name>Demo4Servlet</servlet-name>
        <servlet-class>com.groupies.test04_快速创建Servlet.Demo4Servlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>Demo4Servlet</servlet-name>
        <!--方式三:扩展名匹配-->
        <!--
            前边随便写,后缀名必须是:.hh
            例如: http://ip地址:端口号/随便写... .hh
        -->
        <url-pattern>*.hh</url-pattern>
    </servlet-mapping>

  访问:http://localhost/Demo4Servlet/aa/bb/d/eee.hh?id=3

![在这里插入图片描述](https://img-blog.csdnimg.cn/20210705155113208.png]

  访问:http://localhost/Demo4Servlet/aa/bb/d/eee.h?id=3,扩展名不匹配,无法访问

在这里插入图片描述


2.3.4 三种都匹配上,执行哪个

  • 原则1: 级别不同,按照 优先级 匹配(普通写法>通配符>扩展名)
  • 原则2: 级别相同,按照 相似度 最高的匹配

  • 原则1假设: Servlet映射路径
    • Servlet1 映射路径为 /abc  普通写法
    • Servlet2 映射路径为 /abc/*通配符
    • Servlet3 映射路径为 /*    扩展名匹配

  • 访问路径 localhost/abc 时,级别不同,按照 优先级 匹配(普通写法>通配符>扩展名)
    • 原则1结果: 访问的是Servlet1

  • 原则2假设: Servlet映射路径
    • Servlet1 映射路径为 /abc/*通配符
    • Servlet2 映射路径为 /*    通配符

  • 访问路径 localhost/abc/ddd 时,级别相同,按照 相似度 高的匹配
    • 原则2结果: 访问的是Servlet1

2.4 ServletConfig


  • 作用: 配置当前servlet的配置信息

  • 特点: 每个Servlet都会有一个对应的ServletConfig对象


为什么要有ServletConfig对象呢?

  大家可以把ServletConfig对象想象成是一个海飞丝洗发水, 海飞丝是不是有不同容量的, 有80ml, 200ml, 500ml等, 我们使用成员变量来保存, 每次更改都需求修改java代码, 再重新编译class文件, 再重新部署到服务器软件中, 是不是很麻烦? 而且你让一个非java程序员去做,是否存在难度?

  我们能否只修改容量值, 重启服务器就搞定, 这时就用到了ServletConfig对象。

在这里插入图片描述


案例代码六获取ServletConfig【Servlet类】

package com.groupies.test06_ServletConfig; /**
 * @author GroupiesM
 * @date 2021/07/05
 * @introduction 获取ServletConfig
 */

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Date;

public class Demo6Servlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {
        doGet(request, response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("text/html;charset=UTF-8");
        response.getWriter().write("我是demo6Servlet的 doGet()方法" + new Date().toLocaleString());

        // 当前servlet的配置信息 被服务器封装到config对象,再将config在初始化期间传给Servlet
        // 1 获取servletConfig对象
        ServletConfig cfg = this.getServletConfig();
        // 2 从config对象中取出数据
        int size = Integer.parseInt(cfg.getInitParameter("size"));
        System.out.println(size + "ml 的 海飞丝洗发水!!!");
    }
}

案例代码六获取ServletConfig【web.xml】

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
		  http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
           version="3.0">

    <!--配置Demo2Servlet-->
    <!--确定要访问的Java代码-->
    <servlet>
        <!--起别名,可以随便写-->
        <servlet-name>Demo2Servlet</servlet-name>
        <!--确定唯一的JAva代码,要写全类名-->
        <servlet-class>com.groupies.test02_Servlet快速入门.Demo2Servlet</servlet-class>
    </servlet>
    <!--确定浏览器访问Java代码的路径-->
    <servlet-mapping>
        <!--引用别名,要和上边配置的别名一致-->
        <servlet-name>Demo2Servlet</servlet-name>
        <!--
            第一个"/"不表示           http://ip:端口号/项目名/
            "/demo2Servlet"表示:   http://ip:端口号/项目名/demo2Servlet
        -->
        <url-pattern>/demo2Servlet</url-pattern>
    </servlet-mapping>

    <!--配置Demo3Servlet-->
    <servlet>
        <servlet-name>Demo3Servlet</servlet-name>
        <servlet-class>com.groupies.test02_Servlet快速入门.Demo3Servlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>Demo3Servlet</servlet-name>
        <url-pattern>/demo3Servlet</url-pattern>
    </servlet-mapping>

    <!--配置Demo4Servlet-->
    <servlet>
        <servlet-name>Demo4Servlet</servlet-name>
        <servlet-class>com.groupies.test04_快速创建Servlet.Demo4Servlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>Demo4Servlet</servlet-name>
        <url-pattern>/demo4Servlet</url-pattern>
    </servlet-mapping>

    <!--配置Demo5Servlet-->
    <servlet>
        <servlet-name>Demo5Servlet</servlet-name>
        <servlet-class>com.groupies.test05_获取浏览器提交的参数.Demo5Servlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>Demo5Servlet</servlet-name>
        <url-pattern>/demo5Servlet</url-pattern>
    </servlet-mapping>

    <!--配置Demo6Servlet-->
    <servlet>
        <servlet-name>Demo6Servlet</servlet-name>
        <servlet-class>com.groupies.test06_ServletConfig.Demo6Servlet</servlet-class>
        <init-param>
            <param-name>size</param-name>
            <param-value>500</param-value>
        </init-param>
    </servlet>
    <servlet-mapping>
        <servlet-name>Demo6Servlet</servlet-name>
        <url-pattern>/demo6Servlet</url-pattern>
    </servlet-mapping>
</web-app>

2.5 ⭐️⭐️登陆案例⭐️⭐️


2.5.1 思路分析

在这里插入图片描述


2.5.2 创建Servlet

  • Step1: 创建form表单

在这里插入图片描述

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>登录页面</title>
</head>
<body>
    <!--action 属性规定当提交表单时,向何处发送表单数据。-->
    <form method="post" action="/loginServlet">
        用户名:<input type="text" name="username"><br>
        密码:<input type="password" name="password"><br>
        <input type="submit" value="点我提交">
    </form>
</body>
</html>
  • Step2: 自定义Servlet

在这里插入图片描述

package com.groupies.web; /**
 * @author GroupiesM
 * @date 2021/07/05
 * @introduction
 */

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

public class LoginServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        /* 处理响应乱码问题:字节流需getBytes("UTF-8") */
        response.setContentType("text/html;charset=UTF-8");
        /* 处理post请求乱码问题 */
        request.setCharacterEncoding("UTF-8");

        //1.获取浏览器提交的数据
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        System.out.println(username + "..." + password);
        //2.查询数据库,看有wu无该对象

        //3.有:提示登陆成功

        //4.无:提示 用户名或密码错误
    }
}
  • Step3: 配置web.xml

在这里插入图片描述

    <!--配置LoginServlet-->
    <servlet>
        <servlet-name>LoginServlet</servlet-name>
        <servlet-class>com.groupies.web.LoginServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>LoginServlet</servlet-name>
        <url-pattern>/loginServlet</url-pattern>
    </servlet-mapping>
  • Step4: 访问表单 http://localhost/login.html

在这里插入图片描述

  • Step5: 查看控制台

在这里插入图片描述


2.5.3 创建数据库sql

use day10_db;
create table user(
	id int primary key auto_increment,
	username varchar(50) unique not null,
	password varchar(50) not null,
	nickname varchar(50)
);
insert into user values(NULL,'zhangsan','123','张三');
insert into user values(NULL,'lisi','abc','李四');
insert into user values(NULL,'ww','ww','王五');

在这里插入图片描述


2.5.4 导入lib、工具类

  • 所需资源【tomcat+jar包+servlet_src+jdk】
    • 链接:https://pan.baidu.com/s/1WzEIhZxXl7puaY_GTXEYtg
    • 提取码:dqt2

  • Step1: 导入依赖

在这里插入图片描述

  • Step2: 导入数据库连接配置文件(c3p0-config.xml)和工具类(JDBCUtils.java)

在这里插入图片描述


2.5.5 创建实体类(domain)

  • 在domain下创建User实体类

在这里插入图片描述

package com.groupies.domain;

/**
 * @author GroupiesM
 * @date 2021/07/05
 * @introduction
 */
public class User {
    private int id;
    private String username;
    private String password;
    private String nickname;

    public User() {
    }

    public User(int id, String username, String password, String nickname) {
        this.id = id;
        this.username = username;
        this.password = password;
        this.nickname = nickname;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getNickname() {
        return nickname;
    }

    public void setNickname(String nickname) {
        this.nickname = nickname;
    }
}

2.5.6 查询sql逻辑

  • web.LoginServlet

在这里插入图片描述

package com.groupies.web;
/**
 * @author GroupiesM
 * @date 2021/07/05
 * @introduction
 */

import com.groupies.domain.User;
import com.groupies.utils.JDBCUtils;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.sql.SQLException;

public class LoginServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }


    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        /* 处理响应乱码问题:字节流需getBytes("UTF-8") */
        response.setContentType("text/html;charset=UTF-8");
        /* 处理post请求乱码问题 */
        request.setCharacterEncoding("UTF-8");

        //1.获取浏览器提交的数据
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        System.out.println(username + "..." + password);
        //2.查询数据库,看有无该对象
        QueryRunner qr = new QueryRunner(JDBCUtils.getDataSource());
        String sql = "select * from user where username = ?  and password = ?;";

        try {
            User user = qr.query(sql, new BeanHandler<>(User.class), username, password);
            if (user != null) {
                //3.有:提示登陆成功
                response.getWriter().write("<font color='green' size=10>登陆成功</font>");
            } else {
                //4.无:提示 用户名或密码错误
                response.getWriter().write("<font color='red' size=10>用户名或密码错误</font>");
            }
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }

    }
}
2.5.7 测试登录

  • 第一次测试提交,zhangsan,321

在这里插入图片描述

在这里插入图片描述

  • 第二次测试提交,lisi,abc

在这里插入图片描述

在这里插入图片描述


2.5.8 代码汇总

在这里插入图片描述


  • ① User
package com.groupies.domain;

/**
 * @author GroupiesM
 * @date 2021/07/05
 * @introduction
 */
public class User {
    private int id;
    private String username;
    private String password;
    private String nickname;

    public User() {
    }

    public User(int id, String username, String password, String nickname) {
        this.id = id;
        this.username = username;
        this.password = password;
        this.nickname = nickname;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getNickname() {
        return nickname;
    }

    public void setNickname(String nickname) {
        this.nickname = nickname;
    }
}
  • ② JDBCUtils
package com.groupies.utils;

import com.mchange.v2.c3p0.ComboPooledDataSource;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;

public class JDBCUtils {
	//自动读取c3p0
	static ComboPooledDataSource cpds = new ComboPooledDataSource();

	// 获取连接池
	public static DataSource getDataSource() {
		return cpds;
	}

	// 获取连接
	public static Connection getConnection() throws SQLException {
		return cpds.getConnection();
	}
}
  • ③ LoginServlet
package com.groupies.web;
/**
 * @author GroupiesM
 * @date 2021/07/05
 * @introduction
 */

import com.groupies.domain.User;
import com.groupies.utils.JDBCUtils;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.sql.SQLException;

public class LoginServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }


    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        /* 处理响应乱码问题:字节流需getBytes("UTF-8") */
        response.setContentType("text/html;charset=UTF-8");
        /* 处理post请求乱码问题 */
        request.setCharacterEncoding("UTF-8");

        //1.获取浏览器提交的数据
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        System.out.println(username + "..." + password);
        //2.查询数据库,看有无该对象
        QueryRunner qr = new QueryRunner(JDBCUtils.getDataSource());
        String sql = "select * from user where username = ?  and password = ?;";

        try {
            User user = qr.query(sql, new BeanHandler<>(User.class), username, password);
            if (user != null) {
                //3.有:提示登陆成功
                response.getWriter().write("<font color='green' size=10>登陆成功</font>");
            } else {
                //4.无:提示 用户名或密码错误
                response.getWriter().write("<font color='red' size=10>用户名或密码错误</font>");
            }
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
    }
}
  • ④ c3p0-config.xml
<?xml version="1.0" encoding="UTF-8"?>

<c3p0-config>
  <default-config>
    <property name="driverClass">com.mysql.jdbc.Driver</property>
    <property name="jdbcUrl">jdbc:mysql://localhost:3306/day10_db</property>
    <property name="user">root</property>
    <property name="password">123</property>
  </default-config>

  <!-- This app is massive! -->
  <named-config name="intergalactoApp"> 
  </named-config>
</c3p0-config>
  • ⑤ web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
		  http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
           version="3.0">
    <!--配置LoginServlet-->
    <servlet>
        <servlet-name>LoginServlet</servlet-name>
        <servlet-class>com.groupies.web.LoginServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>LoginServlet</servlet-name>
        <url-pattern>/loginServlet</url-pattern>
    </servlet-mapping>
</web-app>
  • ⑥ login.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>登录页面</title>
</head>
<body>
    <!--action 属性规定当提交表单时,向何处发送表单数据。-->
    <form method="post" action="/loginServlet">
        用户名:<input type="text" name="username"><br>
        密码:<input type="password" name="password"><br>
        <input type="submit" value="点我提交">
    </form>
</body>
</html>

三、Idea配置Servlet模板


  发现新建Servlet类后,每次都进行一些重复操作(doGet、setContentType), 我们可以自己新建一个Servlet模板,创建Servlet后自动生成指定格式;

  • Step1: 双击shift,搜索 file and code templates

在这里插入图片描述

  • Step2: 配置模板

在这里插入图片描述

#if (${PACKAGE_NAME} && ${PACKAGE_NAME} != "")package ${PACKAGE_NAME};#end
#parse("File Header.java")

#if ($JAVAEE_TYPE == "jakarta")
import jakarta.servlet.*;
import jakarta.servlet.http.*;
#else
import javax.servlet.*;
import javax.servlet.http.*;
#end
import java.io.IOException;

public class ${Class_Name} extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request,response);
    }
    
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        /* 处理响应乱码问题:字节流需getBytes("UTF-8") */
        response.setContentType("text/html;charset=UTF-8");
        /* 处理post请求乱码问题 */
        request.setCharacterEncoding("UTF-8");
    }
}
  • Step3: 测试Servlet模板,创建Test02

在这里插入图片描述

  • Step4: 新建Servlet使用了指定模板生成

在这里插入图片描述


21/07/05

M

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值