3.1_43 JavaSE-WEB核心 P1 【Tomcat、Servlet】
相关链接
- Excel目录
目录
- P1 【Tomcat、Servlet】
- 一、Tomcat
- 1.1 web开发基本概念
- 1.1.1 web应用服务器
- 1.1.2 web资源
- 1.1.3 常用web服务器
- 1.1.4 BS架构、CS架构
- 1.2 Tomcat入门体验
- 1.2.1 ⭐️ Tomcat原理(图解)⭐️
- 1.2.2 常见问题1:无法启动、闪退
- 1.2.3 常见问题2:端口被占用
- 1.2.2.1 方式1 根据pid结束该进程
- 1.2.2.2 方式2 修改tomcat端口号
- 1.3 ⭐️Tomcat启动与关闭⭐️
- 1.4 ⭐️Tomcat目录结构⭐️
- 1.4 Idead创建JavaWeb项目
- 1.4.1 版本选择
- 1.4.2 ⭐️操作步骤⭐️
- 1.4.2.a 2020.2 之前的版本
- 1.4.2.b 2020.2 (包括)之后版本
- 1.4.3 ⭐️Tomcat热部署配置⭐️
- 1.4.3.1 ⭐️小结⭐️
- 1.4.4 war 和 war exploded的区别
- 1.4.5 web项目目录结构
- 1.4.6 ⭐️web项目添加依赖(lib)⭐️
- 1.4.6.1 准备工作
- 1.4.6.2 操作步骤
- 二、Servlet
- 2.1 Servlet快速入门(浏览器访问Java代码)
- 2.1.1 准备工作
- 2.1.2 ⭐️操作步骤⭐️
- 2.1.3 ⭐️Servlet细节(图解)⭐️
- 2.1.4 ⭐️Servlet生命周期⭐️
- 2.2 ⭐️HttpServlet⭐️
- 2.2.1 快速创建HttpServlet
- 2.2.2 HttpServlet响应时乱码问题
- 2.2.3 获取浏览器提交的参数
- 2.2.3.1 创建表单和Servlet
- 2.2.3.2 接收浏览器提交的数据(两种方式)
- 2.3 web.xml中url-pattern的三种写法
- 2.3.1 普通写法
- 2.3.2 通配符
- 2.3.3 扩展名匹配
- 2.3.4 三种都匹配上,执行哪个
- 2.4 ServletConfig
- 2.5 ⭐️⭐️登陆案例⭐️⭐️
- 2.5.1 思路分析
- 2.5.2 创建Servlet
- 2.5.3 创建数据库sql
- 2.5.4 导入lib、工具类
- 2.5.5 创建实体类(domain)
- 2.5.6 查询sql逻辑
- 2.5.7 测试登录
- 2.5.8 代码汇总
- 三、Idea配置Servlet模板
P1 【Tomcat、Servlet】
- 今日要掌握的内容:
- Tomcat
- 【应用】tomcat服务器的下载和安装
- 【应用】tomcat如何部署项目
- Servlet
- 【应用】通过Idea创建JavaWeb项目(部署tomcat服务器),并且会添加依赖(classes,lib文件夹)
- 【应用】通过Servlet接收:浏览器提交到服务器的数据
- 【理解】Servlet原理、Servlet的生命周期
- 【应用】doGet()方法和doPost()方法
- 【掌握】模拟登陆案例
- Tomcat
- 所需资源【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服务器内部 html, js,图片,视频等资源。
静态资源: 指web页面中供人们浏览的数据始终是不变的。如:图片,视频, 音频,html文件,js文件等;场景:优酷上播放的电影;
动态资源: 值web页面中供人们浏览的数据是由程序产生的,不同的时间点访问web页面看到的内容各不相同. 如: jsp/Servlet,ASP,Php等;场景: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.
- 就会自动找到资源目录下的文件访问,同一局域网其他电脑也可以通方式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.1 | JavaEE7 | |||
7.0.x | 3.0 | 2.2 | JavaEE6 | |
6.0.x (archived) | 2.5 | 2.1 | 1.2、2.0 | JavaEE5 |
5.5.x (archived) | 2.4 | 2.0 | 1.1 | J2EE1.4 |
4.1.x (archived) | 2.3 | 1.2 | J2EE1.3 | |
3.3.x (archived) | 2.2 | 1.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: QueryRunnerQueryRunner qr = new QueryRunner();}
}
- Step9:继续添加DBUtils依赖 ->
mysql-connector-java-5.0.8-bin.jar
和c3p0-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 {@Overridepublic 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());}@Overridepublic void destroy() {//销毁(servlet)的方法}@Overridepublic String getServletInfo() {return null;}@Overridepublic 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/javaeehttp://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");}@Overridepublic void init(ServletConfig servletConfig) throws ServletException {System.out.println("2.初始化方法:面试,携带简历,离职证明,体检证明 *1");}@Overridepublic void service(ServletRequest request, ServletResponse response) throws ServletException, IOException {response.getWriter().write("This is Demo3Servlet " + new Date().toLocaleString());System.out.println("3.Service方法:敲代码,还是敲代码 *n");}@Overridepublic void destroy() {System.out.println("4.销毁的功能:离职,提交离职报告,交接文档 *1");}@Overridepublic ServletConfig getServletConfig() {return null;}@Overridepublic 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/javaeehttp://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
继承关系:1级 interface Servlet2级 abstract GenericServlet implements Servlet3级 abstract HttpServlet extends GenericServlet4级 自定义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: 【乱码原因:编解码不一致】【解决方法:编解码一致】
- 告诉浏览器,用文本或页面方式解析(text/html) => Response.setContentType对应的类型大全
- 默认编码规则:(java7=GBK,java8=UTF-8)
案例代码四 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>*/@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {doGet(request,response);}/*你知道的post提交方式有哪些?<form method="post">*/@Overrideprotected 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/javaeehttp://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 {@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {doGet(request, response);}@Overrideprotected 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/javaeehttp://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
访问: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/javaeehttp://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 {@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {doGet(request, response);}@Overrideprotected 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 {@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {doGet(request, response);}@Overrideprotected 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 {//自动读取c3p0static 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 {@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {doGet(request, response);}@Overrideprotected 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/javaeehttp://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 {@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {doGet(request,response);}@Overrideprotected 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
3.1_43 JavaSE-WEB核心 P1 【Tomcat、Servlet】相关推荐
- Web页面或app等前端页面之Java Web的JSP、Servlet、Cookie、Session等技术小结
Java Web学习,掌握JSP.Servlet.Cookie.Session等内容,使用JSTL进行数据展示完成实际应用. 2.3.1 XML基础 XML的用途.语法规则.语义约束.如何解析XML, ...
- 一、Web服务器——Tomcat Servlet学习笔记
今日内容 web相关概念回顾 web服务器软件:Tomcat Servlet入门学习 一.web相关概念回顾 软件架构 C/S:客户端/服务器端 B/S:浏览器/服务器端 资源分类 静态资源:所有用户 ...
- 张利国java pdf_Java Web开发与实战–Eclipse+Tomcat+Servlet+JSP整合应用 (刘伟张利国) PDF...
资源名称:Java Web开发与实战–Eclipse+Tomcat+Servlet+JSP整合应用 (刘伟,张利国) PDF 第1章 web开发工具的安装与使用 第2章 web编程技术基础 第3章 s ...
- java web核心编程_JavaWeb核心编程之(三)Servlet配置
Servlet配置 1.配置Serlvet加载时机 2.配置多映射 配置加载时机 新建项目config->创建包com.xiaoan.config->创建类FirstServlet imp ...
- Tomcat是什么:Tomcat与Java技、Tomcat与Web应用以及Tomcat基本框架及相关配置
1.Tomcat是什么 Apache Tomcat是由Apache Software Foundation(ASF)开发的一个开源Java WEB应用服务器. 类似功能的还有:Jetty ...
- JavaWeb(一)——web服务器、Tomcat安装和配置
文章目录 1. 基本概念 1.1 前言 1.2 web应用程序 1.3 静态web 1.4 动态web 2. web服务器 2.1 技术讲解 2.2 web服务器 3. Tomcat 3.1 安装To ...
- python搭建web服务器需要tomcat吗_如何快速学习网站基本搭建和服务器环境配置(LAMP/LNMP/Tomcat)?...
一.基本概念 实验1: 在阿里云上部署Tomcat服务器 业务背景 Tomcat为网站的服务器,每个网站在后面都有一个服务器来解析那个网页,Tomcat 对于 Java 来说它就是一个 Servlet ...
- Web服务器之Tomcat大全
目录 一.概念 1.Web服务器的作用 2.Tomcat概念 3.tomcat包下的各个文件中的作用? 4.JavaEE概念 5.Tomcat官网 6.Tomacat官网的下载和安装 7.Tomcat ...
- Tomcat Servlet Request
Tomcat & Servlet Web相关概念回顾 软件架构 C/S:客户端/服务器端 B/S:浏览器/服务器端 资源分类 静态资源:所有用户访问后,得到的结果都是一样的,静态资源可以被浏览 ...
最新文章
- JVM垃圾回收机制总结(5) :JDK垃圾收集器的配置命令
- ITK:建立一个Hello World程序
- 每日一笑 | 史上最贴心的骗子
- Overview of ISA and TMG Networking and ISA Networking Case Study (Part 2)
- “减压”成今年前十个月关键词:80后压力最大
- 重庆大学微型计算机基础实验,计控课程方案设计书.doc
- bytearrayinputstream java_java io系列02之 ByteArrayInputStream的简介,源码分析和示例(包括InputStream)...
- 利用高级筛选功能巧妙删除Excel的重复记录
- React Native开发之IDE(Atom+Nuclide)安装,运行,调试
- 新技能 get —— Python 断点续传下载文件
- 【Android】Scrollview返回顶部,快速返回顶部的功能实现,详解代码。
- 线性代数-线性转化和矩阵
- Bookmarks(2005-4-23)
- 服务器如何装linux 系统教程,教程/操作系统 手把手教你装Linux系统
- 2016年360校招笔试题
- 纯CSS实现多行文本溢出显示省略号(兼容不同浏览器)
- oracle基础语句练习
- (微软官方工具)局域网键鼠共享工具:Mouse without borders
- App应用双开技术,Android沙盒
- 「MOSS - 16」MOSS队:Scrum Meeting 7
热门文章
- MAC汉化LOL美服
- 电脑内存不足-增加虚拟内存
- SCI, SCIE, 和 ESCI 的区别汇总 | MethodsX 期刊分析
- c语言小球反弹的编程,少儿创意编程scratch一反弹小球游戏教程
- 5月19日----疯狂猜成语-----第四周第一次站立会议 杨霏,袁雪,胡潇丹,郭林林,尹亚男,赵静娜...
- c语言验证卡不列克常数,卡布列克数
- 《移动微技(Mobile Widget)应用开发权威指南》正式出版
- C | C语言学习(三)输入数据、输出数据、类型转换、数组、char数组和字符串、字符串长度
- python 全角半角字符转换
- ATX770 ATX770D 公爵600的哪个是性价比之王