Service 常用知识
nginx 反向代理服务器
作用:
- 作为http服务器,例如网页静态服务器;
- 虚拟主机,在一台服务器虚拟出多个网站(域名不同,端口不同);
- 反向代理,负载均衡;
常用命令:
./nginx
启动
./nginx -s stop
关闭
./nginx -s quit
关闭
重启:
先关闭后启动;刷新配置文件;
./nginx -s reload
刷新配置
配置虚拟主机配置文件:
usr/local/nginx/conf/nginx.conf
//一个server节点就是一个虚拟主机;
server{
listen 80;
server_name localhost;
location/{
//html是nginx安装目录下的html目录;
root html-80;
index index.html index.htm;
}
}
反向代理:
反向代理服务器决定哪台服务器提供服务,与正向一样也是请求转发;
正向
: 用户->局域网->代理服务器,请求转发->internet;
反向
: 用户->internet->nginx反向代理服务器,请求转发->哪台服务器提供服务;
配置反向代理配置文件:
//server_name 可使用域名tomcat2;
server{
listen 80;
server_name localhost;
location/{
proxy_pass http://tomcat2
index index.html index.htm;
}
}
负载均衡
一个服务由多个服务器提供,需要将负载分配到不同的服务器处理;
配置负载均衡配置文件:
//与server同级,名称为proxy_pass对应;
upstream tomcat2{
server 192.168.1.1:8080;
server 192.168.1.2:8080 weight=2;
}
域名,端口,ip间的关系
域名: 就是网站,与ip关系是ip:域名->一对多
dns服务器: 将域名解析成ip地址,保存的就是域名和ip的映射关系;
一,二,三级域名,按照.
分隔,例如Jd.com
是一级域名;以此类推,加前缀则级数变多;
redis no-sql缓存
常用命令:
String: key-value
get-set
,incr-decr
可用于生成订单号,
Hash: key-map
Hset-Hget
用于对key进行归类;
List:
lpush list1 a b c d
push一个列表;
lrange list1 0 -1
查看一个列表,start end(-1表示所有)
lpop list1
将list1列表的最后加入的元素弹出;
rpop list1
将列表第一个加入的元素弹出;
del list1
删除列表;
Set:
sadd set1 a b c d
添加一个set集合;
smembers set1
查看一个set集合
srem set1 a
删除一个元素;
zset: 有顺序,不能重复;
zadd zset1 2 a 3 b 1 c 4 d
添加一个zset集合,元素|排序输入方式;
zrange zset1 0 -1
查看一个zset集合;
zrange zset1 0 -1 withscores
显示排序序号;
zrem zset1 a
移除一个元素;
zrevrange zset1 0 -1
逆序查看
expire: 设置过期时间
expire key second
设置key的存储时间
ttl key
查看key的过期时间
persist key
清除key的过期时间,持久化
redis使用加前缀
的方法的key进行分类:
一般将一个二维表保存到redis中:
ITEM_INFO:123456:BASE
- 表名是第一层
- 主键是第二层
- 字段名是第三层
freemarker 网页静态化
常用步骤:
- 创建一个
configuration
对象,直接new一个对象. - 设置模板文件所在的路径;
- 设置模板文件使用的字符集,
utf-8
; - 加载一个模板,创建一个模板对象
Template
; - 创建一个模板使用的数据集,一般是
Map
orpojo
; - 创建一个Writer对象,一般创建FileWriter对象,指定生成的文件名;
- 调用模板对象的process方法输出文件;
- 关闭流;
[图片上传失败...(image-656242-1546077311961)]
模板语法:
访问map中的key ${key}
访问pojo中的属性 ${pojoKey.propertyName}
访问集合中的数据
<#list studentList as stu>
${stu.id}/${stu.name}
<#list>
访问循环的下标
<#list studentList as stu>
${stu_index}
<#list>
控制流语句
<#list studentList as stu>
<#if stu_index % 2 ==0>
<@else>
<#if>
<#list>
日期类型格式化
当前日期${date?date}
,
当前时间${date?time}
,
当前日期和时间${date?datetime}
,
自定义日期格式${date?string("yyyyMM/dd HH:mm:ss")}
null值的处理
${myval!"myval为null"}
<#if myval?? >
Include
标签
<#include "模板名称.ftl">
sso 单点登录系统
登录流程:
- 登录页面表单提交;
- 登录成功后生成token,token相当于原来的jsessionid,字符串,可以使用uuid;
- 将用户信息保存到redis中,key就是token,value就是用户对象信息json;
- 使用string类型保存session信息,可以使用"前缀:token"为key;
- 设置key的过期时间,模拟session的过期时间,一般为半小时;
- 将token写入cookie中;
- cookie需要跨域(二级域名需要设置setDomain,setPath);
- 登录成功后,刷新生存期为最长;
跨域相关
问题: js不可以跨域请求数据;
跨域: 域名不同,域名相同端口不同;
解决跨域问题: jsonp
js特性绕过跨域请求,js可跨域加载js文件;
[图片上传失败...(image-385f16-1546077311961)]
服务端调用处 @RequestMapping(value="",produces=MediaType.APPLICATION_JSON_VALUE + ";charset=utf-8")
添加参数
@ResponseBodyString callback
,
返回String strResult = callback +"("+ JsonUtils.objectToJson(result) +")"
返回的类似mycall({id:1,name:a})
的字符串到调用的ajax处,由于js的特性,成为一个function语句,即success的回调;
解决跨域问题二: MappingJacksonValue spring4.1以上
- MappingJacksonValue mjv = new MappingJacksonValue(object);
- mjv.setJsonFunction(callback)
spring 拦截器
可以为每个接口做验证功能,如单点登录,手机端token验证;
实现HandlerInterceptor
接口,
preHandler : 执行handler之前执行方法,可再次判断单点登录;
postHandler : 执行handler之后返回ModelAndView之前,渲染视图之前;
afterCompletion : 返回ModelAndView之后执行,渲染视图完毕,相当于finally,执行异常处理,性能监控等;
运行流程:
1、拦截器执行顺序是按照Spring配置文件中定义的顺序而定的。
2、会先按照顺序执行所有拦截器的preHandle方法,一直遇到return false为止,比如第二个preHandle方法是return false,则第三个以及以后所有拦截器都不会执行。若都是return true,则按顺序加载完preHandle方法。
3、然后执行主方法(自己的controller接口),若中间抛出异常,则跟return false效果一致,不会继续执行postHandle,只会倒序执行afterCompletion方法。
4、在主方法执行完业务逻辑(页面还未渲染数据)时,按倒序执行postHandle方法。若第三个拦截器的preHandle方法return false,则会执行第二个和第一个的postHandle方法和afterCompletion(postHandle都执行完才会执行这个,也就是页面渲染完数据后,执行after进行清理工作)方法。(postHandle和afterCompletion都是倒序执行)
前端知识 html关键
input
form属性
action提交路径
method提交方式
input
标签类型:
- test : 文字
- password : 密码
- radio : 单选
- checkbox : 多选
- file : 文件
- submit : 提交
- reset : 重新设置
- button : 按钮
- image : 图片
- hidden : 隐藏
转义字符:
构成: &
#
;
emoji unicode码
> >
& &
前端知识 css关键
格式: 选择器[属性:值,属性:值]
html&css连接方式:
- 内联样式表: style属性直接设置;
- 内部样式表: head中style标签通过id,class,属性名等方式指定样式;
- 外部样式表: 新建css文件,head中link标签导入;
eg:
选择器:
- id选择器:
#
引入指定元素设置样式,#id1{ ... }
- class选择器:
.
引入一类元素设置样式,.class1{ ... }
- 元素选择器:
元素名
引入一种元素设置样式,div{ ... }
- 派生选择器:
- 属性选择器: 元素选择器特殊用法,
div[name="name1"]{ ... }
- 后代选择器: 在一个选择器的条件下找后代的选择器,设置样式;
div span{ ... }
- 属性选择器: 元素选择器特殊用法,
- 锚伪类选择器: 设置连接样式,
a:link{未访问连接样式},a:visited{已访问连接样式},a:hover{鼠标悬浮},a:action{选定连接}
常用style:
float: left,right,both,clear(设置元素两边允许有其他浮动元素)
display: none,bolck(块级,换行),inline(内联,不换行)
前端知识 js关键
定义: 直译式脚本语言,弱语言类型,基于事件驱动;
一般用于修改html,修改css样式,表单验证;
组成:
- EcmaScript 语法
- BOM 浏览器对象模型
- DOM 文档对象模型
html&js连接方式:
- js放在
script标签
中,可放在任何地方,可放在head标签中,一般放在body的后面; - 外部通过script的
src
导入,注意使用了src路径后,该标签体中的js代码不执行;
js操作css: document.getElementById("id").style.属性 = "..."
原始类型:
Undefined,Null,Boolean,Number,String
typeof 关键字判断;
引用类型:
- Array 数组; new Array(...); var arr = [...];
- push 压顶部,返回长度;
- pop 弹顶部,返回元素;
- shift 取底部,返回元素;
- unshift 放底部,返回长度;
- join 打印数组,默认,;
- concat 连接多个数组,返回;
- sort 排序;
- reverse 反转;
- String 伪对象; new String() 对象;String(s) 返回原始类型;
- Boolean 伪对象;
- Number 伪对象;
- Date
- RegExp 正则;
- 全局函数;
decodeURL
,parseInt
,eval(将普通字符串转换为js代码)
函数:
- 事件驱动函数:
function 函数名(参数){
函数体;
}
- 匿名函数:
var 函数名= function(参数){
函数体;
}
onload 函数,写在script中
onload = function(){
页面加载时运行的方法;
}
事件:
Dom event: onclick
,onsubmit="return 函数名()"
事件绑定,派发事件:
标签绑定事件
元素派发匿名事件
document.getElementById().onclick = function(参数){
函数体;
}
元素派发事件,按照函数名(这种的无参数列表);
document.getElementById().onclick = 函数名
BOM
- Dom Window 窗口;
- Dom Navigator 浏览器信息;
- Dom Screen 屏幕信息;
- Dom History 历史(上下一步)
- Dom Location 定位信息(地址栏)
window 可获取其他的四个对象参数;
window.location
window常用方法:
alert,confirm,prompt
弹框
setInterval()周期执行某个方法,setTimeout()延迟执行一次,clearInterva(id),clearTimeout(id)
window.open(URL,name,features,replace) window.close
打开或关闭;
window.location.href = "url"
window.location.href.reload()
获取或设置当前页面url;
window.history.back()
window.history.forward()
window.history.go(int)
回退和前进;
DOM
过程: 当流览器接受到html代码时,浏览器会将所有的代码装载到内存中,生成document树;包含文档节点``元素节点``属性节点``文本节点
获取节点:
- document.getElementById(id) 获取特定元素;
- document.getElementByTagName(标签) 通过标签名获取一种元素(多个)
- document.getElementByClassName(class属性的值)通过class属性获取一类元素(多个)
- document.getElementByName(name属性的值) 通过name属性获取一类的元素(多个)
jQuery ☕☕☕
格式: ${"选择器"} jQuery{"选择器"}
与原生js的转换:
//dom -> jquery
var obj = document.getElementById(id);
var $obj = ${obj};
$obj.val();
//jquery -> dom
var $obj = ${"#id"};
var obj1 = $obj.get(0);
var obj2 = $obj[0];
事件派发:
//onload 事件,可多次使用
$(function(){ ... })
$(document).ready(function(){ ... })
//普通事件,去除原生的`on`
$("选择器").click(function(){ ... })
jQuery选择器:
- 基本选择器:
- (".cls"),("[属性]");
- ("#id,.cls1")获取多个元素;
- $("#id").css("",""); 改变样式;
- 层次选择器:
- $(a b) : a标签的所有b标签的元素;
- $(a>b) : a的所有子元素为b的元素(包括a的子元素,不包括b的子元素);
- $(a+b) : a的下一个兄弟(a下一个元素,不包括子元素,不包括a);
- $(a~b) : a的所有弟弟(a后面的所有元素,不包括子元素,不包括a)
- 基本过滤选择器:
- $("div:first") : 第一个元素;
- $(div:last) : 最后一个;
- $(div:odd): 索引奇数;
- $(div:even): 索引偶数;
- $(div:eq(index)): 指定索引的元素;
- $(div:gt(index)): 大于索引;
- $(div:lt(index)): 小于索引;
- 内容过滤器:
- $(#id:has("div")) : 包含指定选择器的元素;
- 可见过滤选择器:
- $("div:hidden") : 隐藏的div元素;
:visiable属性
- $("div:hidden") : 隐藏的div元素;
- 属性选择器:
- $("[属性名]") : 元素
- $("[属性名='值']") : 元素
- $("[属性名!="值"][属性名2="2"]")
- $("标签名[属性名]") : 联用;
- 表单选择器:
- $(":input") : 所有的表单子标签; ":select,:textarea"
- ("form1 input")`层次选择器;
- 表单对象属性过滤选择器:
- :enable,:disable
- :checked ,:selected;
jQuery 属性操作符:
- attr()
$("#id").attr( ... )
attr("attr name") 获取属性;
attr("attrname","value") 设置属性;
attr({attr1:value1,attr2:value2})
removeAttr("attrname")
//快捷添加样式;
addClass("classname")
removeClass("classname")
- prop(1.6) 兼容checked属性,attr不支持;
$("input[type='checkbox']").prop('checked')
removeProp("属性")
JQuery css 操作:
css("attrname")
: 获取或设置css的属性;
JQuery 数组遍历:
- $array.each(function(参数){ ... })
- array,function(){ ... })
JQuery 文档操作:
内部插入:
- a.append(c) 将c插入到a的内部后面(标签体后面)
- a.prepend(c) 将c插入到a的内部前面;
- appendTo,prependTo
外部插入:
- a.after(c) : 将c放在a的后面
- a.before(c) : c放在c的前面;
empty 清空元素,remove 删除元素;
bootstrap
栅格布局媒体查询
屏幕分辨率 >1200px 使用col-lg-;每行显示6个,col-lg-2;
屏幕分辨率>992 && <1200 使用col-md-;每行显示4个,col-md-3
屏幕分辨率<992 >768 使用col-sm-;每行显示2个,col-sm-6
屏幕分辨率<768 使用col-xs-;每行显示一个,col-xs-12
〰〰〰〰〰〰〰〰〰〰〰〰〰〰我是分隔线
〰〰〰〰〰〰〰〰〰〰〰〰〰〰
xml 可扩展标记语言;
格式:
CDATA: 输入原始文字
xml约束:
- DTD约束:
- SHEMA约束:
.xsd
命令空间:
<根标签 xmlns=" ... ">
引入命令空间,约束文件名称;
xmlns:aaa =" ... "
声明当前的xml文件是一个xml实例文件;
aaa:schemaLocation="约束的名称空间,约束文件的位置"
Http 超文本传输协议
请求:
- 请求行 : 请求信息第一行,为协议/版本
- 请求头 : 第二行到空行;
- Referer : 防盗链 ,来自哪个页面;
- User-Agent: 用户代理信息;浏览器内核等;
- Cookie
- if-Modified-Since : 缓存文件的最后修改时间;
- 请求体
请求转发: req.getRequestDispathcher("内部路径").forward(req,resp)
常用方法:
- String getMethod() 获取请求方式;
- String getRemoteAddr() 获取请求者ip地址;
- String getContextPath() 在java中获取项目名称;
- String getRequestUrl() 获取完整路径
http://localhost:8080/项目名/path
String getRequestUri() 获取项目名到参数前的内容/项目名/pathname
- String getQueryString() get请求的所有参数;
- String getProtocol() 获取协议版本;
http/1.1
- String getHeader(String key):通过key获取指定的value(一个)
Enumeration getHeaders(String key):通过key获取指定的value(多个)
Enumeration getHeaderNames();:获取所有的请求头的名称
int getIntHeader(String name);获取整形的请求头 - long getDateHeader(String name);获取时间的请求头
- String getParameter(String key):获取一个请求参数
String[] getParameterValues(String key):通过一个key获取多个值
MapgetParameterMap():获取所有的参数名称和值 - 自己的数据:getAttribute();
响应:
- 响应行: 响应信息第一行;格式: 协议/版本 状态码 状态码说明
HTTP/1.1 200 OK
- 状态码 :
- 1xx: 已发送请求;
- 2xx:已完成响应;
- 3xx: 还需浏览器再一步操作;
- 4xx:用户操作错误;
- 5xx:服务器错误;
- 200: 正常
- 302: 重定向 (
resp.setStatus(302)
和Location搭配) - 304: 读取缓存
- 404: 不存在
- 500:服务器内部错误;
- 状态码 :
- 响应头:
- Location: 跳转方向,与302一起使用;
resp.sendRedirect("url")
- Content-Type: 数据类型mine,设置响应流的编码,浏览器编码格式打开;
resp.setHeader("content-type","text/html;charset=utf-8")
- Last-Modified: 最后修改时间;
- Refresh: 定时刷新;
resp.setHeader("refresh","1000;url=xxx")
- Content-Disposition: 下载有关;
Content-Disposition: attachment;filename=aaa.zip
resp.setHeader("content-disposition","attachment;filename=URLEncoder.encode(filename,"utf-8")")
- Set-Cookie:缓存;
- Location: 跳转方向,与302一起使用;
- 响应体
常用方法:
- setHeader(String,string),setIntHeader() 设置响应头
- setDataHeader() 设置Date时间的响应头;
- addHeader():添加响应头;
- 定时刷新的方法2 元数据 ->
;
方法3 定时器
Servlet 生命周期 (小服务程序,服务连接器)
三大组件(servlet,listener,filter)
servlet 是单实例多线程,默认第一次访问的时候,服务器创建servlet并调用init初始化,并调用一次service方法,每当请求来的时候,服务器创建一个线程,调用service方法执行自己的业务逻辑;当servlet被移除或服务器正常关闭时,服务器调用servlet的destroy方法执行自己的业务逻辑;
load-on-startup
修改servlet初始化时机,正整数,值越大,优先级越低;
- init(ServletConfig) : 服务器创建并调用,默认第一次访问的时候执行一次;
load-on-startup
大于等于0时,在应用程序启动时加载servlet,这时init方法调用一次;如果为负数或没有设置时,容器会在servlet被请求时调用init; - service(ServletRequest,ServletResponse) : 服务器收到请求的时候请求一次执行一次;
- destroy() : 服务器在servlet被移除时或服务器正常关闭时会执行一次;
- getServletConfig()
listener:
- 监听web中的域对象创建销毁(ServletContextListener,ServletRequestListener,HttpSessionListener)
- 监听域对象属性的变化(ServletContextAttributeListener,ServletRequestAttributeListener,HttpSessionAttributeListener)
- 监听session中Javabean的状态
- HttpSessionActivitionListener
- 钝化(JavaBean:session->磁盘)
- 活化(JavaBean:磁盘->session);
- HttpSessionBindingListener
- 绑定和解绑,是否放入session或从session中移除;
- HttpSessionActivitionListener
filter:
单实例多线程,服务器启动的时候,服务器创建filter,调用init方法,实现初始化操作;请求来的时候,创建一个线程,根据路径调用doFilter,执行业务逻辑;当filter被移除的时候或服务器正常关闭的时候,调用destory方法销毁;
常用方法:
- destory 销毁
- init(FilterConfig) 初始化;
- doFilter(ServletRequest,ServletResponse,FilterChain) 需放行;
chain.doFilter(req,resp);
域对象
ServletContext 全局管理器
当项目启动的时候,服务器为每一个web项目创建一个servletContext对象,当项目被移除的时候或服务器关闭的时候servletcontext销毁;
存放共享的数据
常用方法:
ServletContext getServletContext()
ServletContext getServletConfig().getServletContext()
setAttribute(String key,Object value); Object getAttribute(String key); removeAttribute(String key);//移除值
下
String getInitParameter();Enumeration getInitParameterNames()getRealPath(String path);获取文件部署到tomcat上的真实路径(带tomcat路径);getRealPath("/"):获取项目发布到服务器的根目录D://XXXX/项目名
getResourceAsStream(String):以流的形式返回一个文件,获取tomcat上的文件,可用于下载
getMimeType(String 文件名称):获取文件的mime类型 大类型/小类型
Request HttpServletRequest
- xxxAttribute()方法
- 创建于一次请求类的时候;
- 销毁于响应生成的时候;
- 存放一次请求里面的数据;
Session HttpSession
- xxxAttribute()方法
- 创建于 第一次调用request.getSession()或访问jsp,servlet就直接创建session;
- 销毁于 服务器非正常关闭,session超时,默认时间20分钟自动失效;
- 手动退出session
session.invalidate()
; - 存放私有数据;
请求转发和重定向的区别:
ReDirect&Forward
- 重定向发送两次请求,请求转发一次请求;
- 重定向地址栏发生改变,请求转发不变;
- 重定向从浏览器发送,请求转发服务器内部;
- 重定向不存在request域对象,请求转发可使用request域对象;
- 重定向是response方法,请求转发是request方法;
- 重定向可以请求站外资源,请求转发不可以;
cookie&session 浏览器,服务器端的会话技术;
cookie: 由服务器生成,通过response写回浏览器(响应头header.set-cookie),保留在浏览器中,浏览器下一次访问根据一定的规则request携带不同的cookie(请求头header.cookie),服务端接受cookie; (注意跨域问题)
常用方法:
- new Cookie(String,String)
- response.addCookie(Cookie) 写回浏览器;
- Cookie[] request.getCookies() 获取cookie
- setMaxAge(int) 秒,设置0则删除;
- setPath(String) 设置cookie的路径,当访问的路径包含此cookie的path,则request携带;默认路径为:
/项目名
开始 到最后一个/
结束;
session:
服务器向客户端浏览器发送一个名为JSESSIONID的Cookie,它的值为该Session的id(也就是HttpSession.getId()的返回值)。Session依据该Cookie来识别是否为同一用户。该Cookie为服务器自动生成的,它的maxAge属性一般为-1,表示仅当前浏览器内有效,并且各浏览器窗口间不共享,关闭浏览器就会失效。(不支持就使用URL地址重写
);
URL地址重写的原理是将该用户Session的id信息重写到URL地址中。服务器能够解析重写后的URL获取Session的id。这样即使客户端不支持Cookie,也可以使用Session来记录用户状态。HttpServletResponse类提供了encodeURL(String url)实现URL地址重写,该方法会自动判断客户端是否支持Cookie。如果客户端支持Cookie,会将URL原封不动地输出来。如果客户端不支持Cookie,则会将用户Session的id重写到URL中。
流程:
第一次访问服务器,服务器从cookie中获取jsessionId,
如果有jsessionid,用jsessionid在session池中查找有无session,有 存入已有数据;没有 创建session,保存已有数据,通过cookie写回jsessionid到浏览器
没有jsessionid,创建session,保存用户数据,将当前的jsessionid保存到cookie中写回到浏览器;
常用方法:
- request.getSession()
- session.invalidate 清除session;
- session.setMaxInactionInterval(-1) 设置session的超时时间;
el 表达式 与 jstl表达式
获取域中数据
简单数据: ${域名.域中属性名} || ${键(域中属性名)}
{域中名称key[index]} || {域["域中属性名"]}
${域中名称key . bean属性名}`
javabean:
运算:
${empty list} 判断一个容器长度是否为0或判断一个对象是否为null;
el的内置对象: (共11个,10个是map,pageContext不是map)
- pageScope: pageContext域属性 ,
pageContext.getAttribute("xxx")
- requestScope: request域;
request.getAttribute("xxx")
- sessionScope: session域;
session.getAttribute("xxx")
- applicationScope: application域,相当于servletContext域;
application.getAttribute("xxx")
- param 单值
request.getParameter("xxx")
- 对应于参数的map集合;
- ${param.key}
- paramValues 多值 对应于参数
request.getParameterValues("xxx")
- header 单值
request.getHeader("xxx")
- headerValues 多值
request.getHeaders("xxx")
- initParam 全局初始化参数,web.xml中
内的参数,${ initParam.xxx},xxx就是 标签内的值,进而得到 中的值 - cookie 和cookie相关的内置对象
Map
${cookie.JSESSIONID.value}
获取jsessionid的值; - pageContext 不是map,
pageContext.request.contextPath
获取项目名称;
可获取
jsp的九大内置对象(jsp页面可直接使用,详情以下)
- session (HttpSession) 域对象
- request (HttpServletRequest) 域对象
- response (HttpServletResponse)
- out (JspWriter)
- application (ServletContext) 域对象
- pageContext (PageContext) 域对象
- config (ServletConfig)
- page (Object,this)
- Exception
jstl常用方法: (使用 thymeleaf 代替)
c:if if表达式
c:forEach for循环
${i} 取值
${vr.count} 记录次数;
${vr.current} 当前遍历内容;
//可以直接使用items
事务 一件完成的事情 提交or回滚
mysql事务: 默认自动提交, oracle 默认手动提交;
set autocommit = off
关闭自动事务后,每个操作都需要commit;
start transaction
手动开启一个事务, rollback; commit;
事务特性: ACID
- 原子性: 不可分割;
- 一致性: 事务执行前后 ,业务状态保持一致;
- 隔离性: 一个事务执行时不受其他事务影响;
- 持久性: 一旦事务提交或回滚,持久化到数据库中;
隔离性读问题:
- 脏读: 在一个事务中读取到另一个事务中没有提交的数据;
- 不可重复读: 在一个事务中,两次查询的结果不一致(update);一个事务读取另一个事务已经提交的更改数据;前后多次读取,数据内容不一致;(解决思想: 行级锁,读取的时候不让其他人更改;)
- 虚读: 前后多次读取,数据总量不一致;(insert)(解决思想: 表级锁,读取的时候不让其他人插入;)
读问题解决方法: 设置数据库的隔离级别;
-
read uncommited 读未提交
- 出现所有读问题;
- set session transaction isolation level read uncommited;
-
read commited 读已提交 (oracle 默认)
- 避免脏读;
- set session transaction isolation level read commited;
-
repeatable read 可重复读 (mysql 默认)
- 避免脏读和不可重复读;
- set session transaction isolation level repeatable read;
-
serializable 串行化
- 避免所有问题;
- set session transaction isolation level serializable;
效率对比: read uncommited > read commited > repeatable read > serializable;
令牌机制
使用请求转发时,防止表单重复提交,重定向
或者令牌机制
- 用户访问页面时,分配一个令牌
hidden
; - 获取session中的令牌和表单提交的令牌;
- 对比令牌,通过后,销毁session中的令牌;
- 再次提交后,找不到session的令牌判断为二次提交;
ajax 快速动态网页技术,与后台少量数据交换,网页异步更新;
XMLHTTPRequest
常用属性:
- onreadystatechange: 检测readyState状态改变;
- readyState状态
- 0 : 核心对象XMLHttpRequest的创建;
- 1 : 调用open; 编写(请求方式,请求路径[,是否异步])
- 2 : 调用send; 发送请求,如果有参数则为post方式的参数;
- 设置请求头
xmlhttp.setRequestHeader("content-type","application/x-www-form-urlencoded")
意为form表单的enctype的属性;
- 设置请求头
- 3 : 部分响应已经完成;
- 4 : 响应已经完成;
state ==400 && readyState ==4
- responseTest : 响应回来的文本;
jquery ajax:
load
通过ajax请求从服务器加载数据,将返回的数据放置在指定的元素中;
- url
- data {json} 可选
- function(response,status,xhr)
$.get
$.post
- url 请求路径;
- params 请求参数,json格式;
- fn 回调函数,参数就是服务器发送回来的数据;
- type 返回内容格式,
xml,html,script,json,text,defalut
$.ajax
- url 请求路径
- type 请求方法
- data 发送到服务器数据
- success 成功后的回调
- error 异常的回调
- dataType 返回内容格式,
json jsonp
- async 设置是否异步请求;
类加载器
编写.java -> .class 运行时加载到内存中,需要类加载器加载;
层次结构:
- 引导类加载器
rt.jar
Bootstrp loader - 扩展类加载器
ext/*.jar
ExtClassLoader - 应用类加载器 自己编写的类; AppClassLoader
全盘委托机制 ( 双亲委派机制 ):
- 当前ClassLoader首先从自己已经加载的类中查询是否此类已经加载,如果已经加载则直接返回原来已经加载的类。每个类加载器都有自己的加载缓存,当一个类被加载了以后就会放入缓存,等下次加载的时候就可以直接返回了。
- 当前classLoader的缓存中没有找到被加载的类的时候,委托父类加载器去加载,父类加载器采用同样的策略,首先查看自己的缓存,然后委托父类的父类去加载,一直到bootstrp ClassLoader.
- 当所有的父类加载器都没有加载的时候,再由当前的类加载器加载,并将其放入它自己的缓存中,以便下次有加载请求的时候直接返回。