快捷键:ctrl +shift+f代码整理
ctrl +shift+o快速导包
1-----。请求转发:
作用:
实现多个servlet联动操作处理请求。这样避免代码冗余,让servlet的职责更加明确。
使用:
req.getRequestDispatcher(“要转发的地址”).forward(req,resp);
地址:相对地址,应该书写servlet的别名即可
特点:
一次请求,浏览地址信息不变。
注意:
请求转发后直接return即可
2-----。重定向:
解决了表单重复提交的问题,以及当前servlet无法处理的请求的问题。
使用:
resp.sendRedirect(String url);
实例:
resp.sendRedirect("/login/main");
特点:
两次请求。
浏览器地址栏信息改变。
时机:
如果请求中有表单数据,而数据比较重要,不能重复提交,建议使用。
如果请求被servlet接收后,无法进行处理,使用重定向定位到可以处理的资源。
3-----。Cookie学习:
作用:
解决了发送的不同请求的数据共享问题
使用:
Cookie的创建和存储:
创建Cookie对象
Cookie c=new Cookie(key,value)//(String name,String value);
设置cookie(可选)
1.设置有效期
c.setMaxAge(int seconds(以秒为单位));
2.设置有效路径
c.setPath(String uri);
响应Cookie信息给客户端
resp.addCookie©;
Cookie的获取:
获取Cookie信息数组
Cookie[] cks=req.getCookies();
遍历数组获取Cookie信息
使用for遍历即可,示例:
if(cks!=null){
for(Cookie c:csk){
String name=c.getName();
String value=c.getValue();
}
}
注意:
一个cookie对象存储一条数据。多条数据,可以多创建几个Cookie对象进行存储。
特点:
浏览器端的数据存储技术。
存储的数据声明在服务器端。
临时存储:存储在浏览器的运行内存中,浏览器关闭即失效。
定时存储:设置了Cookie的有效期,存储在客户的硬盘中,在有限期内符合路径的请求都会附带信息。
默认cookie信息存储好之后,每次请求都会附带,除非设置路径。
Cookie信息校验:
判断请求中是否携带正确的Cookie信息
如果有则校验Cookie信息是否正确
如果校验正确则直接响应主页面给用户
如果校验不正确则响应登录页面给用户
没有则请求转发给登录页面
4------。Session技术学习:
问题:
一个用户的不同请求处理的数据共享怎么办?
解决:
使用session结束
原理:
用户第一次访问服务器,服务器会创建一个session对象给此用户,并将该session对象的JSESSIONID使用
Cookie技术存储到浏览器中,保证用户的其他请求能够获取到同一个session对象,也保证了不同请求能够
获取到共享数据。
特点:
存储在服务器端
服务器进行创建
依赖Cookie技术
session有限期(一次会话)
使用:
创建session对象/获取session对象
HttpSession hs=req.getSession();
如果请求中拥有session的标识符也就是JSESSIONID,则返回其对应的session对象
如果请求中没有session的标识符也就是JSESSIONID,则创建新的session对象,并将其JESSIONID
作为从cookie数据存储到浏览器内存中。
如果session对象是失效了,也会重新创建一个session对象,并将其JSESSIONID存储在浏览器内存中。
设置session存储时间:
hs.setMaxInactiveInterval(int seconds);//以秒作为单位
注意:
在指定的时间内session对象没有被使用则销毁,如果使用了则重新计时。
设置Session强制失效
hs.invalidate();
存储和获取数据:
存储:hs.setAttribute(String name,Object value);
获取:hs.getAttribute(String name) 返回的数据类型为Object
注意:
存储的动作和取出的动作可以发生在不同的请求中,但是存储要先于取出执行。
使用时机:
一般用户在登陆web项目时,会将用户的个人信息存储到session中,供该用户的其他请求使用。
总结:
session解决了一个用户的不同请求的数据共享问题,只要在JSESSIONID和session对象不失效的情况下。
用户的任意请求都能获得到同一个session对象。
作用域:
一次会话
在JSESSIONID和SESSION对象不失效的情况下为整个项目内。
Session失效处理:
将用户请求中的JSESSIONID和后台获取到的SESSION对象的id进行比对,如果一致
则Session没有失效,如果不一致则证明session失效了。重定向到登录页面,让用户重新登录。
注意:
JSESSIONID存储在了cookie的临时存储空间中,浏览器关闭即失效。
*解决主页面用户名显示Null的问题。
原因:
因为在用户登录成功后使用重定向显示主页面,两次请求,而用户信息在
第一次请求中,第二次请求中没有数据,所以显示null。
解决:
使用session
5--------。SerlvetContext对象:
问题:
Request解决了一次请求内的数据共享问题,session解决了用户不同请求的数据共享问题,那么
不同的用户的数据共享该怎么办?
解决:
使用ServletContext对象
作用:
解决了不同用户的数据共享问题
原理:
ServletContext对象由服务器进行创建,一个项目只有一个对象。不管在项目的任意位置进行获取
得到的都是同一个对象,那么不同用户发起的请求获取到的也就是同一个人对象了,该对象由用户
共同拥有。
特点:
服务器进行创建
用户共享
一个项目只有一个
生命周期:
服务器启动到服务器关闭
作用域:
项目内
使用:
获取ServletContext对象
//第一种方式
ServletContext sc=this.getServletContext();
//第二种方式
ServletContext sc2=this.getServletConfig.getServletContext();
//第三种方式
ServletContext sc3=req.getSession().getServletContext();
使用ServletContext对象完成数据共享
//数据存储
sc.setAttribute(“str”,"…");
//数据获取
sc.getAttribute(“str”);返回object类型
注意:
不同的用户可以给ServletContext对象进行数据的存储。
获取的数据不存在返回null。
//获取项目中web.xml文件中的全局配置数据。
sc.getInitParameter(String name);根据键的名字返回web.xml中配置的全局数据的值,返回String类型。如果数据不存在返回Null。
sc.getInitParameterNames();返回键名的枚举。
注意:
一组标签只能存储一组键值对数据,多组可以声明多个进行存储。(静态数据)
作用:讲静态数据和代码解耦。
获取项目webroot下的资源的绝对路径:
String path=sc.getRealPath(String);
获取的路径为项目根目录,path参数为项目根目录中的路径
获取项目根目录下资源的流对象:
InputStream is=sc.getResourceAsStream(String path);
注意:
此种方式只能获取项目根目录下的资源流对象,class文件的流对象需要使用类加载器获取。
6--------------。JSP
JSP的三种注释:
前端语言注释:
会被转译,也会被发送,但不会被浏览器执行。
java语言注释:
会被转译,但不会被servlet执行
JSP注释:
不会被转译。
JSP的page指令学习:
<%@page 属性名=“属性值” 属性名=“属性值”…%>
language:声明jsp要被转译的语言。
import:声明转译的java文件要导入的包。不同的包使用逗号隔开。
pageEncoding:设置JSP文件的数据编码格式。
contentType=“text/html; charset=utf-8” 设置jsp数据响应给浏览器,浏览器的解析和编码格式。
session:设置转译的serlvet中是否开启session支持,默认开启,true表示开启,false表示关闭。
errorpage:设置Jsp运行错误跳转的页面
extends:设置Jsp转译的java文件要继承的父类(包名+类名)。
作用:
配置jsp文件的转译相关的参数。
JSP的局部代码块:
特点:
局部代码块中声明的java代码会被原样转译到jsp对应的servlet文件的_JspService方法中
代码块中声明的变量都是局部变量。
使用:
<% java代码%>
缺点:
使用局部代码块在jsp中进行逻辑判断,书写麻烦,阅读困难
开发:
servlet进行请求逻辑处理,使用jsp进行页面展示。
JSP的全局代码块:
特点:
声明的java代码作为全局代码转译到对应的servlet类中。
使用:
<%!全局代码 %>
注意:
全局代码块声明的代码,需要使用局部代码调用。
JSP的脚本段语句:
特点:
帮助我们快速的获取变量或者方法的返回值作为数据响应给浏览器。
使用:
<%=变量名或者方法%>
注意:
不要在变量名或者方法后使用分号。
位置:
除jsp语法要求以外的任意位置。
JSP的静态引入和动态引入:
静态引入:
<%@include file =“要引入的jsp文件的相对路径” %>
特点:
会将引入的jsp文件和当前jsp文件转译成一个java文件使用。
在网页中也就显示了合并后的显示效果。
注意:
静态引入的jsp文件不会单独转译成java(Servlet)文件。
当前文件和静态引入的jsp文件中不能够使用java代码块声明同名变量。
动态引入:
<jsp:include page=“要引入的jsp文件的相对路径”></jsp:include>
特点:
会将引入的jsp文件单独转译,在当前文件转译好的java文件中调用引入的jsp文件的转译文件。
在网页中显示合并后的显示效果。
注意:
动态引入允许文件中声明同名变量。
优点:
降低代码的冗余,便于维护升级。
jsp的转发标签forward:
使用:
<jsp:forward page=“要转发的jsp文件的相对路径”></jsp:forward>
特点:
一次请求。
地址栏信息不改变。
注意:
在转发标签的两个标签中间除了写<jsp:param value=“str” name=“aaa”/>子标签不会报错,其他任意 字符都会报错。
JSP的九大内置对象:
内置对象:
jsp文件在转译成对应的Servlet文件的时候自动生成的并声明的变量,我们在jsp页面中直接使用即可。
注意:
内置对象在jsp页面中使用,使用局部代码块或者脚本段语句来使用。不能够在全局代码块中使用。
内容:九个对象
pageContext:
页面上下文对象,封存了其他内置对象。 封存了当前的jsp的运行信息。
注意:每个Jsp文件单独拥有一个pageContext对象。
作用域:当前页面。
request:
封存当前请求数据。 由tomcat服务器创建。一次请求。
session:
此对象用来存储用户的不同请求的共享数据。一次会话。
application:
也就是ServletContext对象,一个项目只有一个。
response:
响应对象,用来响应请求处理结果给浏览器的对象。设置响应头,重定向。
out:
响应对象,jsp内部使用。带有缓冲区的相应对象,效率高于response对象。
page:
代表当前jsp的对象。相当于java中的this。
exception:
异常对象。存储了当前运行的异常信息。
注意:使用此对象需要在page指定中使用属性isErrorPage=“true”开启。
config:
也就是servletConfig ,主要是获取web.xml的配置数据,完成一些初始化数据的读取。
四个作用域对象:
pageContext:
当前页面,解决了在当前页面内的数据共享问题。
request:
一次请求。一次请求的servlet的数据共享。通过请求转发,将数据流转给下一个servlet。
session:
一次会话。一个用户的不同请求的数据共享。将数据从一次请求流转给其他请求。
application:
项目内,不同用户的数据共享问题,将数据从一个用户流转给其他用户。
作用:
数据流转
JSP的路径:
在jsp中资源路径可以使用相对路径完成跳转,但是:
问题1:资源的位置不能随意更改。
问题2:需要使用…/进行文件夹的跳出。使用比较麻烦。
使用绝对路径:
/虚拟项目名/项目资源路径/
注意:
在jsp中资源的第一个/表示的是服务器根目录,相当于:Localhost:8080
7------------。ajax学习
1.什么是ajax
异步刷新技术,用来响应当前页面内响应不同的请求内容。
2.为什么需要ajax
需求:
有的时候我们需要将本次的响应结果和前面的响应结果内容在同一个页面中展示给用户。
解决:
1.在后台服务器端多次响应内容重新拼接成一个jsp页面,响应。
但是这样会造成很多响应内容被重复的响应,资源浪费。
3.使用Ajax
1.ajax的概念
局部刷新技术。是浏览器端的技术。
2.ajax的作用
实现在当前结果页中显示其他请求的响应内容。
3.ajax的使用
ajax的基本流程
//创建ajax引擎对象
var ajax;
if(window.XMLHttpRequest(){
ajax=new XMLHttpRequest();
}else if (windows.ActiveXobject){
ajax=new ActiveXobject(Msxm12.XMLHTTP);
}
//复写onreadystatement函数
ajax.onreadystatechange=funtion(){
//判断ajax状态码
if(ajax.readystate==4){
//判断响应状态码
if(ajax.status==200){
//获取响应内容(响应内容的格式)
var result=ajax.responseText;
//处理响应内容(js操作文档)
}
}
}
//发送请求
//get方式:请求实体直接拼接在URL后面
ajax.open(“get”,“ajax?name=张三&pwd=123”);
ajax.send(null);
//post方式
ajax.open(“post”,“url”);
req.setRequestHeader(“Content-Type”,“application/x-www-form-urlencoded”);
ajax.send(“name=张三&pwd=123”);
Ajax的状态码
readystate:0,1,2,3,4
0:表示还未执行的open方法
1:表示已执行open方法但未执行send方法
2:表示已执行send方法
3:表示客户端已经正在接收服务器响应数据
4:表示响应内容被成功接收
响应状态码:
200:表示一切Ok
404:表示资源未找到
500:内部服务器错误
Ajax的同步和异步:
ajax.open(method,url,async)
async:设置同步代码执行是同步还是异步
true代表异步,默认是异步
8-----------。 EL表达式
问题:
在servlet进行请求处理后,使用作用域对象作为数据流转的载体。将数据流转给对应的jsp文件。
怎么在jsp中获取作用域中的数据?
使用:
传统方式:在jsp页面中使用Java脚本段语言。
缺点:
1.导入包
2.需要强转
3,获取数据的代码过于麻烦
作用:获取作用域 对象中的数据。
注意:
获取的是pageContext、request、session、application 四个对象中的数据,其他数据一概不理会。
找到了则获取返回,找不到则什么都不做,也不报错。
语法:
${表达式}
表达式:
request 对象存储了请求数据—>param.键名 返回值。
request 对象存储了请求数据—>paramvalues.键名 返回的是数组。
通过setAttribute方法存储到作用域的数据
${键名} 返回键名所对应的值。
注意:
如果存储的是普通的字符串则直接返回
如果存储的是对象,则返回的是对象
获取对象中的数据:
普通对象
${键名.属性名.属性名…}
集合对象
List集合->${键名[角标]}
map集合->${键名.map集合存储的键名}
作用域查找顺序:
默认查找顺序:
pageContext–> request–> session–>application
注意:
每次查找都是从小到达进行查找,找到了则获取,不再继续找了。
指定查找:
p a g e s c o p e . 键 名 − − − {pagescope.键名}--- pagescope.键名−−−{requestScope.键名}------ s e s s i o n S c o p e . 键 名 − − − − − − {sessionScope.键名}------ sessionScope.键名−−−−−−{applicationScope.键名}
9---------。 JSTL学习
作用:
提高在jsp中的逻辑代码的编写效率,使用标签。
使用:
JSTL的核心标签库(重点)
JSTL的格式化标签库
JSTL的SQL标签库
JSTL的XML标签库
JSTL的核心标签库:
1.导入jar包
2.声明jstl标签库的引入(核心标签库)
<%@taglib prefix=“c” uri=“http://java.sun.com/jsp/jstl/core” %>
3.内容:
基本标签:
<c:out value=“数据” default=“默认值”></c:out>
数据可以为常量值也可以是EL表达式。
作用:
将数据输出给客户端。
<c:set var=“hello” value=“hello pageContext” scope=“page”></c:set>
作用:存储数据到作用域对象中
var:表示存储的键名
value:表示存储的数据
scope:表示存储的作用域对象 page request session application
10-----------。过滤器
作用:
对服务器接受的请求资源和响应给浏览器的资源进行管理。
保护servlet
使用:
创建一个实现了Filter接口的普通java类
覆写接口的方法:
init方法:初始化资源(服务器启动即执行)
doFilter方法:拦截请求的方法,在此方法中可以对资源实现管理。
注意:
需要手动对请求进行放行。chain.doFilter(request,response);//放行
destory方法:服务器关闭执行。
在web.xml中配置过滤器
@webFilter(/*)
表示拦截所有请求。
@webFilter(*.do)
表示拦截.do结尾的请求, 一般用于进行模块拦截处理。
@webFilter(/ts)
表示拦截指定的url请求。针对某个servlet的请求进行拦截,保护servlet。
总结:
过滤器程序员声明和配置,服务器根据请求中的uri信息调用。
执行:
浏览器发起请求到服务器,服务器接收到请求后,根据URI信息在web.xml中找到对应的
过滤器执行doFilter方法,该方法对此次请求进行处理后如果符合要求则放行,放行后如
果还有符合要求的过滤则继续进行过滤,找到执行对应的servlet进行请求处理。servlet
对请求处理完毕后,也就service方法结束了。则继续返回相应的doFilter方法继续执行。
过滤器的生命周期:
服务器启动到服务器关闭。
11---------。监听器
监听器的使用:
作用:
监听作用域对象request、session、application的创建、销毁和内容的改变
使用:
创建了一个实现接口的java类
监听request–>ServletRequestListener//监听request对象的创建和销毁
requestInitialized(ServletRequestEvent sre)//创建
requestDestoryed(ServletRequestEvent sre)//销毁
注意:
形参可以获取监听的request对象。
监听request–>ServletRequestAttributeListener//监听request作用域的变更。
attributeAdded(ServletRequestArributeEvent srae)
attributeRemoved(ServletRequestArributeEvent srae)
attributeReplaced(ServletRequestArributeEvent srae)
注意:
形参可以获取被监听的数据
srae.getName()//获取监听数据的键
srae.getValue()//获取监听数据的值
监听seesion–>HttpSessionListener//监听session的创建和销毁。
sessionCreated(HttpSessionEvent se)//创建
sessionDestoryed(HttpSessionEvent se)//销毁
注意:
形参可以获取被监听的session对象
se.getSession();
…变更
监听application
在web.xml中配置监听器类
@webListener
案例:
统计当前在线人数。
统计网页浏览器次数。
12-----------。vue
Vue的基本使用:
1.引入 Vue.js
a.创建js文件夹,讲vue.js粘贴至文件夹内。
b.<script type=“text/javascript src=”…/js/vue.js">
2.创建Vue实例
例子:
<div id="app"><!--view-->
<input type="text">
<p>
hello ???
</p>
</div>
var app=new Vue({
el:’#app’,
data:{
message:‘hello Vue!’
}
})
el:element:选择器
data{message:}:model:数据
双向数据绑定:v-model
显示数据:{{xxx}}
MVVM:
model:模型,数据对象(data)
view:视图,模板页面
viewModel:视图模型(Vue的实例)
模板语法:
1.指令一:强制数据绑定
例:
或者直接 :src
2.指令二:绑定事件监听
例:
或者 @click
13--------------。Spring
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8oKFGlFu-1608003509023)(https://i.loli.net/2020/09/23/knhXGoRwe5pFxr1.png)]
Test:spring的单元测试模块;
Core Container:核心容器(IOC);黑色代表这部分的功能由哪些jar包组成;要使用这个部分的完整功能,这些jar包都需要导入。
AOP+Aspects(面向切面编程模块)。
数据访问/
web:Spring开发web应用的模块
a. IOC:(Inversion(反转)of Control):控制反转;
控制:资源的获取方式;
主动式:(要什么资源都自己创建即可)
BookServlet{
BookService bs=new BookService();
AirPlane ap=new AirPlane();//复杂对象的创建是比较庞大的工程。
}
被动式:资源的获取不是我们创建,而是交给一个容器来创建和设置
BookServlet{
BookService bs;
public void test01(){
bs.checkout();
}
}
容器:管理所有的组件(有功能的类);假设,BookServlet受容器管理,BookService也受容器管理;容器可以自动探查出
那些组件(类)需要用的另一组件(类);容器帮我们创建BookService对象,并把BookService对象赋值过去。
容器:主动的new资源变为被动的接收资源;
b. DI:(dependency Injection)注入依赖;
容器能知道哪个组件(类)运行的时候,需要另一个组件(类);容器通过反射的形式,将容器准备的Bookservice对象注入
(利用反射给属性赋值)到BookServlet中。
只要是容器组件,都能使用容器的功能。
c. 给容器中注册一个组件以及获取:
几个细节:
1)applicationContext(IOC容器的接口)
2)给容器中注册一个组件,我们也从容器中按照id拿到了这个组件的对象。
组件的创建工作,是容器完成;
Person对象是什么时候建好的?
容器中对象的创建在容器创建完成的时候就已经创建好了。
3)同一个组件在ioc容器中是单实例的;容器启动完成都已经创建好了;
4)容器中如果没有这个组件,获取组件?
抛出异常。(No bean named ‘xxx’ is define)
5)ioc容器在创建这个组件对象的时候,(property)会利用setter方法为javaBean的属性进行赋值。
6)JavaBean的属性名是由什么决定的?getter/setter方法是属性名;set去掉后面那串首字母小写就是属性名
所有的getter /setter都自动生成。
d. 根据bean的类型从IOC容器中获取bean的实例
如果ioc容器中这个类型(Person.class)的bean有多个,查找就会报错。
如果使用ioc.getBean(String,class)就可以使用id或者别的元素查询。
e. 通过P名称空间为bean赋值
名称空间:
在xml中名称空间是用来防止标签重复。
f. 正确的为各种属性赋值
14-------------。SpringMVC-RestfulCRUD
员工列表展示;查询所有员工;
访问index.jsp----直接发送/emps-------控制器(controller)查询所有员工---------放在请求域中-----------转发到list页面进行展示
员工添加:
在list页面点击“员工添加”----(查询所有部门信息展示在页面)—来到添加页面(add.jsp)--------输入员工数据---------点击保存--------处理器收到员工保存请求(保存员工)---------保存完成(/emps)--------回到列表页面
员工的修改:
点击edit---------(查询出要修改的员工信息,放在请求域中,来到修改页面进行回显 /emp/1 GET)------------来到edit.jsp------(输入完成数据点击修改 /emp/1 PUT)-----(ModelAttribute提前查询员工)--------修改员工
删除信息:
点击删除-----(发送删除请求/emp/1 DELECT)-------删除员工-----------列表页面
15-----------。数据转换&数据格式化&数据校验
1)步骤:
ConversionService:是一个接口;它里面有Convertor(转换器)进行工作;
1)Converter是ConversionService中的组件;
1、你的Converter得放进ConversionService中;
2、将WebDataBinder中的ConversionService设置成我们这个加了自定义类型转换器的ConversionService;
2)实现Converter接口,写一个自定义的类型转换器;
3)配置出ConversionService;
!****----------
只要请求不好使就召唤mvc:annotation-driven;
1)mvc:default-servlet-handler/现象
1)什么都没配?动态资源(@requestmapping映射的资源能访问,静态资源(.html、.js、.img))
2) mvc:default-servlet-handler/静态资源ok,动态资源完蛋
动态不能访问:DefaultAnnnotationHandlerMapping没有了;用SimpleUrlHandlerMapping替换了,他的作用就是将所有的请求直接交给tomcat;
静态能访问的原因:SimpleUrlHandlerMapping把所有的请求都映射给tomcat;
HandlerAdapter:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LD0gZIWh-1608003509026)(D:%5CLFYtest%5C%E5%9B%BE%E7%89%87%5C2222.png)]
AnnotationMethodHandlerAdapter都没有了;
3)加上上面两个才都能访问
SimpleUrlHandlerMapping:将请求直接交给Tomcat:有他,静态啊资源就没有问题
HandlerAdapter:原来的AnnotationMethodHandlerAdapter被换成了RequestMappingHandlerAdapter
确定参数都成解析器了
4)只加mvc:annotation-driven/,静态资源
DefaultAnnotationHandlerMapping中的handlerMap中保存了每一个资源的映射信息;
静态不能访问;
就是handlerMap中没有保存静态资源映射的请求;
HandlerAdapter:方法执行的适配器
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lFG7tDJg-1608003509028)(https://i.loli.net/2020/11/30/dAykHKT9qb287Yp.png)]
AnnotationMethodHandlerAdapter:帮我们执行目标方法,过时的
-------格式化
页面提交的数据格式如果不正确,就是400
日期格式:2017-12-19
conversionServiceFactoryBean:创建的conversionService组件是没有格式化器存在的;
-------数据校验
只做前端校验是不安全的;
在重要数据一定要加上后端验证;
1)可以写程序将我们每一个数据取出进行校验,如果失败直接来到添加页面,提示其重新填写;X
2)springmvc:可以利用JSR303来做数据校验
JDBC:规范–实现(各个厂商的驱动包)
JSR303:规范—Hiberbate Validator(第三方校验框架)
3)如何快递的进行后端校验
1)、导入校验框架的jar包;
2)、只需要给JavaBean的属性添加上校验注解
3) 、在Springmvc封装对象的时候,告诉SpringMVC这个JavaBean需要校验
public String addEmp(@valid Employee employee){}
4)、如何知道校验结果:
给需要校验的JavaBean后面跟一个BindingResult,这个BindingResult就是封装了前一个bean的校验结果;
5)、根据不同的校验结果 决定怎么办
-------
1)原生的表单怎么办?
将错误放在请求域中就行了;
2)定制自己的错误消息显示:
编写国际化的文件:
errors_zh_CN.properties
errors_en_US.properties
key=lastname between 6 and 18
key有规定:
1)先编写国际化配置文件properties
2)让SpringMVC管理国际化资源文件 ;
3)来到页面取值
4)高级国际化?
动态传入消息参数;
Length.java.lang.String=length incorrect {0}{1}!!!
{0}:永远都是当前属性名;
{1}{2}
-------ajax;
1.SpringMVC快速的完成ajax功能?
1)、返回数据是Json就ok;
2)、页面,$.ajax();
2.原生javaweb:
1) 、导入GSON;
2)、返回的数据用GSON转成json
3) 、写出去;
3.SpringMVC:
1 、导包
2 、写配置
3 、测试
16-------------。拦截器
SpringMVC提供了拦截器机制;允许运行目标方法之前进行一些拦截工作 ,或者目标方法之后进行一些其他处理 ;
Filter:javaweb
HandlerInterceptor:SpringMVC
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ru2pRauF-1608003509029)(D:%5CLFYtest%5C%E5%9B%BE%E7%89%87%5CHandler.png)]
preHandle:在目标方法运行之前调用;返回boolean;return true;(chain.doFilter())放行;return false;不放行
postHandle:在目标方法运行之后调用;目标方法调用之后
afterCompletion:在请求整个完成之后;来到目标页面之后;chain.doFilter()放行。资源响应之后;
1)、拦截器是一个接口
2)、实现HandlerInterceptor接口;
3)、配置拦截器
4)、拦截器的运行流程
1.正常运行流程:
拦截器的PreHandle--------目标方法---------拦截器postHandle--------页面---------拦截器的afterCompletion;
MyFirstInterceptor....PreHandle....
test01....
MyFirstInterceptor...postHandle....
success.jsp
MyFirstInterceptor....afterCompletion....
其他流程:
1.只要PreHandler不放行就没有以后的流程;
2.只要放行了,afterCompletion都会执行;
2.多个拦截器
正常流程:
MyFirstInterceptor....PreHandle....
MySecondInterceptor...PreHandle....
test01....
MySecondInterceptor...postHandler....
MyFirstInterceptor...postHandle....
success.jsp
MySecondInterceptor...afterCompletion....
MyFirstInterceptor....afterCompletion....
异常流程:
1、不放行;
1)、哪一块不放行从此以后都没有;
MySecondInterceptor不放行;但是他前面已经放行的了的拦截器的AfterCompletion还是会执行;
MyFirstInterceptor....PreHandle....
MySecondInterceptor...PreHandle....
MyFirstInterceptor...afterCompletion....
流程:filter的流程;
拦截器的PreHandler:是按照顺序执行
拦截器的PostHandle:是按照逆序执行
拦截器的afterCompletion:是按照逆序执行
已经放行的了的拦截器的AfterCompletion还是会执行;
preHandle:
第一次:conversionServiceExposingInterceptor intercetorIndex=0;
第二次:MyFirstInterceptor intercetorIndex=1;
第三次:MySecondInterceptor 执行afterCompletion();
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7FynxZpX-1608003509029)(D:%5CLFYtest%5C%E5%9B%BE%E7%89%87%5C4444.png)]
17------------- 。国际化
1.写好 国际化资源文件
2.让Spring的ResourceBundleMessageSource管理国际化资源文件
<bean id="MessageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basename" value="loginpage/login"></property>
</bean>
3.直接去页面取值
4.现象:是按照浏览器带来的语言信息决定;
Locale locale=request.getLocale();//获取到浏览器的区域信息
SpringMVC中区域信息是由区域信息解析器得到的;
private LocaleResolver localeResolver;
默认会用一个AcceptHeaderLocaleResolver
所有用到区域信息的地方,都是用到AcceptHeaderLocaleResolver 获取的
@override
public Locale resolveLocale(HttpServletRequest request){
return request.getLocale();
}
点击链接切换国际化:(国际化信息是要能改变的)
AcceptHeaderLocaleResolver:使用请求头的区域信息
FixedLocaleResolver:使用系统默认的区域信息
SessionLocaleResolver:区域信息是从session中获取。
可以根据请求参数创建一个Locale对象,把他放在session中;
CookieLocaleResolvers :
1.什么时候用Filter什么时候用拦截器?
如果某些功能;需要某些组件配合完成,我们就使用拦截器;
其他情况可以写filter:
两者的区别:https://www.cnblogs.com/panxuejun/p/7715917.html
18-------------。异常处理
默认就是这几个HandlerExceptionResolver
ExceptionHandlerExceptionResolver:@ExceptionHandler
ResponseStatusExceptionResolver:@ResponseStatus
DefaultHandlerExceptionResolver:判断是否SpringMVC自带的异常
如果异常解析器都不能处理就直接抛出去;
19-------------。SpringMVC的运行流程
1.所有请求,前端控制器(DispatcherServlet)收到请求,调用doDispatch进行处理
2.根据HandleMapping中保存的请求映射信息找到,处理当前请求的,处理器执行链(包含拦截器);
3.根据当前处理器找到他的HandleAdapter(适配器)
4.拦截器的PreHandle先执行
5.适配器执行目标方法,并返回ModelAndView
1)、ModelAttribute注解标注的方法提前运行
2) 、执行目标方法的时候(确定目标方法用的参数)
1)有注解:
2)没注解:
1)看是否Model、Map以及其他的
2)如果是自定义类型
1.从隐含模型中看有没有,如果有就从隐含模型中拿
2.如果没有,再看时是否SessionAttributes标注的属性,如果是从Session中拿,如果拿不到会抛异常
3.都不是,就利用反射创建对象
6.拦截器的postHandle执行
7.处理结果;(页面渲染)
1)、如果有异常使用异常解析器处理异常‘;处理完后还会返回ModelAndView;
2) 、调用render进行页面渲染
1)视图解析器根据视图名得到视图对象;
2)视图对象调用render方法 ;
3)、执行拦截器的afterCompletion;
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jyxoE7z2-1608003509030)(D:%5CLFYtest%5C%E5%9B%BE%E7%89%87%5C5555.png)]
20-------------。SpringMVC与Spring整合
SpringMVC和Spring整合的目的:分工明确;
SpringMVC的配置文件就来配置和网站转发逻辑以及网站功能有关的(视图解析器,文件上传解析器,支持ajax…)。
Spring的配置文件来配置和业务有关的(事务控制,数据源…);
合并文件
SpringMVC和Spring分容器;
Spring管理业务逻辑组件;(容器)
SpringMVC管理控制器组件;(web)
有关Spring以及SpringMVC的关系:https://www.cnblogs.com/ibcdwx/p/13821939.html
21-------------。MyBatis
1.MyBatis;和数据库交互;持久化层框架(SQL映射框架);
1)原始的jdbc-------DBUtils(QueryRunner)-------JDBCTemplate;
称为工具;一些功能的简单封装
框架:某个领域的整体解决方案;缓存、考虑异常处理、考虑部分字段映射。。。
不用原生JDBC:
1)麻烦;
2)Sql语句是硬编码在程序中;(数据库层和Java编码耦合a
2)Hibernate-数据库交互的框架(ORM框架)
ORM(OBject Relation Mapping)对象关系映射;
1、创建好JavaBean; class Employee{}
2、加上@Table(“t_employee”);
3.session.get(“1”,Employee.class)(查询)
缺点:
1)、无法自行编写Sql;
2) 、HQL;SQL;
3) 、全映射框架;部分字段映射很难;能做;
2.MyBatis的优点
1)MyBatis将重要的步骤抽取出来可以人工定制,其他步骤自动化;
2)重要步骤都是写在配置文件中(好维护)
3)完全解决数据库的优化问题;
4)MyBatis底层就是对原生JDBC的一个简单封装;
5)既将Java编码与sql抽取了出来,还不会失去自动化功能;半自动化的持久层框架。
6)Mybatis是一个轻量级的框架;
MyBatis
1)创建测试库,测试表,以及封装数据的javaBean,和操作数据库的dao接口
创建表:
创建javaBean:Employee(封装表的数据)
创建一个Dao接口,用来操作数据库;
2)用MyBatis操作数据库
1、导包
//mysql-connector-java
//mybatis-
//建议导入日志包 :这样在优化Mybatis关键的环节就会有日志打印;
//log4j(日志框架);依赖类路径下一个Log4j.xml配置文件;
2、写配置(两个,全局配置文件(指导Mybatis运行的),dao接口的实现文件(描述每个方法怎么运行的))
1)、第一个配置文件;(称为mybatis的全局配置文件,指导Mybatis如何正确运行,比如连接向哪个数据库)
2)、第二个配置文件:(编写每一个方法如何向数据库发送sql语句,如何执行等等。。相当于接口的实现类)
1】、将mapper的namespace属性改为接口的全类名
2】、配置细节
<mapper namespace="com.martin.dao.EmployeeDao">
<!-- select:用来定义一个查询操作
id:方法名,相当于这个配置是对某个方法的实现
resultType:指定方法运行的返回值类型;(查询操作必须执行)
#{属性名}:代表取出来传递过来的某个参数的值
-->
<select id="getEmpById" resultType="com.martin.bean.Employee">
select * from t_employee where id=#{id}
</select>
</mapper>
3】、我们写的dao接口实现文件,Mybatis默认是不知道的,需要在全局配置文件中注册;
<!-- 引入我们自己编写的每一个接口的实现文件 -->
<mappers>
<!-- resource:表示从 类路径下找资源 -->
<mapper resource="EmployeeDao.xml"/>
</mappers>
3)、测试
1】、根据全局配置文件先创建一个
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
2】、sqlSessionFactory中获取sqlSession对象操作数据库即可
//2.获取和数据库的一次会话:getConnection();
SqlSession openSession = sqlSessionFactory.openSession();
//3.使用SqlSession操作数据库,获取到dao接口的实现
EmployeeDao employeeDao = openSession.getMapper(EmployeeDao.class);
//调用之前的方法;
Employee employee = employeeDao.getEmpById(1);
System.out.println(employee);
如何写Xml有提示:
1)、只要eclipse找到了这个文件的dtd约束文件的位置即可
2)、绑定约束文件的位置
1)复制dtd的引用网址
两个文件:
1)、全局配置文件:mybatis-config.xml ;指导Mybatis正确运行的一些全局设置;
2)、SQl映射文件:EmployDao.xml;相当于是对dao接口的实现描述
细节:
1)获取到的是接口的代理对象:mybatis自动创建的;
2)sqlSessionFactory和sqlSession;
sqlSessionFactory创建sqlSession对象,Factory只new 一次就行了
sqlSession:相当于Connection和数据库进行交互,和数据库的一次会话,就应该创建一个新的sqlSession;
全局配置文件:
configuration(配置)
- properties(属性)
- settings(设置)
- typeAliases(类型别名)
- typeHandlers(类型处理器)
- objectFactory(对象工厂)
- plugins(插件)
- environments(环境配置)
- environment(环境变量)
- transactionManager(事务管理器)
- dataSource(数据源)
- environment(环境变量)
- databaseIdProvider(数据库厂商标识)
- mappers(映射器)
Mybatis缓存机制:Map;能保存查询出的一些数据;
一级缓存:线程级别的缓存;本地缓存;sqlSession级别的缓存;
二级缓存:全局范围的缓存;除过当前线程;sqlSession能用外其他也可以使用;
一级缓存:Mybatis:sqlSession级别的缓存是默认存在的;
机制:只要之前查询过的数据;mybatis就会保存在一个缓存中(Map);下次获取直接从缓存中拿;
一级缓存失效的几种情况:
1.不同的sqlSession,使用不同的一级缓存;
只有在用一个SqlSession期间查询到数据会保存在这个sqlsession的缓存中;
下次使用sqlSession查询会从缓存中拿
2.同一个方法,不同的参数由于可能之前没查过。所以还会发新的sql
3.在sqlSession期间执行任何一次增删改操作,增删改操作会把缓存清空,
4.手动清空了缓存;
二级缓存:namespace级别的缓存
一级缓存;sqlSession关闭或者提交以后,一级缓存的数据会放在二级缓存中;
mybatis默认没有使用的;配置;
二级缓存的使用:
1.全局配置开启二级缓存
<!-- 开启全局缓存开关; -->
<setting name="cacheEnable" value="true"/>
2.配置某个Dao.xml文件,让其使用二级缓存;
<cache><cache/>
1.不会出现一级缓存和二级缓存中有同一个数据;
二级缓存中:一级缓存关闭了就有了;
一级缓存中:二级缓存中没有此数据,就会看一级缓存,一级缓存也没有去查数据库;
数据库的查询后的结果放在一级缓存中了;
2.任何时候都是先看二级缓存、在看一级缓存,如果大家都没有就去查询数据库;
口诀: 二–>一–>库
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SoFrSidY-1608003509031)(D:%5CLFYtest%5C%E5%9B%BE%E7%89%87%5CQQ%E5%9B%BE%E7%89%8720201206154347.png)]
缓存有关的设置:
1、全局setting的cacheEnable:
配置二级缓存的开关。一级缓存一直是打开的。
2、select标签的useCache属性:
配置这个select是否使用二级缓存。一级缓存一直是使用的
3、sql标签的flushCache属性:
增删改默认flushCache=true。sql执行以后,会同时清空一级和二级缓存。查询默认flushCache=false。
4、sqlSession.clearCache():
只是用来清除一级缓存。
5、当在某一个作用域 (一级缓存Session/二级缓存Namespaces) 进行了 C/U/D 操作后,默认该作用域下所有 select 中的缓存将被clear。
整合第三方缓存:
Mybatis;----cache;
整合ehcache;ehcache是非常专业的java进程内的缓存框架;
1.导包
ehcache
ehcache-core-2.6.8 jar(ehcache核心包)
mybatis-ehcache-1.0.3 jar(ehcache的整合包)
2.ehcache要工作有一个配置文件;
文件名叫ehcache.xml;放在类路径的根目录下
3.在mapper.xml中配置使用自定义的缓存
<cache type="org.mybatis.caches.ehcache.EhcacheCache"></cache>
4.别的dao还要用缓存;
<!--和别的dao公用一块缓存>
<cache-ref namespace="com.martin.dao.teacherDao"/>
22-------------。SSM整合
ssm;Spring+SpringMVC+MyBatis
1.导包
1)、spring
2) 、springMVC
3) 、Mybatis
4) 、其他的
2.写配置
0.web.xml配置
<web-app>
<display-name>Archetype Created Web Application</display-name>
<!-- 配置Spring容器启动 -->
<!-- needed for ContextLoaderListener -->
<context-param>
<param-name>contextConfigLocation</param-name>
<!-- 指定Spring配置文件位置 -->
<param-value>classpath:spring/applicationContext.xml</param-value>
</context-param>
<!-- Bootstraps the root web application context before servlet initialization -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- 配置Springmvc的前端控制器 -->
<!-- The front controller of this Spring Web application, responsible for
handling all application requests -->
<servlet>
<servlet-name>springDispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring/applicationContext-mvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<!-- Map all requests to the DispatcherServlet for handling -->
<servlet-mapping>
<servlet-name>springDispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<!-- 两个标准配置 -->
<!-- 配置一个字符编码的Filter:一定要注意:字符的filter一般在其他的filter之前 -->
<filter>
<filter-name>encode</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<!-- encoding:指定解决POST请求乱码 -->
<init-param>
<param-name>encoding</param-name>
<param-value>utf-8</param-value>
</init-param>
<init-param>
<!-- forceEncoding:顺手解决响应乱码 -->
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encode</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- 支持rest风格的filter -->
<filter>
<filter-name>HiddenHttpMethodFilter</filter-name>
<filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>HiddenHttpMethodFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
1.Spring配置
2.SpringMVC的配置
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.1.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd">
<!-- 让SpringMVC只扫描控制器 ;禁用默认的规则-->
<context:component-scan base-package="com.martin" use-default-filters="false">
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="WEB-INF/pages/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
<!-- 配置文件上传解析器 -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="defaultEncoding" value="UTF-8"></property>
<property name="maxUploadSize" value="#{1024*1024*20}"></property>
</bean>
<!-- 扫静态资源 -->
<mvc:default-servlet-handler/>
<!-- 扫动态资源 -->
<mvc:annotation-driven></mvc:annotation-driven>
</beans>
3.Mybatis的配置
4.其他
ping>
encode
/*
1.Spring配置
2.SpringMVC的配置
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.1.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd">
<!-- 让SpringMVC只扫描控制器 ;禁用默认的规则-->
<context:component-scan base-package="com.martin" use-default-filters="false">
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="WEB-INF/pages/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
<!-- 配置文件上传解析器 -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="defaultEncoding" value="UTF-8"></property>
<property name="maxUploadSize" value="#{1024*1024*20}"></property>
</bean>
<!-- 扫静态资源 -->
<mvc:default-servlet-handler/>
<!-- 扫动态资源 -->
<mvc:annotation-driven></mvc:annotation-driven>
</beans>
3.Mybatis的配置
4.其他
3.测试