JavaWeb知识回顾及查漏补缺
基本概念
JavaWeb是指所有通过Java语言编写的,可以通过浏览器访问的程序的总称;
JavaWeb是基于请求和响应来开发的;
什么是请求
请求是指客户端给服务器发送数据
什么是响应
响应是指服务器给客户端回传数据
请求和响应的关系
请求和响应是成对出现的,有请求就有响应
Tomcat
安装目录详解
- bin:用来存放Tomcat服务器的可执行程序
- conf:用来存放Tomcat服务器的配置文件
- lib:用来存放Tomcat服务器的jar包
- logs:用来存放Tomcat服务器运行时输出的日志信息
- temp:用来存放Tomcat运行时产生的临时数据
- webapps:用来存放部署的web工程
- work:是Tomcat工作时的目录,用来存放Tomcat运行时jsp翻译为servlet的源码,和session钝化的目录
Servlet
基本概念
- Servlet是JavaEE规范之一,是一个接口
- Servlet是Javaweb三大组件之一,三大组件分别是:Servlet程序,Filter过滤器,Listener监听器
- Servlet是运行在服务器上的一个Java程序,它可以接受客户端发送过来的请求,并响应数据给客户端
访问地址配置
-
xml方式:在web.xml中配置
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18<web-app>
<!-- servlet标签给Tomcat配置servlet程序 -->
<servlet>
<!-- 给servlet程序起唯一标志名 -->
<servlet-name>CustomServlet</servlet-name>
<!-- servlet程序类的全路径 -->
<servlet-class>com.zhuweitung.javaweb.custom.CustomServlet</servlet-class>
</servlet>
<!-- 给servlet程序配置访问地址 -->
<servlet-mapping>
<!-- 关联上面的唯一标志名 -->
<servlet-name>CustomServlet</servlet-name>
<!-- 配置访问地址 -->
<url-pattern>/custom</url-pattern>
</servlet-mapping>
</web-app> -
注解方式:在Servlet实现类上添加
@WebServlet
注解,value属性为访问路径1
2
3@WebServlet(name = "CustomServlet", value = "/custom")
public class CustomServlet implements Servlet {
}
生命周期
- 执行Servlet构造器方法:若没有配置自动加载,在第一次请求servlet时调用
- 执行init初始化方法:若没有配置自动加载,在第一次请求servlet时调用
- 执行service方法
- 执行destroy销毁方法
继承体系
-
Servlet:接口,只负责定义Servlet程序的规范
-
ServletConfig:Servlet程序的配置信息类
- 获取Servlet程序唯一标识名
- 获取初始化参数 getInitParameter
- 获取ServletContext对象
-
GenericServlet:抽象类,做了一些空实现,并持有一个ServletConfig类的引用
-
ServletContext:接口,表示Servlet的上下文,一个web工程只有一个ServletContext对象实例(是一个域对象),在工程启动时创建,工程停止时销毁
-
获取web.xml中配置的上下文参数 context-param
1
2
3
4<context-param>
<param-name>jdbcUrl</param-name>
<param-value>jdbc:mysql://localhost:3306/tmp</param-value>
</context-param>1
String jdbcUrl = ctx.getInitParameter("jdbcUrl");
-
获取当前工程路径(发布名)
1
String contextPath = ctx.getContextPath();
-
获取工程部署后再服务器上的绝对路径
1
String realPath = ctx.getRealPath("/");
-
像Map类一样存取数据,setAttribute、getAttribute、removeAttribute
-
-
HttpServlet:抽象类,实现了service方法,并实现了请求的分发处理
-
继承HttpServlet的类根据需要实现doGet和doPost方法
HTTP协议
请求的HTTP协议格式
GET请求报文示例:
1 |
|
POST请求报文示例:
1 |
|
报文格式
-
请求行
- 请求方式:POST/GET
- 请求的资源路径[?请求参数],如 /custom?id=1
- 请求的协议的版本号,如 HTTP/1.1
-
请求头:键值对形式,常见键如下
- Accept:告诉服务器,客户端可以接收的数据类型
- Accept-Encoding:告诉服务器,客户端可以接收的数据编码格式
- Accept-Language:告诉服务器,客户端可以接收的语言类型
- User-Agent:浏览器信息
- Host:请求的服务器ip端口或域名
- Connection:告诉服务器请求连接如何处理
- keep-alive:回传数据不要马上关闭,保持一小段时间的连接
- closed:马上关闭
- Cache-Control:表示如何控制缓存,no-cache表示不缓存
- Cookie
- Referer:请求发起时浏览器地址栏中的地址(请求来源)
- Content-Type:表示发送的数据的类型,格式为 type/subtype;parameter;
- application/x-www-form-urlencoded:提交的数据格式为 name=value&name=value,然后对其进行url编码
- multipart/form-data:表示以多段的形式提交数据给服务器(以流的形式提交,用于上传)
- application/json:提交的数据以json形式传输,会将数据序列化为json字符串放进请求体中
- Content-Length:表示请求体的长度
-
空行,这个空行属于请求头
-
请求体:发送给服务器的数据,若没有数据也是空行
响应的HTTP协议格式
报文示例:
1 |
|
报文格式
- 响应行
- 协议和版本号,如 HTTP/1.1
- 响应状态码,如 200
- 响应状态描述符。如 OK
- 响应头:键值对形式,常见键如下
- Date:响应时间
- Content-Type:表示响应数据的类型,格式为 type/subtype;parameter;
- Content-Length:响应体的长度
- 空行,这个空行属于响应头
- 响应体
常见响应码
- 200:请求成功
- 302:重定向
- 404:服务器收到请求,但是请求的资源不存在
- 500:服务器收到请求,但是服务器内部错误(代码错误)
HttpServlet
HttpServletRequest
继承ServletRequest接口
作用
当有请求进入tomcat服务器时,tomcat服务器就会把请求过来的http协议信息解析好封装到request对象中;
然后传递到Servlet的service方法中;
通过HttpServletRequest对象可以获取到所有请求的信息;
常用方法
- getRequestURI:获取请求的资源路径
- getRequestURL:获取请求的统一资源定位符(绝对路径)
- getRemoteHost:客户端的ip地址
- getHeader:获取请求头
- getParameter:获取请求参数
- getParameterValues:获取请求参数,多值
- getMethod:获取请求方式,POST/GET
- setAttribute:设置属性
- getAttribute:获取属性
- removeAttribute:移除属性
乱码问题解决
1 |
|
请求转发
1 |
|
特点:
- 地址栏不发生变化
- 只有一次请求
- 转发地址中不需要加上下文地址
- 请求域中的数据不会丢失
- 是服务端行为
- 不能访问工程以外的资源
HttpServletResponse
继承ServletResponse接口
作用
通过HttpServletResponse对象来设置需要响应给客户端的数据
输出流
- 字节流:响应二进制数据,常用于下载
- 字符流:响应字符数据
一个响应同时只能使用一个流
乱码问题解决
1 |
|
请求重定向
1 |
|
特点:
- 地址栏中地址变为重定向后的地址
- 请求两次(客户端第一次请求后响应
302
状态,再请求重定向地址) - 重定向地址中需要加上下文地址以保证路径的正确
- 请求域中的数据丢失
- 是客户端行为
JSP
基本概念
JSP全称为 Java server pages;
JSP的主要作用是代替servlet程序回传html页面的数据;
本质
JSP页面本质上是一个servlet程序;
当第一次访问JSP页面的时候,tomcat服务器会把JSP页面翻译为一个Java源文件(.java文件),并将它编译为字节码文件(.class文件);具体的文件可以在tomcat的work目录下查看到;
index.jsp翻译的Java源文件示例:
1 |
|
其中HttpJspBase类继承自HttpServlet类
语法
page指令
page指令可以修改JSP页面中一些重要的属性或者行为
1 |
|
- contentType:响应数据类型,是 response.setContentType() 方法的参数值
- pageEncoding:JSP页面本身字符集
- language:JSP翻译后的文件格式,暂时只支持Java
- import:导入包、类
- autoFlush:设置输出流缓冲区满了之后,是否自动刷新缓冲区,默认为true
- buffer:设置输出流缓冲区大小,默认8kb
- errorPage:设置当前JSP页面出错时,自动跳转去的错误页面路径
- isErrorPage:设置当前JSP页面是否错误信息页面,默认是false,若为true可以获取异常信息
- session:设置当前JSP页面是否会创建HttpSession对象,默认是ture
- extends:设置JSP页面翻译出来的Java类默认继承的类
常用脚本
-
声明脚本:<%!%>,其中写的内容将来会直接翻译在Servlet类中,可以声明类、方法、属性、全局变量
-
代码脚本:<%%>
-
代码脚本会被翻译在_jspService方法中
-
可以使用声明中的局部变量或者方法以及_jspService方法中能访问的对象
-
可以和表达式脚本组合使用
1
2
3
4
5
6
7<ul>
<%for (User user : users) {%>
<li>
<%=user.name%>,<%=user.age%>
</li>
<%}%>
</ul>
-
-
表达式脚本:<%=%>,将已经声明的变量或者表达式输出到网页上
- 所有表达式脚本都会被翻译到_jspService方法中
- 表达式脚本都会被翻译成为out.write()输出到页面上
- 表达式脚本中可以使用_jspService方法中能访问的对象
- 表达式脚本中的表达式不能以分号结束
内置对象
- request:HttpServletRequest,请求对象
- response:HttpServletResponse,响应对象
- pageContext:PageContext,上下文对象
- session:HttpSession,会话对象
- application:ServletContext对象
- config:ServletConfig对象
- out:JspWriter,输出流对象
- page:Object,指向当前jsp的对象
- exception:Throwable,异常对象,isErrorPage开启后才有
域对象
内置对象中request、pageContext、session、application为域对象
四大域对象都可以像Map一样存取数据,功能一样,但对数据的存取范围不一样
-
pageContext:jsp页面范围内
-
request:一次请求内
-
session:一个会话内
-
application:整个工程范围内(只要web工程不停止,数据都在)
response与out对象
这两个对象都可以向页面输出内容,并且各自持有一个缓冲区
当jsp页面代码执行完成后会依次执行
-
执行out.flush()操作,会把out缓冲区中的数据追加写入到response缓冲区
-
会执行response的刷新操作,把全部数据写给客户端
所以当out没有手动调用out.flush()方法时,它输出的内容都在response输出内容的后面
常用标签
静态包含
语法:
1 |
|
特点
- 不会翻译被包含的jsp页面
- 静态包含其实是把被包含的jsp页面的代码拷贝到包含的位置执行输出
动态包含
语法:
1 |
|
特点:
-
会将被包含的jsp页面也翻译为Java代码
-
底层使用如下代码实现
1
org.apache.jasper.runtime.JspRuntimeLibrary.include(request, response, "header2.jsp", out, false);
转发标签
语法:
1 |
|
Listener监听器
作用是监听变化,然后通过回调函数反馈给程序去做一些处理
ServletContextListener
ServletContextListener对象可以监听ServletContext对象的创建和销毁
接口包含方法
- contextInitialized:在ServletContext对象创建之后马上调用,做初始化
- contextDestroyed:在ServletContext对象对象销毁之后调用
使用方式
-
编写一个类去实现ServletContextListener接口,并实现需要的方法
-
在实现类上加上
@WebListener
注解或者在web.xml中加上以下内容1
2
3<listener>
<listener-class>com.zhuweitung.javaweb.listener.WebServletContextListener</listener-class>
</listener>
EL表达式
EL表达式主要是代替jsp页面中表达式脚本在jsp页面中进行数据的输出;
主要是输出域对象中的数据;
若四个域中都存入了相同key的数据,则按pageContext>request>session>application的顺序取,找到就输出;
隐含对象
变量 | 类型 | 作用 |
---|---|---|
pageContext | PageContextImpl | 可以获取jsp中的九大内置对象 |
pageScope | Map<String, Object> | 可以获取pageContext域中的数据 |
requestScope | Map<String, Object> | 可以获取request域中的数据 |
sessionScope | Map<String, Object> | 可以获取session域中的数据 |
applicationScope | Map<String, Object> | 可以获取application域中的数据 |
param | Map<String, String> | 可以获取请求参数的值 |
paramValues | Map<String, String[]> | 可以获取请求参数的值,值为数组 |
header | Map<String, String> | 可以获取请求头的信息 |
headerValues | Map<String, String[]> | 可以获取请求头的信息,值为数组 |
cookie | Map<String, Cookie> | 可以获取当前请求的Cookie信息 |
initParam | Map<String, String> | 可以获取在web.xml中配置的上下文参数 |
JSTL标签库
标签库为了替代代码脚本,可以使整个页面变得更加简洁
功能范围 | URI | 前缀 |
---|---|---|
核心标签库 | http://java.sun.com/jsp/jstl/core | c |
格式化 | http://java.sun.com/jsp/jstl/fmt | fmt |
函数 | http://java.sun.com/jsp/jstl/functions | fn |
数据库(不使用) | http://java.sun.com/jsp/jstl/sql | sql |
XML(不使用) | http://java.sun.com/jsp/jstl/xml | x |
使用方式
-
导入依赖(引入jar包)
-
页面引入
1 |
|
核心标签库常用标签
标签 | 作用 | 示例 |
---|---|---|
c:set | 往域中保存数据 | <c:set scope=“page” var=“key” value=“value”/> |
c:if | 做if判断 | <c:if test=“${ true or false }”></c:if> |
c:choose c:when c:otherwise | 做多路判断 | <c:choose><c:when test=${confition}></c:when><c:otherwise></c:otherwis></c:choose> |
c:forEach | 遍历输出 | <c:forEach items=“${list}” var=“item” varStatus=“status”>${item.name}</c:forEach> |
文件上传
上传报文解析
Servlet处理
思路就是从request中获取字节输入流,然后将输入流数据写入到输出流,保存到服务器;
常规开发可以使用现有工具类;
示例代码:
1 |
|
文件下载
示例代码:
1 |
|
Cookie
Cookie是服务器通知客户端保存键值对数据的一种技术;
客户端有了Cookie后,每次请求都发送给服务器;
每个Cookie的大小不能超过4kb;
Cookie的创建
1 |
|
浏览器收到的响应头中包含Set-Cookie
属性
服务器获取客户端的Cookie
1 |
|
修改Cookie
方式一
服务器重新创建一个同名Cookie
方式二
从request中获取需要修改的Cookie,调用 setValue() 方法设置新值
1 |
|
生命周期控制
通过 setMaxAge() 方法来设置Cookie最大生存时间,以秒为单位
- 正数:表示cookie在经过该秒数后过期
- 负数:表示cookie不会被持久存储,在浏览器退出时删除,也就是session级别的cookie
- 0:删除cookie
Path属性
path属性可以有效的过滤哪些cookie可以发送给服务器;
path属性是通过请求的地址来进行有效的过滤;
Session
Session是一个接口,HttpSession是它的实现类;
用来维护一个客户端和服务器之间关联的一种技术;
每个客户端都有自己的一个session;
每个session都有一个唯一的标识;
1 |
|
jsp页面可以从session域中获取已设置的值
生命周期控制
通过 setMaxInactiveInterval() 方法来设置Session超时时间,以秒为单位,默认为30分钟;
- 正数表示设定session超时时长
- 负数表示永不超时
通过 invalidate() 方法立即销毁session;
可以通过修改tomcat配置文件中的web.xml或者工程的web.xml文件来更改默认超时时长;
1 |
|
session的超时指的是,客户端两次请求的最大间隔时长;
浏览器与Session关联的原理
浏览器请求服务器后,服务器创建session(存储在内存中),并创建一个cookie对象,这个cookie对象的key值永远为JSESSIONID
,value值为新创建的session的id;
服务器再把cookie信息通过响应发给客户端;
客户端有了cookie后,每次请求都会吧session的id以cookie的形式发给服务器;
服务器通过session的id在内存中查找对应的session对象;
Filter过滤器
作用是拦截请求,过滤响应
拦截请求常见场景
- 权限检查
- 日志记录
- 事务管理
使用方式
-
编写一个类去实现Filter接口,并实现需要的方法
-
在实现类上加上
@WebFilter
注解或者在web.xml中加上以下内容1
2
3
4
5
6
7
8
9
10<!-- 配置拦截器 -->
<filter>
<filter-name>AdminFilter</filter-name>
<filter-class>com.zhuweitung.javaweb.filter.AdminFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>AdminFilter</filter-name>
<!-- 拦截资源路径的匹配规则 -->
<url-pattern>/admin/*</url-pattern>
</filter-mapping>
注意事项
若开发使用4.x以上版本的serlvet-api,而tomcat的serlvet-api的版本是3.x,需要重写Filter的init方法和destroy方法;
因为4.x后这两个方法有default关键字修饰,而3.x版本没有;
生命周期
- 构造器
- init初始化方法,在工程启动后执行
- doFilter方法,每次拦截到请求就会执行
- destroy方法,停止工程就会执行
FilterConfig
用于获取filter过滤器的配置内容
- getFilterName():获取过滤器名称
- getServletContext():获取上下文
- getInitParameter(String name):获取初始化参数
- getInitParameterNames():获取初始化参数,Enumeration<String>格式
FilterChain
作用是执行下一个过滤器,直到没有过滤器为止,再返回请求资源;
所有filter和目标资源默认都执行在同一个线程中;
所有filter都使用同一个request对象;
执行顺序
- 若使用web.xml方式配置过滤器,则按照xml中配置的顺序执行
- 若使用@WebFilter 注解方式配置,按过滤器名称自然排序
拦截路径匹配模式
- 精确匹配,如 /module/index.jsp
- 目录匹配,如 /module/*
- 后缀名匹配,如 *.htm
过滤器不检测资源是否存在,且匹配模式不能混合使用
其他用法
- 使用过滤器+ThreadLocal可以实现全局事务提交和回滚
- 过滤器和请求的资源在同一个线程,将业务中的jdbc连接存储在ThreadLocal,用过滤器捕获全局异常
- 当过滤器没有捕获异常时,获取当前线程的jdbc连接并提交事务
- 出现异常时,获取当前线程的jdbc连接并回滚事务