概述
web 服务器、项目、资源概述
web 服务器:可以被浏览器访问到的服务器
常见的 web 服务器:
- tomcat:中小型的服务器软件,免费开源,支持 JSP 和 Servlet apache 公司的产品
- WebLogic:Oracle 公司的产品,是目前应用最广泛的 Web 服务器,支持 J2EE 规范。WebLogic 是用于开发、集成、部署和管理大型分布式 Web 应用、网络应用和数据库应用的 Java 应用服务器。收费的大型的服务器软件
- WebSphere:IBM 公司的产品,支持 JavaEE 规范。WebSphere 是随需应变的电子商务时代的最主要的软件平台,可用于企业开发、部署和整合新一代的电子商务应用。收费的大型的服务器软件
web 项目: 部署在 web 服务器上面,可以被浏览器直接访问到的项目,特点:项目的结构得按照指定规则
web 资源:
- 静态资源:指在页面写死的、始终不变的数据,比如:HTML、CSS、JS、图片、音频、视频。
- 动态资源:指web页面中浏览的数据是由程序产生的,不同时间点访问web页面看到的内容各不相同。 比如:在不同时间搜索微博的热门话题内容是不一样的。这些数据由程序生成,/Servlet、ASP、PHP等技术都可以完成。
软件的架构
网络中有很多的计算机,它们直接的信息交流,称之为:交互。
在互联网交互的过程的有两个非常典型的交互方式 —— B/S 交互模型和 C/S 交互模型。
- C/S架构 Client/Server 客户端/服务器
特点:需要安装一个客户端,例如:QQ客户端 游戏各种客户端 迅雷客户端
优点:效果比较炫,好看
缺点:占用硬盘空间,服务器只要升级就要求客户端跟着升级
- B/S架构 Browser/Server 浏览器/服务器
特点:不需要安装客户端,一个浏览器足矣,例如:网页淘宝 网页京东 网页12306
优点:不会占用硬盘空间,服务器只要升级不要求跟着升级
缺点:效果不炫,所有压力都在服务器
相同点: 都需要和服务器进行数据交互,都是先有请求,后给响应,一定是请求和响应成双成对
Tomcat 服务器
Tomcat 的目录结构
bin 里面存放的都是tomcat的二进制命令 关注点:开启服务: startup.bat 关闭服务:shutdown.bat
conf 里面存放的都是tomcat的配置文件 关注点:server.xml(配置端口) web.xml
lib 里面存放的都是tomcat运行过程中提供支撑的jar包
logs 里面存放的都是日志文件 关注点:错误信息的日志文件查看 catalina.2020-xx-xx.log
temp 里面存放的是tomcat运行过程中创建的临时文件 由tomcat维护
work 里面存放的内容和jsp相关
webapps(核心) 用来存放web项目 存放在这个里面的项目可以被浏览器直接访问到 http://localhost:8080 --> webapps文件夹下
虚拟路径发布项目
方式1:配置独立xml文件
- 在 tomcat/conf 目录下新建一个 Catalina 目录(如果已经存在无需创建)
- 在 Catalina 目录下创建 localhost 目录(如果已经存在无需创建)
在 localhost 中创建 xml 配置文件,名称为:xxx.xml(xxx名就是项目的浏览器访问别名)
xxx.xml中代码如下:
<Context docBase="项目所在的硬盘位置" />
好处:使用配置文件对项目的部署和卸载不用重启 tomcat 了,也不影响 tomcat 整体的配置文件
方式2:配置 server.xml,添加 context 标签
在 server.xml 配置文件的最后加上如下代码:
<Context path="项目的浏览器访问别名" docBase="项目所在的硬盘位置" />
注意:谨慎使用(最好单独独立出来一个配置文件)
电脑安装 Tomcat(了解)
在电脑安装一个 tomcat 软件,将电脑变成 web 服务器,步骤:
- 下载一个 tomcat 服务器软件,官网地址 http://tomcat.apache.org
- 解压下载好的 tomcat。注意:将解压后的文件 copy 到一个没有中文和空格的路径下
- 启动 tomcat 服务:进入 bin 路径,双击 startup.bat 服务器就可以启动(默认占用电脑的8080端口)
- 测试:在页面输入地址访问 http://localhost:8080
- 关闭 tomcat 服务:直接关闭 或者去 bin 路径双击 shutdown.bat
Tomcat启动的常见问题总结
1、一闪而过
原因:没有配置环境变量JAVA_HOME 或者配置错误
解决:配置环境变量JAVA_HOME,因为tomcat在启动的时候会去找环境变量JAVA_HOME
Tomcat的底层需要JDK的支撑
JAVA_HOME=jdk的安装路径(不要加bin目录)
path=%JAVA_HOME%\bin
2、报错 java.net.BindException: Address already in use: bind
原因:端口号被占用
解决:
方式1:结束正在占用端口的进程
1) netstat -ano 查看端口对应的pid
2) 打开任务管理器 结束pid对应的进程
方式2:改变自己的端口号
修改conf文件夹中的server.xml 大概在69行的位置
或者修改端口号为80: 80是默认端口号.可以不写
idea 集成 Tomcat 环境(了解)
idea 自动用的是虚拟路径的方式给 tomcat 管理的
idea集成tomcat步骤:
idea创建web项目:
idea发布项目:
Http协议
概念及作用
概念:
协议:规定了被约束对象都需要去遵守的规则
http协议:
- 是互联网上运用最为广泛的一种浏览器和服务器之间的协议,规定了浏览器和服务器之间要遵守的规则
- 只要浏览器访问服务器或者是服务器响应浏览器必须要遵循一些规则,这些规则都是由http协议制定好的
- http协议就是咱们浏览器和服务器之间的合同,双方都要遵循这份合同的规定内容
作用:
- 规定了浏览器去请求服务器时候必须带哪些数据,以及这些数据都要以什么格式进行传递
- 规定了服务器去响应浏览器的时候必须响应哪些数据回去,以及这些数据都要以什么格式进行传递
请求内容:请求行 请求头 请求体
请求内容分为:
请求行(第一行)
POST /web02_1/demo1.html HTTP/1.1 提交方式 要请求的服务器资源 使用的是http协议的那个版本(固定)
请求头(key:value)
数据的格式:键值对的数据
常用头数据:Referer User-Agent
- Referer:当前页面的来源地址,可以解决防盗链
- User-Agent:用户的浏览器版本信息,可以解决下载
- 请求体(要传递给服务器的页面数据)
只有 post 提交才有 是页面表单的数据要传递给服务器的内容
响应内容:响应行 响应头 响应体
响应内容分为:
响应行
// 组成部分: HTTP/1.1 200 固定协议版本 状态码 // 常见的响应状态码: 200 OK 请求已成功,响应也没问题。出现此状态码是表示正常状态。 302 资源重定向 304 去找缓存数据 403 服务器拒绝执行 (文件或文件夹加了权限) 404 请求的资源没找到 405 请求的方法不存在 500 服务器错误 (代码写的有问题)
响应头
常用响应头:
- location:重定向操作,通常告知浏览器马上向该地址发送请求
- refresh:定时刷新操作,指定时间后跳转到指定页面
- content-disposition:通知浏览器以何种方式获取数据(直接展示数据或者以附件方式)--下载
- content-type:通知浏览器返回的资源类型以及编码格式 --处理响应数据的中文乱码
- 响应体
浏览器页面要解析显示的内容即是响应体的内容
get 提交和 post 提交的区别
- get 提交的数据不安全,因为所有的页面表单数据都在请求行中,意味着资源都在地址栏暴露了
post 提交的数据安全,因为所有的页面表单数据都在请求体中,意味着资源都不会在地址栏暴露了
- get 提交有着大小的限制,post 提交没有大小的限制
- get 提交没有请求体,所有的表单的数据都在请求行中
post 有请求体,所有的表单数据都在请求体中
Java web 项目
项目的结构
在 JavaEE 规范中,WEB 项目存在一定的目录结构,具体结构如
web项目(myweb)
|| ------ 静态资源(如html、css、js、img等)、二级目录等
||
||
|| ------ WEB-INF目录(放在该目录下的资源浏览器是不能直接访问到)
|| ------ classess目录:放的都是java代码的 .class
|| ------ lib目录:放入项目需要的jar
|| ------ web.xml:配置文件(配置的是项目的内容) 是tomcat首先会去加载的配置文件
servlet如果是2.5的版本这个web.xml文件必须有
servlet如果是3.0的版本这个web.xml文件可以不要 用注解代替
三大技术:Servlet、Filter、Listener
java web 项目服务器有三大技术:Servlet、Filter、Listener
- servlet:本质就是一个类,这个类实现了 java 提供的 Servlet 规范。
可以对浏览器的请求和响应进行处理
- filter:本质上是一个类,这个类需要实现 java 提供的 Filter 规范。
可以对浏览器访问服务器资源时的一种拦截,可以让符合条件放行,不符合条件不放行
- listener:本质上是一个类,实现了 java 的 Listener 规范,可以监听其它对象(域)的状态变化
Servlet
概述
Servlet 运行在服务端的 Java 小程序,是 sun 公司提供一套规范,用来处理客户端请求、响应给浏览器的动态资源。
servlet 的实质就是 java 代码,通过 java 的 API 动态的向客户端输出内容。
servlet 的作用:
- 在服务器端接受浏览器带来的请求数据(请求行、请求头、请求体)
- 给浏览器做响应数据(响应行、响应头、响应体)
servlet 与普通的 java 程序的区别:
- 必须实现 servlet 接口
- 必须在 servlet 容器(服务器)中运行
- servlet 程序可以接收用户请求参数以及向浏览器输出数据
快速入门
servlet2.5 的方式:必须有 web.xml 配置文件
三个步骤创建一个 servlet:
- 创建一个类实现 servlet 接口
- 重写 service 方法
- 在 web.xml 文件中配置创建的类(将请求路径和 java 程序的对应关系建立起来)
tomcat 只要一启动,就会去加载 web.xml 文件,只加载一次
只要这个 web.xml 配置文件修改了任何一处,都要重新 tomcat 重新加载
servlet 的创建和服务方法、service 的执行都是由 tomcat 自动完成
servlet3.0 的方式:没有web.xml配置文件
步骤:
- 创建 JavaEE6(含6) 以上的工程
创建一个类实现 servlet 接口,并在实现类上标注 @WebServle 注解
@WebServlet 注解的属性:
- name 属性:servlet名称,相当于web.xml中的<servlet‐name>
- urlPatterns 属性:请求路径
示例:@WebServlet(name = "HelloServlet", urlPatterns = "/hello")
servlet 的生命周期
一个对象从创建到消亡的过程,就是生命周期。
和 servlet 的生命周期相关的 3 个方法:
// Servlet对象只要一创建出来就会调用的方法
void init(ServletConfig var1)
// 处理浏览器交互的方法
void service(ServletRequest var1, ServletResponse var2)
// 销毁的方法
void destroy()
Servlet 的生命周期:
- 浏览器第一次访问该 servlet 的时候,创建该 servlet 的对象,执行 init 初始化方法,只创建一次,请求使用的都是同一个 servlet 对象(单例对象),线程是不安全的
- 浏览器每次访问的时候都会执行 service 服务方法,访问一次执行一次
- 当服务器关闭的时候,会销毁该 servlet,执行 destory 方法
servlet 的体系结构
- servlet 的继承体系:HttpServlet(功能最多)extends GenericServlet implements Servlet接口
- 在 servlet 中,真正执行程序逻辑的是 service 方法时,对于 servlet 的初始化和销毁,一般由服务器调用执行,开发者本身不需要关心。
企业开发中:继承 HttpServlet,只需要复写 doget 和 dopost 方法,而开发工具已经提供好了模板,直接用即可
Servlet 的配置
url-pattern(路径规则)配置
在创建 servlet 后,如果想要这个 servlet 可以被访问到,必须在 web.xml 文件中对其进行配置。
url-pattern 标签就是用于确定访问一个 servlet 的路径
示例:
<servlet>
<servlet-name>ServletDemo1</servlet-name>
<servlet-class>cn.itcast.web.ServletDemo1</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ServletDemo1</servlet-name>
<url-pattern>/sd1</url-pattern>
<url-pattern>/sd2</url-pattern>
<url-pattern>/sd3</url-pattern>
<url-pattern>/sd</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>ServletDemo2</servlet-name>
<!-- 完全匹配 -->
<url-pattern>/aaa</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>ServletDemo3</servlet-name>
<!-- 扩展名匹配 -->
<url-pattern>*.do</url-pattern>
</servlet-mapping>
注:
- 一个servlet也可以被不同的路径映射,但一般在开发中,只需要配置一个有效路径即可
路径映射的配置方式:
- 完全匹配:必须以 / 开始
例如: /ms1、 /aaa/ms1、/aaa/bb/cc/ms1
- 目录匹配:必须以 / 开始,以
*
结束例如:
/*
、/aaa/*
- 扩展名(后缀名)匹配:以
*.xx
结束(xx 代表的是后缀名)。注意:不能以 / 开始例如:
*.action
、*.do
- 完全匹配:必须以 / 开始
- 多种匹配的优先级:完全匹配 > 目录匹配 > 扩展名匹配
只有一个 servlet 会执行,执行的结果是按照优先级去执行的
load-on-startup(优先级)配置
load-on-startup 标签可以设置 servlet 的加载优先级别和容器是否在启动时加载该 servlet
- 当值为 0 或者大于 0 时,代表容器启动时加载该 servlet。正数的值越小,启动时加载该 servlet 的优先级越高。
- 如果为负数,则容器启动时不会加载该 servlet,只有该 servlet 被选择时才会加载。
servlet 的默认创建是在第一次访问的时候
示例:
<servlet>
<servlet-name>ServletDemo1</servlet-name>
<servlet-class>cn.itcast.web.ServletDemo1</servlet-class>
<load-on-startup>2</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>ServletDemo1</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
注:
- 数字 1 被 tomcat 默认的 servlet 给占用了,在 tomcat 的 web.xml 中可以看到也使用了一个 servlet
tomcat 一启动会加载 2 个 web.xml 文件,一个是项目自定义的 web.xml,一个 tomcat 的 web.xml
<servlet> <servlet-name>default</servlet-name> <servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>default</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping>
该 servlet 是 tomcat 创建的,主要用来处理其它的 servlet 处理不了的请求
比如在当前下访问不到的资源都会走该 servlet,该 servlet 底层默认走写好的页面(404 500...)
Servlet 的路径
servlet 的访问路径分为 2 种:
绝对路径
- 带协议的绝对路径
地址栏的地址方式,一般用于外部资源的访问,例如:http://localhost:8080/web02/ms5
- 不带协议的绝对路径
把协议和端口名省略,永远只能访问到本机的资源,一般用于内部资源的访问, 例如:/web02/ms5,
特点:以/开头 以资源名结尾
- 带协议的绝对路径
- 相对路径:相对比较的是地址栏的地址
特点:同级目录及以下 以 ./ 开头、以资源名结尾(也可省略 ./ )
父级目录 以 ../ 开头,返回父级目录
Servlet 相关对象
HttpServletRequest 请求对象
概述
HttpServletRequest 对象代表浏览器端的请求,当浏览器端通过 HTTP 协议访问服务器时,HTTP 请求中的所有信息都封装在这个对象中,开发人员通过这个对象的 api,可以获得客户通过浏览器传递过来的数据。
HttpServletRequest 对象的作用:封装浏览器的请求数据(请求行、请求头 、请求体)
API
HttpServletRequest extends ServletRequest
获取请求行数据(请求方式、访问的资源、协议版本)
// 获取请求方式
String getMethod()
// 获取请求行中的资源名部分
String getRequestURI()
// 获取客户端请求完整URL
StringBuffer getRequestURL()
// 获取请求协议和版本
String getProtocol()
// 获取端口
int getLocalPort()
// 获取请求者的ip地址
String getRemoteAddr()
// 获取当前的项目名路径
String getContextPath()
获取请求头数据(键值对 key/value 的数据)
// 根据请求头的key获取value
String getHeader(String key)
// 例如:Referer可以获取到来源地址(没有来源为null:直接访问) --防盗链
// 例如:User-Agent可以获取用户的浏览器版本信息 --下载必备、处理下载乱码的
// 返回此请求包含的所有头名称
Enumeration getHeaderNames()
获取请求体数据(所有浏览器提交的表单数据)
// 获取单一name对应的value值
String getParameter(String name)
// 获取多个name对应的多个value值
String[] getParameterValues(String name)
// 获取页面所有的value值
Map<String,String[]> getParameterMap()
// 注意:key:对应的是表单中name属性名,value对应的的是表单的name属性的value值
// 设置编码。一般设置为 utf-8,否则请求中中文可能会乱码
void setCharacterEncoding(String var1)
作为容器数据存取删(request 也被称为域对象)
// 存储数据
void setAttribute(String name, Object o)
// 获取数据
Object getAttribute(String name)
// 移除数据
void removeAttribute(String name)
注意:若想要在多个 servlet 之间的使用 request 传递数据,则需要保证多个 servlet 之间使用的是同一个 request 对象,可以使用请求转发。
request.getRequestDispatcher("/servlet的地址").forward(request, response);
HttpServletResponse 对象
概述
HttpServletResponse 对象:服务器用来给浏览器写内容的一个对象
服务器有数据如果想给浏览器:只能按照 http 协议的规定通过3个方向给:响应行、响应头、响应体
API
操作响应行
格式:协议/版本 状态码
示例:HTTP/1.1 200
状态码含义
200 请求响应已成功 302 重定向 304 去找缓存数据 403 服务器拒绝执行 (文件或文件夹加了权限) 404 请求的资源没找到 405 请求的方法不存在 500 服务器错误 (代码写的有问题)
操作响应头
格式:key:valu
API 方法:
// 设置键值对形式的响应头 setHeader(String key,String value)
常用响应头:
// content-type:通知浏览器响应的内容是什么类型的,并且用什么编码解析内容。解决响应回去的中文乱码问题 response.setHeader("content-type","文件的类型;charset=utf-8"); // 简写 response.setContentType("文件的类型;charset=utf-8"); // location:重定向 response.setHeader("location", "/day31/sd4"); response.setStatus(302); // 简写 response.sendRedirect("url"); // refresh:定时刷新 response.setHeader("refresh","秒数;url=跳转的路径"); // content-disposition:通知浏览器写回去的东西要以附件形式打开 (只用于下载)。默认情况下都是页面直接展示写回去的数据 response.setHeader("content-disposition","attachment;filename=" + aaa.jpg);
操作响应体
页面上要展示的内容
API 方法:
// 字符流 PrintWriter getWriter() // 字节流 (二进制) ServletOutputStream getOutputStream()
特点:
- 若是能写的出来的内容用字符流,其他全用字节流(下载专用)
- 不能同时出现
- 服务器会自动关闭这2个流
ServletContext 对象
概述
ServletContext:servlet 的上下文对象(全局管理者对象),是一个全局的储存信息的空间。
一个 web 项目只有一个全局管理者(SevletContext对象)
生命周期:
- 当 web 应用被加载时,ServletContext 生命周期开始(创建)
- 当 web 应用被移除容器时,ServletContext 生命周期结束(销毁)
- 作用范围:整个 web 应用
作用:
- 可以在整个 web 应用(多个 servlet 之间)共享数据
- 可以获取项目的地址和项目资源流(路径和流)
API
原生获取 ServletContext 对象
在继承 HttpServlet 或 GenericServlet 的自定义类中,直接通过父类方法 getServletContext() 获取 ServletContext 对象
public ServletContext getServletContext()
Spring 项目获取 ServletContext 对象
通过 spring 注入自动注入(推荐)
@Autowired private ServletContext servletContext;
通过 HttpServletRequest 对象
@GetMapping("/test") public String test(HttpServletRequest request) { ServletContext servletContext = request.getServletContext(); return "success"; }
实现 WebApplicationInitializer 接口,重写 onStartup() 方法
import javax.servlet.ServletContext; import javax.servlet.ServletException; import org.springframework.web.WebApplicationInitializer; public class ApplicationInitializer implements WebApplicationInitializer { @Override public void onStartup(ServletContext servletContext) throws ServletException { System.out.println(servletContext); } }
创建一个实现 ServletContextListener 的监听器
// 必不可少,声明为监听器,注册到web容器中 @WebListener public class InitContextListener implements ServletContextListener { @Override public void contextInitialized(ServletContextEvent servletContextEvent) { ServletContext servletContext = servletContextEvent.getServletContext(); System.out.println(servletContext); } @Override public void contextDestroyed(ServletContextEvent servletContextEvent) { } }
通过 ContextLoader 类
ServletContext servletContext = ContextLoader.getCurrentWebApplicationContext().getServletContext();
注意:使用这种方式需要 webApplicationContext 完成初始化后才能获取到 servletContext 对象,否则获取的是空值导致空指针异常
操作 ServletContext 对象
数据存取操作:保存在 ServletContext 中的数据是项目全局共享的数据,可以用来在多个 servlet 之间传递信息数据
// 存。特点:可以存多对 但是存在key值覆盖
void setAttribute(String name, Object value)
// 取。特点: \没取到返回null
Object getAttribute(String name)
// 删
void removeAttribute(String name)
读取项目资源的方法
// 获取WEB项目的磁盘路径。场景:上传
String getRealPath(String path)
// 根据WEB项目的磁盘资源获取流。场景:下载
InputStream getResourceAsStream(String path)
// 获取web.xml中<context>标签的参数内容
String getInitParameter(String name)