javaweb
java web
文章目录
1.基本概念
1.1前言
web开发:
- web,网页的意思,www.baidu.com
- 静态web
- html,css
- 提供给所有人看的数据始终不会发生变化
- 动态web
- 提供给所有人看的数据始终会发生变化
- 每个人在不同的时间,不同的地点看到的信息各不相同
- 淘宝,几乎所有的网站
- 技术栈 Servlet,JSP,ASP,PHP
在java中动态web资源开发的技术称为javaweb;
1.1web应用程序
程序:数据结构+算法
web应用程序可以提供浏览器访问的程序:
- a.html,b.html…多个web资源可以被外界访问,对外界提供服务
- 你们能访问到的任何页面或者资源都存在与这个世界的某个角落的计算机上
- URL:
- 这些统一的web资源会被放在同一个文件夹下,web应用程序——》Tomcat:服务器
- 一个web应用由多部分组成(静态web,动态web
- html,css,js
- jsp,servlet
- java程序
- jar包
- 配置文件(Properties)
- web应用程序编写完后,若想提供给外界访问:需要一个服务器同一管理、
1.3静态web
- *. htm, *.html,这些都是网页的后缀,如果服务器上一直存在这些东西,我们就可以直接进行读取》
- 静态web的缺点:
- web无法更新,所有用户看到的页面都是一个页面
- 轮播图,点击特效,伪动态
- VB
- JAVAScript[实际开发,用的最多]
- 他无法和数据库交互(数据无法持久化,用户无法交互)
- web无法更新,所有用户看到的页面都是一个页面
1.4动态web
页面会动态展示:“Web 的页面展示的效果因人而异”
缺点
-
假如服务器的动态web资源出现了错误,我们需要重新编写我们的后台程序,重新发布:
- 停机维护
优点:
- web可以更新,所有用户看到的页面不是一个页面
- 可以数据库交互(数据持久化,注册,商品信息,用户信息)
分析原理,看源码
2.web服务器
webserver
2.1技术讲解
ASP:
- 微软,国内最早流行的就是ASP;
- 在HTML中嵌入vb脚本,ASP+DOM
- 在ASP开发中,基本一个页面有几千行代码,十分难看
- 维护成本高
- C#
- IIS
<h1>
<h1><h1>
<h1>
<h1>
<h1>
<h1>
<%
System.out.println("hello");
%>
<h1>
<H1><h1>
<h1>
PHP
- PHP开发速度很快,功能强大,跨平台,代码很简单(70%,WP)
- 无法承载大的访问量的情况(有局限性)
JSP/Servlet:
B/S:浏览器和服务器
C/S:客户端和服务器
- sun公司主推的B/S架构
- 基于java语言(所有的大公司,或者一些的开源的组件都是,用java写的)
- 可以承载三高问题带来的影响(高并发,高可用,高性能)
- 语法像ASP
。。。。
3.web服务器
服务器是一种被动的操作,用来处理用户的请求,和给用户一些响应信息;
IIS:
微软的:ASP。。。window自带
Tomcat
面向百度编程
Tomcat是Apache 软件基金会(Apache Software Foundation)的Jakarta 项目中的一个核心项目,最新的Servlet 和JSP 规范总是能在Tomcat 中得到体现,Tomcat 5支持最新的Servlet 2.4 和JSP 2.0 规范。因为Tomcat 技术先进、性能稳定,而且免费,因而深受Java 爱好者的喜爱并得到了部分软件开发商的认可,成为目前比较流行的Web 应用服务器。
Tomcat 服务器是一个免费的开放源代码的Web 应用服务器,属于轻量级应用服务器,在中小型系统和并发访问用户不是很多的场合下被普遍使用,是开发和调试JSP 程序的首选。对于一个java初学web的人来说,他是最佳的选择
Tomcat 实际上运行JSP 页面和Servlet。目前Tomcat最新版本为10.0.5
工作3-5年之后,尝试手写Tomcat
下载Tomcat;
- 安装or解压
- 了解配置文件及目录结构
- 这个东西的作用
3.Tomcat
1.安装Tomcat
Tomcat官网
3.2Tomcat启动和配置
将解压完成的文件夹放在environment中
文件夹的作用
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yh1UgS2J-1651655442744)(https://gitee.com/cl2854697833/my-picture/raw/master/img/202205041707306.png)]
3.2启动、关闭
访问测试:
http://localhost:8080/
可能遇到的问题:
- java环境没有设置
- 闪退问题,兼容性
- 乱码问题,配置文件总设置
3.3配置问题
server.xml可以配置启动的端口号,
- tomcat默认端口号为8080
- mysql:3306
- http:80
- https:443
<Connector port="8081" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" />
主机的名称:
- 默认的主机名为:localhost>127.0.0.1
- 默认网站应用存放的位置为:webapps
<Host name="www.qingjian.com" appBase="webapps"
unpackWARs="true" autoDeploy="true">
高难度面试题
请你谈谈网站是如何进行访问的!
-
输入域名;回车
-
检查本机的C:\Windows\System32\drivers\etc\host配置文件下有没有这个域名映射:
- 有,直接返回对应的IP地址
# 127.0.0.1 localhost # ::1 localhost 127.0.0.1 www.qingjian.com
- 没有,去DNS服务器上找,找到就返回,找不到就丢失了
4。配置和环境变量(可选项)
3.4发布一个web网站
不会就模仿
- 将自己写的网站放到服务器(Tomcat)总指定的web文件夹(webapps)下,就可以访问了
网站应该有的结构:
--webapps:Tomcat服务器web的目录
--ROOT
--kuangstudy:网站的目录名
-web-INF
-classes:java程序
-lib:web应用所依赖的jar包
-web.xml
--index.html//默认的首页
-static
-css
-style.css
-js
-img
.....
HTTP协议:面试
Maven:构建工具
- Maven安装包
Servlet入门
- hellWorld
- Servlet配置
- 原理
参考样例
http://localhost:8080/examples/
4、Http
4.1、什么是http
超文本传输协议(Hypertext Transfer Protocol,HTTP)是一个简单的请求-响应协议,它通常运行在TCP之上。
- 文本:html,字符串~。。。
- 超文本:图片,音乐,视频,定位,地图。。。
- http:80
- https(security):443
4.2、两个时代
- http1.0
- http/1.0:早些年,客户端可以和web服务器连接后,只能获得一个web资源,断开连接,
- http2.0
- http/1.1:客户端可以和web服务器连接后,可以获得多个web资源
4.3、HTTP请求
- 客户端–发请求(Request)—服务器
百度:
Request URL: https://www.baidu.com/ //请求地址
Request Method: GET //请求方法 get方法,post方法
Status Code: 200 OK //状态码:200 ok
Remote Address: 39.156.66.18:443 //远程地址
引用站点策略: unsafe-url
Accept:text/html
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9,zh-TW;q=0.8,en-US;q=0.7,en;q=0.6///语言
Cache-Control: no-cache
Connection: keep-alive
1.请求行
- 请求行中的请求方式:GET
- 请求方式:GET(不安全)/POST(安全),HEAD,DELETE,PUT,TRACT…
- get:一次请求能够携带的参数比较少,大小有限制,会在浏览器的URL地址栏显示数据内容,不安全,但高效
- post:一次请求能够携带的参数没有限制,大小没有限制,不会在浏览器的URL地址栏显示数据内容,安全,但不高效
2.消息头
Accept://告诉浏览器,它所支持的数据类型
Accept-Encoding://支持那种编码格式,gbk,utf8,GB2312,ISO8859-1
Accept-Language: //告诉浏览器的语言环境
Cache-Control: //缓存控制
Connection: //告诉浏览器(服务器),请求完成是断开还是保持连接
HOST:主机
。。。
4.4、HTTP响应
- 服务端—响应—客户端
百度:
0.响应头
//Bdpagetype: 1
//Bdqid: 0x8337075c0023e88d
Cache-Control: private //缓存控制
Connection: keep-alive //连接:保持连接
Content-Encoding: gzip //编码
//Content-Type: text/html;charset=utf-8
//Date: Fri, 23 Apr 2021 15:27:40 GMT
//Expires: Fri, 23 Apr 2021 15:27:40 GMT
//Server: BWS/1.1
Set-Cookie: BDSVRTM=12; path=/
Set-Cookie: BD_HOME=1; path=/
Set-Cookie: H_PS_PSSID=33848_33759_33855_26350_22158; path=/; domain=.baidu.com
Strict-Transport-Security: max-age=172800
Traceid: 161919166005002288749455034034408384653
Transfer-Encoding: chunked
X-Ua-Compatible: IE=Edge,chrome=1
1.响应体
Accept://告诉浏览器,它所支持的数据类型
Accept-Encoding://支持那种编码格式,gbk,utf8,GB2312,ISO8859-1
Accept-Language: //告诉浏览器的语言环境
Cache-Control: //缓存控制
Connection: //告诉浏览器(服务器),请求完成是断开还是保持连接
HOST:主机
refresh:刷新,告诉客户段,多久刷新一次
location:让网页重新定位
2.状态码(重点)
200:响应成功
3**:(304):请求重定向
- 重新到新位置去
4xx:(404)
- 资源不存在
5xx:服务器代码错误 500
- 502网关错误
常见面试题:
当你的浏览器中地址栏输入并回车的一瞬间到页面能够展现回来,经历了什么
5.Maven
我为什么要学习这个技术?
1.在javaweb开发中,需要大量的jar包,我们手动去导入:
2.如何能够让一个东西自动帮我们道路和配置这个jar包
3.由此Maven诞生了!
5.1Maven项目架构管理工具
我们目前就是用来方便导入jar包
Maven核心思想:预定大约配置
- 有约束不要去违反
Maven会规定好你该如何去写java代码,必须要按照这个步骤来
5.2下载和安装Maven
https://maven.apache.org/
下载完,解压即可,之后看源码,看目录
电脑上的所有环境都放在同一个文件夹下
5.3配置环境变量
尽量配
在我们的系统环境变量中配置如下配置
- M2_HOME:MAVEN目录下的bin目录
- MAVEN_HOME:MAVEN目录
- 在系统的path中配置MAVEN_HOME
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-i1nqrq3K-1651655442747)(https://gitee.com/cl2854697833/my-picture/raw/master/img/202205041707315.png)]
测试Maven是否安装成功
5.4修改阿里云镜像
mirrors
镜像,方便下载
Maven在国外,访问速度会有点慢
<mirror>
<id>nexus-aliyun</id>
<mirrorOf>*,!jeecg,!jeecg-snapshots</mirrorOf>
<name>Nexus aliyun</name>
<url>http://maven.aliyun.com/nexus/content/groups/public</url>
</mirror>
默认的
<mirror>
<id>maven-default-http-blocker</id>
<mirrorOf>external:http:*</mirrorOf>
<name>Pseudo repository to mirror external repositories initially using HTTP.</name>
<url>http://0.0.0.0/</url>
<blocked>true</blocked>
</mirror>
5.5本地仓库
在本地的仓库,远程仓库
本地仓库localRepository
D:\Environmant\apache-maven-3.8.1\maven-repo
<localRepository>D:\Environmant\apache-maven-3.8.1\maven-repo</localRepository>
5.6在IDEA中使用Maven
1.启动maven
2.创建一个maven项目
3.等待项目初始化完毕
选择 enable auto import
4.观察maven-repo仓库多了什么东西
5.IDEA中的设置
IDEA项目创建后,看一眼Maven的配置
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ovtduEwB-1651655442750)(https://gitee.com/cl2854697833/my-picture/raw/master/img/202205041707324.png)]
6.到这里Maven在IDEA中的配置和使用就ok了
5.7创建一个普通Maven项目
直接下一步
记得设置本地项目
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NNVXCExp-1651655442751)(https://gitee.com/cl2854697833/my-picture/raw/master/img/202205041707325.png)]
这个只有在web应用下次有
5。8在IDEA中标记文件夹功能
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Mrijym0i-1651655442751)(https://gitee.com/cl2854697833/my-picture/raw/master/img/202205041707327.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VkeDOLEC-1651655442751)(https://gitee.com/cl2854697833/my-picture/raw/master/img/202205041707328.png)]
选中项目
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1JzKIu4P-1651655442752)(https://gitee.com/cl2854697833/my-picture/raw/master/img/202205041707330.png)]
5.9在IDAE中配置Tomcat
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0mhwUu6T-1651655442753)(https://gitee.com/cl2854697833/my-picture/raw/master/img/202205041707332.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nIFzT0sd-1651655442753)(https://gitee.com/cl2854697833/my-picture/raw/master/img/202205041707334.png)]
解决警告:
为什么会有这个问题,我们访问一个网站,需要指定一个文件夹的名字
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yZiRpnSg-1651655442754)(https://gitee.com/cl2854697833/my-picture/raw/master/img/202205041707337.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-I8mmZwJO-1651655442755)(https://gitee.com/cl2854697833/my-picture/raw/master/img/202205041707339.png)]
5.10pom文件
pom.xml是maven的核心文件
<?xml version="1.0" encoding="UTF-8"?>
<!--Maven版本和头文件-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<!-- 这里就是我们刚才配置的GAV-->
<groupId>com.kuang</groupId>
<artifactId>javaweb-01-maven</artifactId>
<version>1.0-SNAPSHOT</version>
<!-- page:项目的打包方式
jar:java应用
war:javaweb应用
-->
<packaging>war</packaging>
<!-- 配置-->
<properties>
<!-- 项目默认编码-->
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<!-- 编码版本-->
<maven.compiler.source>1.7</maven.compiler.source>
<maven.compiler.target>1.7</maven.compiler.target>
</properties>
<!-- 项目依赖-->
<dependencies>
<!-- 具体依赖的jar包依赖-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
</dependencies>
<!-- 项目构建用的东西-->
<build>
<finalName>javaweb-01-maven</finalName>
<pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
<plugins>
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<version>3.1.0</version>
</plugin>
<!-- see http://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_war_packaging -->
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>3.0.2</version>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.1</version>
</plugin>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>3.2.2</version>
</plugin>
<plugin>
<artifactId>maven-install-plugin</artifactId>
<version>2.5.2</version>
</plugin>
<plugin>
<artifactId>maven-deploy-plugin</artifactId>
<version>2.8.2</version>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-osLT4ONb-1651655442755)(https://gitee.com/cl2854697833/my-picture/raw/master/img/202205041707341.png)]
<?xml version="1.0" encoding="UTF-8"?>
<!--Maven版本和头文件-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<!-- 这里就是我们刚才配置的GAV-->
<groupId>com.kuang</groupId>
<artifactId>javaweb-01-maven</artifactId>
<version>1.0-SNAPSHOT</version>
<!-- page:项目的打包方式
jar:java应用
war:javaweb应用
-->
<packaging>war</packaging>
<!-- 配置-->
<properties>
<!-- 项目默认编码-->
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<!-- 编码版本-->
<maven.compiler.source>1.7</maven.compiler.source>
<maven.compiler.target>1.7</maven.compiler.target>
</properties>
<!-- 项目依赖-->
<dependencies>
<!-- 具体依赖的jar包依赖-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
</dependencies>
<!-- 项目构建用的东西-->
<build>
<finalName>javaweb-01-maven</finalName>
<pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
<plugins>
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<version>3.1.0</version>
</plugin>
<!-- see http://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_war_packaging -->
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>3.0.2</version>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.1</version>
</plugin>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>3.2.2</version>
</plugin>
<plugin>
<artifactId>maven-install-plugin</artifactId>
<version>2.5.2</version>
</plugin>
<plugin>
<artifactId>maven-deploy-plugin</artifactId>
<version>2.8.2</version>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>
Maven由于他的约定大于配置,我们之后可能会遇到我们写的配置文件,无法被导出或者生效的问题,解决方案:
<!-- 在build中配置resourse,;来防止我们的资源导出失败问题-->
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>true</filtering>
</resource>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>true</filtering>
</resource>
</resources>
</build>
5.12IDEA操作
5.13解决遇到的问题
1.Maven遇到的问题3.6.2
解决方法:降级3.6.1
2.Tomcat闪退
3.IDEA中每次都是重复配置Maven
在IDEA中的全局默认配置中去配置
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ByRjFk2X-1651655442756)(https://gitee.com/cl2854697833/my-picture/raw/master/img/202205041707345.png)]
4.maven中无法配置Tomcat
5.maven默认web项目中的web.xml版本问题
6.替换为webapp4.0版本和tomcat版本一致
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0"
metadata-complete="true">
</web-app>
7.Maven仓库的使用
学习一个新技术可以看源码(帮助文档)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SuX8AtMw-1651655442757)(https://gitee.com/cl2854697833/my-picture/raw/master/img/202205041707347.png)]
https://mvnrepository.com/
但是在maven仓库里面直接搜索HttpServlet没有
接下来我们要思考,Tomact能成功那么一定有书需要的jar包所以到lib目录下去查看是否与servlet相关的jar包,进行查询
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6Q0sMsn4-1651655442758)(https://gitee.com/cl2854697833/my-picture/raw/master/img/202205041707351.png)]
要么最新,要么最多
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MaKX45Ml-1651655442759)(https://gitee.com/cl2854697833/my-picture/raw/master/img/202205041707352.png)]
将下载的dependence放在pom.xml里面
6、servelt
6.1什么是servelt
- servelt是sum公司用来开发动态web的一门技术
- sum公司在这些API中提供的一种接口叫:servrlt,如果想开发一个servlet程序,只需要完成两个小步骤
- 编写一个类实现servlet接口
- 把开发好的java部署到web服务器中
把实现了servlet接口的java程序叫做servlet
6.2helloservlet
servlet在sun公司有两个默认的实现类:HttpServlet,GenericServlet
1.构建一个普通的maven项目,删掉里面的src目录,以后我们的学习就在这个项目里面建立Moudel;这个空的工程就是Maven的主工程
2.向poml中添加dependence中的servletjar包依赖
3.关于maven父子工程的理解:
- 它可以有很多模块
子项目中会有
<parent>
<artifactId>java-02-servlet</artifactId>
<groupId>com.kuang</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
父项目中会有
<modules>
<module>servlet-01</module>
</modules>
父项目中的Java子项目可以直接使用
son extend father
4.将webapp中的web.xml换成tomcat中web.xml中的
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0"
metadata-complete="true">
</web-app>
4.maven环境优化
- 修改web.xml为最新的
- 将maven的结构搭建完整
5.编写一个servlet程序
1.包名要规范
2.编写一个普通类
3.实现Servlet接口,这里我们直接继承HttpServlet
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-K42tDt40-1651655442760)(https://gitee.com/cl2854697833/my-picture/raw/master/img/202205041707358.png)]
4.重写doget,和doPost方法 ctrl+o
package com.kunag.servlet;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
//导的父项目的包
public class HelloServlet extends HttpServlet {
//由于get和post只是请求实现的不同方式,可以互相调用,业务逻辑都一样
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// req.getInputStream()
//ServletOutputStream outputStream = resp.getOutputStream();
PrintWriter writer = resp.getWriter();//响应流
writer.print("Hello, Servlet");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
5.编写Servlet的映射
为什么需要映射:我们写的是java程序,但是要通过浏览器访问,而浏览器需要连接web服务器,所以我们要在web服务器中注册我们写的servlet,还需要给他一个浏览器能够访问的路径;
<!--注册servlet-->
<servlet>
<servlet-name>hello</servlet-name>
<servlet-class>com.kunag.servlet.HelloServlet</servlet-class>
</servlet>
<!--servlet的请求路径
前端输入hello,进入HelloServlet方法,并执行它
-->
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>
6.配置Tomcat
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0iXl3mkO-1651655442761)(https://gitee.com/cl2854697833/my-picture/raw/master/img/202205041707361.png)]
注意配置项目发布的路径
7.启动测试,ok
6.3Servlet原理
servlet是由web服务器调用,web服务器是在收到浏览器请求之后,会:
web服务器和web容器web服务器包含web容器,
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XKFOFnnx-1651655442761)(https://gitee.com/cl2854697833/my-picture/raw/master/img/202205041707363)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6N5JF76F-1651655442761)(https://gitee.com/cl2854697833/my-picture/raw/master/img/202205041707365.png)]
6.4Mapping问题
1.一个servlet请求可以指定一个映射路径
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>
2.一个servlet请求可以指定多个映射路径
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello1</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello2</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello3</url-pattern>
</servlet-mapping>
3.一个servlet请求可以指定通用映射路径
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello/*</url-pattern>
</servlet-mapping>
4.默请求路径
<!--默认请求路径-->
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cJ8imn6F-1651655442762)(https://gitee.com/cl2854697833/my-picture/raw/master/img/202205041707367.png)]
5.指定一些后缀和前缀。。。
<!-- 可以自定义后缀实现请求
注意!,*前面不能加项目的映射路径
*前面也不能有/-->
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>*.qingjiang</url-pattern>
</servlet-mapping>
6.优先级问题
制定了固有的映射路径优先机最高,如果找不到,就会走默认的处理请求
<servlet>
<servlet-name>error</servlet-name>
<servlet-class>com.kunag.servlet.ErrorServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>error</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
public class ErrorServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setCharacterEncoding("utf-8");
resp.setContentType("text/html");
PrintWriter writer = resp.getWriter();
writer.print("<h1>404</h1>");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
6.5、ServletContext(上下文)
- 新建一个servlet-02模块
- 修改poml和web.xml
- 重写servlet中的doGet方法
- 编写xervlet映射(再web.xml中)
- 启动tomcat
- 删除上次的war包
web容器在启动的时候,Servletcontext为每一个web程序都创建一个对应的servletcontext对象,他代表了当前的web应用;
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uAsc8B9p-1651655442763)(https://gitee.com/cl2854697833/my-picture/raw/master/img/202205041707370.png)]
1.共享数据
我在这个servlet中保存的数据可以在另一个servlet中拿到、
- 放置数据的类
package com.kuang.servlet;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class HelloServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// this.getInitParameter() 初始化参数
// this.getServletConfig() servlet的配置
// this.getServletContext() servlet的上下文
ServletContext servletContext = this.getServletContext();
String username="秦酱";
servletContext.setAttribute("username",username);//将一个数据保存在了servlet中,名字"username",值username
System.out.println("Hello");
}
}
- 读取数据的类
package com.kuang.servlet;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class getServlet extends HelloServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
ServletContext servletContext = this.getServletContext();//共用的servletContext
String username = (String) servletContext.getAttribute("username");
resp.setContentType("text/html;charset=utf-8");
resp.getWriter().print("名字"+username);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
- 配置web。xml
<servlet>
<servlet-name>hello</servlet-name>
<servlet-class>com.kuang.servlet.HelloServlet</servlet-class>
<!-- <init-param>-->
<!-- <param-name></param-name>-->
<!-- <param-value></param-value>-->
<!-- </init-param>-->
</servlet>
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>getcontext</servlet-name>
<servlet-class>com.kuang.servlet.getServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>getcontext</servlet-name>
<url-pattern>/getcontext</url-pattern>
</servlet-mapping>
-
测试结果
1.首先访问helloyemian,这样就会放置username
2.接着访问getContext页面[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-O2EIjfcU-1651655442763)(https://gitee.com/cl2854697833/my-picture/raw/master/img/202205041707371.png)]
成功
2、获取初始化参数
public class servletDemo03 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
ServletContext servletContext = this.getServletContext();
String url = servletContext.getInitParameter("url");
resp.getWriter().print(url);
}
<servlet>
<servlet-name>gp</servlet-name>
<servlet-class>com.kuang.servlet.servletDemo03</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>gp</servlet-name>
<url-pattern>/gp</url-pattern>
</servlet-mapping>
3、请求转发Dispatcher
- 重写方法
- 创建servletcontext对象
- 调用getRequestDispatcher方法(输入请求转发的路径)
- 在调用forward方法实现转发
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("进入了Demo4");
ServletContext servletContext = this.getServletContext();
// RequestDispatcher requestDispatcher = servletContext.getRequestDispatcher("/gp");//在context中通过请求获取转发
// requestDispatcher.forward(req,resp);//前往
servletContext.getRequestDispatcher("/gp").forward(req,resp);
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2rzqLnUo-1651655442763)(https://gitee.com/cl2854697833/my-picture/raw/master/img/202205041707372.png)]
4、读取资源文件
Properties
- 在java目录下新建properties
- 在resources目录下新建properties、
发现:都被打包到了同一个路径下:classes,我们俗称这个路径为classpath
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MtaU05iB-1651655442764)(https://gitee.com/cl2854697833/my-picture/raw/master/img/202205041707373.png)]
思路需要一个文件流
package com.kuang.servlet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
public class ServletDemo05 extends HelloServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
InputStream is = this.getServletContext().getResourceAsStream("/WEB-INF/classes/db.properties");
Properties prop=new Properties();
prop.load(is);
String username = prop.getProperty("username");
String passworld = prop.getProperty("passworld");
resp.getWriter().print(username+passworld);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
username=root
passworld=123
访问测试即可
6.7、HttpServletResponse
web服务器接受到客户端的http请求,针对这个请求,分别创建一个代表请求的HttpServletRequest对象,代表响应的一个HttpServletResponse;
- 如果要获取客户端请求过来的参数:找HttpServletRequest
- 如果要给客户端相应一些信息:找HttpServletResponse
1.简单分类
负责向浏览器发送数据
ServletOutputStream getOutputStream() throws IOException;
PrintWriter getWriter() throws IOException;
负责向浏览器发送响应头
void setCharacterEncoding(String var1);
void setContentLength(int var1);
void setContentLengthLong(long var1);
void setContentType(String var1);
void setDateHeader(String var1, long var2);
void addDateHeader(String var1, long var2);
void setHeader(String var1, String var2);
void addHeader(String var1, String var2);
void setIntHeader(String var1, int var2);
void addIntHeader(String var1, int var2);
相应的状态码
200 ok
300 重定向
400 未找到
500 服务器异常
2.常见应用
- 像浏览器输出消息(getwrite()getoutputstrem())
- 下载文件
- 获取下载文件的路径
- 获取下载文件的名称
- 设置想办法让浏览器能支持下载我们需要的东西
- 获取下载文件的输入流
- 创建缓冲区
- 获取OutPutStream对象
- 将FileOutputStream流写入到buffer缓冲区
- 使用OutPutStream将缓冲区中的数据输出到客户端
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.HashMap;
public class FileServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 1. 获取下载文件的路径
String realPath = ("D:\\Java\\kuang_study\\javaweb\\java-02-servlet\\response\\target\\response\\WEB-INF\\classes\\秦酱.png");
System.out.println(realPath);
// 2. 获取下载文件的名称
String fielname = realPath.substring(realPath.lastIndexOf("\\" )+1);
// 3. 设置想办法让浏览器(Content-Disposition,attachment;filename)能支持下载我们需要的东西,中文文件名需要进行URLencoding编码,否则会出现乱码
resp.setHeader("Content-Disposition","attachment;filename="+ URLEncoder.encode(fielname,"utf-8"));
// 4. 获取下载文件的输入流
FileInputStream in = new FileInputStream(realPath);
// 5. 创建缓冲区
int len=0;
byte[]buffer=new byte[1024];
// 6. 获取OutPutStream对象
ServletOutputStream outputStream = resp.getOutputStream();
// 7. 将FileOutputStream流写入到buffer缓冲区,使用OutPutStream将缓冲区中的数据输出到客户端
while ((len=in.read(buffer))>0){
outputStream.write(buffer,0,len);
}
in.close();
outputStream.close();
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
3、验证码功能
验证码怎么实现?
前端可以
后端亦可以:需要用到java的图片类,生产一个图片
import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;
public class ImageServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//如何让浏览器5s自动刷新一次
resp.setHeader("refresh","3");
//在内存中创建图片
BufferedImage image = new BufferedImage(80,20,BufferedImage.TYPE_INT_RGB);
//得到图片,2d画笔
Graphics2D g = (Graphics2D) image.getGraphics();//笔
//设置图片背景颜色
g.setColor(Color.blue);
g.fillRect(0,0,80,20);
//给图片写数据
g.setColor(Color.red);
g.setFont(new Font(null,Font.BOLD,20));
g.drawString(makeNumber(),0,20);
//告诉浏览器,这个请求用图片方式打开,
resp.setContentType("image/jpeg");
//网站存在缓存,不让浏览器缓存
resp.setDateHeader("expires",-1);
resp.setHeader("Cache-Contro","no-cache");
resp.setHeader("Pragma","no-cache");
//把图片写给浏览器
ImageIO.write(image,"jpg",resp.getOutputStream());
}
//生成随机数
public String makeNumber(){
Random random = new Random();
String number= random.nextInt(99999999)+" ";//8位验证码
StringBuffer sb = new StringBuffer();
for (int i = 0; i <7-number.length() ; i++) {
sb.append("0");
}
String s = sb.toString() + number;
return s;
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
<servlet>
<servlet-name>ImageServlet</servlet-name>
<servlet-class>ImageServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ImageServlet</servlet-name>
<url-pattern>/img</url-pattern>
</servlet-mapping>
4、实现重定向
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lrci8AAM-1651655442765)(https://gitee.com/cl2854697833/my-picture/raw/master/img/202205041707375.png)]
一个web资源(B)收到客户端(A)请求后,会通知客户端(A)去访问另一个web资源©,这个过程叫重定向
常见场景:
- 页面登录
void sendRedirect(String var1) throws IOException;
测试:
public class ReDirectServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.sendRedirect("/response_war/img");
//原理
// resp.setHeader("location","/response_war/img");
// resp.setStatus(HttpServletResponse.SC_MOVED_TEMPORARILY);
}
}
原理:
resp.setHeader("location","/response_war/img");
resp.setStatus(HttpServletResponse.SC_MOVED_TEMPORARILY);
面试题:请你聊聊重定向和转发的区别?
相同的:页面都会实现跳转
不同的
- 请求转发的时候,url不会发生变化
- 重定向的时候,url地址栏会发生变化
req:request
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class RequestText extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// System.out.println("进入了这个页面");
//处理请求
String username = req.getParameter("username");
String pwd = req.getParameter("pwd");
System.out.println(username+":"+pwd);
//重定向时候一定要注意路径问题,否则404
resp.sendRedirect("/response_war/success.jsp");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
<html>
<body>
<h2>Hello World!</h2>
</body>
<%--@ page contentType="text/html; charset=UTF-8" --%>
<%--这里提交的路径,需要需找到项目的路径$--%>
<%--pageContext.request.contextPath代表当前的项目--%>
<form action="${pageContext.request.contextPath}/rt" method="get">
用户名:<input type="text" name="username"><br>
密码:<input type="password" name="pwd"><br>
<input type="submit">
</form>
</html>
<servlet>
<servlet-name>RequestText</servlet-name>
<servlet-class>RequestText</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>RequestText</servlet-name>
<url-pattern>/rt</url-pattern>
</servlet-mapping>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1>
success
</h1>
</body>
</html>
6.6、HttpServletRequest
HttpServletRequest代表客户端的请求,用户通过http协议访问服务器;http请求中的所有消息会被封装到HttpServletRequest,
通过这个HttpServletRequest方法,获得客户端的所有信息。
1、获取前端传递的参数parameter\并且请求转发
public class LoginServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("utf-8");
resp.setCharacterEncoding("utf-8");
String username = req.getParameter("username");
String pwd = req.getParameter("pwd");
String[] hobbys = req.getParameterValues("hobbys");
System.out.println("===============================");
System.out.println(username+pwd);
//后台接收中文乱码问题
System.out.println(Arrays.toString(hobbys));
System.out.println("===============================");
// resp.sendRedirect();
// 通过请求转发
// 这里的/代表当前的web应用
// 重定向需要写项目名 请求转发不需要
req.getRequestDispatcher("/success.jsp").forward(req,resp);
}
重点:面试题:请你聊聊重定向和转发的区别?
相同的:页面都会实现跳转
不同的
- 请求转发的时候,url不会发生变化 307
- 重定向的时候,url地址栏会发生变化 302
7、cookies、session
7.1会话
会话:用户打开了一个浏览器,点击了很多超链接,访问多个web资源,关闭浏览器,这个过程可以称之为会话
有状态会话:****
你能怎么怎么你是西开的学生?
你 西开
- 发票 西开给你开发票
- 学校登记 西开标记你来过了
一个网站怎么证明你来过?
客户端 服务端
- 服务器给客户端一个信件,客户端下次访问服务端带上信件就行了;cookies
- 服务器登记你来过了,下次你来的时候我来匹配你;session
7.2、保存会话的两种技术
cookie
- 客户端技术(响应,请求)
session
- 服务器技术,利用这个技术,可以保存用户的会话信息?,我们可以把信息或数据放在session中~!
常见场景:
网站登录后,你下次不要登录了,第二次访问直接上去了!
万物皆可api
7.3、cookie
- 从请求中拿到cookie信息
- 服务器响应给客户端cookie
Cookie[] cookies = req.getCookies();//从请求中拿到cookie信息
cookie.getName()//获得cookie中的key
cookie.getValue()//获得cookie的value
new Cookie("lastLoginTime",System.currentTimeMillis()+"")//新建一个cookie
cookie.setMaxAge(24*60*60);//设置cookie的有效期
resp.addCookie(cookie);//响应给客户端一个cookie
cookie一般会保存在本地的用户目录下appdata;
一个网站的cookie是否存在上限~!(聊聊细节信息)
- 一个cookie只能保存一个信息
- 一个web站点可以给浏览器发送多个cookie,每个站点最多存放20个cookie
- cookie大小有限制:4KB
- 300个cookie浏览器上限
删除cookie
- 不设置有效期,关闭浏览器,自动失效
- 设置有效期时间为0
编码解码
URLEncoder.encode("秦酱","utf-8")
URLDecoder.decode(cookie.getValue())
- cookie应用
package com.kuang.servlet;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Date;
public class CookiesDemo01 extends HttpServlet {
//保存用户上一次访问的时间
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//解决中文乱码
resp.setContentType("text/html; charset=UTF-8");//浏览器显示中文编码
req.setCharacterEncoding("utf-8");
resp.setCharacterEncoding("utf-8");
PrintWriter out = resp.getWriter();
//cookie
Cookie[] cookies = req.getCookies();//这里返回数组,说明cookie可能存在多个
//判断cookie是否存在
if (cookies!=null){
//如果存在怎么办?
out.write("你上一次访问的时间是:");
for (int i = 0; i <cookies.length ; i++) {
Cookie cookie = cookies[i];
//获取cookie的名字
if (cookie.getName().equals("lastLoginTime")){
//获取cookie的值 字符串转化为时间
long lastLongTime = Long.parseLong(cookie.getValue());
Date date = new Date(lastLongTime);
out.write(date.toLocaleString());
}
}
}else{
out.write("这是你第一次访问");
}
//服务器给客户端响应一个cookie
Cookie cookie = new Cookie("lastLoginTime",System.currentTimeMillis()+"");
cookie.setMaxAge(24*60*60);
resp.addCookie(cookie);//addcookies中需要一个cookie我们就new一个cookie
/*
每次访问给你一个小饼干,有了也给你一个新的小饼干
*/
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doPost(req, resp);
}
}
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.kuang</groupId>
<artifactId>javaweb-cookies-session</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
<name>javaweb-cookies-session Maven Webapp</name>
<!-- FIXME change it to the project's website -->
<url>http://www.example.com</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.7</maven.compiler.source>
<maven.compiler.target>1.7</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>javax.servlet.jsp-api</artifactId>
<version>2.3.3</version>
</dependency>
</dependencies>
<build>
<finalName>javaweb-cookies-session</finalName>
<pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
<plugins>
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<version>3.1.0</version>
</plugin>
<!-- see http://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_war_packaging -->
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>3.0.2</version>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.1</version>
</plugin>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>3.2.2</version>
</plugin>
<plugin>
<artifactId>maven-install-plugin</artifactId>
<version>2.5.2</version>
</plugin>
<plugin>
<artifactId>maven-deploy-plugin</artifactId>
<version>2.8.2</version>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>
package com.kuang.servlet;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class cookieDemo02 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//创建一个cookie,名字一定要和删除的名字相同
Cookie cookie = new Cookie("lastLoginTime", System.currentTimeMillis() + "");
//将cookie有效期设置为0
cookie.setMaxAge(0);
resp.addCookie(cookie);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
package com.kuang.servlet;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.Date;
public class cookieDemo03 extends HttpServlet {
//中文数据传输
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/html; charset=UTF-8");//浏览器显示中文编码
req.setCharacterEncoding("utf-8");
resp.setCharacterEncoding("utf-8");
Cookie[] cookies = req.getCookies();//这里返回数组,说明cookie可能存在多个
PrintWriter out = resp.getWriter();
//判断cookie是否存在
if (cookies!=null){
//如果存在怎么办?
out.write("你上一次访问的时间是:");
for (int i = 0; i <cookies.length ; i++) {
Cookie cookie = cookies[i];
//获取cookie的名字
if (cookie.getName().equals("name")){
// System.out.println(cookie.getValue());
//解码
out.write(URLDecoder.decode(cookie.getValue()));
}
}
}else{
out.write("这是你第一次访问");
}
//编码,
Cookie cookie = new Cookie("name", URLEncoder.encode("秦酱","utf-8"));
resp.addCookie(cookie);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
7.4、session(重点)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gYLVWgWf-1651655442767)(https://gitee.com/cl2854697833/my-picture/raw/master/img/202205041707382.png)]
分布式
1.什么是session
- 服务器会给每一个用户(浏览器)创建一个session对象
- 一个session独占一个浏览器,只要浏览器没有关闭,这个session就存在
- 用户登录之后,整个网站它都可以访问,——>保存用户信息,保存购物车信息。。
sesson和cookie区别
-
cookie是把用户的数据写给用户的浏览器,浏览器保存(可以保存多个)
-
session是把用户的数据写到用户独占的session中,服务器端保存(保存重要的信息,减少服务的浪费)
-
session由服务器创建
session使用场景
- 保存一个用户的登录信息
- 购物车信息
- 经常在整个网站中经常会使用的数据我们将它保存在session中
使用session
package com.kuang.servlet;
import com.kuang.pojo.Person;
import javax.servlet.ServletException;
import javax.servlet.http.*;
import java.io.IOException;
public class SessionDemo01 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//解决乱码问题
req.setCharacterEncoding("utf-8");
resp.setCharacterEncoding("utf-8");
resp.setContentType("text/html; charset=UTF-8\"");
//得到session
HttpSession session = req.getSession();
//给session中存东西
session.setAttribute("name",new Person("秦酱",1));
//获取session的id
String id = session.getId();
//判断是不是新的session,新创建的
if (session.isNew())
{
resp.getWriter().write("session id 是"+id);
}else{
resp.getWriter().write("session is exist "+id);
}
// //session创建的时候做了什么事情:
// Cookie cookie = new Cookie("JSESSIONID", "id");
// resp.addCookie(cookie);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
//得到session
HttpSession session = req.getSession();
Person person = (Person) session.getAttribute("name");
System.out.println(person);
//获得session
HttpSession session = req.getSession();
session.removeAttribute("name");
//手动注销
session.invalidate();
会话自动过期:web.xml
<!--设置session默认的失效时间-->
<session-config>
<!-- 1分钟后session自动失效,一分钟为单位-->
<session-timeout>1</session-timeout>
</session-config>
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7q6PvDVp-1651655442768)(https://gitee.com/cl2854697833/my-picture/raw/master/img/202205041707384.png)]
8.JSP
8.1什么是JSP
java service page :Java服务器端页面,也和Servlet一样,用于动态web技术!
最大的特点:写jsp就像在写HTML
区别
- HTML只给用户提供静态的页面
- JSP页面中可以嵌入java代码,为用户提供动态数据
8.2、JSP原理
思路:JSP到底怎么执行的?
-
代码层面没有问题(就是html页面中增加了可执行的java代码)
-
服务器内部工作
tomcat中有一个work目录;
IDEA中使用Tomcat的会在IDEA的Tomcat中产生一个work目录
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VQuorrVL-1651655442768)(https://gitee.com/cl2854697833/my-picture/raw/master/img/202205041707385.png)]
我电脑的地址:
C:\Users\Lenovo\.IntelliJIdea2019.3\system\tomcat\Unnamed_javaweb-cookies-session\work\Catalina\localhost\ROOT\org\apache\jsp
发现页面变成了java程序!
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zc2tGo1J-1651655442769)(https://gitee.com/cl2854697833/my-picture/raw/master/img/202205041707386.png)]
浏览器向服务器发送请求,不管访问什么资源,其实都是在访问Servlet!!
JSP最终也会被转化为一个java类
JSP本质上还是一种Servlet
JSP源码:
//初始化
public void _jspInit() {
}
//销毁
public void _jspDestroy() {
}
//JSPService
public void _jspService(HttpServletRequest request, HttpServletResponse response)
throws java.io.IOException, javax.servlet.ServletException {
}
- 判断请求
- 内置一些对象(九大内置对象)
final javax.servlet.jsp.PageContext pageContext; //页面上下文
javax.servlet.http.HttpSession session = null; //session
final javax.servlet.ServletContext application; //ServletContext》》》application
final javax.servlet.ServletConfig config; //配置
javax.servlet.jsp.JspWriter out = null; //out
final java.lang.Object page = this; //page,当前
HttpServletRequest request //请求
HttpServletResponse response //响应
3、输出页面前增加的代码
response.setContentType("text/html"); //设置响应的页面类型
pageContext = _jspxFactory.getPageContext(this, request, response,
null, true, 8192, true);
_jspx_page_context = pageContext;
application = pageContext.getServletContext();
config = pageContext.getServletConfig();
session = pageContext.getSession();
out = pageContext.getOut();
_jspx_out = out;
4.以上的这些对象我们都可以在jsp页面中直接使用!
JSP本质还是Servlet对象,只不过简化了一些东西,只需要写页面部分即可
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HFBRU7kb-1651655442769)(https://gitee.com/cl2854697833/my-picture/raw/master/img/202205041707388.png)]
在JSP中页面中:
只要是java代码就会原封不动的输出;
如果是HTML语言就会转换为:
out.write("\r\n");
这样的格式输出到前端!!!
8.3、JSP基础语法
任何语言都有自己的语法,java有,jsp作为java技术的一种应用,它也拥有一些自己扩充的语法(了解即可),java所有语法都支持。
JSP表达式
<%--JSP表达式
作用:用来将程序的输出,输出到客户端
<%= 变量或表达式%>
--%>
JSP脚本片段
<%
int sum=0;
for (int i = 0; i <100 ; i++) {
sum+=i;
}
out.println("<h1>sum"+sum+"<h1>");
%>
脚本片段的再实现
<%
int x=10;
out.println(x);
%>
<p>这是一个JSP文档</p>
<%
int y=10;
out.println(y);
%>
<hr>
<%
for (int i = 0; i < 5; i++) {
%>
<h1>Hello World <%=i%> </h1>
<%
}
%>
JSP声明
<%!
static {
System.out.println("Loading Servlet");
}
private int globalVar=0;
public void kaung(){
System.out.println("进入了kaung方法");
}
%>
JSP声明:会被编译到JSP生成到JAVA的类中!!,其他的就会被生成_jspService类中
在jsp中嵌入java代码即可
<%%>
<%=%>
<%!%>
<%--%>
<!--我是HTML的注释-->
<%--我是jsp注释--%>
JSP的注释,不会再客户端显示,HTML就会
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-y4mIsB1W-1651655442770)(https://gitee.com/cl2854697833/my-picture/raw/master/img/202205041707390.png)]
8.4、JSP指令
重点是页面跳转,和设置错误页面
- 页面跳转
<error-page>
<error-code>404</error-code>
<location>/error/404.jsp</location>
</error-page>
<error-page>
<error-code>500</error-code>
<location>/error/500.jsp</location>
</error-page>
- 错误页面‘
<html>
<head>
<title>404</title>
</head>
<body>
<img src="../image/404.png" alt="404">
</body>
</html>
jsp指令格式
<%@ page args %>
<%@ include file=""%>
- @ include file和jsp:include page的区别
<%--@ include会将两个页面合二为一--%>
<%@ include file="common/header.jsp"%>
<h1>网页主题</h1>
<%@ include file="common/footer.jsp"%>
<hr>
<%--标签体--%>
<%--jsp:include:会拼接页面,本质还是三个--%>
<jsp:include page="/common/header.jsp"></jsp:include>
<h1>网页主题</h1>
<jsp:include page="/common/footer.jsp"></jsp:include>
例子:
当在@ include中时;
<%--@ include会将两个页面合二为一--%>
<%@ include file="common/header.jsp"%>
<h1>网页主题</h1>
<%
int i =10;
%>
<%@ include file="common/footer.jsp"%>
<hr>
程序会报错:
因为<%–@ include会将两个页面合二为一–%>,而java不能将重复定义变量
当在jsp:include中时
<jsp:include page="/common/header.jsp"></jsp:include>
<h1>网页主题</h1>
<%
int i =10;
%>
<jsp:include page="/common/footer.jsp"></jsp:include>
没有错误,因为本质上还是三个部分,没有合到一起
main里面就java和resoures,其他的都放在web页面下面
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ElkT112E-1651655442771)(https://gitee.com/cl2854697833/my-picture/raw/master/img/202205041707394.png)]
8.5、九大内置对象
- pageContext 存东西
- Request 存东西
- Response
- Session 存东西
- Application (ServletContext) (存东西)
- Config (ServletConfig)
- out
- page(不用了解)
- exception
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-618EFIQK-1651655442771)(https://gitee.com/cl2854697833/my-picture/raw/master/img/202205041707395.png)]
讲解
pageContext.setAttribute("name1","秦酱1号");//保存到数据只在一个页面中有效
session.setAttribute("name2","秦酱2号");//保存到数据只在一个会话中有效,从打开浏览器到关闭浏览器
application.setAttribute("name3","秦酱3号");//保存到数据只在服务器中有效,从打开服务器到关闭服务器
request.setAttribute("name4","秦酱4号");//在一次请求中有效,请求转发会携带这个数据
request:客户端向服务器发送请求,产生的数据,比如:新闻,用户看完没用的1
session:客户端向服务器发送的请求,产生的数据,用户用完一会还要用,比如购物车;
application:客户端向服务器发送的请求,产生的数据,一个用户用完了,其他用户害可能接着用,比如:聊天数据
8.6、JSP标签、JSTL标签、EL表达式
JSP标签、JSTL标签需要导包
<!-- JSTL表达式依赖-->
<groupId>javax.servlet.jsp.jstl</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<!--standard标签库-->
<dependency>
<groupId>taglibs</groupId>
<artifactId>standard</artifactId>
<version>1.1.2</version>
</dependency>
EL表达式:${ }
- 获取数据
- 执行运算
- 获取web开发的常用对象
- 执行java程序
JSP标签
1.<%--<jsp:include>--%>//页面合并
2.<jsp:forward page="/jsptarget02.jsp">//转发
3. <jsp:param name="name" value="kaunagsheng"/>//设置参数
<jsp:param name="age" value="12"/>
</jsp:forward>
JSTL标签
JSTL标签库的使用就是为了弥补HTML标签的不足;它自定义许多标签,可以供我们使用,标签的功能和java代码一样!!
格式化标签
SQL标签
XML 标签
JSTL函数
核心标签(掌握部分)
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
JSTL标签库的使用步骤
-
引入对应的taglib
-
使用其中的方法
-
在Tomcat中也需要引入jstl包,否则会报错,其实IDEA里面配置好的话就行
-
c:if
<h4>if测试</h4>
<hr>
<%--“POST和GET都是向服务器提交数据,并且都会从服务器获取数据--%>
<form action="coreif.jsp" method="get">
<%--
EL表达式获取表单中的数据
${param.参数名}
--%>
<input type="text" name="username" value="${param.username}">
<input type="submit" value="登录">
</form>
<%--判断如果登录的用户名是管理员则登陆成功--%>
<c:if test="${param.username=='admin'}" var=" IsAdmin">
<c:out value="管理员欢迎你!!"/>
</c:if>
<%--自闭和标签--%>
<c:out value="${IsAdmin}"/>
- c:choose when
<c:set var="socre" value="66"></c:set>
<c:choose>
<c:when test="${socre>=90}">你的成绩为优秀</c:when>
<c:when test="${socre>=80}">你的成绩为一般</c:when>
<c:when test="${socre>=70}">你的成绩为良好</c:when>
<c:when test="${socre>=60}">你的成绩为合格</c:when>
<c:when test="${socre<60}">你的成绩为不及格</c:when>
</c:choose>
- c:foreach
<%
ArrayList<String> people = new ArrayList<>();
people.add(0,"张三");
people.add(1,"尼斯");
people.add(2,"王五");
people.add(3,"赵六");
request.setAttribute("list",people);
%>
<%--var,每一次遍历出来的变量
iteam:要遍历的对象
begin="0" end="" step="1"
--%>
<c:forEach var="people" items="${list}">
<c:out value="${people}"/> <br >
</c:forEach>
<c:forEach var="people" items="${list}" begin="1" end="3" step="2">
<c:out value="${people}"/> <br >
</c:forEach>
9.JavaBean
实体类
JavaBean有特定的写法:
- 必须有一个无参构造
- 属性必须私有化
- 必须有对应的get和set方法
一般用来和数据库的字段做映射 ORM;
ORM对象关系映射:
- 表—>类
- 字段—>属性
- 记录—>对象
id | name | aeg | address |
---|---|---|---|
1 | 秦酱1号 | 1 | 西安 |
2 | 秦酱2号 | 10 | 西安 |
3 | 秦酱3号 | 100 | 西安 |
class people(){
}
<%
people people = new people();
people.setAddress("aa");
people.setAge(12);
people.setId(2);
people.setName("admin");
%>
<jsp:useBean id="people" class="com.kuang.entity.people" scope="page"/>
<jsp:setProperty name="people" property="id" value="1"/>
<jsp:setProperty name="people" property="name" value="秦酱"/>
<jsp:setProperty name="people" property="age" value="12"/>
<jsp:setProperty name="people" property="address" value="xian"/>
<%=people.getAddress()%>
姓名:<jsp:getProperty name="people" property="name"/>
年龄:<jsp:getProperty name="people" property="age"/>
id:<jsp:getProperty name="people" property="id"/>
地址:<jsp:getProperty name="people" property="address"/>
- 过滤器
- 文件上传
- 邮件发送
- JDBC复习
- 如何使用JDBC
- JDBCcurd
- JDBC事务
10、MVC三层架构
什么是MVC:Module View Controller 模型,视图,控制器
10.1、早些年
用户直接访问控制层,控制层就可以直接操作数据库:
servlet---CRUD---->数据库
弊端:程序十分臃肿,不利于维护
servlet的代码中:处理请求,响应,视图跳转,处理JDBC,处理业务代码,处理逻辑代码
架构:没有什么是再加一层解决不了的
程序员调用JDBC
|
JDBC
|
MySQL Oracle sqlserver 。。。。
10.2、三层架构
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-A86SG5QF-1651655442772)(https://gitee.com/cl2854697833/my-picture/raw/master/img/202205041707398.png)]
Module
- 业务处理:业务逻辑(service),
- 数据持久层:CRUD(Dao)
View
- 展示数据
- 提供链接发起servlet请求(a,from,img…)
Controller(Servlet)
- 就收用户的请求:(request ,请求参数,session信息)
- 交给业务层处理对应的代码
- 控制视图的跳转
登录---->接受用户的登录请求---->处理用户的请求(获取用户登录的数据,username,password,)--->交给业务层处理登录业务(判断用户名密码是否正确,事务)---->Dao层查询用户名密码是否一样--->数据库
11、Filter(重点)
filter:过滤器 ,用来过滤网站的数据:
- 处理中文乱码
- 登录验证
和servlet一样
1.导包pom.xml
<dependencies>
<dependency>
<groupId>javax.servlet.jsp.jstl</groupId>
<artifactId>jstl-api</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>javax.servlet.jsp-api</artifactId>
<version>2.3.3</version>
</dependency>
<!--standard标签库-->
<dependency>
<groupId>taglibs</groupId>
<artifactId>standard</artifactId>
<version>1.1.2</version>
</dependency>
<!--连接数据库-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.11</version>
</dependency>
</dependencies>
查询数据库版本
8.0.11
SELECT VERSION();
2.编写过滤器
2.1导包不要错
2.2重写方法,实现Filter接口
package com.kuang.filter;
import javax.servlet.*;
import java.io.IOException;
public class CharaterEncodingFilter implements Filter {
//初始化,web服务器启动时就已经初始化了,随时等待filter对象出现,
public void init(FilterConfig filterConfig) throws ServletException {
// filterConfig.getServletContext()
System.out.println("CharaterEncodingFilter已经初始化了");
}
//chain:链
/*、
1.过滤中的所有代码,在过滤特定请求时都会执行
2.必须要让过滤器dofilter继续同行
chain.doFilter(request,response)
*/
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
request.setCharacterEncoding("utf-8");
response.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=UTF-8");
System.out.println("setCharacterEncoding执行前");
chain.doFilter(request,response);//让我们的请求继续走, 如果不屑,程序走到这就会被拦截
System.out.println("setCharacterEncoding执行后");
}
//销毁,web服务器关闭时,过滤会销毁
public void destroy() {
System.out.println("CharaterEncodingFilter已经销毁了");
}
}
提醒在servlet中如何实行编码
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//设置请求和响应的编码要写在最开始的位置否则前面的文字不会生效
// resp.setContentType("text/html;charset=UTF-8");
//resp.setCharacterEncoding("utf-8");
resp.getWriter().write("你好世界");
}
3.在webxml中配置filter过滤器
<filter>
<filter-name>CharaterEncodingFilter</filter-name>
<filter-class>com.kuang.filter.CharaterEncodingFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>CharaterEncodingFilter</filter-name>
<url-pattern>/servlet/*</url-pattern>
</filter-mapping>
12、监听器
实现一个监听器的接口:有(N)种
1.编写一个监听器
2。实现监听器的接口
package com.kuang.listener;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
//统计网站在线人数,:统计session
public class OnlineCountListener implements HttpSessionListener {
@Override//创建session监听:看你的一举一动
//一旦创建一个session就会触发一次这个事件
public void sessionCreated(HttpSessionEvent se) {
ServletContext ctx = se.getSession().getServletContext();//得到session提高到最高作用域,用来存东西,取东西
System.out.println(se.getSession().getId());
Integer onlineCount = (Integer) ctx.getAttribute("OnlineCount");
//装箱拆箱
if (onlineCount==null){
onlineCount=new Integer(1);
}else {
int count=onlineCount.intValue();
onlineCount=new Integer(count+1);//如果没有session就设置值为1,否则就+1
}
ctx.setAttribute("onlineCount",onlineCount);
}
@Override//销毁session监听
public void sessionDestroyed(HttpSessionEvent se) {
ServletContext ctx = se.getSession().getServletContext();//得到session提高到最高作用域,用来存东西,取东西
Integer onlineCount = (Integer) ctx.getAttribute("OnlineCount");
//装箱拆箱
if (onlineCount==null){
onlineCount=new Integer(0);
}else {
int count=onlineCount.intValue();
onlineCount=new Integer(count-1);//如果没有session就设置值为1,否则就+1
}
ctx.setAttribute("onlineCount",onlineCount);
}
/*
session销毁的两种方案
1.手动销毁 se.getSession().invalidate();
2.自动销毁
<session-config>
<session-timeout>1</session-timeout>
</session-config>
*/
}
3.web。xm中注册
<listener>
<listener-class>com.kuang.listener.OnlineCountListener</listener-class>
</listener>
4.看情况是否使用
13、过滤器、监听器常见应用
用户登录之后才能进入首页! 用户注销就不能进入主页了
思路
- 用户登录之后,向session中放入用户的数据
- 进入主页的时候要判断用户是否已经登录;要求在过滤器中实现:
//获取前端的参数
String username = req.getParameter("username");
//判断
if(username.equals("admin")){
//建议用户信息放到session中
req.getSession().setAttribute("USER_SESSION",req.getSession().getId());
resp.sendRedirect("/sys/success.jsp");//成功就跳转sucess页面
}else {
resp.sendRedirect("/sys/error.jsp");//注意网页后面要加后缀。jsp之类
}
}
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
//将ServletRequest转化为HttpServletRequest,方便存取
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;
// Object user_session = request.getSession().getAttribute("USER_SESSION");
if (request.getSession().getAttribute("USER_SESSION")==null){
response.sendRedirect("/error.jsp");
}
//filterChain也要替换被转换的servletRequest吗?试试,yes
filterChain.doFilter(request,response);
}
14、JDBC
Java database connecting
需要的jar包支持:
- java.sql
- javax.sql
- mysql-connceter-java 连接驱动(必须)
实验环境搭建(就是创建数据库)
导入数据库依赖,连接数据库
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.11</version>
</dependency>
</dependencies>
JDBC固定步骤:
- 加载驱动
- 连接数据库
- 向数据库发送SQL的对象Statement
- 编写SQL
- 执行sql
- 关闭连接
package com.kuang.lesson01;
import java.sql.*;
//我的第一个JDBC程序
public class jdbcFirst {
public static void main(String[] args) throws ClassNotFoundException, SQLException {
//1.加载驱动 ····>>打开sqlyog
Class.forName("com.mysql.cj.jdbc.Driver");//固定写法,加载驱动
/*抛出异常,
mysql80使用com.mysql.cj.jdbc.Driver,
而ymsql5使用"com.mysql.jdbc.Driver"
*/
//2.用户信息和url ..>输入url,用户名,密码。。。
//useUnicode=true&characterEncoding=utf8&useSSL=false
String url="jdbc:mysql://localhost:3306/cjgl? useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=GMT%2B8";
String username="root";
String password="123";
//3.连接成功,数据库对象 ...>成功,即出现了对象
/*
connection 代表数据库
*/
Connection connection = DriverManager.getConnection(url, username, password);
//4.执行sql的对象 ....>
/*
statement 代表执行sql的对象
*/
Statement statement = connection.createStatement();
//5.执行sql的对象去执行sql
String sql="SELECT * FROM `course` WHERE ccredit=3";
ResultSet resultSet = statement.executeQuery(sql);//resultset 返回的结果集,结果集封装了我们全部查询出来的结果
while (resultSet.next()){
System.out.println("cno="+resultSet.getObject("cno"));
System.out.println("cname="+resultSet.getObject("cname"));
System.out.println("ccredit="+resultSet.getObject("ccredit"));
System.out.println("cdept="+resultSet.getObject("cdept"));
System.out.println("--------------------------------------");
}
//6.释放连接
resultSet.close();
statement.close();
connection.close();
/*
口诀:贾琏欲执事(加连预执释)
引入依赖,加载驱动 连接数据库 创建预编译语句 设置参数,执行sql 关闭连接,释放资源
*/
}
}
预编译sql
package com.kuang.lesson03;
import com.kuang.lesson02.utils.JdbcUtils;
import java.sql.*;
public class TextInsert {
public static void main(String[] args) {
Connection conn=null;
PreparedStatement st=null;
ResultSet rs=null;
try {
conn = JdbcUtils.getConnection();
//区别,写insert into。。但是values后面的要另外写
//使用问号占位符
String sql="INSERT INTO `t1` (`id`,`xm`,`score`)VALUES(?,?,?)";
st=conn.prepareStatement(sql);//预编译sql,先写sql,然后不执行
//手动给参数赋值
// INSERT INTO `t1` (`id`,`xm`,`score`)VALUES(20,'chenlon',12)
st.setInt(1,4);
st.setString(2,"chenlon");
st.setInt(3,12);
//执行
int i = st.executeUpdate();
if (i>0){
System.out.println("成功");
}
} catch (SQLException e) {
e.printStackTrace();
}finally {
JdbcUtils.relase(conn,st,null);
}
}
}
事务
ACID特性
junit单元测试
依赖
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
</dependencies>
简单使用:
@Test注解只有在方法上使用有效,只要加了这个注解的方法,就可以直接运行
@Test
public void text(){
System.out.println("这是一个junit测试");
//使用junit注解可以在不使用main方法的情况下进行测试
}
成功:
错误代码:
环境搭建
…
回滚
package com.kuang.lesson04;
import com.kuang.lesson02.utils.JdbcUtils;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class TextTrasaction {
public static void main(String[] args) {
Connection conn=null;
PreparedStatement st=null;
ResultSet rs=null;
try {
conn= JdbcUtils.getConnection();
//关闭自动提交功能,自动会开启事务
conn.setAutoCommit(false);//开启事务
String sql1="update account set balance=balance-100 where aID= '001'";
st=conn.prepareStatement(sql1);
st.executeUpdate();
String sql2="update account set balance=balance+100 where aID= '002'";
st=conn.prepareStatement(sql2);
st.executeUpdate();
//提交事务
conn.commit();
System.out.println("成功");
} catch (SQLException e) {
try {
conn.rollback();//如果失败,则回滚
} catch (SQLException ex) {
ex.printStackTrace();
}
e.printStackTrace();
}finally {
JdbcUtils.relase(conn,st,rs);
}
}
}
rintln(“--------------------------------------”);
}
//6.释放连接
resultSet.close();
statement.close();
connection.close();
/*
口诀:贾琏欲执事(加连预执释)
引入依赖,加载驱动 连接数据库 创建预编译语句 设置参数,执行sql 关闭连接,释放资源
*/
}
}
## **预编译sql**
```java
package com.kuang.lesson03;
import com.kuang.lesson02.utils.JdbcUtils;
import java.sql.*;
public class TextInsert {
public static void main(String[] args) {
Connection conn=null;
PreparedStatement st=null;
ResultSet rs=null;
try {
conn = JdbcUtils.getConnection();
//区别,写insert into。。但是values后面的要另外写
//使用问号占位符
String sql="INSERT INTO `t1` (`id`,`xm`,`score`)VALUES(?,?,?)";
st=conn.prepareStatement(sql);//预编译sql,先写sql,然后不执行
//手动给参数赋值
// INSERT INTO `t1` (`id`,`xm`,`score`)VALUES(20,'chenlon',12)
st.setInt(1,4);
st.setString(2,"chenlon");
st.setInt(3,12);
//执行
int i = st.executeUpdate();
if (i>0){
System.out.println("成功");
}
} catch (SQLException e) {
e.printStackTrace();
}finally {
JdbcUtils.relase(conn,st,null);
}
}
}
事务
ACID特性
junit单元测试
依赖
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
</dependencies>
简单使用:
@Test注解只有在方法上使用有效,只要加了这个注解的方法,就可以直接运行
@Test
public void text(){
System.out.println("这是一个junit测试");
//使用junit注解可以在不使用main方法的情况下进行测试
}
成功:
错误代码:
环境搭建
…
回滚
package com.kuang.lesson04;
import com.kuang.lesson02.utils.JdbcUtils;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class TextTrasaction {
public static void main(String[] args) {
Connection conn=null;
PreparedStatement st=null;
ResultSet rs=null;
try {
conn= JdbcUtils.getConnection();
//关闭自动提交功能,自动会开启事务
conn.setAutoCommit(false);//开启事务
String sql1="update account set balance=balance-100 where aID= '001'";
st=conn.prepareStatement(sql1);
st.executeUpdate();
String sql2="update account set balance=balance+100 where aID= '002'";
st=conn.prepareStatement(sql2);
st.executeUpdate();
//提交事务
conn.commit();
System.out.println("成功");
} catch (SQLException e) {
try {
conn.rollback();//如果失败,则回滚
} catch (SQLException ex) {
ex.printStackTrace();
}
e.printStackTrace();
}finally {
JdbcUtils.relase(conn,st,rs);
}
}
}