Web执行流程

讲清楚一个SSH框架的WEB请求的详细经过,FILTER+web.xml,包括JSP和SERVLET的调度过程,Tomcat的线程池和JDBC连接池,STRUTS2的拦截器和自动装配机制及涉及的相关类,SPRING的事务,AOP,及自动装配及涉及的相关类,HIBERNATE的CACHE和自动装配机制和事务;

一。JSP请求
1.浏览器发起请求:
      一般有POST和GET方法,两者的处理过程基本相同,因此通常在Servlet端只实现其中之一,然后在另一个方法中调用已实现的方法;
      两者的区别在于:
      (1)参数长度:
         GET方法的参数在浏览器地址栏中,因此有长度的限制;?将路径和参数分开,&将参数之间分开;
         POST方法的参数则放在消息体中,因此无长度限制;
     (2)安全
         GET方法的参数显示在地址栏中,可见,故不安全;
         POST方法的参数放在消息体中,不可见,故较安全;
     (3)书签
         GET可建立,而POST不可建立;
     (4)幂等
         理论上讲GET方法应该是幂等的(可重复执行多次无副作用),POST方法是非幂等的,实际应用中不一定;
    (5)转码区别
         在实际中发现,GET和POST还会有一个问题,即GET方法的参数通常还需要手工解码,而POST则不需要,原因在于应用服务器的编码未正确设置,默认为ISO-8859-1;
2.经过Filter
   (1)一般来说,需要先经过SPRING的字符集转码机制,CharacterEncodingFilter,用来处理前台JSP页面与后台JAVA代码编码机制不同的情况;
   (2)然后会经过其它的Filter,有时是权限和安全验证,更多的情况是直接由STRUTS2来拦截请求,由SSH框架来处理;
  Tomcat中各种配置的加载顺序:
    context-param -> listener -> filter -> servlet
    context-param用来配置容器的上下文初始化参数,只在容器重新部署时初始化,一般来说,配置的参数是SPRING的配置文件名;
    listener 用来将上下文初始化参数组装成对象,一般来说,为SPRING的org.springframework.web.context.ContextLoaderListener 类;
    filter主要用于对用户请求进行预处理,一般来说,首先是SPRING的转码机制,然后是安全和权限控制(如果有),再下来是STRUTS2的框架或者Webservice;Filter的加载顺序由其在web.xml中的配置顺序决定;
 
  安全和权限控制(Session):
    基本的方法是先登录,然后在Session中存储用户信息以及状态信息,以后的会话通过传送SessionID来进行确认;
    Session存在有效期,一般来说二十分钟,也可人工设置;
    Tomcat设置SESSION有效期的三种方法:在server.xml中定义context时defaultSessionTimeOut设置
                                       在web.xml中通过<session-config>的<session-timeout>设置
                                       在程序中通过HttpSession的setMaxInactiveInterval设置;
    sessionID的交换:第一次生成时会通过首部的set-cookie和在URL后追加来传递sessionID,因为有可能有的浏览器不支持COOKIE;
                     如果后来客户发送的请求中有sessionID的COOKIE,则以后只通过第一种方法来传递;
    HTTPSession中存储信息:ActionContext.getContext().getSession().put()方法来存储;
