Java Web
1、基本概念
1.1、前言
Web 开发:
-
web 网页的意思,www.baidu.com
-
静态web
- html、css
- 提供给所有人看的数据始终不会发生变化
-
动态web
-
淘宝等…几乎所有的网站
-
提供给所有人看的数据会发生变化(不同时间、不同地点(场合))
-
技术栈:Servlet/Jsp、ASP、PHP
-
在Java中,动态web资源开发的技术统称为 JavaWeb;
1.2、Web应用程序
Web应用程序,可以提供浏览器访问的程序:
-
a.html 、b.html…多个Web资源,这些Web资源可以被外界访问,对外界提供服务;
-
能访问到的任何一个页面或者资源,都存在于这个世界上的某一角落的计算机上
-
URL:在WWW上,每一信息资源都有统一的且在网上唯一的地址,该地址就叫URL(Uniform Resource Locator,统一资源定位器),它是WWW的统一资源定位标志,就是指网络地址。
URI = Universal Resource Identifier 统一资源标志符
URL = Universal Resource Locator 统一资源定位符URL代表资源的路径地址,而URI代表资源的名称。
-
这个统一的Web资源会被放在同一个文件夹下,Web应用程序—>TomCat(服务器)
-
一个Web应用由多部分组成(静态web、动态web)
- html、css、js
- jsp、servlet
- java程序
- jar包
- 配置文件(properties)
Web应用程序编写完毕后,若想提供给外界访问,需要一个服务器来统一管理;
1.3、静态Web
- *.htm、 *.html这些都是网页的后缀,如果服务器上一直存在这些东西,我们就可以直接进行读取。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ky8GIK7g-1627784097289)

- 静态Web存在的缺点
- Web页面无法动态更新,所有用户看到的都是同一个页面
- 轮播图,点击特性:伪动态
- JavaScript【实际开发用得多】
- VBScript
- 无法和数据库交互(数据无法持久化,用户无法交互)
- Web页面无法动态更新,所有用户看到的都是同一个页面
1.4、动态Web-
页面动态展示:“Web页面” 千人千面

