JavaWeb
JavaWeb
JavaWeb概述
B/S架构
B/S 架构:Browser/Server,浏览器/服务器架构模式,它的特点是:客户端只需要浏览器,应用程序的逻辑和数据都存储在服务器端。浏览器只需要请求服务器,获取Web资源,服务器把Web资源发送给浏览器即可。
静态资源
静态资源主要包含HTML、CSS、JavaScript、图片等,主要负责页面的展示。
动态资源
动态资源主要包含Servlet、JSP等,主要用来负责逻辑处理。
动态资源处理完逻辑后会把得到的结果交给静态资源来进行展示,动态资源和静态资源要结合一起使用。
数据库
数据库主要负责存储数据。
整个Web的访问过程就如下图所示:
HTTP协议
HTTP协议主要定义通信规则
Web服务器
Web服务器负责解析 HTTP 协议,解析请求数据,并发送响应数据
HTTP
HTTP概念
HyperText Transfer Protocol,超文本传输协议,规定了浏览器和服务器之间数据传输的规则。
HTTP协议特点
- 基于TCP协议:面向连接,安全。
- 基于请求-响应模型的:一次请求对应一次响应
- HTTP协议是无状态协议:对于事物处理没有记忆能力。每次请求-响应都是独立的。
请求数据格式
请求数据总共分为三部分内容:
-
请求行:HTTP请求中的第一行数据,请求行包含三块内容,分别是 GET[请求方式] /[请求URL路径] HTTP/1.1[HTTP协议及版本]
请求方式有七种,最常用的是GET和POST
-
请求头:第二行开始,格式为key: value形式
请求头中会包含若干个属性,常见的HTTP请求头有:
Host: 表示请求的主机名 User-Agent: 浏览器版本,例如Chrome浏览器的标识类似Mozilla/5.0 ...Chrome/79,IE浏览器的标识类似Mozilla/5.0 (Windows NT ...)like Gecko; Accept:表示浏览器能接收的资源类型,如text/*,image/*或者*/*表示所有; Accept-Language:表示浏览器偏好的语言,服务器可以据此返回不同语言的网页; Accept-Encoding:表示浏览器可以支持的压缩类型,例如gzip, deflate等。
-
请求体:POST请求的最后一部分,存储请求参数
如上图红线框的内容就是请求体的内容,请求体和请求头之间是有一个空行隔开。此时浏览器发送的是POST请求。
GET和POST的区别:
- GET请求请求参数在请求行中,没有请求体,POST请求参数在请求体中。
- GET请求请求参数大小有限制,POST没有。
响应数据格式
响应数据总共分为三部分内容:
-
响应行:响应数据的第一行,响应行包含三块内容,分别是 HTTP/1.1[HTTP协议及版本] 200[响应状态码] ok[状态码的描述]。
-
响应头:第二行开始,格式为key:value形式。
响应头中会包含若干个属性,常见的HTTP响应头有:
Content-Type:表示该响应内容的类型,例如text/html,image/jpeg; Content-Length:表示该响应内容的长度(字节数); Content-Encoding:表示该响应压缩算法,例如gzip; Cache-Control:指示客户端应如何缓存,例如max-age=300表示可以最多缓存300秒
-
响应体:最后一部分,存放响应数据。
上图中…这部分内容就是响应体,它和响应头之间有一个空行隔开。
响应状态码
关于响应状态码,先主要认识三个状态码,其余的等后期用到了再去掌握:
- 200 ok 客户端请求成功
- 404 Not Found 请求资源不存在
- 500 Internal Server Error 服务端发生不可预期的错误
Tomcat
简介
Web服务器是一个应用程序,对HTTP协议的操作进行封装,使得程序员不必直接对协议进行操作,让Web开发更加便捷。Web服务器软件使用步骤:
- 准备静态资源
- 下载安装Web服务器软件
- 将静态资源部署到Web服务器上
- 启动Web服务器使用浏览器访问对应的资源
Tomcat是Apache软件基金会一个核心项目,是一个开源免费的轻量级Web服务器,支持Servlet/JSP少量JavaEE规范。因为Tomcat支持Servlet/JSP规范,所以Tomcat也被称为Web容器、Servlet容器。Servlet需要依赖Tomcat才能运行。
下载安装
直接解压即可,其中文件大致如下:
- bin:目录下有两类文件:
- 一种是以
.bat
结尾的,是Windows系统的可执行文件 - 一种是以
.sh
结尾的,是Linux系统的可执行文件。
- 一种是以
- webapps就是以后项目部署的目录
启动
双击:bin\startup.bat
启动后,通过浏览器访问 http://localhost:8080
能看到Apache Tomcat的内容就说明Tomcat已经启动成功。
关闭
关闭有三种方式 :
- 直接x掉运行窗口:强制关闭[不建议]
- bin\shutdown.bat:正常关闭
- ctrl+c:正常关闭
配置
解决log中文乱码
默认采用UTF-8,在conf\logging.propertoes中如下位置改为GBK即可:
修改端口号
Tomcat默认的端口是8080,修改Tomcat启动的端口号,需要修改 conf/server.xml如下位置:
Tips:Tomcat的端口号取值范围是0-65535之间任意未被占用的端口,如果设置的端口号被占用,启动的时候就会包如下的错误
部署
将项目放置到webapps目录下,即部署完成。
随着项目的增大,项目中的资源也会越来越多,项目在拷贝的过程中也会越来越费时间,一般JavaWeb项目会被打包称war包,然后将war包放到Webapps目录下,Tomcat会自动解压缩war文件。
Web项目结构
Web项目的结构分为开发中的项目和开发完可以部署的Web项目,这两种项目的结构是不一样的。
-
开发中的项目
-
开发完成部署的Web项目
- 开发项目通过执行Maven打包命令package,可以获取到部署的Web项目目录。
- 编译后的Java字节码文件和resources的资源文件,会被放到WEB-INF下的classes目录下。
- pom.xml中依赖坐标对应的jar包,会被放入WEB-INF下的lib目录下。
IDEA使用Tomcat
集成本地Tomcat
-
在运行/调试配置中添加本地Tomcat
-
选择本低Tomcat路径,设置名称
-
选择需要部署的项目
- xxx.war和 xxx.war exploded这两种部署项目模式的区别:
- war模式是将WEB工程打成war包,把war包发布到Tomcat服务器上。
- war exploded模式是将WEB工程以当前文件夹的位置关系发布到Tomcat服务器上。
- war模式部署成功后,Tomcat的webapps目录下会有部署的项目内容。
- war exploded模式部署成功后,Tomcat的webapps目录下没有,而使用的是项目的target目录下的内容进行部署。
- 建议大家都选war模式进行部署,更符合项目部署的实际情况。
- xxx.war和 xxx.war exploded这两种部署项目模式的区别:
Tomcat Maven插件
在pom.xml中添加Tomcat插件
<build>
<plugins>
<!--Tomcat插件 -->
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.2</version>
</plugin>
</plugins>
</build>
在IDEA中安装Maven Helper插件后右键项目即可运行
Servlet
简介
Servlet是JavaWeb最为核心的内容,它是Java提供的一门动态web资源开发技术。使用Servlet就可以实现,根据不同的登录用户在页面上动态显示不同内容。
Servlet是JavaEE规范之一,其实就是一个接口,将来我们需要定义Servlet类实现Servlet接口,并由web服务器运行Servlet。
快速入门
-
创建Web项目
web-demo
,导入Servlet依赖坐标<dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>3.1.0</version> <scope>provided</scope> </dependency>
-
创建:定义一个类,实现Servlet接口,并重写接口中所有方法,并在service方法中输入一句话
package com.itheima.web; public class ServletDemo1 implements Servlet { public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException { System.out.println("servlet hello world~"); } public void init(ServletConfig servletConfig) throws ServletException { } public ServletConfig getServletConfig() { return null; } public String getServletInfo() { return null; } public void destroy() { } }
-
配置:在类上使用@WebServlet注解,配置该Servlet的访问路径
@WebServlet("/demo1")
-
访问:启动Tomcat,浏览器中输入URL地址访问该Servlet
http://localhost:8080/web-demo/demo1
-
浏览器访问后,在控制台会打印
servlet hello world~
说明servlet程序已经成功运行。
执行流程
- 浏览器发出
http://localhost:8080/web-demo/demo1
请求,从请求中可以解析出三部分内容,分别是localhost:8080
、web-demo
、demo1
- 根据
localhost:8080
可以找到要访问的Tomcat Web服务器 - 根据
web-demo
可以找到部署在Tomcat服务器上的web-demo项目 - 根据
demo1
可以找到要访问的是项目中的哪个Servlet类,根据@WebServlet后面的值进行匹配
- 根据
- 找到ServletDemo1这个类后,Tomcat Web服务器就会为ServletDemo1这个类创建一个对象,然后调用对象中的service方法
- ServletDemo1实现了Servlet接口,所以类中必然会重写service方法供Tomcat Web服务器进行调用
- service方法中有ServletRequest和ServletResponse两个参数,ServletRequest封装的是请求数据,ServletResponse封装的是响应数据,后期我们可以通过这两个参数实现前后端的数据交互
方法介绍
Servlet中总共有5个方法
-
初始化方法,在Servlet被创建时执行,只执行一次
void init(ServletConfig config)
-
销毁方法,当Servlet被销毁时,调用该方法。在内存释放或服务器关闭时销毁Servlet
void destroy()
-
提供服务方法, 每次Servlet被访问,都会调用该方法
void service(ServletRequest req, ServletResponse res)
-
获取Servlet信息
String getServletInfo() //该方法用来返回Servlet的相关信息,没有什么太大的用处,一般我们返回一个空字符串即可 public String getServletInfo() { return ""; }
-
获取ServletConfig对象
ServletConfig getServletConfig()
体系结构
HttpServlet类
这玩意儿可以简化代码开发。
如果直接继承Servlet接口,为了能处理不同的请求方式,我们得在service方法中进行判断,然后写不同的业务处理:
package com.itheima.web;
@WebServlet("/demo5")
public class ServletDemo5 implements Servlet {
public void init(ServletConfig config) throws ServletException {
}
public ServletConfig getServletConfig() {
return null;
}
public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
//如何调用?
//获取请求方式,根据不同的请求方式进行不同的业务处理
HttpServletRequest request = (HttpServletRequest)req;
//1. 获取请求方式
String method = request.getMethod();
//2. 判断
if("GET".equals(method)){
// get方式的处理逻辑
}else if("POST".equals(method)){
// post方式的处理逻辑
}
}
public String getServletInfo() {
return null;
}
public void destroy() {
}
}
现在这么写就行:
@WebServlet("/demo4")
public class ServletDemo4 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//TODO GET 请求方式处理逻辑
System.out.println("get...");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//TODO Post 请求方式处理逻辑
System.out.println("post...");
}
}
-
要想发送一个GET请求,请求该Servlet,只需要通过浏览器发送
http://localhost:8080/web-demo/demo4
,就能看到doGet方法被执行了。 -
要想发送一个POST请求,请求该Servlet,单单通过浏览器是无法实现的,这个时候就需要编写一个form表单来发送请求,在webapp下创建一个
a.html
页面,内容如下:<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <form action="/web-demo/demo4" method="post"> <input name="username"/><input type="submit"/> </form> </body> </html>
urlPattern配置
Servlet类编写好后,要想被访问到,就需要配置其访问路径。
一个Servlet,可以配置多个urlPattern:
@WebServlet(urlPatterns = {"/demo7","/demo8"})
这样在浏览器上输入http://localhost:8080/web-demo/demo7
,http://localhost:8080/web-demo/demo8
这两个地址都能访问到ServletDemo7的doGet方法。
urlPattern配置规则
-
精确匹配
@WebServlet(urlPatterns = "/user/select")
访问路径:
http://localhost:8080/web-demo/user/select
-
目录匹配
@WebServlet(urlPatterns = "/user/*")
访问路径:
http://localhost:8080/web-demo/user/任意
-
扩展名匹配
@WebServlet(urlPatterns = "*.do")
访问路径:
http://localhost:8080/web-demo/任意.do
-
任意匹配
@WebServlet(urlPatterns = "/") @WebServlet(urlPatterns = "/*")
访问路径:
http://localhost:8080/demo-web/任意
二者区别:
- 当我们的项目中的Servlet配置了 “/”,会覆盖掉tomcat中的DefaultServlet,当其他的url-pattern都匹配不上时都会走这个Servlet。
- 当我们的项目中配置了”/*”,意味着匹配任意访问路径。
- DefaultServlet是用来处理静态资源,如果配置了”/”会把默认的覆盖掉,就会引发请求静态资源的时候没有走默认的而是走了自定义的Servlet类,最终导致静态资源不能被访问。
五种配置的优先级:精确匹配 > 目录匹配> 扩展名匹配 > /* > / ,无需记,以最终运行结果为准。
XML配置
前面对应Servlet的配置使用的是@WebServlet,这个是Servlet从3.0版本后开始支持注解配置,3.0版本前只支持XML配置文件的配置方法。
在webapp/WEB-INF/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的名称,名字任意-->
<servlet-name>demo13</servlet-name>
<!--servlet的类全名-->
<servlet-class>com.itheima.web.ServletDemo13</servlet-class>
</servlet>
<!-- Servlet 访问路径-->
<servlet-mapping>
<!-- servlet的名称,要和上面的名称一致-->
<servlet-name>demo13</servlet-name>
<!-- servlet的访问路径-->
<url-pattern>/demo13</url-pattern>
</servlet-mapping>
</web-app>
Fliter
Filter概述
Filter 表示过滤器,是 JavaWeb 三大组件(Servlet、Filter、Listener)之一,过滤器可以把对资源的请求拦截下来,从而实现一些特殊的功能。
浏览器可以访问服务器上的所有的资源(servlet、jsp、html等),而在访问到这些资源之前可以使过滤器拦截来下,也就是说在访问资源之前会先经过 Filter,如下图:
过滤器一般完成一些通用的操作,比如每个资源都要写一些代码完成某个功能,我们总不能在每个资源中写这样的代码吧,而此时我们可以将这些代码写在过滤器中,因为请求每一个资源都要经过过滤器。
Filter快速入门
开发步骤
进行 Filter 开发分成以下三步实现:
-
定义类,实现
Filter
接口,并重写其所有方法public class FilterDemo implements Filter { @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) { } @Override public void init(FilterConfig filterConfig) throws ServletException { } @Override public void destroy() { } }
-
配置Filter拦截资源的路径:在类上定义
@WebFilter
注解。而注解的value
属性值/*
表示拦截所有的资源@WebFilter("/*")
-
在doFilter方法中输出一句话,并放行
@Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { System.out.println("1.FilterDemo..."); //放行 chain.doFilter(request,response); }
Filter执行流程
- 执行放行前逻辑
- 放行
- 访问资源
- 执行放行后逻辑
Filter拦截路径配置
拦截路径表示 Filter 会对请求的哪些资源进行拦截,使用 @WebFilter
注解进行配置。如:@WebFilter("拦截路径")
,拦截路径的配置方式和 Servlet
的请求资源路径配置方式一样,但是表示的含义不同,拦截路径有如下四种配置方式:
- 拦截具体的资源:/index.jsp:只有访问index.jsp时才会被拦截
- 目录拦截:/user/*:访问/user下的所有资源,都会被拦截
- 后缀名拦截:*.jsp:访问后缀名为jsp的资源,都会被拦截
- 拦截所有:/*:访问所有资源,都会被拦截
过滤器链
过滤器链是指在一个Web应用,可以配置多个过滤器,这多个过滤器称为过滤器链:
上图中的过滤器链执行是按照以下流程执行:
- 执行
Filter1
的放行前逻辑代码 - 执行
Filter1
的放行代码 - 执行
Filter2
的放行前逻辑代码 - 执行
Filter2
的放行代码 - 访问到资源
- 执行
Filter2
的放行后逻辑代码 - 执行
Filter1
的放行后逻辑代码
代码演示
编写第一个过滤器 FilterDemo ,拦截所有资源
@WebFilter("/*")
public class FilterDemo implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
//1. 放行前,对 request数据进行处理
System.out.println("1.FilterDemo...");
//放行
chain.doFilter(request,response);
//2. 放行后,对Response 数据进行处理
System.out.println("3.FilterDemo...");
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void destroy() {
}
}
编写第二个过滤器 FilterDemo2 ,拦截所有资源
@WebFilter("/*")
public class FilterDemo2 implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
//1. 放行前,对 request数据进行处理
System.out.println("2.FilterDemo...");
//放行
chain.doFilter(request,response);
//2. 放行后,对Response 数据进行处理
System.out.println("4.FilterDemo...");
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void destroy() {
}
}
修改 hello.jsp 页面中脚本的输出语句
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1>hello JSP~</h1>
<%
System.out.println("3.hello jsp");
%>
</body>
</html>
运行效果:
Listener
Listener概述
Listener 表示监听器,是 JavaWeb 三大组件(Servlet、Filter、Listener)之一,监听器可以监听就是在 application
,session
,request
三个对象创建、销毁或者往其中添加修改删除属性时自动执行代码的功能组件。
分类
监听器分类 | 监听器名称 | 作用 |
---|---|---|
ServletContext监听 | ServletContextListener | 用于对ServletContext对象进行监听(创建、销毁) |
ServletContextAttributeListener | 对ServletContext对象中属性的监听(增删改属性) | |
Session监听 | HttpSessionListener | 对Session对象的整体状态的监听(创建、销毁) |
HttpSessionAttributeListener | 对Session对象中的属性监听(增删改属性) | |
HttpSessionBindingListener | 监听对象于Session的绑定和解除对Session数据的钝化和活化的监听 | |
HttpSessionActivationListener | 对Request对象进行监听(创建、销毁) | |
Request监听 | ServletRequestListener | 对Request对象中属性的监听(增删改属性) |
ServletRequestAttributeListener |
这里面只有 ServletContextListener
这个监听器后期我们会接触到,ServletContextListener
是用来监听 ServletContext
对象的创建和销毁。
ServletContextListener
接口中有以下两个方法:
void contextInitialized(ServletContextEvent sce)
:ServletContext
对象被创建了会自动执行的方法void contextDestroyed(ServletContextEvent sce)
:ServletContext
对象被销毁时会自动执行的方法
快速入门
演示一下 ServletContextListener
监听器
- 定义一个类,实现
ServletContextListener
接口 - 重写所有的抽象方法
- 使用
@WebListener
进行配置
代码如下:
@WebListener
public class ContextLoaderListener implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent sce) {
//加载资源
System.out.println("ContextLoaderListener...");
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
//释放资源
}
}
启动服务器,可以在启动的日志信息中看到 contextInitialized()
方法输出的内容,同时也说明了 ServletContext
对象在服务器启动的时候被创建了。