JavaWeb笔记
JavaWeb笔记
1. js简单复习
1. 鼠标悬停效果实现
在head标签中的script标签中引入
在tr标签中: onmouseover=”调用的方法()”
方法中的event:当前发生的事件,event.srcElement:事件源
onmouseout:当鼠标离开时
系统提供的对象:window:当前浏览器窗口,窗口显示的所有内容叫document(给定浏览器窗口中的html文档),浏览器上面的导航栏叫location
```js
window.onload=fuction(){
//当页面加载完成,需要绑定各种事件,举例:
var fruitTabl=document.getElementById(“tb_fruit”); //通过document对象获取fruit表
var rows=fruitTabl.rows;//获取表格行数
for(var i=0;i<rows.length;i++){
var tr=rows[i];//循环获取每一行的所有列
tr.onmouseover=showBGColor;//1.绑定鼠标悬浮设置背景颜色事件(事件绑定)
}
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
### 2.更新单价
-----
## 2.servlet
### 1.tomcat

### 2.快速入门
1. 获取参数:用户在网站输入发请求:如`action=add`
2. 项目中*web.xml*找到`url-pattern= /add` 然后找到`servlet-name = AddServlet`,找到和`servlet-mapping`中同名的`servlet-name`,然后找`servlet-class`的路径来找到对应的类
3. 看用户发送的请求,用户发送的是`method = post`请求,故tomcat会执行servlet类中的`doPost`方法
4. 新建项目:
- 新建模块,在模块中添加web模块,创建arctifact-部署包(war包:web项目的压缩包)
- lib-artifact:现有artifact,后来才添加jar包(javaapi的包),此时,jar包并没有添加到部署包中。在projectStructure中会有提示。在problems中的fix可以添加。
- 默认的`localhost/项目`访问的是欢迎页`index.xml`,在tomcat中的web.xml可以设置<welcome-file-list>标签里面的值来更改欢迎页访问谁,默认是`index.html`。或者在自己的web.xml中设置也行。
5. 修改请求参数中的中文乱码问题:
- post方式下`String fname = request.getParameter("fname")`之前,需要先设置一下编码,`request.setCharacterEncoding("UTF-8")` (request就是浏览器的请求,对应这个项目就是表单提交请求,也就是点击添加按钮)。
- get方式基于tomcat8,不需要设置编码。
- 注意:设置编码那句话必须在获取参数之前,否则已经获取到乱码了就不能再改了。
### 3.servlet继承关系以及service方法
1. 
2. 
3. **service方法:**
- ```java
String method = req.getMethod();//获取请求的方式
获取完之后,if判断,请求是哪个就执行
doXXX
方法。当执行方法时,默认你重写了父类的doXXX方法,而重写的方法是
super.(req,res)
即默认是调用父类的方法。或者你没写doXXX方法,也会调用父类的方法。而父类的方法会通过获取协议值来判断是否sendError(405/400,msg)
msg是通过support的key值来获取的报错信息。
- servlet的生命周期:
servlet是tomcat容器帮我们去维护,自动调用方法
生命周期:从出生到死亡的过程,init()初始化——–>service()服务———>destroy()销毁。
只有第一次发请求的时候会初始化,即调用init()方法。servlet会进行实例化,初始化,然后服务,service()。
容器的销毁会调用destroy()销毁方法
Servlet实例tomcat,只会创建一个,所有的请求都是这个实例去响应。默认情况下,第一次请求时,tomcat才会去实例化,初始化,然后再服务。可以提高系统的启动速度。缺点:第一次请求时耗时较长。
如果想提高初始化速度,可以设置servlet的初始化时机:在servlet标签中添加
标签,将标签内容设置为1,数字越小,启动的时间越靠前。设置了1之后tomcat直接启动并且创建。 servlet在容器中是单例的(单个的实例,不管几个请求,都是同一个),线程不安全的。线程不安全:一个线程需要根据这个实例中的某个成员变量值去做逻辑判断。但是在中间某个时机,另一个线程改变了这个成员变量的值,从而导致第一个线程的执行路径发生了变代。线程不安全,我们尽量不要在servlet中定义成员变量的值,不得不定义的话也不要去修改成员变量的值。
4.HTTP协议
1.请求和响应:
2.会话:
1. http无状态:
- HTTP会无状态,服务器无法判断这两次请求是同一个客户端发过来的,还是不同的客户端发过来的。
- 现实问题举例:第一次请求是添加商品到购物车,第二次请求是结账;如果这两次请求服务器无法区分是同一个用户的,就会导致混乱。
- 如何解决?——————->通过会话跟踪技术来解决无状态的问题。
2.会话跟踪技术:
- 客户端第一次发请求给服务器,服务器会找请求要session(服务器获取session),获取不到,则创建新的,然后告诉客户端他的sessionid是什么(服务器响应给客户端)
- 下次客户端给服务器发送请求时,会把sessionid带给服务器,服务器这次获取就可以获取到,那么服务器就判断这次请求是不是和之前的某次请求时同一客户端,从而区分不同的客户端,解决http无状态的问题。
3.保存作用域:
同一客户端的(浏览器)session可以互相获取,不同的不行。同一webapp可以获取,不同的不行。session的作用域保存session的id和k,v值,可以存放n个kv值,但是重命名key,value值会被覆盖掉。
4.内部转发和重定向
服务器内部转发:一次请求响应的过程,对于客户端而言,内部经过了多少次转发,客户端是不知道的。地址栏没有变化。
重定向:两次请求响应的过程,客户端肯定知道URL有变化。地址栏有变化。
5. Thymeleaf-视图模板技术
1.快速入门
- servlet从3.0开始支持注解方式的注册,在servlet类前直接标注
@WebServlet("/路径")
,省去在web.xml中配置映射路径等步骤。 - Thymeleaf:添加jar包,然后再在web.xml文件中配置。然后cv ViewBaseServlet:processTemplate方法,处理模板——>完成资源的转发和数据的渲染。
- 然后在web.xml中添加配置,配置视图前后缀。
2.渲染index页面
- 通过thymeleaf语法,判断session中的fruitList是否为空。不为空:将list中的每一个元素迭代取出来。在每一列进行渲染,数据库中取出的元素动态放在对应的列。
3.thymeleaf review
知识点集合,上面都有,略。
4.保存作用域
- 原始情况下,我们认为有四个:page(页面级别,现在几乎不用),request(一次请求响应范围),session(一次会话范围),application(整个应用程序范围)
- request:一次请求响应范围:第一个重定向取不到值,因为是重定向,相当于两次响应。第二个可以取到值,因为是请求转发,一次响应,故可以取到值。
- session:一次会话范围,只要session没有过期失效,不管采取的是哪种方式,都可以获取到。但是面对图下情况,两个客户端分别访问不同的servlet,不可以获取到,因为不是同一个session。
- application:整个应用程序范围,相当于是公共的,不同客户端都可以取到。需要获取application保存作用域保存的数据:servlet上下文
ServletContext application = request.getServletContext();
- request:一次请求响应范围:第一个重定向取不到值,因为是重定向,相当于两次响应。第二个可以取到值,因为是请求转发,一次响应,故可以取到值。
5.路径问题
相对路径和绝对路径,略。需要注意的是可以写成下面那两行那样的:@{}就相当于
localhost:8080/pro10/
了
6.小实战1(2 3 4跳)
- 只要不是form表单提交,或者method=post,都是get请求。
- 隐藏域:功能类似于文本框,它的值会随着表单的发送也会发送给服务器,但是界面上看不到。
7.review(和234有关)
6.servlet-mvc优化(重要)
1.旧的结构:
2.新的结构:
- 将几个servlet进行功能集合:将增删改查几个功能做成方法集成在一个servlet中。
- 通过if判断:如果请求是空的,那么就赋给请求”index”,进入index页面。如果请求不是空的,进入switch语句判断:是什么就进入对应什么的页面。
3.修改:
不用switch语句,而用method属性进行获取方法,遍历methods方法列表进行if判断:如果方法名和operate值相等,就用反射执行这个语句。但是会有弊端:这只是一个servlet中遍历各种方法,如果是多个servlet呢?每个servlet都要写反射吗?——>引出DispatcherServlet:核心控制器/中央控制器:处理所有请求,根据请求的不同来赋值给后面的不同servlet,再根据不同的servlet赋值给不同的方法上去。
4.引出mvc原理:
- servlet接收
*.do
:意思是所有的访问请求都会由这个servlet进行接收处理。 - 获取该请求的servletpath,比如 /hello.do
- 进行字符串截取:/hello.do——>hello
- 对应下级servlet(controller):hello——–>helloController,此时helloservlet将不复存在,而是把原来的servlet类改为普通类。那么如何对应controller?:通过配置文件applicationContext.xml进行约定——>JavaBeans:设置
标签的id和class属性,作用:servletPath中涉及的名字对应的是你设置的这个id,就用class路径对应的controller类来处理。约定好了applicationContext.xml如何将DispatcherServlet联系起来?——–>通过DispatcherServlet的构造方法,用流获取applicationContext.xml文件的内容:然后 - 创建DocumentBuilderFactory对象
- 创建DocumentBuilder对象
- 创建Document对象(org.3c.dom),传入配置文件的流。
- 获取所有的bean节点:调用对象的方法getElementsByTagId并传入bean,得到beanNodeList
- for循环这个List获取每一个节点然后进行if判断,如果这个节点是元素节点,就获取它的id和name属性,通过name(全类名),找到它的对象,再把id和这个对象存入hashmap中(即解析好后放入map容器中)。
- 总结:这样通过
中的标签设定,通过DispatcherServlet能直接由路径找到对应的controller,然后再用笔记6.3中的步骤(赋operate的值),获取这个controller中的对应方法,然后反射执行,即:设置 标签中的id和controller的全类名,就可以直接通过访问路径来执行对应controller。
5.提取视图资源通用代码:
继续修改:
- 因为controller中每个方法都要重定向,不妨放在DispatcherServlet进行统一调度:即controller中方法结束直接return “redirect:xxx页面”(视频中的更新功能要给用户展示更新后的界面,因此更新方法最后需要跳转进入fruit界面,也就是刷新一下fruit界面)
- 然后在DispatcherServlet获取该方法的反射调用后的返回值
- 然后进行视图处理:也就是在DispatcherServlet中进行真正的重定向。如果返回值没有redirect前缀,则直接进入页面。
6.在DispatcherServlet中统一获取参数以及视图处理:
- 将在controller中的各种方法中的
request.getParameter("xxx")
删除,转而在形参列表获取参数(此时还没有将request中的字段和形参列表的参数联合起来),降低耦合。 - 在DispatcherServlet中统一获取参数:先for循环获取所有方法,然后每个方法用
method.getParameters()
获取当前方法的形参,返回的是数组,需要设置(因为数组中显示的是arg0,arg1…而不是显示形参的名字:在idea中设置build–>java compiler并且添加如图参数),这样就能获取方法的形参。
- 再遍历
2.
中获取的数组,循环得到方法的名字(2.
中返回的是对象) - 再判断获取的形参属于什么类型(request?response?session?),那么就不是通过请求中获取参数的方式了。
- 总结:在controller中不需要先获取request中的parameter了,只需在形参列表规定好,DispatcherServlet会自动获取。
7.总结:
1.优化总结:
- 开始是一个请求对应一个servlet,会导致servlet过多——>用一个servlet判断,通过operate的值来决定调用servlet中的哪个方法(controller)。
- servlet如何调用方法?—–>判断operate的赋的值和方法名是否一致:一致就反射调用,否则抛异常。
- 每个servlet都反射,如何优化?—->设置中央控制器DispatcherServlet
- DispatcherServlet都有何功能?——>
2.DispatcherServlet的功能:
- 通过访问路径和读取applicationContext.xml(通过dom技术去解析xml文件,在中央控制器形成一个beanMap容器,用来存放所有的Controller组件)的设置,匹配到对应controller。
- 然后根据operate的值,通过反射调用controller中的对应方法。
- 获取参数,也就是直接读取形参列表的参数,直接在形参列表设置要读取的request字段:获取即将要调用的方法的参数签名信息存放在数组,然后获取名称,参数值。通过获取类型,还要考虑类型转换。
- 执行方法:通过反射执行方法。
- 视图处理:获取反射的返回值,如果返回值的字符串匹配”redirect:xxx”,就重定向哪,否则匹配xxx,就…,以此类推。也就是根据方法的返回值字符串来完成跳转的操作。
7.servlet-api
1.servlet初始化:
- 如果我们想在servlet初始化阶段带一些值,可以重写init()。
- 前提是要在web.xml中的servlet标签中配置
的kv值,然后再init方法中获取config对象,获取初始化参数值(v值)。 - 或者使用注解也可以,
@WebServlet(urlPatterns={"xxxx"},initParams={@WebInitParam(name="xxx",value="xxx"),@WebInitParam....以此类推})
2.servlet上下文设置一些值:
- 在web.xml中配置
,设置kv值。可以再初始化中获取:getServletContext()。 - 在服务方法中也可以通过request对象获取:req.getSession.getServletContext。
- 获取初始化值servletContext.getInitParameter()。
3.mvc-service的引入
- 什么是业务层:
- model1(jsp)和model2(mvc),mvc:model(有很多种,简单的pojo,难的如业务模型组件,数据访问层组件:*pojo/vo,dao,bo**,bo是业务模型组件),view(视图,网页,和用户交互),controller(控制器,接待请求)*。
- 区分业务对象和数据访问对象:dao中的方法都是单精度方法(一个方法只考虑一个操作),bo中的方法是复杂的业务方法,如注册功能,需要多个dao方法的组合调用,才能完成这个功能。
- 引入业务层(重点):
为什么要有业务层?:以前调用controller里面的各种业务方法,业务方法里还有很多dao层方法重复写,会让controller方法代码冗余。现在在controller层和dao层中添加service层,许多dao层方法的调用集合到service层,controller层调用service层的方法实现更复杂的业务逻辑。实现了解耦。
ioc:耦合/依赖:层与层的设计是依赖的,不能离开,也叫耦合。系统架构和设计的一个原则是:高内聚,低耦合。
以前是在controller中new xxxServiceImpl,才能调用service方法,现在为了降低耦合———>如何做?
如何反射创建对象?—->io流读取applicationContext.xml,创建document对象,获取bean节点,放入map容器中。(前文中有讲过)
原理1(重点!):在applicationContext.xml中配置bean,bean就是组件,spring通过控制反转(创建好Map容器,反射创建对象,放入map中,key是对象名,value是创建好的对象。beanFacatory接口中定义getbean方法,在ClassPathXmlApplicationContext中实现:根据id从map容器中获取对象。),bean的id是对象名,class是哪个类的对象。
修改dispatcherservlet:在其中的初始化方法中添加beanFactory对象,即当dispatcherservlet加载时自动创建beanFactory对象。
原理2(原理1是知道了需要哪些组件,但是还不知道组件和组件之间的关系):在
标签中设置属性,即用 标签设置: 是属性名,是引用其他bean的id值。即描述bean之间的调用关系。 标签的调用关系是怎么实现的?——>承接上文,在ClassPathXmlApplicationContext中获取对象之后,需要组装bean之间的依赖关系:for循环拿到每一个bean(map中的对象),读取bean中的内容(怎么读取?再次for循环,判断是否为元素节点并且节点名是否为property,然后取出name属性和ref属性),通过ref的值找到对应的对象(在map中找到那个ref的bean对象,这个叫对象a),然后给当前bean对象的name属性赋值(在map中找到当前对象,叫对象b)。获取当前对象(b)的属性,并改为ref对象(a)的属性。简单来说就是,引用谁(ref哪个类)要赋给谁(bean中的属性名name)。 **在bean类中:Ref name = new ref()**。
- 总结:控制反转(ioc)和依赖注入(di): 以上。
4.filter过滤器
- 在客户端和servlet中间有过滤器
客户端发来请求和接收响应,浏览器执行请求和进行响应都会经过过滤器。
- 如何实现过滤器?——> servlet类实现 Filter(注意是javax.servlet.Filter的包),配置
@WebFilter("拦截路径")
也可以在web.xml中添加路径,和servlet一样,只是servlet换成filter。 - 如何放行?——->重写doFilter方法,
filterChain.doFilter(servletreq..,servletrsp..)
然后执行service - 当执行完响应时,又会拦截住,执行
filterChain.doFilter
这句话之后的代码。 - 可以设置通配符,如 *.do ,表示 .do结尾的都拦截。
- 过滤器链:过滤器的角色不一样,每个过滤器各司其职。
要配置链的话,注解按全类名排序顺序,xml配置文件按配置的顺序。
- 过滤器的应用:
- 事务管理的应用:
所以事务管理就不能在dao层进行操作,需要在service层进行管理:
继续将事务管理提前
因为之前需要同一个connection,所以使用threadlocal来管理,设置好conn,之后get即可。
事务管理涉及到的组件:
OpenSessionInviewFilter
TransactionManagerThreadLoca
ConnUtil
BaseDAO
- ThreadLocal
- 本地线程:我们可以通过set方法在当前线程上存储数据、通过get方法在当前线程上获取数据。get(),set(obj)
4.01 Listener监听器
1.
servletContextListener:监听servletContext对象的创建和销毁的过程(观察者模式)。
HttpSessionListener-监听HttpSession对象的创建和销毁的过程。
ServletRequestListener-监听ServletRequest对象的创建和销毁的过程。
2.
- ServletContextAttributeListener-监听ServletContext的保存作用域的改动(add,remove,replace)
- HttpsessionAttributeListener-监听Httpsession的保存作用域的改动(add,remove,replace)
- ServletRequestAttributeListener-监听ServletRequest的保存作用域的改动(add,remove,replace)
3.
- HttpsessionBindingListener-监听某个对象在Sessioni域中的创建与移除
- HttpSessionActivationListener-监听某个对象在Sessioni域中的序列化和反序列化
- 用哪个listener,servlet实现对应的接口,重写方法,加
@WebListener
注解,或者在web.xml中配置:标签。 - 监听上下文启动,在上下文启动的时候去创建虹oc容器,然后将其保存到application作用域。后面中央控制器再从application作用域中去获取IOC容器。
- dao组件有多个方法,同一个线程,才能共享数据,可以从线程上面获取。(像旋转火锅)
4.02大总结
5.QQZone
6.书城
7.Cookie
什么是cookie?—–>浏览器分配给客户端的session id是以cookie的形式保存的。cookie是在客户端保存数据的,session是在服务器端保存数据的。
怎么保存数据?——>创建cookie并保存:
设置cookie的有效时长为60秒:cookie.setMaxAge(60)。
cookie的path和domain:随着本地cookie越来越多,每次访问时不能全把cookie带上。浏览器会通过这两个属性和访问地址作比较,从而决定是否携带这个cookie。
cookie.setDomain (pattern);
cookie.setpath(url);
cookie的应用:记住用户名和密码,免登录等等。注意cookie是保存在本地的,所以最好在自己的设备上保存。
6.kaptcha技术:
- 验证码:为什么需要?—–>防止恶意攻击。
- 如何使用?——>在web.xml文件中注册KaptchaServlet,并设置验证码图片的相关属性。
- 在html中设置一个img标签,设置src等于KaptchaServlet对应的url-pattern
- kaptcha验证码图片的各个属性在常量接口:Constants中
- KaptchaServlet在生成验证码图片时,会同时将验证码信息保存到session中
因此,我们在注册请求时,首先用户文本框中输入的验证码值和session中保存的值进行比较,相等,则进行注册。
8.正则表达式(8和8以下js)
- 定义正则表达式对象:
- 对象形式
var reg = new RegExp("abc")
- 直接量形式
var reg = /abv/
- 匹配模式:g全局匹配,i忽略大小写匹配,m多行匹配,gim可以组合使用(不区分先后顺序)。
var reg = new RegExp("abc","gim");
,var reg = /abv/igm;
意思相同。
- 定义待校验的字符串
- 校验
- 元字符:
- 字符集合:
中括号[ ]:若目标字符串有中括号中的任意一个就可以匹配。不加中括号必须精确匹配,如/abc/,目标字符串必须有连续的abc才行。
中括号加小尖号^,表示目标字符串有除括号内以外的才匹配。
-:表示范围,从哪儿到哪儿。
- 出现次数:
- 或者:|
- 常用正则表达式:
- 注意:一般使用正则表达式,百度就行。
9.Vue
传统js创建对象的两种方式:
vue创建对象的的方式:
快速定位操作的对象,省去了传统的获取步骤。
绑定元素的属性:v-bind表示绑定value属性,v-bind可以省略,直接写成: 。v-model表示双向绑定:以前msg的值决定输入框的内容,现在v-model可以让输入框的值来改变msg
v-model:value可以直接写成,v-model=xxx。trim可以去除首尾空格:v-model.trim=xxx。输入框内容的首尾空格会被去除掉。
v-if,v-else,v-show:if-else可以进行编程操作,但是v-if和v-else之间不能有其他节点。v-show:根据=的值的true或false来决定display的值(也就是显示或者不显示)。
迭代v-for:语法v-for=”xxx in xxx”,for循环。
v-on,事件驱动与事件绑定:之前是onclick:”方法”,现在v-on:click= “方法”(注意在这儿的方法意思是调用,不能加(),加了括号意思是方法的返回值)。split(”x”):意思是以x分割,若什么都不写就是把每个字符都分割。v-on:click可以简写为@click
```js
var vue = new Vue({
data:{//自己定义的变量
msg:”hello”
}
methods:{
xxx:function(){//自己定义的方法名
this.msg.spilt(“”).reverse().join(“”)//翻转字符串
}
}
})1
2
3
4
5
6
7
8
9
9. function(event)可以获取鼠标坐标:
10. 侦听属性:watch
```js
xxx:function(newValue){ //监视xxx这个属性的变化,如果它变了,就继续操作。
}
11.vue对象的生命周期:对象创建之前和之后,数据装配之前之后,数据加载之前之后
10.Axios
- Axios是Ajax的一个框架,简化Ajax的操作。
- Axios执行Ajax的操作步骤:
添加并引入axios的js文件。
客户端向服务器端异步发送参数值。
如何发送?——->前端部分:
后端部分:接收打印
- 当点击按钮触发axios时,axios会发送一个带普通请求参数值的异步请求,服务器端接收。
- 那么如何进行响应?——>设置编码然后响应
前端接收打印结果(成功响应时进行,否则catch),有问题会执行catch(异常处理)。
- 发送的请求体是json格式(客户端向服务器发送的是json格式的数据):
- json:是一种数据格式,kv值显示,有点类似python的字典。json表达数据更简单。json很灵活,内容可以是各种数据类型,可以是对象,可以是json嵌套。
- 重点:
- 如何使用:
- 若user是从数据库查出来的,需要将java对象转换为json格式的字符串,响应给客户端
mime-type是告诉浏览器响应的是什么数据。
- 前后端分离: