抗锯齿、材质与可视距离为超高,其它全部非常低
1.Http协议
1.定义
http协议:客户端浏览器和web服务器通讯格式的规范
2.协议内容
1.请求头和响应头
请求头和响应头是键值对
请求头:
Accept: 浏览器告诉服务器返回的数据格式
Accept-Encoding: 浏览器告诉服务器返回数据的压缩格式
Cache-Control: 是否缓存数据
Connection: 保持连接
Cookie:
Host: 访问的主机
响应头:
Server: nginx 告诉浏览器,服务器使用的nginx
Date: 返回时间
Content-Type: 浏览器返回类型
Location: 表示新资源的地址,配合重定向使用,不单独使用
Refresh: 延迟一定时间后刷新资源
Status: 指定返回响应的响应状态码
Content-Disposition:选择是打开页面还是下载内容
2.请求体和响应体
请求体和响应体是传输的数据
响应体:保存了服务器返回给浏览器的数据,使用响应输出流写数据
3.请求行
GET /day06/html/user/login?username=cj3048&pwd=2222 HTTP/1.1
http协议版本:(https是http的加密版)
http1.0:一次连接只能发送一次请求
http1.1:一次连接可以发送多次请求
2.Http对象
1.HttpServletResponse对象
1.常见方法
setHeader(String name, String value): 设置响应头,同时可以设置响应码
setStatus(int code): 设置响应状态码
sendError(int code): 设置错误的响应吗
setContentType(String type): 设置响应体返回类型
sendRedirect(String url): 重定向
3.Servlet
1.servlet映射路径
模糊匹配 : 用户访问的地址与servlet的映射关系是多对一的
1) /* 所有的地址都可以访问到指定的servlet
2) /user/* 以/user/开头的地址可以访问到指定的servlet
3) *.do 以.do结尾的地址可以访问到指定的servlet
注意:
1. 如果使用前面模糊,*前不能使用/
2. 当输入一个地址同时匹配上精确匹配和模糊匹配,这时精确匹配生效(精确匹配优先级高)
3. 在日常给servlet配置地址的时候,基本上使用精确匹配,我们配置过滤器的时候一般用模糊匹配
2.servlet缺省路径
当我们输入/的时候,会自动访问index.jsp,什么原因?
1. 当我们输入/的时候,缺省的servlet会生效
Web服务器(tomcat)自带一个servlet,名为DefaultServlet,配置的url就是/
<servlet>
<servlet-name>default</servlet-name>
<servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class>
<init-param>
<param-name>debug</param-name>
<param-value>0</param-value>
</init-param>
<init-param>
<param-name>listings</param-name>
<param-value>false</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
2. 缺省的servlet执行后,返回哪个资源?
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
缺省servlet匹配上请求后,会返回欢迎页面,也就是tomcat的web.xml文件中定义的welcome-file-list标签中的内容.
欢迎页面列表中定义了多个页面,缺省servlet会按顺序查找对应的页面,找到后返回页面停止查找,没有找到继续查找,如果都没找到返回404.
3. 如果自己项目的欢迎页面不是index,我们可以修改tomcat的web.xml文件,将欢迎页面改为自己的页面即可.
但是tomcat下的web.xml文件是全局配置文件,针对于web服务器下所有的项目都会生效,所以修改后,其他项目的欢迎页面就会发生改变.
4. 一般修改欢迎页面我们采用的方式是修改自己项目的web.xml中的配置信息,这样只会影响当前项目.
5. Web服务器加载配置文件的顺序是,先加载服务器的配置文件,再加载项目的配置文件,如果配置信息出现冲突,项目的web.xml文件会覆盖tomcat的web.xml文件(只覆盖冲突的信息)
6. 如果我们自己的servlet的url配置为/,缺省servlet将失效.
3.servlet生命周期
1.构造方法 web容器启动后,用户第一次访问servlet的时候执行 执行一次
2.init方法 构造方法后立即执行 执行一次
3.doXX方法 用户访问一次执行一次 执行N次
4.destroy方法 web容器关闭或者重启 执行一次
通过servlet的生命周期是发现servlet是单例多线程的;
servlet创建对象类似于单例模式的懒汉模式
4.servlet的自动加载-启动时机
Servlet对象的创建延迟到用户第一次访问的时候,能否将对象的创建提前至容器启动的时候?
1. 在配置servlet的时候,可以在servlet标签中添加如下代码:
<load-on-startup>1</load-on-startup>,servlet就会随着容器的启动而创建对象
2. <load-on-startup>中可以指定一个正整数,代表servlet创建对象的优先级,数字越小优先级越高,先创建对象
如果不知道配置哪个数字,就指定1.
3. 通过这个案例我们发现这种模式下的servlet类似于单例的饿汉模式.
5.Servlet的多线程并发问题
我们发现servlet是单例多线程的,是否会出现线程安全问题?
1. 线程安全问题出现的根本原因在于: 在多线程环境下出现并发写的问题
2. Servlet在设计之初已经考虑到线程安全问题,正常情况下是线程安全的.
3. 如果在servlet中定义了成员变量.在doxxx方法中出现了并发写成员变量的情况,可能会出现线程安全问题
4. 解决办法:
1) 避免出现在servlet中定义成员变量
2) 另外可以使用同步锁
4.ServletContext对象
1.介绍
ServletContext对象全局只有一个,通过它可以取到servlet的各种信息
2.对象的创建和获取
创建:有Web容器创建,当项目启动时创建
获取: 1.req.getServletContext() 通过请求对象获取
2.config.getServletContext() 通过config对象获取
3.核心API
1.域对象相关
req.setAttribute(key, value): 添加值
req.getAttribute(key): 通过key获取值
req.removeAttribute(key): 删除
2.全局初始化参数相关:
1) getInitParameter(String name) : 获取全局初始化参数
2) getInitParameterNames() : 获取所有全局初始化参数名称集合
3. 读取资源相关:
1) String getRealPath(String path) : 根据相对路径获取绝对路径,这里的相对路径是指out目录下的,从 "/WEB-INF/classes/"开始;可以结合
类名.class.getClassLoader使用,这个方法的作用是直接获取路径到classes下
2) InputStream getResourcesAsStream(String path) : 根据相对路径读取资源返回字节输入流
4. 转发:
1) getRequestDispatcher(String path).forward(request,response) : 转发资源
4.域对象作用域
ServletContext:全局级别作用域,一个项目只有一个ServletContext
Request:请求级别作用域
5.转发和重定向
请求转发:req.getRequestDispatcher("路径").forward(req,resp)
1.转发可以访问项目内部的静态和动态资源
2.不能访问项目外部的资源
转发和重定向的区别:
路径问题:转发不需要写根路径,重定向相当于重新发起一次请求,需要写完整的路径
1.转发只能访问项目内部的资源,重定向可以访问项目外部的资源
2.转发的发起者是Request对象,重定向是Response对象
3.转发发起1次请求,重定向发起2次
4.转发地址栏不发生改变,重定向地址栏发生改变
5.Cookie技术
1.特点
Cookie是将会话数据保存在客户端的技术
1.不能直接保存中文
2.数据明码保存
3.数量有限制
4.大小不能超过4k
2.Cookie创建和存活时间
Cookie是一个对象,保存的数据时键值对格式
Cookie cookie = new Cookie(String key, String Value)
使用响应将cookie对象发送给浏览器
Response.addCookie(cookie)
通过请求对象获取cookie对象
Cookie[] cookies = Request.getCookie()
cookie的保存时间:
1.默认情况下:
cookie是客户端存储技术,服务器重启不会影响cookie;
浏览器关闭,cookie失效
2.设置cookie的存活时间:cookie.setMaxAge(秒)
正整数,代表cookie脱离浏览器内存,cookie的存活时间与浏览器无关,不受浏览器关闭的影响;
负整数(源码中默认为-1),代表cookie保存在浏览器内存中,浏览器关闭,cookie销毁;
零:可以间接的实现cookie的删除,具体做法就是设置一个与要删除的cookie同名的新cookie,设置存活时间为零.也有的cookie会被覆盖,新cookie的存活时间为零,立即销毁
浏览器会携带什么样的cookie发送给服务端程序:
1) 浏览器访问服务器的时候,会检查本地保存的cookie信息,查看cookie的domain属性是否 与服务器主机一致,一致就会携带,不一致就不携带
2) 同一个项目中不同的资源访问到的cookie也不一致,是由cookie的path属性决定,访问的 资源与path路径一致才能看到cookie
3.Cookie原理
1.cookie对象如何发送到浏览器?
当我们使用Response.addCookie(cookie)后,实际上是使用Set-Cookie的响应头将 cookie信息发送给浏览器
2.浏览器如何知道服务端什么时候需要什么样的cookie?
浏览器并不知道,浏览器在访问服务端程序的时候,总会携带符合条件的cookie给服务端程序
3. 浏览器如何将cookie发送给服务端程序的?
浏览器借助请求头Cookie,将符合条件的cookie信息发送给服务端程序
6.session技术
1.特点
cookie有很多缺陷,不能保存中文,不能直接存对象,明码保存不安全
服务端存储技术:session,session对象由web服务器创建
2.技术核心
1.session对象的创建
session对象由web服务器创建
2.session对象的获取
request.getSession(): 获取session对象;如果客户端没有分配对象,web服务器就会创建一个新的session对象返回;如果客户端已经分配了session对象,web服务器就会返回一个已经绑定的session对象
request.getSession(true)等效于request.getSession()
request.getSession(false):如果客户端没有分配session,返回null;如果已经分配,返回分配对象
3.session对象的销毁:
session.invalidate(): 销毁session
4.设置某个session的存活时间,单位是秒
session.setMaxInactiveInterval(时间): 不是时间到了就销毁了,而是失去活动的时间超过定义的时间,就会销毁;如果用户一直处于活动状态,就不会销毁
修改自己项目所有session的超时时间,在web.xml中
<session-config>
<session-timeout>120</session-timeout>
<session-config>
3.原理
1.存活时间:打开浏览器访问网站第一哥资源,直到关闭浏览器结束;
2.在session的作用范围内,多次获取session是同一个对象
3.session对象可以与浏览器绑定,session对象可以区分不同的浏览器
4.req.getsession()相当于在cookie中保存了一个名称为JSESSIONID的cookie
7.Jsp
1.三个编译指令(了解)
1.包含另一个页面
<%@ include file="文件路径" %>
2.page指令
语法:<%@ page 属性值1="值1" 属性值2="值2"... %>
2.九大内置对象(重点)
1.PageContext
2.HttpServletRequest
3.HttpSession
4.ServletContext
5.HttpServletResponse
6.ServletConfig
7.JspWriter
8.Object
9.Exception
8.EL表达式和c标签
1.EL表达式
${}
2.c标签
1.导入两个jar包
standard.jar
jstl.jar
2.引入标签
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
9.分页
1.总记录数--totalNum
2.总页数--totalPage
3.当前页码--currentPage
4.每页显示数--pageSize
5.当前页数据集合--list<T>
10.Filter–过滤器
1.生命周期
1.构造方法 tomcat容器启动时
2.init方法 构造方法执行之后
3.doFilter方法 放行方法;servlet执行时
4.destroy方法 tomcat容器关闭时
2.多个filter执行顺序
1.web.xml中配置
同时拦截一个servlet时,先配置的先执行
2.使用注解配置
根据name排序,在前面的先执行
3.转发和重定向拦截
1.dispatcher标签配置
REQUEST: 转发和重定向不拦截(默认值)
例如:servlet1设置不拦截,servlet2设置拦截
如果在servlet1中转发到servlet2,则servlet2不执行拦截器;
如果在servlet1中重定向到servlet2,则servlet2执行拦截器;
FORWORD: 转发地址拦截
例如:servlet1设置不拦截,servlet2设置拦截
如果在servlet1中转发到servlet2,servlet2会执行拦截器
以上两个一起用,则有拦截器的会全部拦截
ERROR: 当资源出错了,才会拦截
11.监听器
1.创建时期
tomcat容器启动时,第一个创建(比ServletComtext对象和过滤器对象都要早)
2.分类
1.域对象监听器
都是监听域对象的创建和销毁
ServletContextListener
HttpSessionListener : 其中sessionDestroyed()方法,在浏览器关闭时不会触发,session有个默认的存活时间,时间到了才会关闭
ServletRequestListener
2.属性监听器
监听setattribute的变化
ServletContextAttributeListener
HttpSessionAttributeListener
ServletRequestAttributeListener
3.实体类监听器
写在实体类中
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Student implements HttpSessionBindingListener {
private String name;
private Integer age;
@Override
public void valueBound(HttpSessionBindingEvent event) {
System.out.println("student对象已经放进session中");
}
@Override
public void valueUnbound(HttpSessionBindingEvent event) {
System.out.println("student对象已经从session中移除");
}
}
3.小案例
1.在servletcontext域对象中保存一个List<String>集合
2.在context对象创建完成后,添加一个空的集合
3.当session中添加登录信息时,将账户保存进list集合
4.当session中删除登陆信息时,将list中的账户删除
5.当session被销毁时,将list中的账户删除
12.数据库连接池
1.概念
一个空间中保存多个数据库连接,这些链接是共享的,线程需要链接就从池子获取连接,使用后再将链接归还给池子;
平时使用jdbc连接数据库,需要自己创建链接对象.使用数据库连接池,只需要向链接池要即可获取链接,无需自己创建;
数据库连接池应该具有的功能:
1.链接池对象创建完成后初始化一些数据库链接供使用
2.当空余链接没有时,根据设置在创建一些新的链接
3.当池子中链接数量达到极限,再有线程需要链接就需要等待,需要设置等待时间
4.需提供最大等待次数
5.空余链接较多,需要销毁一些链接
2.使用
1.DBCP连接池
jar包
• Commons-dbcp.jar:连接池的实现
• Commons-pool.jar:连接池实现的依赖库
连接方式
// 加载prop配置文件
Properties prop = new Properties();
// 获取文件流
InputStream inStream = App_DBCP.class.getResourceAsStream("db.properties");
// 加载属性配置文件
prop.load(inStream);
// 根据prop配置,直接创建数据源对象
DataSource dataSouce = BasicDataSourceFactory.createDataSource(prop);
// 获取连接
Connection con = dataSouce.getConnection();
db.properties
url=jdbc:mysql://localhost:3306/...
driverClassName=com.mysql.cj.jdbc.Driver
username=root
password=123456
initialSize=3
maxActive=6
maxIdle=3000
2.C3P0
jar
c3p0-0.9.1.2.jar
连接方式
// 创建c3p0连接池核心工具类
// 自动加载src下c3p0的配置文件【c3p0-config.xml】
ComboPooledDataSource dataSource = new ComboPooledDataSource();// 使用默认的配置
// 获取连接
Connection con = dataSource.getConnection();
c3p0-config.xml
<c3p0-config>
<default-config>
<property name="jdbcUrl">jdbc:mysql://localhost:3306/zz2205?useUnicode=true&characterEncoding=UTF-8&useSSL=true&serverTimezone=UTC
</property>
<property name="driverClass">com.mysql.cj.jdbc.Driver</property>
<property name="user">root</property>
<property name="password">123456</property>
<property name="initialPoolSize">3</property>
<property name="maxPoolSize">6</property>
<property name="maxIdleTime">1000</property>
</default-config>
</c3p0-config>
3.druid
jar
druid-1.2.3.jar
连接方式
InputStream is = App1.class.getClassLoader().getResourceAsStream("druid.properties");
Properties properties = new Properties();
properties.load(is);
DataSource ds = DruidDataSourceFactory.createDataSource(properties);
// 2.获取数据库链接
Connection conn = ds.getConnection();
druid.properties
driverClassName=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/zz2205?useUnicode=true&characterEncoding=UTF-8&useSSL=true&serverTimezone=UTC
username=root
password=root
13.Ajax
1.原始的Ajax
var ajax = createAjax() //创建Ajax对象
var method = 'get' //提交方式
var url = 'http://localhost:3306/servlet' //请求的路径
ajax.open(method, url) //提交
// 使用post请求的时候,需要设置一下请求头
ajax.setRequestHeader("content-type","application/x-www-form-urlencoded");
var sendData = null //提交的参数,get在url中传递
ajax.send(sendData) //提交参数
//ajax对象的状态,0-1-2-3-4,每当状态发生变动,就会触发这个事件
//0---Ajax对象创建完成
//1---调用open方法
//2---调用send方法
//3---服务端已经处理完成,正在返回的路上
//4---响应到达浏览器
ajax.onreadystatechange = function(){
//状态为4表示响应返回
if(ajax.readyState == 4){
//响应状态码为200,表示成功
if(ajax.status == 200){
ajax.responseText //读取响应的内容
//如果是集合 JSON.parse(ajax.responseText) 转成数组
}
}
};
function createAjax(){
let ajax = null;
try{
ajax = new XMLHttpRequest();
}catch(e){
new ActiveXObject("microsoft.xmlhttp")
}
}
2.jQueryAjxa
各种参数说明
url: 请求路径
type:'post', 请求方式 默认是get
data: {"pname":pname,"typeid":typeid,"lprice":lprice,"hprice":hprice}, 规定要发送到服务器的数据类型
dataType:'json', 期望服务器返回的数据类型
async: 布尔值,表示请求是否异步处理。默认是 true
contentType: 发送数据到服务器时所使用的内容类型。默认是:"application/x-www-form-urlencoded"。
success:function(result){
成功函数
},
error:function(...){
失败函数
}
路径问题
tomcat中配置为 Application context: /day06
1.
<form action="/day06/login">
账号:<input type="text" name="username" id="username"><br>
密码:<input type="password" name="pwd" id="pwd"><br>
<input type="submit" value="登录">
</form>
浏览器默认补: localhost:8080
最终路径:localhost:8080/day06/login
<form action="/day06/day07/login">
web.xml中: /day07/login
最终路径:localhost:8080/day06/day07/login
2.
<form action="login">相当于<form action="/day06/html/user/login">
如果没有写"/",浏览器默认: localhost:8080/day06/html/user/login
也就是该html文件在webapps文件夹下的路径,加上login
最终路径:localhost:8080/day06/html/user/login
web.xml中需要写上 /html/user/login
3.
<form action="http://localhost:8080/day06/login">
最终路径:localhost:8080/day06/login
总结:
action中的是浏览器默认补 localhost:8080 + action中的地址; 注意:action写的时候,要默认加上tomcat中配置的后缀,
web.xml中写的是localhost:8080/day06 后面的;
2.最终解决
jsp中
"${pageContext.request.contextPath}/pages/login.jsp"
也可以在head里面加入一个标签,这个要求jsp中路径都是相对路径
<base href="${pageContext.request.contextPath}/"
href="pages/login.jsp"
servlet中
//转发,写绝对路径即可
req.getRequestDispatcher("/upload/images/猫.png").forward(req,resp);
//重定向 要加入tomcat的上下文路径
//原始:resp.sendRedirect("/day08/upload/images/mao.png");
resp.sendRedirect(req.getContextPath + "/upload/images/mao.png");