缺点:
- 假如服务器的动态Web资源出现了错误,我们需要重新编写我们的后台程序,重新发布(停机维护)
优点:
- Web页面可以动态更新,所有用户看到的都不是同一个页面
- 可以和数据库交互(数据持久化:注册,商品信息,用户信息)
2、Web服务器
2.1、技术讲解
ASP:
- 微软:国内最早流行的就是ASP
- 在html中潜入了VB的脚本,ASP+COM;
- 在ASP开发中,基本一个页面(几千行业务代码,页面极其混乱)
- 维护成本高
- C#
- IIS
PHP:
- php开发速度很快,功能强大,跨平台,代码简单 (70% 中小型网站)
- 无法承载大访问量的情况(局限性)
JSP/Servlet:
B/S :浏览器和服务器
C/S: 客户端和服务器
- sun 公司主推的B/S架构
- 基于Java语言(大公司,或者一些开源的组件,都是用 Java写的)
- 可以承载三高(高并发、高可用、高性能)问题带来的影响
- 语法像ASP
2.2、Web服务器
服务器是一种被动的操作,用来处理用户的一些请求和给用户一些响应信息:
IIS:
微软的:ASP…Windows 中自带
TomCat
Tomcat是Apache 软件基金会(Apache Software Foundation)的Jakarta 项目中的一个核心项目,最新的Servlet 和JSP 规范总是能在Tomcat 中得到体现,因为Tomcat 技术先进、性能稳定,而且免费,因而深受Java 爱好者的喜爱并得到了部分软件开发商的认可,成为目前比较流行的Web 应用服务器。
Tomcat 服务器是一个免费的开放源代码的Web 应用服务器,属于轻量级应用服务器,在中小型系统和并发访问用户不是很多的场合下被普遍使用,是开发和调试JSP 程序的首选。对于一个初学者来说,最佳选择
Tomcat 实际上运行JSP 页面和Servlet。另外,Tomcat和IIS等Web服务器一样,具有处理HTML页面的功能,另外它还是一个Servlet和JSP容器,独立的Servlet容器是Tomcat的默认模式。不过,Tomcat处理静态HTML的能力不如Apache服务器。目前Tomcat最新版本为10.0.5**。**
…
下载TomCat
-
安装
-
了解配置文件及目录结构
3、TomCat
3.1、安装TomCat
官网: https://tomcat.apache.org/
配置安装教程:https://blog.csdn.net/weixin_45737584/article/details/105324829?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522162656722216780262563479%2522%252C%2522scm%2522%253A%252220140713.130102334…%2522%257D&request_id=162656722216780262563479&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2alltop_positive~default-2-105324829.first_rank_v2_pc_rank_v29&utm_term=tomcat%E5%AE%89%E8%A3%85%E5%8F%8A%E9%85%8D%E7%BD%AE%E6%95%99%E7%A8%8B&spm=1018.2226.3001.4187
可以配置启动的端口号:
默认为 8080
E:\learing softwares\Maven\apache-tomcat-9.0.45\conf\server.xml 文件
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" />
可以配置主机的名称
- 默认主机名称:localhost->127.0.0.1
- 默认网站应用存放地址:webapps
<Host name="localhost" appBase="webapps"
unpackWARs="true" autoDeploy="true">
谈谈网站是如何访问的?
1、输入一个域名,回车
2、检查本机 C:\Windows\System32\drivers\etc\hosts 配置文件下有没有这个域名映射:
-
有:直接返回对应的ip地址,这个地址中有我们需要访问的web程序
127.0.0.1 www.lyStudy.com -
没有:去DNS服务器找(全世界的域名),找到就返回,找不到就返回找不到;
3.2、发布一个Web网站
- 将自己写的网站,放到服务器(Tomcat)中指定的web应用的文件夹下(webapps)下,就可以访问了
网站应该有的结构
--webapps:Tomcat服务器的web目录
-ROOT
-lyStudy:网站目录名
-classes:java程序
-lib:web应用所依赖的jar包
-web.xml网站配置文件
-index.html//默认的首页
-static
-css
-jss
-img
- ...
4、HTTP
4.1、什么是HTTP
HTTP (超文本传输协议)是一个在计算机世界里专门在两点之间传输文字、图片、音频、视频等超文本数据的约定和规范
是一个简单的请求、响应协议,通常运行在TCP之上
https:(安全的)
4.2、两个时代
- http 1.0
- HTTP/1.0:客户端与web服务器连接,只能获得一个web资源,断开连接
- http 2.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
Remote Address:14.215.177.39:433 //原创地址
Referrer Policy:no-referrer-when-downgrade//协议
1、请求行
-
请求行中的请求方式:GET
-
请求方式:Get,Post,HEAD,DELETE,PUT,TRACT.…
-
get:请求能够携带的参数比较少,大小有限制,会在浏览器的URL地址栏显示数据内容,不安全,但高效
-
post:请求能够携带的参数没有限制,大小没有限制,不会在浏览器的URL地址栏显示数据内容,安全,但不高效。
-
2、消息头
Accept:告诉浏览器,它所支持的数据类型
Accept-Encoding:支持哪种编码格式GBK UTF-8 GB2312 ISO8859-1
Accept-Language:告诉浏览器,它的语言环境
Cache-Control:缓存控制
Connection:告诉浏览器,请求完成是断开还是保持连接
HOST:主机..../.
4.4、Http响应
服务器—响应—客户端
Cache-Control:private 缓存控制
Connection:Keep-Alive 连接
Content-Encoding:gzip 编码
Content-Type:text/html 类型
1、响应体
Accept:告诉浏览器,它所支持的数据类型
Accept-Encoding:支持哪种编码格式GBK UTF-8 GB2312 ISO8859-1
Accept-Language:告诉浏览器,它的语言环境
Cache-Control:缓存控制
Connection:告诉浏览器,请求完成是断开还是保持连接
HOST:主机..../.
Refresh:告诉客户端,多久刷新一次;
Location:让网页重新定位
2、响应状态码
200:请求响应成功200
3xx:请求重定向·重定向:你重新到我给你新位置去;
4xx:找不到资源404·资源不存在;
5xx:服务器代码错误 500 502:网关错误
5、Maven
Why Maven ?
1、在javaweb开发中,需要使用大量的jar包,我们手动去导入;
2、如何能够让一个东西帮我们自动导入和配置这个jar包
由此,Maven诞生了!
5.1、Maven项目架构管理工具
我们目前用来方便导入jar包的!
Maven核心思想:约定大于配置
- 有约束,不要去违反
Maven会规定好你们如何去编写我们的java代码,必须按照这个规范来;
5.2、下载Maven
官网:https://maven.apache.org/
下载完成后,解压即可;
5.3配置环境变量
在我们的系统环境变量中配置如下配置:
- M2_HOME maven目录下的bin目录
- MAVEN_HOME maven的目录
- 在系统的path中配置%MAVEN_HOME%\bin
测试Maven是否安装成功,保证必须配置完毕!
5.4阿里云镜像
-
镜像:mirrors
-
作用:加速我们的下载
-
国内建议使用阿里云的镜像
<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>E:\learing softwares\Maven\apache-maven-3.8.1\conf\settings.xml
5.5本地仓库
在本地的仓库,远程仓库; 建立一个本地仓库:localRepository
<localRepository>E:\learing softwares\Maven\apache-maven-3.8.1\repository</localRepository>
5.6、IDEA中使用Maven

