静态web
html,css
动态web
技术栈:Servlet/jsp,asp,php
可以提供浏览器访问的程序: a.html , b.html…
tomcat服务器
一个web应用由多部分组成(静态web,动态web)
web应用程序编写完毕后,若想要提供给外界访问,需要一个服务器来统一管理
*.html *.htm,这些都是网页的后缀,如果服务器上一直存在这些东西,就可以直接进行读取,
静态web存在的缺点:
页面会动态展示:“web的页面展示的效果因人而异”
缺点:
优点:
ASP:
php:
Jsp/servlet:
本质上是servlet
sun公司主推的B/S架构
(B/S:浏览器和服务器 C/S:客户端和服务器)
基于java语言的(所有的大公司,或者一些开源的组件,都是用java写的)
可以承载三高问题带来的影响,高并发,高性能,高可用
语法像ASP,ASP–>JSP,加强市场强度
Tomcat
面向百度编程;
apache 软件基金会
工作3-5年,尝试手写Tomcat;
下载Tomcat:
Tomcat官网
tomcat server.xml 文件可以修改启动的端口号,可以修改主机名称,
默认端口号:
tomcat:8080
mysql:3306
http:80
https:443
默认主机名称:
localhost—>127.0.0.1
默认网站应用存放的位置:
webapps
高难度面试题:
请你谈一下网站如何进行访问的?
输入域名,回车 www.baidu.com
检查本机的 C:\Windows\System32\drivers\etc\hosts配置问下有没有这个域名映射;
有,就直接返回对应ip的地址
127.0.0.1 www.baidu.com
这个地址中有我们需要访问的web程序,可以直接访问
没有,去DNS服务器,(DNS全世界的域名都在这里管理 14.215.117.39:443)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PwMM33nX-1658156711620)(https://s2.loli.net/2022/07/06/tAkM2RQg3PNewsh.png)]
IIS
微软的; ASP … Windows中自带
…
服务器是一种被动的操作,用来处理用户的请求和给用户一些响应信息;
将自己写的网站 *.html文件,放到服务器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 超文本传输协议,简单的请求、响应协议
HTTPS:
http1.0
http/1.0:客户端可以和web服务器连接后,只能获得一个web资源,断开连接。
http2.0
http/1.1:客户端可以与web服务器连接后,可以获得多个web资源。
客户端—发请求(request)—服务器
以百度为例:
General 通用的:请求和响应都有
Request URL: https://www.baidu.com/ 请求地址
Request Method: GET get/post方法
Status Code: 200 OK 状态码:200
Remote Address: 180.101.49.11:443 远程地址
Referrer Policy: strict-origin-when-cross-origin 引荐来源网址策略 “strict-origin-when-cross-origin”,用于修剪用户敏感信息,例如路径和查询字符串,以保护隐私。
referrer 头经常包含用户的隐私数据,比如用户在引用网站上阅读哪些文章、甚至是用户在网站上的账户信息。因此,W3C 官方提出了一些候选策略 Referrer Policy,以规范 referrer 内容。
即当从 HTTPS 网站跳转到 HTTP 网站或者请求其资源时(安全降级 HTTPS→HTTP),不显示 referrer 的信息,其他情况(安全同级 HTTPS→HTTPS,或者 HTTP→HTTP)则在 referrer 中显示完整的源网站的 URL 信息。
Request header:
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,... 请求类型信息
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9 语言
Connection: keep-alive 连接:一直连接
中间一堆cookie信息
Cookie: BIDUPSID=27CCFA0EF0EC7BE270189BCE89C465F1; PSTM=1597130134; BAIDUID=5B74033ED4696DC25CC97B295A443D76:FG=1; BD_UPN=12314753; MCITY=-352%3A; BAIDUID_BFESS=5B74033ED4696DC25CC97B295A443D76:FG=1; ZFY=N9RnKbDDv1VWhF3plEYx2jnBibjkBClK4C5W7h3a5A0:C; COOKIE_SESSION=4581192_2_9_9_8_9_1_0_8_5_1_0_4581192_0_37_0_1657009934_1652341087_1657009897%7C9%232235112_315_1652341085%7C9; baikeVisitId=fa2ebb37-2746-49fd-a81f-da7ca55cf1f9; BA_HECTOR=04a58la00g25818g201hccfrq14; BDRCVFR[-HoWM-pHJEc]=mk3SLVN4HKm; BD_HOME=1; H_PS_PSSID=31254_26350
Host: www.baidu.com 主机
sec-ch-ua: ".Not/A)Brand";v="99", "Google Chrome";v="103", "Chromium";v="103"
sec-ch-ua-mobile: ?0 移动
sec-ch-ua-platform: "Windows" 平台 windows
Sec-Fetch-Dest: document 文档
Sec-Fetch-Mode: navigate 导航
Sec-Fetch-Site: none 网站
Sec-Fetch-User: ?1 用户
Upgrade-Insecure-Requests: 1 升级-不安全-请求
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36 用户代理
请求行
消息头
Accept: 告诉浏览器,它所支持的数据类型
Accept-Encoding: 支持哪种编码格式 GBK UTF-8 GB2312 ISO8859-1
Accept-Language: 告诉浏览器,他的语言环境
cache-Control: 缓存控制
Connection: keep-alive 告诉浏览器请求完成是断开还是连接
Host...主机
服务器—响应(respose)—客户端
以百度为例,respose header
Cache-Control: private 缓存控制
Connection: keep-alive 保持连接
Content-Encoding: gzip 内容编码 压缩程序
Content-Type: text/html;charset=utf-8 内容类型:文本/超文本标记语言 text/html, 字符集=utf-8 utf:Unicode Transformation Format Unicode转换格式
Date: Thu, 07 Jul 2022 02:13:05 GMT 当前时间 GMT:格林尼治时间
Expires: Thu, 07 Jul 2022 02:12:14 GMT 有效期
Server: BWS/1.1 浏览器服务信息
Strict-Transport-Security: max-age=172800 严格传输安全
Traceid: 1657159985069125325811992526401082961452 跟踪id
Transfer-Encoding: chunked 转移编码:分块
X-Frame-Options: sameorigin 框架选项:同源
X-Ua-Compatible: IE=Edge,chrome=1 兼容
响应体
Accept: 告诉浏览器,它所支持的数据类型
Accept-Encoding: 支持哪种编码格式 GBK UTF-8 GB2312 ISO8859-1
Accept-Language: 告诉浏览器,他的语言环境
cache-Control: 缓存控制
Connection: keep-alive 告诉浏览器请求完成是断开还是连接
Host...主机
Refrush:告诉客户端,多久刷新一次;
Location: 让网页重新定位;
响应状态码
200 请求响应成功
3** 请求重定向 303
4** 找不到资源 404
5** 服务器代码错误 500 502 网关错误1
常见面试题
当你的浏览器中地址栏输入地址并回车到页面能够展示回来,经历了什么?
帮助管理jar包,java开发中大量jar包,需要手动导入很麻烦
maven帮助自动导入和配置jar包
maven是一个项目架构管理工具
目前用它来导入jar包
核心思想:约定大于配置
maven会规定如何编写java代码,必须按规范来
下载安装maven
apache maven progect 官网下载 bin.zip & src.zip
https://maven.apache.org/
解压 bin.zip
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KcI60xi3-1658156711621)(https://s2.loli.net/2022/07/07/6cMiyOqJwLPSYQG.png)]
conf – 配置
在系统环境变量中,配置如下配置:
镜像 mirrors
国内建议使用阿里云的镜像
<mirror>
<id>alimavenid>
<mirrorof>centralmirrorof>
<name>aliyun mavenname>
<url>http://maven.aliyun.com/nexus/comtent/groups/publicurl>
mirror>
或者
<mirror>
<id>nexus-aliyunid>
<mirrorof>*,!jeecg,!jeecg-snapshotsmirrorof>
<name>Nexus aliyunname>
<url>http://maven.aliyun.com/nexus/comtent/groups/publicurl>
mirror>
在本地的仓库,远程仓库;
建立一个本地仓库: 不需要每次去网上下载 localRepository
setting.xml中
<localRepository>
这里放的是本地自己新建的maven仓库地址
localRepostory>
选中maven web项目模板,进行创建
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fBZ8odAK-1658156711627)(https://s2.loli.net/2022/07/07/GDkg4VK5uTNvf17.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RO34m2Bx-1658156711633)(https://s2.loli.net/2022/07/07/FEU8VgQwxmy1S2Z.png)]
点击finish
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nEOBjf3C-1658156711635)(https://s2.loli.net/2022/07/07/HXDvqAWdYKGybra.png)]
构建maven项目成功
观察maven仓库中多了什么东西?
IDEA中的maven设置:
idea项目创建成功后,看一下maven配置
maven在idea中的配置和使用就ok了
创建一个普通的maven项目
不选中创建模板,直接next
maven web项目结构:
WEB-INF----web.xml index.jsp 这个只有在web应用下才会有!
普通maven项目结构:
在 maven web项目下加入一个 java文件 和 resources文件;
java文件中放代码 ,标记为源码目录 Sources Root
resources文件中放资源,标记为资源目录 Resource Root
标记文件夹功能:
项目结构配置:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yYIPRklw-1658156711641)(https://s2.loli.net/2022/07/07/aA6B5lE3nXFYqQ9.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JIalTbHb-1658156711642)(https://s2.loli.net/2022/07/07/OfMJo8Lyj6zPpNq.png)]
创建了一个 maven web项目后,配置Tomcat;
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-iAlxCtIu-1658156711647)(https://s2.loli.net/2022/07/07/g4KObFYvNVfUjMo.png)]
解决了警告问题。
为什么会有警告问题?
我们访问一个网站,需要指定一个文件夹的名字;idea没有主动去找项目名字,需要手动配置。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GSetS5Rh-1658156711648)(https://s2.loli.net/2022/07/07/sWMRih7ST8NdxO2.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LxOwlLpP-1658156711651)(https://s2.loli.net/2022/07/07/pNCzPoGbJMWk6Ht.png)]
pom.xml是maven的核心配置文件
maven命令使用:
clean:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Kbf5AV9J-1658156711652)(https://s2.loli.net/2022/07/07/d8h7IbCpU9vmZMH.png)]
Maven导入jar包:
Maven由于他的约定大于配置,所以默认的maven项目在构建编译时不会把我们其他目录下的配置文件导出到target目录中,从而导致配置文件无法导出或者生效的问题。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UwamquG2-1658156711654)(https://s2.loli.net/2022/07/18/IfHKinyBx2RqPWt.png)]
解决方案:在项目的pom.xml文件中手动配置资源过滤,让它把src/main/java目录下的.properties和.xml文件也能够被导出。
<build>
<resources>
<resource>
<directory>src/main/resourcesdirectory>
<includes>
<include>**/*.propertiesinclude>
<include>**/*.xmlinclude>
includes>
<filtering>truefiltering>
resource>
<resource>
<directory>src/main/javadirectory>
<includes>
<include>**/*.propertiesinclude>
<include>**/*.xmlinclude>
includes>
<filtering>truefiltering>
resource>
resources>
build>
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4HttIY9A-1658156711655)(https://s2.loli.net/2022/07/18/UgIaw9Db4hOsM5J.png)]
Maven 3.6.2 版本有问题,建立依赖的时候依赖无法导入,导入的时候会报错
解决方法:降级为3.6.1
Tomcat闪退
因为tomcat需要java的环境,但是tomcat中没有配置java环境,所以就会闪退。
解决办法:tomcat安装文件\bin\catlina.bat用记事本打开,找到Java环境配置的地方,配置下java的环境。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-c3T7okhr-1658156711656)(https://s2.loli.net/2022/07/07/Tl9cWprqdtvPYQo.png)]
IDEA中每次都要重复配置Maven
解决办法:在IDEA中的全局默认配置中去配置
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GhIw4GV4-1658156711657)(C:\Users\16431\AppData\Roaming\Typora\typora-user-images\image-20220707174107079.png)]
Maven项目中Tomcat无法配置
Maven默认web项目中的web.xml版本问题
默认生成web-app_2_3,这个版本太老了,
替换为webapp4.0版本,和tomcat保持一致
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yWloyZME-1658156711658)(https://s2.loli.net/2022/07/08/2S7IazXFbjR5QlY.png)]
所以需要更换使用 D:\Program Files\apache-tomcat-9.0.43\webapps\ROOT\WEB-INF\web.xml 中的xml模板:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lqzGrWjg-1658156711659)(https://s2.loli.net/2022/07/08/Es7OqhtynUCacjx.png)]
<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">
<display-name>Welcome to Tomcatdisplay-name>
<description>
Welcome to Tomcat
description>
web-app>
创建maven web项目结构:
这个类模板在tomcat\webapps\examples\servlet中;
操作:启动tomcat,访问localhost:8080/examples/servlets即可得到Servlets examples
项目启动后,浏览器输入url,进行访问,得到页面,后端是怎么进行的?
/hello,就是给tomcat下加了一层包,包名字叫hello,访问的时候地址变为:localhost:8080/hello
如果没有加,访问 localhost:8080 默认进入后端index.jsp页面
如果给tomcat这里加了新的包层,则访问路径为localhost:8080/hello/,访问页面默认进入后端index.jsp页面
访问 localhost:8080/hello/kuangsheng 访问时先从WEB-INF中的web.xml文件找 servlet-mapping 中 url-pattern 请求路径为 /kuang 的 servlet-name , 由于一个servlet 对应一个 servlet-mapping ,所以再通过找到的servlet-name 去找servlet中的 servlet-class ,servlet-class中是这个类的 路径 ,从而找到类响应的页面;
不需要勾选 create Maven-webapps模板;
删掉里面的src目录,以后我们的学习就在这个项目里面建立Moudel;这个空的工程就是Maven主工程;
父项目中pom.xml中多了一个
<modules>
<module>servlet-01module>
modules>
子项目中pom.xml中多了一个
<parent>
<artifactId>javaweb-02-servletartifactId>
<groupId>com.kuanggroupId>
<version>1.0-SNAPSHOTversion>
parent>
父项目中的jar包,子项目可以直接使用;
子项目中的jar包,父项目不能直接使用;
son extends father
更换子项目中web.xml内容为tomcat安装包\webapps\ROOT\WEB-INF\web.xml中的内容;因为模板中的webapp版本太老了,和下载的Tomcat版本不匹配;
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZT1X3sv0-1658156711667)(https://s2.loli.net/2022/07/08/YmU97cgPNBFrqw6.png)]
main包下添加java包和resource包
编写一个普通类
实现Servlet接口 ,这里我们直接继承HttpServlet
Servlet接口在Sun公司有两个默认的实现类:HttpServlet和GenericServlet 即httpServlet和通用servlet.
package com.kuang.servlet;
import javax.servlet.ServletException;
import javax.servlet.ServletInputStream;
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 HollerServlet extends HttpServlet {
//由于get或post只是请求实现的不同方式,可以互相调用,业务逻辑一样
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doGet(req, resp);
//输入流
//ServletInputStream writer = 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 {
super.doPost(req, resp);
}
}
为什么需要映射:我们写的是Java程序,但是要通过浏览器访问,而浏览器需要连接web服务器,所以我们需要在web服务中注册我们写的Servlet,还需要给他一个浏览器能够访问的路径。
<servlet>
<servlet-name>helloservlet-name>
<servlet-class>com.kuang.servlet.HelloServletservlet-class>
servlet>
<servlet-mapping>
<servlet-name>helloservlet-name>
<url-pattern>/hellourl-pattern>
servlet-mapping>
注意:配置项目发布的路径就行了
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PKdVB5qB-1658156711671)(https://s2.loli.net/2022/07/08/UuOKbcZf6nIQWqF.png)]
访问:localhost:8080/s1/hello/ 就访问到了写的java代码的响应流的内容。
Servlet是由web服务器调用,web服务器在收到浏览器的请求后,会:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CEMvuQgo-1658156711672)(https://s2.loli.net/2022/07/08/bm5dlrws3qNU7PI.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CVL2inOi-1658156711672)(https://s2.loli.net/2022/07/08/MmWdtxgrOklNIXS.png)]
访问:http://localhost:8080/s1/hello
就会访问到HelloServlet类中的响应的内容。
<servlet>
<servlet-name>helloservlet-name>
<servlet-class>com.kuang.servlet.HelloServletservlet-class>
servlet>
<servlet-mapping>
<servlet-name>helloservlet-name>
<url-pattern>/hellourl-pattern>
servlet-mapping>
访问:
http://localhost:8080/s1/hello1
http://localhost:8080/s1/hello2
http://localhost:8080/s1/hello3
访问到的都是HelloServlet类中响应的内容。
<servlet>
<servlet-name>helloservlet-name>
<servlet-class>com.kuang.servlet.HelloServletservlet-class>
servlet>
<servlet-mapping>
<servlet-name>helloservlet-name>
<url-pattern>/hello1url-pattern>
servlet-mapping>
<servlet-mapping>
<servlet-name>helloservlet-name>
<url-pattern>/hello2url-pattern>
servlet-mapping>
<servlet-mapping>
<servlet-name>helloservlet-name>
<url-pattern>/hello3url-pattern>
servlet-mapping>
访问 http://localhost/s1/hello/任意符号
都可以访问到HelloServlet类响应的内容。
<servlet>
<servlet-name>helloservlet-name>
<servlet-class>com.kuang.servlet.HelloServletservlet-class>
servlet>
<servlet-mapping>
<servlet-name>helloservlet-name>
<url-pattern>/hello/*url-pattern>
servlet-mapping>
访问 http://localhost:8080/s1/jskfljadf 后面任意符号
都可以访问到HelloServlet类响应的内容。
<servlet>
<servlet-name>helloservlet-name>
<servlet-class>com.kuang.servlet.HelloServletservlet-class>
servlet>
<servlet-mapping>
<servlet-name>helloservlet-name>
<url-pattern>/*url-pattern>
servlet-mapping>
例1:*.do
<servlet>
<servlet-name>helloservlet-name>
<servlet-class>com.kuang.servlet.HelloServletservlet-class>
servlet>
<servlet-mapping>
<servlet-name>helloservlet-name>
<url-pattern>*.dourl-pattern>
servlet-mapping>
注意: * 前面不能加项目映射的路径
如果路径格式有误,服务器会报错:
java.lang.IllegalStateException异常是什么问题?解决办法_宋丹敏的博客-CSDN博客
指定了固有的映射路径,优先级最高; 如果找不到,就会走默认的路径。
<servlet>
<servlet-name>helloservlet-name>
<servlet-class>com.kuang.servlet.HelloServletservlet-class>
servlet>
<servlet-mapping>
<servlet-name>helloservlet-name>
<url-pattern>/hellourl-pattern>
servlet-mapping>
<servlet>
<servlet-name>errorservlet-name>
<servlet-class>com.kuang.servlet.ErrorServletservlet-class>
servlet>
<servlet-mapping>
<servlet-name>errorservlet-name>
<url-pattern>/*url-pattern>
servlet-mapping>
对于web.xml文件中的头每次都要复制粘贴,很麻烦,这时候就可以建一个note.md文件,作为临时文件,将web.xml的内容复制进来,每次使用的时候从这里粘贴就行。
web容器在启动的时候,它会为每个web程序都创建一个对应的ServetContext对象,它代表了当前的web应用。
我在这个Servlet中保存的数据,可以在另一个Servlet拿到;
HelloServlet类:保存数据到ServletContext中;
package com.kuang.servlet;
import javax.servlet.ServletContext;
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 {
@Override
public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
//给前端响应进入了HelloServlet
// 1 设置响应的类型
resp.setContentType("text/html");
// 2 设置响应格式
resp.setCharacterEncoding("utf-8");
// 3 获取打印输出流,并打印出来内容
PrintWriter writer = resp.getWriter();
writer.print("HelloServlet!
");
/*
this是怎么来的? 来自父类或者Object类
this.getServletContext() 获取servlet上下文
this.getServletConfig() 获取Servlet配置
this.getInitParameter() 获取初始化参数
这些可以在配置servlet中的web.xml文件中的 中进行配置,例如:
*/
/*
ServletContext:获取servlet上下文
servlet-01访问路径 URL/s1 servlet-02访问路径:URL/s2 servlet-03访问路径:URL/s3
但是三个servlet之间没有办法通信怎么办,这时候就需要ServletContext
ServletContext是在web应用中的,凌驾在在所有子Servlet之上的,来帮助子Servlet之间进行通信的
*/
// 1:获取这个web项目的ServletContext,命名为context
ServletContext context = this.getServletContext();
// 2:给servlet-02中存个数据,数据为String类型的常量
String username = "宋丹敏"; //作为Servlet-02中的数据
// 3: 将数据存到名字为context的 ServletContext中去,存储格式设置为键值对形式,键:username 值:username
context.setAttribute("username", username); //将一个数据保存到ServletContext中,名字:username,值:username中的值“宋丹敏”
// 4:另一个GetServlet去拿到存在这个HelloServlet的数据,就是从名字为context的ServletContext中取
}
@Override
public void doPost(HttpServletRequest req, HttpServletResponse resp){
}
}
GetServlet类:获取ServletContext中数据;
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 GetServlet extends HttpServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 5:先获取ServeltContext
ServletContext context = this.getServletContext();
// 6:从ServeltContext中获取键为username的属性值,对属性值进行强制类型转换为String类型
String username =(String)context.getAttribute("username");
// 7:响应给前端并打印出来username的值
resp.getWriter().print(username);
}
@Override
protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
}
}
测试访问结果:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ykqFxJ9c-1658156711677)(https://s2.loli.net/2022/07/18/JA75P6pb2suUO9w.png)]
web.xml中配置servlet和web应用初始化参数:
<servlet>
<servlet-name>gpservlet-name>
<servlet-class>com.kuang.servlet.ServletDemo03servlet-class>
servlet>
<servlet-mapping>
<servlet-name>gpservlet-name>
<url-pattern>/gpurl-pattern>
servlet-mapping>
<context-param>
<param-name>urlparam-name>
<param-value>jdbc:mysql://localhost:3306//mybatisparam-value>
context-param>
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 ServletDemo03 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
ServletContext context = this.getServletContext();
//配置一些web应用初始化参数,在web.xml中通过标签配置
String url = context.getInitParameter("url");
resp.getWriter().print(url); //打印输出url
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
}
}
把对ServletDemo04的请求转发到ServletDemo03的请求中去;
ServletDemo03:
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 ServletDemo03 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
ServletContext context = this.getServletContext();
//配置一些web应用初始化参数,在web.xml中通过标签配置
String url = context.getInitParameter("url");
resp.getWriter().print(url); //打印输出url
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
}
}
ServletDemo04:
package com.kuang.servlet;
import javax.servlet.RequestDispatcher;
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;
/*
ServletContext请求转发功能演示
*/
public class ServletDemo04 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//测试是否进入ServletDemo04中的get方法
System.out.println("进入了ServletDemo04中的get方法!");
// 1 获取ServletContext
ServletContext context = this.getServletContext();
// 2 获得请求转发,转发给路径为/gp的请求中去
RequestDispatcher requestDispatcher = context.getRequestDispatcher("/gp");
// 3 将请求转换格式,传req,resp两个参数,实现请求
requestDispatcher.forward(req,resp);
// 2 3 合并
//context.getRequestDispatcher("/gp").forward(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
}
}
web.xml:
<servlet>
<servlet-name>gpservlet-name>
<servlet-class>com.kuang.servlet.ServletDemo03servlet-class>
servlet>
<servlet-mapping>
<servlet-name>gpservlet-name>
<url-pattern>/gpurl-pattern>
servlet-mapping>
<servlet>
<servlet-name>dpservlet-name>
<servlet-class>com.kuang.servlet.ServletDemo04servlet-class>
servlet>
<servlet-mapping>
<servlet-name>dpservlet-name>
<url-pattern>/dpurl-pattern>
servlet-mapping>
测试访问结果:
访问的/dp,显示的页面是/gp路径下页面的内容:
请求转发:a需要的数据在c那:a请求b,b请求c,c响应给b,b响应给a;
请求转发a和c之间是没有直接的联系;
重定向:a需要的数据在c那:a请求b,b告诉a数据在c那,a再去请求c;
重定向a和c之间有直接联系;
思路:需要一个文件流;
Piroperties类
发现:.properties文件都被打包到了同一个路径下:classes文件中,我们俗称这个路径为classpath;类路径
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1CsraV89-1658156711680)(https://s2.loli.net/2022/07/18/kby3sxSfHTE64ZI.png)]
在java目录下新建properties,读取aa.properties文件
aa.properties
username=root
password=123456
只需修改类中获取文件流的路径即可,如下面ServletDemo5类中注释所示。
在resources目录下新建properties,读取resources目录下的db.properties文件
ServletDemo5.java
package com.kuang.servlet;
import jdk.internal.util.xml.impl.Input;
import javax.servlet.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.beans.PropertyEditor;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
/*
ServletContext读取文件资源功能演示:
通过ServletContext对象获取文件db.properties文件中的文件流
1 先从ServletContext中获取到db.properties文件流
2 把获取的文件流加载到Properties类中去
3 测试,得到文件流中的属性值
*/
public class ServletDemo05 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//从ServletContext中获取到文件流,并返回出一个流
InputStream is = this.getServletContext().getResourceAsStream("/WEB-INF/classes/db.properties"); // /-代表当前web项目,指向target/servlet-02文件夹
//InputStream is = this.getServletContext().getResourceAsStream("/WEB-INF/classes/com/kuang/servlet/aa.properties"); // /-代表当前web项目,指向target/servlet-02文件夹
//把流加载到Properties中去,new的Properties类就是为了存储获取到的文件流中的属性值
Properties prop = new Properties();
prop.load(is);
//获取流的属性
String user = prop.getProperty("username");
String pwd = prop.getProperty("password");
//测试 是否获取到文件流中的属性值
resp.getWriter().print(user+":"+pwd);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
}
}
web.xml
<servlet>
<servlet-name>sd5servlet-name>
<servlet-class>com.kuang.servlet.ServletDemo05servlet-class>
servlet>
<servlet-mapping>
<servlet-name>sd5servlet-name>
<url-pattern>/sd5url-pattern>
servlet-mapping>
resources/db.properties
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zYp0Gd4g-1658156711681)(https://s2.loli.net/2022/07/18/7iTUv3ekJOAcXol.png)]
username=root
password=123456
测试:访问到了db.properties文件中的数据
Response 响应
web服务器接收到客户端http请求,会针对这个请求,分别创建一个代表请求的HttpServletRequest对象,代表响应的一个HttpServletResponse对象;
ServletResponse.java
// 一般写平常流用getOutputStream(),写中文用getWriter()
public ServletOutputStream getOutputStream() throws IOException;
public PrintWriter getWriter() throws IOException;
ServletResponse.java
public void setCharacterEncoding(String charset);
public void setContentLength(int len);
public void setContentLengthLong(long len);
public void setContentType(String type);
public void setBufferSize(int size);
HttpServletResponse.java
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);
void setStatus(int var1);
ServletResponse.java
int SC_CONTINUE = 100;
int SC_SWITCHING_PROTOCOLS = 101;
int SC_OK = 200;
int SC_CREATED = 201;
int SC_ACCEPTED = 202;
int SC_NON_AUTHORITATIVE_INFORMATION = 203;
int SC_NO_CONTENT = 204;
int SC_RESET_CONTENT = 205;
int SC_PARTIAL_CONTENT = 206;
int SC_MULTIPLE_CHOICES = 300;
int SC_MOVED_PERMANENTLY = 301;
int SC_MOVED_TEMPORARILY = 302;
int SC_FOUND = 302;
int SC_SEE_OTHER = 303;
int SC_NOT_MODIFIED = 304;
int SC_USE_PROXY = 305;
int SC_TEMPORARY_REDIRECT = 307;
int SC_BAD_REQUEST = 400;
int SC_UNAUTHORIZED = 401;
int SC_PAYMENT_REQUIRED = 402;
int SC_FORBIDDEN = 403;
int SC_NOT_FOUND = 404;
int SC_METHOD_NOT_ALLOWED = 405;
int SC_NOT_ACCEPTABLE = 406;
int SC_PROXY_AUTHENTICATION_REQUIRED = 407;
int SC_REQUEST_TIMEOUT = 408;
int SC_CONFLICT = 409;
int SC_GONE = 410;
int SC_LENGTH_REQUIRED = 411;
int SC_PRECONDITION_FAILED = 412;
int SC_REQUEST_ENTITY_TOO_LARGE = 413;
int SC_REQUEST_URI_TOO_LONG = 414;
int SC_UNSUPPORTED_MEDIA_TYPE = 415;
int SC_REQUESTED_RANGE_NOT_SATISFIABLE = 416;
int SC_EXPECTATION_FAILED = 417;
int SC_INTERNAL_SERVER_ERROR = 500;
int SC_NOT_IMPLEMENTED = 501;
int SC_BAD_GATEWAY = 502;
int SC_SERVICE_UNAVAILABLE = 503;
int SC_GATEWAY_TIMEOUT = 504;
int SC_HTTP_VERSION_NOT_SUPPORTED = 505;
package com.kuang.servlet;
import sun.net.www.content.image.png;
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;
/*
下载文件功能:
1. 要获取下载文件的路径
2. 下载的文件名?
3. 设置想办法让浏览器可以支持下载我们需要的东西
4. 获取下载文件的输入流
5. 创建缓存区
6. 获得OutputStream对象
7. 将FileOutputStream流写入到buffer缓存区
8. 使用OutputStream将缓冲区中的数据输出到客户端!
*/
public class FileServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
//1. 要获取下载文件的路径
//String realPath = this.getServletContext().getRealPath("/1.png");
String realPath = "D:\\IdeaProjects\\javaweb-02-servlet\\response\\target\\classes\\1.png"; //target\classes\1.png右键copy path
System.out.println("下载文件的路径"+realPath);
//2. 下载的文件名? 从realPath中截取
String fileName = realPath.substring(realPath.lastIndexOf("\\")+1);// \转义字符
//3. 设置想办法让浏览器可以支持下载我们需要的东西,这里就是要设置浏览器行为,通过Response对象来进行设置
//Content-Disposition 通知客户端以下载的方式接受数据
resp.setHeader("Content-Disposition", "attachmen;filename="+fileName);
//4. 获取下载文件的输入流
FileInputStream in = new FileInputStream(realPath);
//5. 创建缓存区
int len = 0;
byte[] buffer = new byte[1024];
//6. 获得OutputStream对象
ServletOutputStream out = resp.getOutputStream();
//7. 将FileOutputStream流写入到buffer缓存区,使用OutputStream将缓冲区中的数据输出到客户端!
while ((len = in.read(buffer))>0){
out.write(buffer,0,len);
}
in.close();
out.close();
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
}
}
测试下载:
图片名命名为中文名时:
修改
package com.kuang.servlet;
import sun.net.www.content.image.png;
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;
/*
下载文件功能:
1. 要获取下载文件的路径
2. 下载的文件名?
3. 设置想办法让浏览器可以支持下载我们需要的东西
4. 获取下载文件的输入流
5. 创建缓存区
6. 获得OutputStream对象
7. 将FileOutputStream流写入到buffer缓存区
8. 使用OutputStream将缓冲区中的数据输出到客户端!
*/
public class FileServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
//1. 要获取下载文件的路径
//String realPath = this.getServletContext().getRealPath("/1.png");
String realPath = "D:\\IdeaProjects\\javaweb-02-servlet\\response\\target\\classes\\秦疆.png"; //target\classes\1.png右键copy path
System.out.println("下载文件的路径"+realPath);
//2. 下载的文件名? 从realPath中截取
String fileName = realPath.substring(realPath.lastIndexOf("\\")+1);// \转义字符
//3. 设置想办法让浏览器可以支持下载我们需要的东西,这里就是要设置浏览器行为,通过Response对象来进行设置
//Content-Disposition 通知客户端以下载的方式接受数据 中文文件名URLEncoder.encode编码,否则可能会有乱码
resp.setHeader("Content-Disposition", "attachmen;filename="+ URLEncoder.encode(fileName, "UTF-8"));
//4. 获取下载文件的输入流
FileInputStream in = new FileInputStream(realPath);
//5. 创建缓存区
int len = 0;
byte[] buffer = new byte[1024];
//6. 获得OutputStream对象
ServletOutputStream out = resp.getOutputStream();
//7. 将FileOutputStream流写入到buffer缓存区,使用OutputStream将缓冲区中的数据输出到客户端!
while ((len = in.read(buffer))>0){
out.write(buffer,0,len);
}
in.close();
out.close();
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
}
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dhbd9jfz-1658156711684)(https://s2.loli.net/2022/07/18/GHIrKnh1XPuQUMp.png)]
验证怎么老的?
前端实现
后端实现,需要用到java的图片类,生成一个图片,图片中的数字3秒刷新一次
ImageServlet.java
package com.kuang.servlet;
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;
/*
HttpServletResponse
验证码实现示例
*/
public class ImageServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//想要响应一个图片到前端去
//如何让浏览器 3s 刷新一次
resp.setHeader("refresh","3");
//在内存中创建一个图片
BufferedImage image = new BufferedImage(80,20,BufferedImage.TYPE_INT_BGR);
//得到图片
Graphics2D g = (Graphics2D) image.getGraphics(); //笔
//设置图片的背景颜色
g.setColor(Color.white);
g.fillRect(0,0,80,20);
//给图片写数据
g.setColor(Color.BLUE);
g.setFont(new Font(null,Font.BOLD,20));
g.drawString(makeNum(), 0, 20);
//告诉浏览器,这个请求用图片的方式打开
resp.setContentType("image/jpeg");
//网站存在缓存,我们需要不要让浏览器缓存
resp.setDateHeader("expires", -1);
resp.setHeader("Cache-Control", "no-cache");
resp.setHeader("Pragma", "no-cache");
//把图片写给浏览器
ImageIO.write(image, "jpg",resp.getOutputStream());
}
//生成随机数 7位, 拼接一个“”空字符串,返回String类型num
private String makeNum(){
Random random = new Random();
String num = random.nextInt(9999999)+"";
StringBuffer sb = new StringBuffer();
for (int i = 0; i < 7-num.length(); i++) {
sb.append("0"); //保证随机数是7位,不是7位用0附加
}
String s = sb.toString()+num;
return s;
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
}
}
web.xml
<servlet>
<servlet-name>ImageServletservlet-name>
<servlet-class>com.kuang.servlet.ImageServletservlet-class>
servlet>
<servlet-mapping>
<servlet-name>ImageServletservlet-name>
<url-pattern>/imgurl-pattern>
servlet-mapping>
测试:访问localhost:8080/r/img
持续更新中