JavaWeb核心篇(1)——HTTP/Tomcat/Servlet
在正式讲解JavaWeb前,我们先来了解一下JavaWeb:
- Web:全球广域网,也被称为万维网(www),能够通过浏览器访问的网站
- JavaWeb:通过Java技术来解决相关Web互联网领域的技术栈
如果说网页是为了展现数据,数据库是为了存储和管理数据,那么JavaWeb就是为了进行逻辑处理
温馨提示:在学习JavaWeb前,需要先学习MYSQL,JDBC和前端三件套。
WEB核心技术栈介绍
既然我们想要学习JavaWeb,那么我们就要先来进行了解:
- B/S框架:Browser/Server,浏览器/服务器 构造模式,它的特点是,客户端只需要浏览器,应用程序和数据都存储在服务器端。浏览器只需要请求服务器,获得Web资源,服务器把Web资源发送给浏览器即可。
- 静态资源:HTML,CSS,JavaScript,图片等,负责页面展示
- 动态资源:Servlet,JSP等,负责逻辑处理
- 数据库:负责存储数据
- HTTP协议:定义通信规则
- Web服务器:负责解析HTTP协议,解析请求数据,并发送响应数据(常用Web服务器:Apache Tomcat)
HTTP
首先我们系统的介绍一下HTTP
- 概念:HyperText Transfer Protocol,超文本传输协议,规定了浏览器和服务器之间数据传输的规则
HTTP特点:
- 基于TCP协议:面向连接,安全
- 基于请求-响应模型:一次请求对应一次响应
- HTTP协议是无状态的协议:对于事务处理没有记忆能力;每次请求-响应都是独立的
HTTP优缺点:
- 优点:速度快
- 缺点:多次请求间不能共享数据。(Java中使用会话技术Cookie,Session来解决这个问题)
HTTP请求数据格式
HTTP请求数据分为三部分:
- 请求行:请求数据的第一行,其中GET表示请求方式(还有POST方法),/表示请求资源路径,HTTP/1.1表示协议版本
- 请求头:第二行开始,格式为key:value形式
- 请求体:POST请求的最后一部分
常见的请求头:
- Host:表示请求的主机名
- User-Agent:浏览器版本
- Accept:表示浏览器能接收的资源类型,其中text/* , image/* 或者 */ *表示所有
- Accept-Language:表示浏览器偏好的语言
- Accept-Encoding:表示浏览器可以支持的压缩类型,类如gzip,deflate等
GET请求和POST请求的区别:
- GET请求请求参数在请求行中,没有请求体;但是POST请求请求参数在请求体中
- GET请求请求参数有限制,但是POST没有
下面给出GET和POST两个例子:
代码语言:javascript复制GET请求数据格式
GET/HTTP/1.1
Host:www.itcast.cn
Connection:keep-alive
Cache-Control:max-age=0 Upgrade-Insecure-Requests:1
User-Agent:Mozilla/5.0Chrome/91.0.4472.106
......
代码语言:javascript复制POST请求数据格式
POST/HTTP/1.1
Host:www.itcast.cn
Connection:keep-alive
Cache-Control:max-age=0 Upgrade-Insecure-Requests:1
User-Agent:Mozilla/5.0Chrome/91.0.4472.106
username=superbaby&password=123456
HTTP响应数据格式
响应数据分为三部分:
- 响应行:响应数据的第一行;其中HTTP/1.1表示协议版本,200表示响应状态码,OK表示状态码描述
- 响应头:第二行开始,格式为key:value形式
- 响应体:最后一部分,存放响应数据
常见HTTP响应头:
- Content-Type:表示该响应内容的类型,类如text/html/image/jpeg
- Content-Length:表示该响应内容的长度(字节数)
- Content-Encoding:表示该响应压缩算法。例如gzip
- Cache-Control:指示客户端应如何缓存,例如max-age=300,表示最多可以缓存300s
下面给出HTTP响应例子:
代码语言:javascript复制HTTP/1.1 200 OK
Server:Tengine
Content-Type:text/html
Transfer-Encoding:chunked...
<html>
<head>
<title></titile>
</head>
<body>
</body>
</html>
重要状态码:
状态码分类 | 说明 |
---|---|
1xx | 响应中——临时状态码,表示请求已经接受,告诉客户端应该继续请求或者如果它已经完成则忽略它 |
2xx | 成功——表示请求已经被成功接收,处理已经完成 |
3xx | 重定位——重定义到其他地方;它让客户端再发起一个请求已完成整个处理 |
4xx | 客户端错误——处理发生错误,责任在客户端,如:客户端请求一个不存在的资源 |
5xx | 服务器端错误——处理发生错误,责任在服务端,如:服务端抛出异常,路由出错,HTTP版本不支持 |
状态码 | 英文描述 | 解释 |
---|---|---|
200 | OK | 客户端请求成功,处理成功 |
404 | NOT FOUND | 请求资源不存在,通常为url错误或资源被删除 |
500 | Internal Server Error | 服务器发生不可预期的错误,服务器出现异常,可以查看日志 |
状态码大全:HTTP 状态码 | 菜鸟教程 (runoob.com)
Tomcat
首先我们知道Tomcat是Web服务器的一种,那么我们从头介绍:
- Web服务器属于一个应用程序,对HTTP协议的操作进行封装,使得程序员不必直接对协议进行操作,让Web开发更加便捷。
- 其主要功能是“提供网上信息浏览服务”。
然后我们对Tomcat做出一个简单解释:
- Tomcat是Apache软件基金会的一个核心项目,是一个开源免费的轻量级Web服务器,支持Servlet/JSP少量JavaEE规范
- JavaEE:Java企业版,指Java企业级开发的技术规范总和,包含13门技术:JDBC,JSP,XML,Servlet等
- Tomcat也被称为Web容器;Servlet需要依赖Tomcat才能运行
- 官网:Apache Tomcat® - Welcome!
通俗来讲,我们自制的HTML网页通常只能在自己电脑上使用 如果我们希望将该网页上传到网络上被其他人阅读,就需要书写HTTP等原本不属于该网页的制造代码 但是我们可以通过Web服务器(Tomcat等)来省略HTTP内容书写的过程,直接将该网页上传至网络被其他人阅读
Tomcat下载
Tomcat下载流程:
- 下载:官网下载即可(示例Tomcat为Tomcat8)
- 安装:绿色版本,直接安装即可(推荐安装在无汉字无空格的文件目录下)
- 启动:双击binstartup.bat即为启动
Tomcat关闭流程:
- 强制关闭:直接按×关闭即可
- 正常关闭:双击binshutdown.bat 或者 在cmd控制面板使用ctrl c
我们给出Tomcat的文件目录展示并解释:
我们对文件夹进行解释翻译:
- bin:可执行文件存放目录
- conf:配置文件存放目录
- lib:jar包存放目录
- logs:日志文件
- temp:临时文件
- webapps:应用发布目录(我们把需要编译的文件放置在该文件夹下,在启动后,就可以在网页中直接搜索)
- work:工作目录
Tomcat配置与项目部署
Tomcat的配置主要是修改端口号:
代码语言:javascript复制我们在conf/server.xml中找到如下代码,修改port端口号即可
<Connector port="80" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" />
注意:HTTP协议默认端口号为80,如果将Tomcat端口号修改为80,则访问时不需要输入端口号
Tomcat部署项目:
代码语言:javascript复制将项目放在webapps目录下,即为部署成功
注意:我们的文件通常打包为war压缩包,放置在webapps下后会自动解压(加快速度)
IDEA创建Maven Web项目整体框架
首先我们先对Maven Web项目的整体框架进行解释:
我们对文件夹进行解释翻译:
- src:主目录
- java:java代码
- resources:资源文件
- webapp:Web项目特有目录
- html:HTML文件目录(可自定义)
- WEB-INF:Web项目核心目录(必须这个名字)
- web.xml:Web项目配置文件
- test:测试目录
在文件打包之后会创建一个target打包包,即为部署成功的JavaWeb项目包:
- 编译后的Java字节码文件和resources资源文件,放到WEB-INF下的class目录下
- pom.xml中依赖坐标对应的jar包会放到WEB-INF下的lib目录下
IDEA创建Maven Web项目
创建方法分为使用骨架和不使用骨架(骨架:项目模板)
- 使用骨架:
- 在创建项目中使用Maven Archetype,直接创建即可
- 在创建后,删除掉pom.xml中的多余坐标(只保留自身groupId即可)
- 需要补全main下的Java目录和resources目录
- 不使用骨架:
- 直接创建Maven项目
- 在pom.xml中的groupId中添加war,使其打包方法为war(默认为jar)
- 补全webapp目录
IDEA中使用Tomcat
我们如果在Tomcat的下载地址下上传网页,需要不停刷新Tomcat,所以我们希望在IDEA中使用Tomcat
- 集成本地Tomcat(IDEA完整版)
我们需要在IDEA中添加配置(Add)中添加Tomcat即可
- Tomcat Maven插件(Tomcat7版本之前)
直接在pom.xml中添加Tomcat插件
代码语言:javascript复制<build>
<plugins>
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<configuration>
<path>/</path>
<port>8080</port>
</configuration>
</plugin>
</plugins>
</build>
然后在Maven Helper插件中快速启动项目,选中项目,右键-> Run Maven ->tomcat7:run
Servlet
最后我们介绍一下Servlet:
- Servlet是Java提供的一门动态Web资源开发技术
- Servlet是JavaEE规范之一,其实就是一个接口,将来我们需要定义Servlet类实现Servlet接口,并由Web服务器运行Servlet
如果说Tomcat是Java网页与互联网连接的一个框架,那么Servlet就是Java网页在登陆互联网后的动态资源
Servlet入门
下面我们通过一个简单的步骤来介绍Servlet的使用过程:
- 创建Web项目,在pom.xml中导入Servlet依赖坐标
<?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>org.example</groupId>
<artifactId>web-demo</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<!-- servlet依赖坐标 -->
<dependencies>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<plugins>
<!-- tomcat 插件 为了方便使用 -->
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.2</version>
</plugin>
</plugins>
</build>
</project>
- 在Java文件夹下创建一个类,并实现Servlet接口,重写所有方法
package com.itheima.web;
import javax.servlet.*;
import javax.servlet.annotation.WebServlet;
import java.io.IOException;
@WebServlet("/demo1")
public class ServletDemo1 implements Servlet {
// service 在每次开启网页后都会启动一次(是主要代码)
@Override
public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
System.out.println("servlet hello world~");
}
@Override
public String getServletInfo() {
return null;
}
@Override
public void destroy() {
}
@Override
public void init(ServletConfig config) throws ServletException {
}
@Override
public ServletConfig getServletConfig() {
return null;package com.itheima.web;
- 在类上方使用@WebServlet注解,配置该Servlet的访问路径
import javax.servlet.*;
import javax.servlet.annotation.WebServlet;
import java.io.IOException;
// 这里使用注解,后面括号内为访问路径
@WebServlet("/demo1")
public class ServletDemo1 implements Servlet {
@Override
public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
System.out.println("servlet hello world~");
}
@Override
public String getServletInfo() {
return null;
}
@Override
public void destroy() {
}
@Override
public void init(ServletConfig config) throws ServletException {
}
@Override
public ServletConfig getServletConfig() {
return null;
}
}
}
}
- 访问:启动Tomcat,输入URL即可访问,并且触动Servlet中的service方法
// /web-demo 是Web项目名称
// /demo1是配置访问路径
http://localhost:8080/web-demo/demo1
Servlet生命周期
在分析执行流程前,我们先明白两个问题:
- Servlet由Web服务器创建,Servlet方法由Web服务器调用
- 因为我们自定义的Servlet,必须实现Servlet接口并复写其方法,所以Servlet接口中必定存在service方法
生命周期概念:
- 生命周期:指一个对象从被创建到被销毁的全过程
Servlet生命周期:
- 加载和实例化:
- 默认情况下,当Servlet第一次被访问时,由容器创建Servlet对象
- 初始化:
- 在Servlet实例化之后,容器将调用Servlet的init()方法初始化这个对象,完成一些如加载配置文件,创建连接等初始化的工作,该方法只调用一次!
- 请求处理:
- 每次请求Servlet时,Servlet容器都会调用Service方法来对请求进行处理
- 服务终止:
- 当需要释放内存或容器关闭时,容器就会调用Servlet实例的destroy()方法完成资源的释放;在destroy方法调用之后,容器会释放这个Servlet实例,该实例随后会被Java的垃圾收集器回收
注意:@WebServlet(urlPatterns = “/demo1”,loadOnStartup = 1) loadOnStartup:当为负整数,表示第一次被访问时创建;当为正整数或0,表示服务器启动时创建,数字越小优先级越高
Servlet方法介绍
Servlet存在五种方法,我们在代码中进行介绍:
代码语言:javascript复制package com.itheima.web;
import javax.servlet.*;
import javax.servlet.annotation.WebServlet;
import java.io.IOException;
/**
* Servlet 生命周期方法
*/
@WebServlet(urlPatterns="/demo2",loadOnStartup = 1)
public class ServletDemo2 implements Servlet {
/**
* 初始化方法
* 1. 调用时机:默认情况下,Servlet被第一次访问时,调用
* * loadOnStartup:
* 2. 调用次数:1次
* @param config
* @throws ServletException
*/
@Override
public void init(ServletConfig config) throws ServletException {
System.out.println("init...");
}
/**
* 提供服务
* 1. 调用时机:每一次Servlet被访问时,调用
* 2. 调用次数:多次
*
*
* @param req
* @param res
* @throws ServletException
* @throws IOException
*/
@Override
public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
System.out.println("servlet hello world~");
}
/**
* 销毁方法
* 1. 调用时机:内存释放或者服务器关闭的时候,Servlet对象会被销毁,调用
* 2. 调用次数:1次
*/
@Override
public void destroy() {
System.out.println("destroy...");
}
// 用于获取Servlet的具体信息
@Override
public String getServletInfo() {
return null;
}
// 用于获取ServletConfig对象
@Override
public ServletConfig getServletConfig() {
return null;
}
}
Servlet体系结构
Servlet属于最高级根接口,为了更加契合HTTP的使用
我们又以Servlet创建了GennericServlet类,再以GennericServlet类为模板创建了HTTPServlet类
在这部分我们将介绍HTTPServlet类:
- 我们的B/S构架的Web的开发,都是针对HTTP协议的,所以我们自定义的Servlet类可以继承HTTPServlet类
HTTPServlet使用步骤:
- 继承HTTPServlet类
- 重写doGet和doPost方法
HttpServlet原理:
- 获得请求方式,并根据不同请求方法,调用不同的do方法
我们给出一个具体实例:
代码语言:javascript复制package com.itheima.web;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/demo4")
public class ServletDemo4 extends HttpServlet {
// HTTPServlet根据其请求的GET或POST方法提供不同的返回信息
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("get...");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("post...");
}
}
Servlet urlPattern配置
Servlet如果想被访问,就必须要配置urlPattern信息(访问路径)
首先我们阐明一个道理:
- 一个Servlet,可以配置多个urlPattern
@WebServlet(urlPattern = {"/demo1","/demo2"})
然后我们介绍Servlet的urlPattern匹配规则:
- 精准匹配
// Java源码
@WebServlet(urlPattern = "/user/select")
// 查询网站
localhost8080/web-demo/user/select
- 目录匹配
// Java源码
@WebServlet(urlPattern = "/user/*")
// 查询网站
localhost8080/web-demo/user/aaa
localhost8080/web-demo/user/bbb
- 扩展名匹配
// Java源码
@WebServlet(urlPattern = "*.do")
// 查询网站
localhost8080/web-demo/aaa.do
localhost8080/web-demo/bbb.do
- 任意匹配
// Java源码
@WebServlet(urlPattern = "/")
@WebServlet(urlPattern = "/*")
// 查询网站
localhost8080/web-demo/hehe
localhost8080/web-demo/haha
/*
介绍一下 / 和 /* 区别:
/*: 可以匹配任意访问路径
/: 当我们的项目中配置了"/"后,会覆盖掉tomcat中的DefaultServlet,这样就会导致你的静态内容(html)都无法被访问,所以尽量不要使用
*/
优先级:精确路径 > 目录路径 > 扩展名路径 > /* > /
XML配置方法编写Servlet
Servlet在3.0版本后才可以使用注解配置(@注解)
在3.0版本之前我们需要采用XML配置文件的配置方法
配置方法:
- 编写Servlet类
- 在web.xml中配置该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>demo13</servlet-name>
<servlet-class>com.itheima.web.ServletDemo13</servlet-class>
</servlet>
<!--
Servlet 访问路径
-->
<servlet-mapping>
<servlet-name>demo13</servlet-name>
<url-pattern>/demo13</url-pattern>
</servlet-mapping>
</web-app>
结束语
好的, 关于JavaWeb的第一期就到这里,具体介绍了HTTP,Tomcat和Servlet三门技术
下一期将会介绍Request和Response以及案例介绍
附录
该文章属于学习内容,具体参考B站黑马程序员陈老师的JavaWeb课程
这里附上链接:01-Web核心介绍_哔哩哔哩_bilibili