3.返回JSP
      如果请求HTML,则返回HTML,请求JSP,一般会由服务器生成HTML并返回;
  (1)JSP与SERVLET的区别:
      JSP也是SERVLET,因为在SERVLET中直接拼HTML的字符串比较麻烦且因为涉及到转码及前后台分工的问题,最终使用JSP来做响应SERVLET;
      JSP先被转化为JAVA文件,再被编译为CLASS文件,然后由窗口加载并初始化成SERVLET对象;
  (2)JSP中include与jsp:include的区别:
      都用来在JSP文件中加入重复内容;
      include的作用等同于直接复制相关文字到标签位置,因此其对位置敏感,include的文件不是一个完整的JSP,应用启动时,包含文件则自动复制到各个JSP中;
      jsp:include的作用则是通过运行时原JSP作为Dispatch响应来发挥,因此其对位置不敏感,jsp:include文件是一个完整的JSP,也会成为SERVLET;
      jsp:include内容若改变则会实时反应到运行中,但现在实现上include内容改变也可反应到运行中;
  (3)forward与sendRedirect的区别
       forward发生在服务器内部,即通过JSP间的调用来实现,故客户端看不到变化,但因此其只能调用同一WEB程序内的资源,参数传递必须通过setAttribute()来设置;
       Redirect发生在客户端,由浏览器直接向服务器请求新的URL,因此可以调用不同WEB程序内的资源,可通过URL来传递参数;
  (4)EL与JSTL
       EL表达式用来向HTML输出WEB程序内的一些参数,如JAVABEAN,SESSION,REQUEST,SERVLET等的参数,只能调用参数,不能调用方法,因为其默认的隐式对象其实并不是WEB中的真正对象,而是将对象内参数复制后生成的MAP;
       JSTL表达式用来用标签来表示一些动作,如输出,循环,判断等;
