------struts2整合spring-----------------------------------------------------
struts2过滤器负责在Tomcat启动时运行,加载和创建静态注入项(也可以在配置文件中加载我们写的类的
),管理struts2容器。负责加载Action,接收特点结尾的请求,为每个请求创建对应Action对象,执行其
相应方法...
不同配置文件在init时加载,其中相同项,后加载的会覆盖先加载的。plugin配置中会有新的工厂,用于
整合spring,启动时加载,覆盖掉原有工厂,这样就会在创建Action对象时把spring容器中同名的对象注
入进来。而spring利用一个监听器,监听ServletContext,在应用启动时即加载spring配置,启动spring
容器创建好所有对象供使用。所以这里既不用手动加载spring配置文件,也不用手动在spring容器中配置
Action对象,向其中注入spring的对象。只要一个整合包,替换生成Action的工厂,一个监听器,应用启
动时加载spring创建对象,那么在用户请求时,工厂就会自动调用spring,向Action注入同名属性。好像
Action要继承ActionSupport,模型类要实现ModelDriven拦截器(切面,代理类?),并在Action中
getModel得到这个属性才能注入(好像没有初始化会自动为你先创建,再注入),通过值栈注入和存取信
息。
改变创建Action的方式:访问Action,则调用你写的工厂创建Action,因为你写的只是打印一句话,而请求
要访问Action的某个方法,所以报一个空指针异常,但打印了一句话说明是调用了你写的工厂企图创建
Action对象!!(工厂是启动时(核心过滤器)就静态注入(加载配置文件)的,也就是创建了,但访问
Action时才利用Action配置和工厂来动态创建Action对象!!)
struts2配置中:bean是静态注入工厂,constant...才是配置成这个工厂!!
plugin配置在整合jar包中,覆盖原有创建Action的工厂和工厂配置!!
struts2中最核心的产生Action的类:DefaultActionInvocation:被注入ObjectFactory(面向接口编程,
多态),并调用其buildAction方法创建Action(代理)
struts2流程:启动核心过滤器,转换request,response,设置编码,其常量值是default.properties中配
置的。获取ActionContext,参数是request,response.ActionContext是绑定到当前线程的(说明一个用户
有一个副本)。获取struts2的IOC,DI(去查!别不专业,别屁也不会!)容器,该容器供注入各种对象.其
结构就是一个Map,键为Class形式,因为会有不止一个此类型对象,值为一个Set.调用该容器获取(没有
就创建)值栈,也是利用多态(ValueStack)建立OgnlValueStack注入到容器。把ValueStack分别放到
contextMap和root(CompoundRoot,去查前面学的!!!).
??查:request,response..都会包装进????ActionContext的Map里??
ValueStack中的OgnlContext也被存入ActionContext的Map中(同一个引用),所以存放在值栈中的元素在
contextMap中也有一份!
request是struts2包装的request,用EL表达式取的原理是其解析类去几个域中找(getAttribute),而返
回的包装request的getAttribute方法,会让EL先在request域中找,找不到再到值栈中找!!
拦截器的责任链模式:ActionInvocation(DefaultActionInvocation)中将拦截器都加入集合,获取迭代
器,然后,在其invoke方法中,是用if而不是while来获取拦截器,拦截器的intercept方法接收
ActionInvocation作为参数,其中再次执行ActionInvocation的invoke方法,这时拦截器并没有执行完,
那么又来到if获取一个拦截器,然后还是返回if...直到执行完所有拦截器,开始执行Action,而每一步相
当于调用:一个拦截器执行到一半调用ActionInvocation的invoke,其中调用另一个拦截器...所以在最后
一个拦截器调用ActionInvocation的invoke时,因为没有后续拦截器而进入Action的执行,执行完自然回
到该拦截器的调用点,执行完剩下的部分,return,而该拦截器终于执行完了,则上层ActionInvocation
的invoke也调用完了,直至执行完,return,则上一个拦截器的调用也执行完了,继续执行其剩余部
分,return,...这样相当于间隔着ActionInvocation,倒序依次回归调用点,就像递归调用的顺序.
看不同的拦截器:如果直接在调用ActionInvocation的地方返回,即return invocation.invoke(),那么
它是没有后续部分的,自然回到这个调用点的时候,它也直接返回上层调用它的调用点。也就是传说中的
“只走一次”(其实也回到它的调用点,只不过它的调用点就是它的终点)
判断依据:return invocation.invoke()的走一次,return 一个字符串的,走两次
(invocation.invoke()在此前调用)
特别的Exception Interceptor:在第一个执行,最后返回到它,内部是try,catch,在try中执行
invocation.invoke(),一旦发生异常,catch捕捉处理,这个Interceptor是最后return,是走两次,回到
调用点后再return,发生异常就捕捉,反正是最后经过它,什么异常都捕捉的到!!
---------------------------------------------------------------------------------------------------------------------------------------------------
----------思想--------------
一定要有解析访问,类间方法调用,解析判断标签,readLine标签间内容封装成对象,调用中封装的对象参
数传递,元程序形成servlet程序,程序只是调用资源和处理数据的工具,我们得到的是其io输出或返回
值的思想!!!至于这边出来的效果,则是另一个程序浏览器根据格式也就是各种协议解析io,解析脚本
,输出给我们的效果!它也是一个处理数据显示的工具!我们访问浏览器程序,浏览器输入网址后底层用
Socket访问服务端程序(ip地址,端口,阻塞式响应,网络流操纵操作系统底层),服务器程序负责解析
,调用,输出,返回,这边的程序接收,解析,输出,显示给用户。底层都是操作系统,和程序调用(甚
至不同主机,操作系统间的),数据解析,封装对象,参数传递,程序处理,返回,输出。
服务器通过加载配置文件加载各种类创建各种对象,将我们写的子程序加入到其主程序中。响应访问时解
析url,调用相应类相应方法,没有对象会创建,Servlet则是单例,创建即存在于内存中,与服务器一起
运行。执行到相应程序转发:一定要有面向对象思想:转发类(Dispatcher)的方法(服务器程序)会解析
地址,访问(调用)相应程序,如果是jsp,第一次访问会(调用jsp编译器,一个java类)翻译成servlet,然后
访问该程序。
标签解析:执行jsp时,遇到标签根据引入的标签库找到标签解析类,执行其方法(传递Web对象过去),
控制标签体(封装成了对象传递了过去,一定要有封装,引用传递,传递封装信息的对象,执行程序文件
后单独产生数据输出或返回值的思想,不要把程序文本看成是用于显示的文本!程序只是一个解析你请求
进行调用的,一个产生结果的工具!!你要的文本不是这个程序的文本,而是这个程序解析,调用资源,
整合调用其他程序,执行完毕后返回给你的数据!jsp也一样!是用于显示的程序,但不是显示本身!是
被一行行解析翻译成servlet之后,html文本直接输出,标签,EL,程序代码段要封装传递数据(jsp编译
器翻译JSP时:readLine标签开始结束符间的数据,封装成对象,调用标签处理器类的方法传递参数给它
,这样形成Servlet程序,编译器相当于元程序,产生Servlet程序的程序,然后我们调用Servlet,已经是
没有标签的形成了正常对象方法调用的程序)参数,调用,执行)在主程序中的执行,显示。一定要有对
象间调用,子程序加入主程序,传递对象参数这些思想,语句的作用就是它字面表达的意思,可以分析到
虚拟机、操作系统之上程序解析和调用资源,调用子程序的过程,操作系统和虚拟机、服务器、浏览器也
不过是运行的程序,至于操作系统底层解析,资源调用和执行,则不用再分析。顶多多线程时知道向操作
系统申请多个线程。
标签解析:jsp翻译程序将标签翻译成对标签处理器类的调用,并负责读取封装标签体数据,传递标签体
对象和jsp对象(servlet)的各种Web对象参数(访问时服务器程序创建,通过调用和作为属性实例化对
象的方式传递给各种对象)过去。
struts标签:其处理器程序是可以解析标签形成url地址,表单,token...各种东西输出给用户,可以解
析OGNL表达式从值栈中获取各种数据的。
拦截器:Action被代理后经过各种拦截器,调用其intercept方法,需要传递对象封装数据就定义在该类
的属性中或直接参数传递,访问Action时,核心过滤器解析地址,拦截器封装表单数据存入值栈,拦截器
判断ModelDrivern向模型类和Action对象注入,拦截器校验表单...
所谓框架就是这种产品:可以在配置文件中无限灵活配置(覆盖)使用什么拦截器,就像拆卸组件。都做
成组件形式,无限灵活拆解应用,形成无限复用!!
熟能生巧。练多了就想明白了:struts启动加载plugin包中的配置文件,用spring方式创建Action的工厂
覆盖原有工厂,那么就在创建Action时利用spring容器中同名对象注入到Action.
AOP:代理,切面,切入点表达式,通知,切面类...
任何表达式,都需要标签解析的支持。表达式本身,只是一种形式,一个约定俗成的协议,标准。重在怎
么解析它。
ActionContext和ValueStack:每-次-访-问-动-作-类都会创建,一直保持在你的线程中(ThreadLocal,你
的副本),而OGNL去它们中取数据(需要标签解析器的支持),那么当然根的栈顶会压入此Action对象!!
如果有模型类,还会压入模型类对象!!
ValueStack对象中一个存储结构叫做根(注意!!不是ValueStack对象本身!!),在contextMap中也找
得到,是一个List结构!!
s:debug标签:访问contextMap和ValueStack,显示给你
struts源码:获取request会包装它,重写getAttribute方法:先按父类原始request找,找不到从根中依
次找对象的属性,没找到再到contextMap中找!!
vs.getRoot:CompoundRoot:contextMap中的根,继承了ArrayList!!(好像是包装类)
OGNL表达式获取contextMap数据:用#开头(只是解析上判断,到哪里找呗),获取根中对-象-属-性,直
接写属性名,会从栈顶对-象一直往下找!!
Action和ModelDriven中属性生成get,set方法:动作类封装参数:
三种数据封装:Action作为model,提供setter方法------>框架调用set,和表单字段同名属性
创建model对象,页面通过ognl封装:Model属性提供get,set方法,ognl那边用model对象.属性的方式封
装。Model对象即使不创建,框架也会帮你创建!
使用ModelDriven接口对请求数据封装:判断Action的这个接口,调用getModel,所以必须先new出这个
Model属性对象!!getModel方法会在动作方法前执行,把模型对象压入栈顶!故封装表单数据set时会先
调用栈顶对象的该方法!
考:(也是工作中必须得深入明白的)创建Action的三种方式:Action接口的就是定义了一些常量(如
SUCCESS),自动执行其execute方法,ActionSupport因为实现了多个接口(自己去读源码!!)可以使用
验证,国际化等多个功能,
考:常用的各种拦截器,名称,作用:动态参数和静态参数注入:params(就是封装用户表单数据,看源
码发现它识别各种方式的提交,比如request,然后封装其数据到访问的Action),staticParams(配置中用
param子标签,相当于给Action属性注入默认值)
ModelDriven拦截器完成上面的第三种动作类封装参数功能
玩一下:struts.xml中覆盖defaultStack中拦截器,去掉一个看效果!
拦截器:代理中调用,采用责任链设计模式,将所有拦截器放在一个集合中链式调用,像一个递归,然后
倒序返回调用点。去多看源码!!!
struts-default包:继承此包,里面定义了各种拦截器,默认使用一些,还有结果集,各种bean...类似
spring容器的配置,加载时利用反射创建这些对象,还生成代理...不继承这个包很多这里面的功能你都
不能用了!struts.xml中自定义拦截器会覆盖掉默认的,所以要把默认的defaultStack也加上!!
验证与类型转换:
编程式:复写validate方法(去查接口或父类源码!!)对所有的方法验证,加SkipValidation标签才能
跳过某方法.编写validate+方法名(首字母大写)方法针对特定方法
INPUT:返回视图
addFieldError方法与s:fielderror标签:取错误集合回显
校验,也是某个拦截器做的,里面的校验类型,又是特定的类,配置去查源码!!
结果集:
s2sh整合:
src下文件会被编译到服务器应用的classes目录下,该目录已经被指定为classpath目录(执行程序就会
寻找该目录)
步骤:spring产生sessionFactory,写Dao,写声明式事务处理(AOP,代理),spring创建Action,注入
service
--------------------------------------------------------------------------------------------
------------------------------面向切面:------------------------------------------------------
切面,通知:代理类对目标类的增强的那些类,就是切面,用于处理各种增强业务,其方法就是通知。
连接点:客户端调用哪个方法,它就是连接点。切入点:代理类的方法体中(拦截器的invoke或
interceptor方法中)的执行各种操作的条件(if判断)。
织入:形成代理对象的方法的过程(对一个被代理类的增强逻辑)。
想想老方的权限系统,和他说的话:做一个service对象的代理类,客户调用service层时实际上是传递一
个service代理对象给他,用于权限拦截(细粒度拦截,业务逻辑层面的拦截)。在客户调用方法时,是
调用代理类的方法,其内容是对用户权限作出判断(还好自己在讲之前又做了一遍,重在项目实战中反复
的练习理解啊!!给自己自信和力量,快速进步,实习,挣钱,争取自己的一切!!),这权限拦截逻辑
就是切面!面向切面(也就是代理)就是对访问目标类的拦截,业务逻辑增强!!这是类层面,业务逻辑
层面的拦截,是一种细粒度拦截!!!
代理类的方法就是目标类的方法+通知,它们是完全松耦合的。
开发时,各个切面是完全没关系的,最后是代理类把它们和目标类整合到一起的(把切面连接到一起!)
。各开发自己的切面,都是面向目标类!!----------这可能就是切面的含义:目标类和目标类的方法(
接口)和各切面对接!!
回调:我们调用HibernateTemplate的get,find...方法,实际是执行execute(最终是doExecute)传入不同
的回调函数(这里是一个类,内部类形式实现其doInHibernate方法),由doExecute调用这个回调函数。
之所以用回调,是因为我们要写一个方法(相当于策略)而自己无法调用,只能传给容器让容器调用。想
想servlet,filter的主方法都是回调,我们写,由服务器来调用!包括Android里的UI程序,是程序员写
好供主程序调用,这样我们点击什么,主程序调用回调函数为什么显示什么,js中的Onclick触发的程序
也是回调,我们写好,不是我们调用,是浏览器收到触发(查查这个专业名词!)后调用。spring注入也
是spring回调我们的set方法为属性注入值。
我们写特定的Hibernate操作,调用HibernateTemplate时,可以自己写回调函数,传给它的execute方法
(其参数是一个回调(类,我们可以用内部类的方式实现其doInHibernate方法))在回调中我们可以使
用session完成最原始的Hibernate操作,因为execute方法调用回调时,会创建session并传入,那么我们
是可以得到这个session直接操作的。
有些东西就是不让我们做才用回调的方式,比如就不让你接触session,sessionFactory,就不让你管事务
处理,都是你配置好了,容器内部干的事情(容器自己添加,调用的!)!
----------------------------Hibernate----------------------------------------------------------------------
session开启事务:
sessionFactory单例、线程安全(读源码):
session,序列化类,事务,缓存,数据库分布式、同步、安全:
绑定到当前线程的session(源码跟踪):去复习Jdbc,想获取仍然要在作用域中,但它只在当前线程有效
持久化对象、副本:
操作持久化对象、刷新:
一级缓存、二级缓存、查询缓存的利用、效率和生命周期:
hql语句取出数据的内存快照:
jdbc连接池、绑定到当前线程的连接:
一个到Mysql数据库的连接(阻塞式方法,创建单独线程,线程中运行的程序Runnable,阻塞式方法支持数
据库操作):
--------------------------------------------------------------------------------------------
-----------基础拾遗----------------------------------------------------
移位:左移相当于乘以2的n次,右移相当于乘以2的n次
数互换位置:
n=m+n
m=n-m
n=n-m
异或方式:
n=n^m
m=n^m
n=n^m
实际开发中还是用中间变量
异或n^m^m=n可用于加密算法
二进制转十六进制:
取低四位:和低四位均为1,其余位都是0的数&,再右移四位,再&
60&15=12
temp=60>>4
temp&15
12转成十六进制的字母:(char)(12-10+'A')
有符号右移,最高位补什么由最高位值决定
要用无符号右移>>>,因为有符号的>>,正数无区别,负数总补1,有效位,永远移不光
获取一个数的二进制表示形式:低1位&1,右移1位
取反:6取反是-7,因为计算机是补码存储,负数补码运算法则为对应正数取反+1,而-7+1正好是6
------------------jsp----------------------------------------------------------------------
jsp与servlet:web.xml文件为每个应用的配置文件,在服务器启动此应用时读取、加载、解析。访问servlet时服务器解析URL,根据该配置文件找到对应servlet.servlet对象在用户第一次访问时创建,此后驻留内存直到应用摧毁或服务器关闭。服务器会为每个应用创建ServletContext对象。为每个servlet请求创建各种对象传递给servlet.jsp本质上也是servlet.在第一次访问时服务器会调用jsp引擎(一个java程序)将jsp解析成servlet.如果jsp不再改动,则此后的访问不会再解析jsp文件而直接调用servlet.访问jsp时(jsp引擎调用其对应servlet时)服务器会为jsp创建九大隐式对象,包括该jsp页面对象(其对应的servlet对象),传递给jsp.jsp页面可调用这九大对象执行各种操作,就像一个servlet.
浏览器、服务器、操作系统都是程序,都在开启时运行,都有阻塞式方法,用户的输入、交互操作或访问在底层都使其阻塞式方法根据端口、协议收到信号后运行,执行其相应响应程序。java程序就是在(收到响应后)创建各种对象封装数据并传递各种对象给其他对象(通过设置字段或方法传参)供调用。服务器各程序不过是长期运行,驻留内存,故各种对象有不同的生命周期。有的是一次性的一段小程序或对象,有的是长期阻塞驻留供响应的程序或对象。配置文件有的是服务器启动时加载,有的是运行时加载,有的是只加载一次,有的是加载多次。有的是一次性读取文件,有的是每次读取文件获取最新内容。要搞清楚创建对象、加载文件的时机,其作用域,线程,和生命周期。
九大隐式对象:request,response,session,application,config,page(this,不是域,page域是指pageContext),out(PrintWriter类型),exception,pageContext
session默认true是访问时创建,因其生命周期较长所以有一个开关可置为false,但通过getSession方法仍可手动创建。exception对象:用jsp的page指令设置某页面为isErrorPage(true)页面,则可在此页面获取exception对象处理(只有这时才能看到九大隐式对象中的此对象)。out对象:默认有缓冲,所有静态数据经过它输出。因为缓冲的原因,会比response.getWriter().write后输出,无论放在它前面还是后面。
page指令定义jsp页面各属性,作用整个jsp.
其中的pageEncoding和contentType属性:分别通知服务器翻译Jsp所用编码和通知浏览器显示编码。Eclipse默认按pageEncoding的编码存储文件到硬盘,不像记事本程序。设置了pageEncoding就不用设置浏览器那个码表了,因为服务器自动将response码表也设置成同样的,所以只要前者即可。
pageContext域:page域,生命周期(其中所存放的数据、其作用域)只在页面范围(页面程序),是四个域中最小的域。大一点的request域作用在整个请求范围内(可能转向多个程序)。Session域作用在会话范围。ServletContext域是最大的域,作用在整个应用程序范围内。
pageContext域:管理所有域的入口,可以调用其他域获取数据。用于自定义标签开发:标签处理器类负责解析处理标签,这时传这一个pageContext给它,就自然获取其他八大隐式对象。
findAttribute方法:逐次从page,request,session,application域中寻找数据。el表达式${}就是调用这个方法。
forward方法:跳转其他资源。
Jsp标签:Jsp动作元素,在Jsp页面提供业务逻辑功能,避免直接写java代码。
静态包含:@include标签,几个页面翻译成一个servlet
动态包含:<jsp:include>标签,pageContext.include(),request.getRequestDispatcher().include(),会在运行时翻译成各自的servlet,性能比静态包含差。
jsp注释与html注释:前者不会打给浏览器,后者会,只不过没显示。后者会把很多没用代码打给浏览器,尽量用前者。
jsp声明:<%! %>其中的代码会定义在service方法外,而脚本片段中的代码默认翻译到service方法中。
脚本表达式:<%= %>直接获取变量或表达式的值。
web.xml中:
<jsp-file>:像配置Servlet一样配置jsp的映射路径。
<error-page>设置错误页面,可设置error-code和抛出指定的异常(其完整类名)的处理页面。特定jsp页面error设定优先于web.xml中的处理。
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
----------------------------------svn------------------------------------------------------
svn:安装时自动配置到环境变量
svn:加入系统服务:
sc create SVN-Service binpath= "F:\Program Files\Subversion\bin\svnserve.exe --service -r
F:\work\svn " displayname= "SVN-Service" start= auto depend= Tcpip
svn:命令行操作这个软件,相当于客户端,svn软件就像我们的Mysql一样!!
svn协议(后面的域名也是localhost,因为在操作系统的host文件中对应本机ip嘛,然后接着就是仓库名称
,因为事先已经通过命令创建了这个仓库,不管它在什么目录下,软件会解析识别的):向仓库发请求,
就像mysql协议,它们都是服务器,所谓协议就是一种文本规范,服务器程序那边当然是解析协议,调用
程序为你访问某个仓库,为你完成某个操作!
你的svn服务配置完之后,要手动点击“启动”!!它才真正被启动,占用3690端口!!不然无法访问!
netstat -ano查看端口
telnet 本机ip 端口号 临时访问
版本导入到user1:
C:\Documents and Settings\Administrator>svn checkout svn://localhost/itheima F:\
work\developer\user1
取出版本 0。
加入一个文件:
F:\work\developer\user1>svn add aa.txt
A aa.txt
提交到svn:要加提交信息,并且不允许匿名用户登录(可以改配置,# anon-access = read打开并改为
write)
F:\work\developer\user1>svn commit -m "fucking add" aa.txt
增加 aa.txt
传输文件数据.
提交后的版本为 1。
这时user2导入版本时,就是user1加入的文件的版本:
F:\work\developer\user2>svn checkout svn://localhost/itheima .
A aa.txt
取出版本 1。
user2更新后提交:
F:\work\developer\user2>svn commit -m "flwfjwl" aa.txt
正在发送 aa.txt
传输文件数据.
提交后的版本为 2。
这时根据最新提交更新user1版本:
F:\work\developer\user2>cd ..
F:\work\developer>cd user1
F:\work\developer\user1>svn update
U aa.txt
更新到版本 2。
乌龟svn软件:直接在文件夹上右键,建立仓库,导入仓库...
乌龟svn软件导入仓库文件格式有误的问题:改仓库db文件夹下的format文件:6改成1-4之间,改不了就
属性把只读去掉!
图标:已导入的显示绿色对号
已导入的项目中新建文件显示问号
右键将文件add之后显示加号
右键这个文件commit:认证失败,此时项目文件夹显示红叹号
说明要改仓库的匿名写权限:anon-access=write
改正后该文件和项目文件夹都显示绿色对号!
user2导入:发现已加入user1加入的文件
再在user2修改该文件,又变成红叹号,表明和服务器上的版本不一致,此时commit
user1再update(!注意!!是它update,而user2是commit!!),发现是user2修改后的文件
svn:权限问题
认证
就是登陆
anon-access = none 匿名用户无任何权限------我没改当然不需要用户名密码了!!
auth-access = write 登陆用户有写权限
password-db = passwd 对应认证文件
注册用户:在passwd文件中:
user1=user1
user2=user2
左边用户名右边密码
授权
就是针对某操作
authz-db = authz 对应授权文件
组:
itheima=user1,user2
[itheima:/] 针对这个仓库,/代表仓库下所有东西,也可以写具体路径
@itheima=rw 这个组下的用户对这个仓库所有东西都可读可写
*= 其他用户什么都不能做
这时你想修改提交,或者更新,就提示你输入用户名密码了
加锁操作:也是需要用户名密码,一个用户锁住一个文件后,另一个用户可以更新,但无法修改!解锁也
用user1
常用操作:不同用户都修改文件,如果一个用户不先更新,那么他可能覆盖另一个用户的操作,这时如果
不更新会提示你该文件已过时,按提示更新,会出现三个新文件:mine自己的,r1最原始的,r2最新的
用edit conflicts打开源文件:
Theirs 他们的
Mine 我的
Merge 合并后的
可以在前两个中选块,合并,可以都要,选择顺序,右键即可找到
选好后,右键文件,Resolve,完成冲突解决(有时候没有这个按钮),然后提交
所以在修改前都先更新,获取服务器最新数据!!
needs lock:必须有锁才能操作
-------------------------------------------------------------------------------------------
------------------------Ajax----------------------------
不是新语言,是新技术,js,xml...结合
核心:Ajax引擎,js发出Ajax请求给它,核心是XmlHttpRequest对象,它是一个js对象,浏览器支持,供
浏览器解析脚本,调用该对象向服务器发出请求,就像响应输入网址或提交表单发出请求一样,底层是
Socket
就当它是js方式访问服务器,java编程吧!!只不过是异步的!!
请求,响应,封装对象,翻译,调用,一切皆是程序,皆是请求与响应,皆是调用与回馈!!
-------------------------------------------------------------------------------------------------------------------------------------
------------------------------------------------jQuery---------------------------------------------------------
它是一个库,用进一步封装的各种对象封装了dom对象,浏览器模型包括dom,bom对象,在页面写js脚本,
由浏览器解释,调用(对象,方法),执行。浏览器也是操作系统之上的程序,浏览器执行js就像调用子
程序,浏览器程序最终是操作系统调用,高级语言最终调用底层,产生各种页面效果!!一切皆程序,调
用,传参,一切皆对象!!
所谓解释型语言,就是解释一行执行一行,所以下面定义的对象上面是访问不到的。想访问,放在
window.οnlοad=function(){}中,函数会在载入整个页面后执行!!
浏览器程序逻辑遇到会解释$(),创建jQuery对象!
firebug:监控浏览器执行脚本的小组件,相当于启动子程序,获取执行每一步的对象信息。
选择器:获取jQuery对象,浏览器程序解析,调用相应类获取
css:根据class或id名创建类,将类属性应用到相应页面dom对象属性中
onclick等:回调,响应用户事件,调用相应js函数,获取dom对象,改其表现样式(属性)
以上都是浏览器程序解析,调用相应函数,类,操作页面元素,执行。
之所以能调用,是因为jquery等文件中将各种形式都定义成了函数,对象,为一些对象添加了函数等。
struts2与ajax整合jar包:新定义了一个结果集,名称为json:将数据库取出的持久化对象转成json输出
多例的Action:用户访问,调用Action工厂,用spring容器中的Action,该Action将其getInstance时会创
建新对象,而不是获得已经创建的单例。这个创建方式属于spring机制,而改变Action工厂是Struts整合
包,配置文件的内容。
-----------------------------------------------------------------------------------------------------------------------------------------
-----------------------------------------js高级----------------------------------------------------
prototype:json没有,只有函数对象有,是函数的一个属性,只有创建(new)函数对象时它才有
prototype,指向同一个prototype.
函数加的属性并不能加到原型上,验证:再次创建一个函数(同一个原型),并没有这个属性。
回调:οnclick=function(){}就是回调函数,供触发事件时浏览器内部调用!!onclick就是Dom对象写好
的函数里的callback参数!!!这里如果引用this,this就是这个Dom对象!!
this:注意!!是谁调用这个函数,this指向谁!!
构造器函数:一个函数对象,可以用它来创建新的对象,新的对象都指向其prototype.
-----------------------------------------------------------------------------------------------------------------------------------------------------
---------------------------------------------------jQuery组件开发:
思想:在jQuery上加方法,还不够,需要加json对象:凡是不能确认的东西都封装成参数数据,由使用者
传递,传递给方法,在方法中使用这些数据,加上逻辑,完成功能.其实和Java类的封装是一个道理,如
果不封装成json对象中的字段而只是调用方法传递参数,那么这些参数不能被所有方法共用!!但注意!
!!!!:js都是对象级别的,所以即使在方法编写里使-用-字-段也一定要找到实-际-对-象-使-用-实-
际-对-象-的-值,而不像Java直接调用类的字段!!!即使Java直接调用类字段也是隐含一个this呢!而
Js中只有实际对象,没有类属性的概念!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!!!!!!
前台Dom:凡是组件代码需要的,都应有按照规定的标识,以便扫描,定位,封装参数。
所谓jQuery组件,插件,就是在jQuery上(原型或本身上)添加属性和功能性方法的代码,加入这些代码
(文件)就有了这些组件可以直接用。这些方法都是高度抽象的,只要你按照要求标识一些Dom,传递一些
参数来调用,就可以实现各种Js功能!所以我们自己可以开发,也可以按要求直接用别人的!!
$.fn.each和$.each都要有的原因:有时无法通过选择器返回jQuery对象($),那么无法用选择器返回的
jQuery对象调用,只能用后者,用参数传入对象,还有jQuery对象来自后台的情况。
???疑问:jQuery.extend和jQuery.fn.extend这两个函数,并没有参数,那么使用的时候,传递哪门
子参数呢?并且还是传递一个,传递两个都行!!(重载?还是什么?)
jQuery中所谓的上下文,就是指调用回调函数的对象!!那么该回调函数中的this,就是这个调用它的对
象!!详见each之类的函数说明!!!
!!!记住吧(源码以后深究吧!!):凡是$.fn函数都只有一个回调函数参数,因为调用者本身的每个
Dom元素就是上下文this,而$.函数都有两个参数:$只代表jQuery源码文件中的jQuery对象,也就是绑定
到window属性上的jQuery对象,因为无法通过选择器获取实际的jQuery对象,所以必须传入jQuery对象!
然后在回调函数中使用这个参数(源码中用一个对象记住,然后使用call,强制让参数循环出的Dom调用回
调函数,这样在用户对回调函数的编写中就可以引用this,指代这些Dom,这些Dom就是回调函数上下文,也
就是this!!)详见代码例子中自己实现myeach的代码!!(也就是jQuery源码中each函数的实现!一定
要时时注意源码和实际使用的区别!function和回调function的区别!原型和对象的区别!!!)
注意那么多层的对象中形式参数和实际参数的作用域,使用!!不要乱调用!!调用不到的!!结果出不
来,错误都无法查!!!
$.each(不是$.fn.each)中的this:
我们通过选择器获取的jQuery对象,包括jQuery说明中的each(其说明中,each指$.fn.each,jQuery.each
指$.each!!!),都是指的$.fn中的each,因为我们自己没有在new对象上定义each,它用的是prototype的
each,而我们使用jQuery源码中的jQuery对象调用each,是源码中定义的$.each,它接收两个参数,有一个
是传入的选择器jQuery对象,那么它回调函数中的this???--->经实际应用代码阅读,就是第一个参数
循环出来的对象。
一定要注意调用和源码编写的区别!!内层函数没有上下文this就到外层找,这里的this:属于调用this
,类似实参,通过调用者确定,这里因为调用对象的append函数的源码并没有上下文this传递进来,所以
this并不是调用对象,那么就要到外一层找:发现是$.each函数的参数array中的每个元素(jQuery API
中,这个$.each函数的callback说明为:callback:每个成员/元素执行的回调函数,说明在该callback中
的this就是第一个参数数组或json遍历中的每个元素!!),传给...createTR函数,是为了让它调用这
个函数,那么函数的编写(源码)中的this(属于源码this,类似形参)就也是这个Dom对象了,那么源码编
写时就可以先假定它是Dom对象,对它各种操作.
!!!看到了:jQuery.fn.xxx(1个参数),jQuery.xxx(1个参数),$.xxx(2个参数)都有!!!第三种就
是让第一个参数或其遍历对象调用回调函数!!!所以回调函数中的this就是第一个参数或其遍历对象!
断点调试:一定要像老师一样,用firebug设置断点,一步步查,缩小范围,写遍历观察其值!!!
!!注意:一个json对象再加上$,就变成了jQuery对象!它-是-一-个-数-组-了!!!!所以才有
each...之类的函数!!有些不该加$的地方千万别加!比如直接用json对象,如果再加个$传递进去,就
是传递一个数组,是不对的!!!相当于在外面又包了一层数组,取不到json的值!!!
练习思路:
通过Ajax在页面加载时访问后台获取json数据,扫描前台table tr th上的约定属性,循环json数据(数
组),创建tr,循环th属性值,用以获取每个json对象对应名字的数据值,创建td给tr,将tr给table,加载
所有后台数据。
实现:数据,方法,都需要封装,记得调用和源码书写的区别,记得this上下文,没有this上下文传入的
方法调用,其中的this指代去外层找,有this的一般是迭代出来的对象。注意一个参数和两个参数的
$().extend和$.extend,前者是原型调用,后者是$这个对象调用。两个参数的each第一个参数是迭代数组
,jQuery对象都是数组,第二个毁掉参数中的this上下文就是第一个参数迭代出来的元素。
绑定:jQuery扩展,插件开发:
$().onload(function(){
$.fn.GridPanel={
}
});
命名空间创建:
$().onload(function(namespaceName){
var json=[];
});
不要少导了JSON.lib其他相关包!!不然错误你都找不到!!!
少一个包你连错误都查不出来!!下次记住:ClassDefNotFound什么玩意是缺包!
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-----------------------------------------------------maven---------------------------------------------------------------
步骤:
1.安装-->添加到path--->conf/settings.xml文件改仓库位置
2.建立项目,结构:
src/main/java
src/main/resources
src/test/java
src/test/resources
target 可自动生成
pom.xml:
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-
4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>cn.xbai</groupId>
<artifactId>hellofriend</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>hellofriend</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>cn.xbai</groupId>
<artifactId>hello</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
</dependencies>
</project>
3.命令:转到该项目目录下
mvn compile 编译
mvn test 测试
mvn package 打包
mvn install 安装,即加入到仓库类库,要想实现依赖(还要依赖传递性),必须先加入仓库类库
4.依赖传递性:2依赖1,加入1依赖,3依赖2,则加入2依赖即可,不用再加1依赖,前提是这三者必须都
加入到maven仓库类库(也就是必须install)!!(Error:Could not find artifact xxx.jar...)
5.jar包继承机制:多个项目之间继承,jar包重叠的问题
被继承的项目的pom.xml中:
<packaging>pom</packaging>
继承的项目pom.xml中:
<parent>
<groupId>cn.xbai</groupId>
<artifactId>xxx</artifactId>
<version>xxxxx</version>
</parent>
6.依赖jar包与库:每个jar包都像上面的工程一样,有一个依赖设置:这是上传到库之后的坐标,一个库
中的工程需要上面依赖,将依据此坐标在库中找到pom文件配置为这些依赖中的坐标配置的工程jar包。库
分三种:安装maven设置的本地库,maven的一个私服(一个工程)库,一个中央库,在互联网上的一个
url.如果一个工程需要一个依赖jar包,会根据以来配置先到本地库找,(本地库根据其自身的
settings.xml)再到私服或中央库,私服自己没有会自动去找中央库.
在maven安装位置的conf/settings.xml中有一个镜像设置:就是设置私服库名和其url.
上传到库的项目,会根据其pom文件在库中找对应于依赖配置的jar包,这些jar包中的pom文件定义了
其库坐标,和这些依赖配置对应。在本地库找不到会到私服、中央库找,这样就不用我们管理jar包了,
只要我们的工程写好各种jar包的依赖配置即可,那些成熟的jar包包括其各版本在其官网上的pom文件配
置都是不同且固定的,也就是指其在库中的坐标。也就是我们这样写依赖配置,maven就会帮我们找到这
些我们需要的jar(下载下来加入到工程):
<dependency>
<groupId>xxx</groupId>
<artifactId>xx</artifactId>
<version>xxxxx</version>
</dependency>
...
<dependency>
<groupId>xxx</groupId>
<artifactId>xx</artifactId>
<version>xxxxx</version>
</dependency>
...
7.插件plug-in:就是到指定库寻找或自动download需要的jar包,加入工程,以及compile,install...等
操作依赖的maven/plugins中的jar包。没有这些也会自动下载这些。
----------------------------------------------------------------------------------------------------------------------------------------------------------