…
用的是Maven webapp 模板(会有问题)
5.7、创建普通Maven项目


web应用下才有

…
5.7、配置Tomcat

点左上角加号

解决警告问题:因为我们访问网站,需要指定一个文件名字

虚拟路径映射
Application context:/
路径可以写 可以不写
不写 ,默认路径为 localhost:8080
假如写了 /ly 那路径就是 localhost:8080/ly

5.8、pom文件
pom.xml是Maven核心配置文件
<?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>
<!-- 就是创建项目时的 gav 设置-->
<groupId>com.ly</groupId>
<artifactId>javaweb-01-maven</artifactId>
<version>1.0-SNAPSHOT</version>
<!-- packaging:项目的打包方式
jar:java应用
war:javaweb应用
-->
<packaging>war</packaging>
<name>javaweb-01-maven 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>
<!-- 具体依赖的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的高级之处在于他会帮你导入这个jar包所依赖的其他jar包-->
pom.xml中加上:
<!--在build中配置 resources,来防止我们的资源导出失败-->
<build>
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>false</filtering>
</resource>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>false</filtering>
</resource>
</resources>
</build>
目录树:jar包关联图

DEA中每次都要重复配置Maven
解决:打开软件右下角configure

设置完成,创建项目
最好每次创建项目之前都设置/确认一遍
6、Servlet
6.1、Servlet简介
-
Servlet就是sun公司开发动态web的一门技术
-
sun公司在这些API中提供一个接口叫做 :Servlet
-
开发Servlet程序,两个步骤
-
编写一个类实现Servlet接口
-
把开发好的java类部署到web服务器中
-
把实现了Servlet接口的java程序叫做 Servlet
6.2、HelloServlet
1、构建一个普通的Maven项目,删除里面的src目录,在这个项目里面建立模块。
2、Maven父子工程的理解:
父项目中的jar包 子项目可以使用 反之则不能
3、Maven环境优化:
1.修改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">
</web-app>
2、在main 目录下添加 java 和 resources 资源目录
3、编写一个Servlet程序
- 编写一个普通类
- 实现Servlet接口(这里我们继承Servlet)
/**
* HelloServlet
* @author LY
*/
public class HelloServlet extends HttpServlet {
//由于get 和 post 只是请求实现的不同方式,可以相互调用,业务逻辑都一样
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// ServletOutputStream outputStream = resp.getOutputStream();
PrintWriter writer = resp.getWriter();//响应流
writer.println("hello servlet");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
4、编写Servlet的映射
我们写的java程序 要通过浏览器访问 ,浏览器需要连接web服务器,所以我们需要在web服务中注册我们写的Servlet,还需要给他一个浏览器能访问的路径
<?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">
<!-- 注册servlet-->
<servlet>
<servlet-name>hello</servlet-name>
<servlet-class>com.ly.servlet.HelloServlet</servlet-class>
</servlet>
<!-- servlet的映射(请求)路径-->
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>hello</url-pattern>
</servlet-mapping>
</web-app>
5、配置Tomcat
6、启动测试
6.3、Servlet原理
Servlet工作过程中,涉及到了客户端(浏览器)、Servlet容器、Servlet应用三种角色。大致过程如下所示:
首先,由客户端发起请求。
然后,Servlet容器接收到客户端的请求,解析请求协议和数据,如果servlet程序还没有被加载,就会执行加载过程并调用service()方法,否则直接调用service()方法。
其中,加载Servlet程序的过程:根据Servlet容器与Servlet程序间的契约,当有请求过来时,如果Servlet程序还没有被载入Servlet容器中,这个时候Servlet容器就会通过调用init()方法将Servlet类载入内存,并产生Servlet实例。在调用init()方法的时候,Servlet容器会传入一个ServletConfig对象进来从而对Servlet对象进行初始化。该过程只会被执行一次,即在一个应用程序中,每类Servlet程序只能有一个实例。其中,在ServletConfig对象中还隐藏一个ServletContext实例对象,这个ServletContext实例对象就表示了Servlet程序在容器中的上下文环境。
而,service()方法执行的过程:首先由Servlet容器解析请求参数并封装成一个ServletRequest和ServletResponse对象。其中,ServletRequest中封装了当前的Http请求,开发者可以操作ServletRequest对象获取用户的请求数据;ServletResponse封装了当前用户的Http响应,开发者可以操作ServletResponse对象把响应内容发回给用户。Servlet容器把ServletRequest和ServletResponse作为参数传递给了service()方法,通过执行service()方法,实现响应的逻辑,并通过ServletResponse对象返回内容到客户端。
最后,如果关闭Servlet容器时,这个时候,Servlet容器就会根据契约,调用destroy()方法,该方法一般都用来编写一些释放资源的逻辑。
6.4、Mapping问题
1、一个servlet可以指定一个通用映射路径
<!-- 设置/hello为默认请求路径-->
<!-- 设置/hello为默认请求路径--><servlet-mapping> <servlet-name>hello</servlet-name> <url-pattern>/*</url-pattern></servlet-mapping>
2、指定一些前缀后缀等等
<!-- 自定义后缀实现请求映射-->
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>*.dylan</url-pattern>
</servlet-mapping>
<!-- http://localhost:8080/abcdsdd.dylan -->
<!--以 .dylan 结尾的 -->
3、优先级问题
指定了固有的优先级最高,如果找不到就会走默认的处理请求
自定义404
<!-- 404 -->
<servlet>
<servlet-name>error</servlet-name>
<servlet-class>com.ly.servlet.ErrorServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>error</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
6.5、ServletContext对象
web容器在启动的时候,它会为每个web程序创建一个ServletContext对象,它代表了当前的web应用;
1、共享数据
在Servlet中保存的数据,可以在另一个Servlet中拿到
/**
传递数据
*/
public class HelloServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// this.getInitParameter() 初始化参数
//this.getServletConfig() Servlet配置
//this.getServletContext() 上下文
ServletContext context = this.getServletContext();
String username="吕布";//数据
context.setAttribute("username",username);//将数据保存在上下文对象中
System.out.println("hello");
}
}
/**
接收数据
*/
public class GetServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
ServletContext context = this.getServletContext();
String username = (String) context.getAttribute("username");
resp.setContentType("text/html");
resp.setCharacterEncoding("utf-8");
resp.getWriter().print(username);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}
<?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">
<servlet>
<servlet-name>hello</servlet-name>
<servlet-class>com.ly.servlet.HelloServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>getc</servlet-name>
<servlet-class>com.ly.servlet.GetServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>getc</servlet-name>
<url-pattern>/getc</url-pattern>
</servlet-mapping>
</web-app>
测试访问结果…
2、获取初始化参数
<!--配置一些web应用初始化参数-->
<context-param>
<param-name>url</param-name>
<param-value>jdbc:mysql://localhost:3306</param-value>
</context-param>
public class ServletDemo03 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
ServletContext context = this.getServletContext();
String url = context.getInitParameter("url");
resp.getWriter().print(url);
}
}
<!--web.xml中注册-->
<servlet>
<servlet-name>gp</servlet-name>
<servlet-class>com.ly.servlet.ServletDemo03</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>gp</servlet-name>
<url-pattern>/gp</url-pattern>
</servlet-mapping>
3、请求转发(请求的地址不会变)
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("进入了Demo04!");
ServletContext context = this.getServletContext();
// RequestDispatcher requestDispatcher = context.getRequestDispatcher("/gp");//转发的请求路径
//requestDispatcher.forward(req,resp);//调用forward实现请求转发
context.getRequestDispatcher("/gp").forward(req,resp);
}
4、读取资源文件
Properties
- 在java目录下新建properties
- 在resources目录下新建properties
都被打包到了 classes 路径下,我们称这个路径为类路径(classpath)
需要一个文件流:
username=rootpassword=123456
public class ServletDemo05 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
InputStream is= this.getServletContext().getResourceAsStream("/WEB-INF/classes/db.properties");
Properties properties = new Properties();
properties.load(is);
String username = properties.getProperty("username");
String password = properties.getProperty("password");
resp.getWriter().print(username+" "+password);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
测试即可
6.6、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);
响应的状态码
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;
2、常见应用
1、向浏览器输出信息
2、下载文件
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 ServletException, IOException {
// 1、要获取文件下载路径
String realPath = "D:\\IDEA project\\javaweb-01-servlet\\response\\target\\classes\\吕布.png";
System.out.println("要下载的文件路径: "+realPath);
//D:\IDEA project\javaweb-01-servlet\response\target\classes\吕布.png
// 2、下载的文件名
String filename = realPath.substring(realPath.lastIndexOf("\\") + 1);
//3、让浏览器支持下载我们需要的东西 下载头信息
resp.setHeader("Content-disposition","attachment;filename"+ URLEncoder.encode(filename,"utf-8"));
//
// 4、获取下载文件的输入流
FileInputStream fis = new FileInputStream(realPath);
//
// 5、创建缓冲区
int count=0;
byte[] buffer = new byte[1024];
//
// 6、获取OutputStream对象
ServletOutputStream os = resp.getOutputStream();
//
// 7、将FileOutputStream 流写入到 buffer 缓冲区 ,使用 OutputStream将缓冲区数据输出到客户端
while ((count=fis.read(buffer))!=-1){
os.write(buffer,0,count);
}
//8 关闭流
fis.close();
os.close();
//
//
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
3、验证码功能
- 前端实现
- 后端实现,需要用到java的图片类,产生一个·图片
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_BGR);
//得到图片
Graphics2D graphics = (Graphics2D) image.getGraphics();//画笔
//设置图片的背景颜色
graphics.setColor(Color.white);
graphics.fillRect(0,0,80,20);
//给图片写数据
graphics.setColor(Color.blue);
graphics.setFont(new Font(null,Font.BOLD,20));
graphics.drawString(makeRandom(),0,20);
//告诉浏览器这个请求用图片的方式打开
resp.setContentType("image/jpeg");
//网站是有缓存的,不让浏览器缓存
resp.setDateHeader("expires",-1);
resp.setHeader("Cache-Control","no-cache");
resp.setHeader("Pragma","no-cache");
//把图片写给浏览器
boolean write = ImageIO.write(image,"jpg", resp.getOutputStream());
}
//制作随机数
private String makeRandom(){
Random random = new Random();
String s = random.nextInt(9999999) + "";
StringBuffer sb = new StringBuffer();
for (int i = 0; i <7-s.length() ; i++) {
sb.append("0");
}
String s1 = sb.toString() + s;
return s1;
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
在web.xml中注册
<servlet>
<servlet-name>image</servlet-name>
<servlet-class>com.ly.servlet.ImageServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>image</servlet-name>
<url-pattern>/image</url-pattern>
</servlet-mapping>
3、实现重定向
web资源B 收到客户端A请求后,B会通知A客户端去访问另一个web资源C,这个过程叫做重定向。
常见场景:用户登录
void sendRedirect(String var1) throws IOException;//源码方法
// resp.setHeader("Location","/response/image");
//resp.setStatus(HttpServletResponse.SC_MOVED_TEMPORARILY); //(系统做了
上面两步)resp.sendRedirect("/response/image");
重定向和转发的区别:
- 相同点:页面都会跳转
不同点:
- 转发:url不会发生变化,重定向:url会发生变化
6.7、HttpServletRequest
HttpServletRequest 代表客户端的请求,用户通过Http协议访问服务器,Http请求中所有的信息会被封装到 HttpServletRequest,通过这个HttpServletReequest 的方法,获得客户端的所有信息;
…
1、获取前端传递的参数
2、获取参数、请求转发
@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 password = req.getParameter("password");
String[] hobbys = req.getParameterValues("hobbys");
System.out.println(username);
System.out.println(password);
System.out.println(Arrays.toString(hobbys));
System.out.println("==========================================");
System.out.println(req.getContextPath());
//通过请求转发(url不变)
//这里的 / 代表当前web应用
req.getRequestDispatcher("/success.jsp").forward(req, resp);
}
重定向和转发的区别:
- 相同点:页面都会跳转
不同点:
- 请求转发:url不会发生变化(307)
- 重定向:url地址栏会发生变化(302)
7、Cookie、Session
7.1、会话
在程序中,会话跟踪是很重要的事情。理论上,一个用户的所有请求操作都应该属于同一个会话,而另一个用户的所有请求操作则应该属于另一个会话,二者不能混淆。例如,用户A在超市购买的任何商品都应该放在A的购物车内,不论是用户A什么时间购买的,这都是属于同一个会话的,不能放入用户B或用户C的购物车内,这不属于同一个会话。
而Web应用程序是使用HTTP协议传输数据的。HTTP协议是无状态的协议。一旦数据交换完毕,客户端与服务器端的连接就会关闭,再次交换数据需要建立新的连接。这就意味着服务器无法从连接上跟踪会话。即用户A购买了一件商品放入购物车内,当再次购买商品时服务器已经无法判断该购买行为是属于用户A的会话还是用户B的会话了。要跟踪该会话,必须引入一种机制。
7.2、保存会话的两种技术
cookie
- 客户端技术(响应、请求)
session
- 服务器技术,利用这个技术,可以保存用户的会话信息,我们可以把信息或者数据放在session中
常见例子:登录网站后,下次不用再登录了(CSDN)
7.3、Cookie
1、从请求中拿到cookie信息
2、服务器响应给客户端cookie
//cookie ,服务器端从客户端获取
Cookie[] cookies = req.getCookies();//cookie存在多个
cookie.getName()//获得cookie中的 key
cookie.getValue()//获得cookie中的value
//服务器给客服端响应cookie
Cookie cookie = new Cookie("lastLoginTime", System.currentTimeMillis()+"");//新建一个cookie
//设置了cookie有效期为一天 (以秒为单位) 浏览器关掉以后cookie还存在(不安全)
cookie.setMaxAge(24*60*60);
resp.addCookie(cookie);//响应给客户端一个cookie!!!
cookie一般会保存在本地的用户目录下的appdata文件夹;
一个网站cookie是否存在上限
- 一个cookie只能保存一个信息
- 一个web站点可以给浏览器发送多个cookie,最多存放20个
- cookie大小有限制4kb(4*1024个字节(Byte))
- 浏览器上限300个cookie
删除cookie:
- 不设置有效期,关闭浏览器,自动失效
- 设置有效时间为0
编码、解码
Cookie cookie=new Cookie("name",URLEncoder.encode("吕布","utf-8"));//编码
out.write(URLDecoder.decode(cookie.getValue(),"utf-8"));//解码
7.4、Session
什么是Session
- 服务器会给每一个用户(浏览器)创建一个Session对象
- 一个Session独占一个浏览器,只要浏览器没有关闭,这个Session就存在
- 用户登录之后,整个网站它都可以访问–>保存用户信息
Session和Cookie区别:
- Cookie 把 用户的数据 写给 用户的 浏览器,浏览器保存(可以保存多个)
- Session把用户数据写到用户独占的Session中,服务器端保存(保存重要信息,减少服务器资源的浪费)
- Session对象由服务器创建
使用场景:
- 保存登录用户的信息
- 购物车信息
- 在整个网站中经常会使用的数据,将它保存在Session中
/*
存Session
**/
public class SessionDemo01 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//解决乱码问题
req.setCharacterEncoding("gbk");
resp.setCharacterEncoding("gbk");
resp.setContentType("text/html;charset=utf-8");
//得到Session
HttpSession session = req.getSession();
//给Session中存东西
session.setAttribute("name",new Person("赵云",22));
//获取Session的id
String id = session.getId();
//判断是不是新的
if (session.isNew()) {
resp.getWriter().write("session 创建成功! sessionId:"+id);
}else {
resp.getWriter().write("session 已经在服务器中存在了! sessionId:"+id);
}
//Sesssion 创建的时候做了什么事
// Cookie cookie = new Cookie("JSESSIONID", id);
// resp.addCookie(cookie);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
```java
/**
得到Session
*/
public class SessionDemo02 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//解决乱码问题
req.setCharacterEncoding("gbk");
resp.setCharacterEncoding("gbk");
resp.setContentType("text/html;charset=utf-8");
//得到Session
HttpSession session = req.getSession();
Person name = (Person) session.getAttribute("name");
System.out.println(name);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
```java
/**
注销Session
*/
public class SessionDemo03 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
HttpSession session = req.getSession();
session.removeAttribute("name");
//手动注销 session
session.invalidate();
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
<!--web.xml中设置-->
<!--设置session的默认失效时间-->
<session-config>
<!-- 1分钟后session自动失效 这里以分钟为基本单位-->
<session-timeout>1</session-timeout>
</session-config>
8、JSP
8.1、什么是JSP
Java Server Pages: Java服务器端页面,也和Servlet一样,用于动态Web技术
最大特点:
- 写JSP就像是在写HTML
- 区别:
- HTML只给用户提供静态数据
- JSP页面中可以嵌入Java代码,为用户提供动态数据
8.2、JSP原理
思路:JSP到底怎么执行
-
代码层面
-
服务器内部工作
tomcat中有一个work目录
IEDA中Tomcat工作空间:
C:\Users\LY\.IntelliJIdea2019.3\system\tomcat
本机上的地址
C:\Users\LY\.IntelliJIdea2019.3\system\tomcat\Unnamed_javaweb-session-cookie\work\Catalina\localhost\jwsc\org\apache\jsp\index_jsp.java
发现页面转变成了java程序!
浏览器向服务器发送请求,不管访问什么资源,其实都是在访问Servlet
JSP最终也会被转换成为一个java类
JSP本质上就是一个Servlet
//初始化
public void _jspInit() {
}
//销毁
public void _jspDestroy() {
}
//jspService
public void _jspService(final javax.servlet.http.HttpServletRequest request, final javax.servlet.http.HttpServletResponse response)
throws java.io.IOException, javax.servlet.ServletException {
1、判断请求
2、内置了一些对象
final javax.servlet.jsp.PageContext pageContext;//页面上下文
javax.servlet.http.HttpSession session = null;//session
final javax.servlet.ServletContextapplication;//applicationContext
final javax.servlet.ServletConfig config;//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页面中:
只要是Java代码就会原封不动输出
如果是HTML代码,就会被转换为
out.write("<html>\r\n");
8.3、JSP基础语法
任何语言都有自己语法,JSP作为java技术的一种应用,它拥有一些自己扩充的语法。
JSP表达式
<%-- JSP表达式--%>
<%--作用 用来将程序的输出, 输出到客户端--%>
<%= 变量或者表达式 %>
<%= new java.util.Date() %>
JSP脚本片段
<%--jsp 脚本片段--%>
<%
int sum=0;
for (int i = 0; i <=100 ; i++) {
sum+=i;
}
out.println("<h1>Sum="+sum+"</h1>");
%>
JSP脚本片段的再实现
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>$Title$</title>
</head>
<body>
<%-- JSP表达式--%>
<%--作用 用来将程序的输出, 输出到客户端--%>
<%= new java.util.Date() %>
<hr>
<%--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=20;
out.println(y);
%>
<hr>
<%-- 在代码中嵌入HTML元素 --%>
<%
for (int i = 0; i <5 ; i++) {
%>
<h1>hello world <%=i%> </h1>
<%
}
%>
</body>
</html>
JSP声明
<%! static{ System.out.println("Loading......");}private int globalVar=0; public void ly(){ System.out.println("进入了方法ly"); }%>
JSP声明:会被编译到 JSP 生成的Java类中
其他的就会被生成到 _jspService()中
在JSP中嵌入java代码即可
<% %><%= %><%! %>
JSP的注释不会在客户端显示,HTML的就会。
9、JavaBean
实体类
JavaBean有特定的写法:
- 必须要有一个无参构造
- 属性必须私有化
- 必须有对应的get/set方法
一般用来和数据库的字段作映射
ORM:对象关系映射
- 表–>类
- 字段–>属性
- 行记录–>对象
People 表
| id | name | age | addresss |
|---|---|---|---|
| 1 | 张三 | 10 | 北京 |
| 2 | 李四 | 11 | 上海 |
| 3 | 王五 | 12 | 成都 |
class People{
private int id;
private String name;
private int age;
private String address;
}
class A {
new People(4"匿名",99,"西安");
}
10、MVC三层架构
什么是MVC:Mode View Controller 模型 视图 控制器
10.1、早些年

用户直接访问控制层,控制层就可以直接操作数据库
servlet----CRUD----->数据库
弊端:程序十分臃肿,不利于维护
servlet的代码中:处理请求、响应、视图跳转、处理JDBC、处理业务代码、处理逻辑代码
架构:没有什么是加一层解决不了的
程序猿
|
JDBC
|
MySQL、Oracle...
10.2、MVC三层架构

Model
- 业务处理:业务逻辑(Service)
- 数据持久层:CRUD (Dao)
View
- 展示数据
- 提供链接发起Servlet请求(a、form,img…)
Controller
- 接收用户请求(request:请求参数 Session信息 …)
- 交给业务层处理对应的代码
- 控制视图的跳转
登录----》接收用户的登录请求--》处理用户的请求(获取用户登录的参数)
----》交给业务层处理登录业务(判断用户名密码是否正确:事务) ----》Dao层查询用户名和密码是否正确--》数据库
11、Filter(过滤器)
用来过滤网站的数据
- 处理中文乱码
- 登录验证

Filter开发步骤
1、导包
2、编写过滤器(包别导错)
package com.ly.filter;
import javax.servlet.*;
import java.io.IOException;
/**
* 自定义过滤器
* @author LY
*/
public class CharacterEncodingFilter implements Filter {
//初始化 web服务器启动,就初始化了,随时等待过滤对象出现
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("CharacterEncoding 初始化");
}
/*Chain:链
1.过滤中的所有代码,在过滤待定请求的时候都会执行
2.必须要让过滤器继续通行
*/
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
request.setCharacterEncoding("utf-8");
response.setCharacterEncoding("utf-8");
response.setContentType("text/html;character=utf-8");
System.out.println("CharacterEncodingFilter 执行前");
chain.doFilter(request,response);//让我们的请求继续走,如果不写,拦截停止
System.out.println("CharacterEncodingFilter 执行后");
}
//销毁 web服务器关闭的时候 过滤器自动销毁
public void destroy() {
System.out.println("CharacterEncoding 销毁");
}
}
3、在web.xml中配置 Filter filtermapping
```xml
<filter>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>com.ly.filter.CharacterEncodingFilter</filter-class>
</filter>
<filter-mapping>
<!-- 只要是/servlet 的任何请求都会 经过这个过滤器 -->
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/servlet/*</url-pattern>
</filter-mapping>
12、监听器
1|编写监听器 实现一个监听器接口:很多种
/**
* 在线人数监听
* @author LY
*/
public class OnlineCountListener implements HttpSessionListener {
//创建session的监听:一举一动
//一旦创建session就会触发一次这个事件
public void sessionCreated(HttpSessionEvent httpSessionEvent) {
ServletContext servletContext = httpSessionEvent.getSession().getServletContext();
System.out.println(httpSessionEvent.getSession().getId());
Integer onlineCount = (Integer) servletContext.getAttribute("OnlineCount");
if(onlineCount==null){
onlineCount=new Integer(1);
}else {
int count=onlineCount.intValue();
onlineCount=new Integer(count+1);
}
servletContext.setAttribute("OnlineCount",onlineCount);
}
//销毁session的监听
public void sessionDestroyed(HttpSessionEvent httpSessionEvent) {
ServletContext servletContext = httpSessionEvent.getSession().getServletContext();
Integer onlineCount = (Integer) servletContext.getAttribute("OnlineCount");
if(onlineCount==null){
onlineCount=new Integer(1);
}else {
int count=onlineCount.intValue();
onlineCount=new Integer(count-1);
}
servletContext.setAttribute("OnlineCount",onlineCount);
}
}
2、web.xml中注册监听器
<!-- 注册监听器--> <listener> <listener-class>com.ly.listener.OnlineCountListener</listener-class> </listener>
3、几乎不用(看情况是否使用)
13、过滤器、监听器常见使用
监听器:GUI编程中经常使用
用户登录之后才能进入首页,注销后就不能进入主页了!
1、用户登录后,向Session中放入用户的数据
2、进入主页的时候要判断用户是否已经登录 在过滤器中实现
<!-- 只要是/sys 的任何请求都会 经过这个过滤器 -->
<filter>
<filter-name>SysFilter</filter-name>
<filter-class>com.ly.filter.SysFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>SysFilter</filter-name>
<url-pattern>/sys/*</url-pattern>
</filter-mapping>
public class SysFilter implements Filter {
public void init(FilterConfig filterConfig) throws ServletException {
}
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest request= (HttpServletRequest) servletRequest;
HttpServletResponse response= (HttpServletResponse) servletResponse;
Object user_session = request.getSession().getAttribute("USER_SESSION");
if(user_session==null){
response.sendRedirect("/error.jsp");
}
filterChain.doFilter(servletRequest,servletResponse);
}
public void destroy() {
}
}
Junit 单元测试
依赖
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
简单实用
@Test注解只有在方法上才有效,只要加了这个注解的方法,可以直接运行测试
回顾 JDBC、事务…
本文详细介绍了JavaWeb的基本概念,包括Web应用程序、静态Web和动态Web的区别,重点讲解了TomCat服务器的安装和使用,以及HTTP协议的原理。此外,还探讨了Maven在JavaWeb项目中的作用和配置,Servlet的实现与原理,以及Cookie和Session在会话管理中的应用。通过对JSP的介绍,阐述了动态网页的生成过程,最后提到了JavaBean和MVC三层架构在Web开发中的重要性。

1069

被折叠的 条评论
为什么被折叠?