二。ACTION请求
  1.浏览器请求:
    两种方式:HTTP和AJAX;
        AJAX通过XMLHttpRequest来进行通信;
        AJAX通过redayState与request.status来确定状态;
        AJAX常用的传输格式有XML和JSON两种,一种结构清晰明了,一种传输量少;
        AJAX的readyState的有几种:0(未初始化),1(开启),2(已传送),3(接收中),4(已载入)
  2.STRUTS2执行
    (1)request请求首先经过一系列的filter(转码,验证以及STRUTS自带Filter),最后到FilterDispatcher;
    (2)FilterDispatcher通过ActionMapper来确定是否需要调用某个Action(应该是通过url-pattern决定),如需要则把请求处理交给ActionProxy
   (3)ActionProxy通过Configuration Manager(struts.xml)找以需要调用的Action类;
   (4)ActionProxy创建一个ActionInvocation实例,该实例通过一个链表(存放拦截器链)来依次调用拦截器及Action方法;
   (5)Action执行完成后,返回result中的结果;
  STRUTS2中的自动组装机制:
     分为属性驱动和模型驱动:STRUTS2负责组装和类型转换,若转换失败,会进入名为input的逻辑视图;
         属性驱动:即在ACTION中直接定义属性,由STRUTS2按名称组装;  
         模型驱动:首先定义模型类,再在ACTION中扩展ModelDriven接口,且须在ACTION中生成模型类的实例,STRUTS2由GET方法得到后组装;
  STRUTS2中的异常机制:
         通过<exception-mapping.../>元素配置,需指定exception和result两个属性;
  3.Action的执行(SPRING)
    生成ACTION实例,一般来说由SPRING来组装,在ACTION中配置类ID,真正的类由SPRING来生成;
    SPRING中主要有三个功能:依赖注入,AOP,事务;
    
    依赖注入:
    (1)依赖注入的实现:分为构造注入或SET注入;
       通过Class.forname()创建新的类,通过构造注入或SET注入;
       构造注入:即用带参数的构造器来创建新类的,须用<constructor-arg..>来配置,一种为基本类型,通过index和value(有相同类型参数时)来                 指定,一种则是非基本类型,通过bean来定义;
       SET 注入:即调用无参数构造器后,通过SET来注入;
    (2)依赖注入的bean的几种作用域:
       singleton,prototype,request,session,global session;
      其中request,session,global session需要在web.xml中配置<listener>RequestContextListener类;
       singleton中依赖prototype时的方法注入:
        <lookup-mehtod name="..." bean="..."/>
   (3)依赖注入的手动组装与自动组装
        常用的为手动组装,因为结构清晰;
        其它的为自动组装,缺点是必须根据与属性类完全一致的类名来装配,接口再不能被实例化;
        自动装配一般用的是byName;
    
    AOP:
     (1)通知类型:前置通知,后置通知,异常通知,最终通知,环绕通知;
          环绕通知与其它通知的区别:可控制何时调用目标方法
                                    可控制返回对象
          后置通知与最终通知的区别:后置通知在方法正常返回时执行
                                    最终通知无论方法正常还是异常都会执行
     
      (2)AOP的两种方式:通过AspectJ即注释(annotation)、XMLSchema的方式;
           AspectJ与XML的区别:
            实现方式:AspectJ通过在通知类中加入匹配的注释来实现,需要在SPRING配置中加<aop:aspectj-autoproxy/>
                      XML则通过在XML中配置来实现,通知类中不需要加注释;
            JDK支持:AspectJ需要JDK5+支持,XML不需要;
            习惯:用户更习惯于XML;
            XML缺点:
              1.比起AspectJ来,配置更繁琐,且会使配置文件混乱,毕竟AOP的配置和一般的配置的写法并不太相同,ASPECTJ则将切面完全封装在一个类中,更符合将需求的实现封装到一个位置的做法;
              2.XML只支持单例模式;
       (3)代理机制:
            Spring的AOP和事务都是用的动态代理来实现的;
            代理分两种:CGLIB和JDK的动态代理,二者的实现机制基本相同,不同点在于JDK只支持接口代理,故须用CGLIB来实现对普通类的代理;
                        Spring默认接口采用JDK,普通类采用CGLIB,也可配置为全部用CGLIB;
        
   SPRING事务基础知识:
     (1)JDBC连接池:
          一般用dbcp来实现,原理为连接池先从数据库获得连接,然后分配给线程;覆盖了原Connection的get和close方法,故getConnection方法是从连接池取连接,而close则将连接归还连接池,并未与数据库进行交互;
     (2)全局事务与本地事务
          全局事务:跨数据库,使用JTA;本地事务:一般为一个连接;
     (3)事务可能出现问题:
          更新丢失(lost update )
          脏读    (dirty read )
          非重复读(nonrepeatable read )
          幻读    (phantom read )
          
     (4)事务隔离
          ISOLATION_READ_UNCOMMITTED  未提交读(可读缓存中的数据)       会造成脏读,非重复读,幻读
          ISOLATION_READ_COMMITTED    提交读  (大部分数据库采用的默认方式)会造成非重复读,幻读
          ISOLATION_REPEATABLE_READ   可重复读(一个事务不会修改已经由另一个事务读取但未提交(回滚)的数据)会造成幻读
          ISOLATION_SERIALIZABLE      序列化   (事务串行执行)               无;
     (5)事务传播
          PROPAGATION_REQUIRED        有则加入,无则新建     这是最常见的选择。
          PROPAGATION_SUPPORTS        有则以事务执行,无则以非事务执行
          PROPAGATION_MANDATORY       有则以事务执行,无则抛出异常
          PROPAGATION_REQUIRES_NEW    新建事务,当前已有的事务挂起
          PROPAGATION_NOT_SUPPORTED   以非事务执行,有则挂起
          PROPAGATION_NEVER           以非事务执行,有则抛异常
          PROPAGATION_NESTED          如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行与PROPAGATION_REQUIRED类似的操作。
     ***PROPAGATION_REQUIRED与PROPAGATION_NESTED与PROPAGATION_REQUIRES_NEW的区别:
         PROPAGATION_REQUIRED:外部事务和内部事务为一个事务,若一个失败,则全部回滚,成功,全部提交;
         PROPAGATION_REQUIRES_NEW:内部事务为一个新事务,和外部事务作为两个事务看待,无论成功失败,都不影响另一个;
         PROPAGATION_REQUIRES_NEW:若内部事务失败,则只回滚内部事务,若外部事务失败,则全部回滚,只有外部事务可以提交,若提交两个都提交;
     (6)事务属性:事务隔离,事务传播,超时,只读属性;
  SPRING事务:
      (1)SPRING事务的三种方式:
           XML配置:先XML配置不同策略的事务拦截器,再像AOP一样插入到aop:poing-cut下面;
           注释形式:在需要事务的类方法前面加@Transactional注释即可,要求JDK5+,须配事务拦截器,但不需配置插入点,因为代码上注明了;
           编程式:new一个PlatformTransactionManager类并设置拦截属性,需要配置事务管理器;
      (2)如何选择:
            较少用到事务,嫌麻烦时,用编程式;大量地还是用声明式(包括XML和注释);
   4.数据访问与修改(hibernate)
     (1)自动生成hibernate实体类与XML文件:
          可通过数据库表来生成对应的实体BEAN和XML配置文件;工具有:PowerDesigher(PD),XDoclet,sechmaExport;
     (2)  hibernate主键生成策略
          assigned:在新增数据时由应用程序指定主键的值;
                   适用于主键不是自动增长的列;
                   缺点:插入数据时需判断主键是否已存在;
        increment:由hibernate自动生成主键值,先查询最大值,再加1;
                   适用于代理主键的主键列;
                   缺点:主键类型只能为int或long ;插入前须先查询一次,低效 ;并发操作时的冲突问题;
        identity: 采用数据库的主键生成机制;
                  适用于DB2,MySQL,MS SQL Server,Sybase,HypersonicSQL
        sequence: 采用数据库的主键生成机制;
                  适用于DB2,ORACLE,SAP DB;
        hilo    : 使用高低位算法来生成标识符;
        native  :根据不同底层数据库,自动选择identity,sequence,hilo主键生成方式;
        UUID    :使用UUID,适合于并发;
        foreign : 用于一对一关系中,适用于MYSQL,SQLSERVER;
      **sequence与identity的区别:
        sequence作用于整个数据库,identity作用于单个表;
      **UUID:
        uuid为一个标准,用4个连字符将32位的字符串分隔生成字符串;
        目前有两种主要实现:GUID和COMB;
        GUID为微软的实现,COMB为数据库特有的一种设计,将UUID的最后6位用来表示时间,因为GUID因为无规律性导致了索引的效率低下;
    (3)hibernate事务
        hibernate层一般不需要事务管理,放在service层由SPRING来管理最好;
     (4)hibernate的乐观锁和悲观锁
        乐观锁使用版本号和时间戳来实现并发控制;
        而悲观锁则使用数据库的锁定机制;一般使用JDBC配置好隔离级别后由数据库来搞定;
    (5)session线程不安全解决方法,使用Threadlocal来保存session;
           之所以不安全的原因就在于hibernate的session内置有一级缓存用来保存数据库数据,故可能读到错的数据;
     (6)hibernate的cache机制:
        hibernate的查询是先到一级缓存查,再到二级缓存(可选)查,再到数据库查;
        session的cache(一级缓存,线程级别):
          一般局限于事务一级,为防止并发事务导致数据不一致,一般使用ThreadLocal来保证一个线程一个session的缓存不会出现数据不一致问题;
        sessionFactory(二级缓存,进程级别)
          故二级缓存不太适用于并发情况,适用于少并发或只读的情况;
          二级缓存策略如下:
              1.条件查询时,使用select *  from 将表中所有数据都查询出来;
              2.把获得的所有数据对象根据ID放入到第二级缓存中
              3.当Hibernate根据ID访问数据对象的时候,首先从Session一级缓存中查;查不到,如果配置了二级缓存,那么从二级缓存中查;查不到,再查询数据库,把结果按照ID放入到缓存。
              4.删除、更新、增加数据的时候,同时更新缓存。
三。WEBSERVICE调用
    SOAP:简单对象访问协议.
    WSDL:Web服务描述语言.
    UDDI(Universal Description, Discovery and Integration):通用描述、发现与集成,它是一种独立于平台的,基于XML语言的用于在互联网上描述商务的协议。




  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值