SSH框架总结

来源:互联网 发布:王柳雯的淘宝店 编辑:程序博客网 时间:2024/06/05 09:22

SSH框架总结

一、搭建SSH框架

1.1导入相关Jar包 大约45个
1.2相关配置文件
1.2.1web.xml
1、配置ContextLoaderLinstener,用于加载spring 的applicationContext.xml配置文件    默认加载位置为web-inf下的,需要指明 配置文件位置  contextConfigLocation    如果配置文件找不到,就会报FileNotFound找不到异常    <!--配置Spring加载 监听器 -->      <listener>        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>      </listener>      <!--配置全局参数  -->      <context-param>        <param-name>contextConfigLocation</param-name>        <param-value>classpath:applicationContext.xml</param-value>      </context-param>    clsspath是spring中特有的用于标识类路径下1、1在配置Struts2可以配置OpenSessionInViewFilter  用于解决nosession问题,非必须,    必须配置在struts2核心控制器之前    <filter>    <filter-name>openSessionInViewFilter</filter-name>    <filter-class>org.springframework.orm.hibernate5.support.OpenSessionInViewFilter</filter-class>  </filter>  <filter-mapping>    <filter-name>openSessionInViewFilter</filter-name>    <url-pattern>/*</url-pattern>  </filter-mapping>2、配置Struts核心控制器  StrutsPreparedAndExecuteFilter          两个作用:加载struts2配置文件在init方法中加载,配置文件只加载一次,对用户的action请求或空白请求进行拦截     <filter>        <filter-name>struts2</filter-name>        <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>      </filter>      <filter-mapping>        <filter-name>struts2</filter-name>        <url-pattern>/*</url-pattern>      </filter-mapping>3、配置Spring编码过滤器   CharacterEncodingFilter   用于解决post请求乱码问题        可以配置参数 encoidng   UTF-8    非必须,因为如果使用struts2与spring整合时,struts2本身就解决了post请求乱码问题        <filter>    <filter-name>encodingFilter</filter-name>    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>    <!--配置参数,指定使用UTF-8编码  -->    <init-param>        <param-name>encoding</param-name>        <param-value>UTF-8</param-value>    </init-param>    </filter>    <filter-mapping>        <filter-name>encodingFilter</filter-name>        <url-pattern>/*</url-pattern>    </filter-mapping>
1.2.2struts.xml文件配置
1、struts2的配置文件:    default.properties    配置struts运行中的常量    struts-default.xml    配置拦截器以及结果视图,以及bean的配置    struts-xxx-plugin.xml   插件的配置文件,非必须    struts.xml            程序员编写的配置文件,配置常量,action,自定义拦截器等    struts.properties    配置常量,一般不需要配置,在struts.xml文件中配置2、package配置    name 包名,唯一       namespace名称空间 默认为 "/"       extends 继承的父包  默认为struts-default3、action配置    name 访问名称   Action_*  *表示访问方法    class 类的全限定类名或者spring中对应的id名称        method 方法       ${1}表示第一个*代表的内容    result 逻辑视图      interceptor-ref 明确指明当前使用的是哪个拦截器        可以配置param  name    namespace+name  路径为action的完整访问路径4、interceptor配置    interceptors 表示所有拦截器        interceptor 配置自定义的拦截器  name  拦截器的名称 ,class拦截器的全限定类名        interceptor-stack  配置拦截器栈              interceptor-ref 配置拦截器引用   name拦截器的名称   自定义拦截器放在默认拦截器栈后面    default-interceptor-ref 默认拦截器配置   name=拦截器或着拦截器栈名称5、拦截器    拦截器是struts2的基石,很多功能都是基于拦截器实现的,在用户访问action方法之前执行,采用责任链的设计模式    ,采用递归调用的方式执行。6、拦截器的编写    实现Interceptor接口    继承AbstractInterceptor类    继承MethodFilterInterceptor类 我们一般使用继承AbstractInterceptor    <struts>        <constant name="struts.enable.DynamicMethodInvocation" value="false" />        <constant name="struts.devMode" value="true" />        <!--配置上传文件大小  -->        <constant name="struts.multipart.maxSize" value="20000000"></constant>         <!-- 加载国际化配置文件 -->        <constant name="struts.custom.i18n.resources" value="uploadError" />        <!--全局包,用于配置全局信息  -->        <package name="public" namespace="/" extends="struts-default">            <interceptors>                <interceptor name="loginInterceptor" class="loginInterceptor"></interceptor>                <interceptor-stack name="myInterceptorStack">                    <interceptor-ref name="defaultStack"></interceptor-ref>                    <!-- 自定义拦截器放在默认拦截器后面 -->                     <interceptor-ref name="loginInterceptor">                     <!--  设置不需要拦截的方法-->            <param name="excludeMethods">customerAction_list,linkmanAction_list,sysUserAction_login,sysUserAction_loginUI</param>                     </interceptor-ref>                 </interceptor-stack>            </interceptors>            <default-interceptor-ref name="myInterceptorStack"></default-interceptor-ref>            <global-results>                <result name="loginError">/login.jsp</result>                <result name="success">/jsp/success.jsp</result>                <result name="error">/jsp/error.jsp</result>            </global-results>        </package>        <include file="struts/struts-sysUser.xml"></include>        <include file="struts/struts-customer.xml"></include>        <include file="struts/struts-linkman.xml"></include>         <include file="struts/struts-saleVisit.xml"></include>    </struts>   
1.2.3applicationContext.xml文件配置
1、配置数据源,用于连接数据库    C3P0数据源   ComboPooledDataSource        driverClass jdbcUrl user password    DBCP数据源   BasicDataSource    JDBC数据源   DriverManagerDataSource2、配置sessionFactory 是sring与hibernate整合的关键点     类LocalSessionFactoryBean    dataSource    configLocations(classpath:hibernate.cfg.xml)3、配置Hibernate事务管理器    transactionManager        需要注入sessionFactory4、配置声明式事务通知    transaction-manger 指明使用的事务管理器    tx:method 表示哪些方法使用事务  name为方法名,propagation为事务行为    <tx:advice id="txAdvice" transaction-manager="transactionManager">        <tx:attributes>            <tx:method name="save*" propagation="REQUIRED"/>            <tx:method name="delete*" propagation="REQUIRED"/>            <tx:method name="update*" propagation="REQUIRED"/>            <tx:method name="find*" read-only="true"/>            <tx:method name="*" propagation="REQUIRED"/>        </tx:attributes>    </tx:advice>    声明式事务的原理:AOP    AOP的原理是什么?动态代理模式    动态代理模式?JDK实现动态代理,cglib实现动态代理    这两种方式的区别:JDK动态代理时目标对象一定实现接口,而cglib可以不实现    JDK动态代理用的类?Proxy.newProxyInstance()    Cglib代理如何实现?        1.创建一个Enhancer eh = new Ehancer();    2.Eh.setSuperClass();    3.设置回调:eh.setCallback();    4.生成代理对象:eh.create();    1.  事务管理器的配置    父接口:PlatformTransactionManager    Hibernate事务管理器的子类:HibernateTransactionManager    Jdbc事务管理器的子类:DataSourceTransactionManager    PlatformTransactionManager它的内部是什么工作的?    TransactionDefinition:事务定义信息    TransactionStatus:事务状态    它需要根据TransactionDefinition这个对象,得到事务的定 义信息,再根据事务的执行状态TransactionStatus,来决定事务是提交还是回滚。    2.  事务通知的配置:<tx:advice>    事务通知advice为什么可以作用到切入点表达式所指定的类中的方法?    因为在配置声明式事务时,它的本质也是去生成代理子类对象,所以此时只要根据你指定的切入点表达式的要求,针对目标对象直接生成代理对象,而同时通过aop来实现横向代码的动态织入,从而实现了事务的控制。它对应的通知类型,可以认为环绕通知。5、配置声明式事务与aop整合    aop:pointcut 配置切入点表达式 expresssion(需要事务执行的方法)      <aop:config>        <aop:pointcut expression="execution(* cn.lx.crm.service.impl.*.*(..))" id="myPointcut"/>        <aop:advisor advice-ref="txAdvice" pointcut-ref="myPointcut"/>    </aop:config>6、配置文件分离的思想    公共配置+分层思想    applicationContext.xml    applicationContext-dao.xml    applicationContext-service.xml    applicationContext-action.xml    公共配置+分模块思想    applicationContext.xml    applicationContext-customer.xml7、bean配置的作用域    request\session\global session\singleton\prototype        signleton 单例        prototype 多实例     配置action时,一定要配置多实例8、bean生命周期  spring配置文件加载时创建    init destory9、bean对象的创建三种方式    构造函数  实例工厂 静态工厂10、bean对象注值的三种方式    setter注值  构造函数注值  p名称空间注值
1.2.4 hibernate.cfg.xml文件配置
1、配置SQL方言<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>2、配置自动建表<property name="hibernate.hbm2ddl.auto">update</property>3、配置显示SQL<property name="hibernate.show_sql">true</property>4、配置格式化SQL<property name="hibernate.format_sql">true</property>5、配置session绑定本地线程<property name="hibernate.current_session_context_class">org.springframework.orm.hibernate5.SpringSessionContext</property>6、配置事务隔离级别<property name="hibernate.connection.isolation">4</property>7、导入映射文件<mapping resource="cn/lx/crm/domain/BaseDict.hbm.xml"/>
1.2.5 准备PO类及映射文件
  1、PO类的编写规范:        1.  私有属性        2.  提供公有的无参构造         3.  提供 私有属性的公有getter与setter        4.  类名不能用final        5.  实现java.io.Serailizable接口        6.  是一个公有类        7.  如果是基本类型的属性,请使用它的对应包装类  2、映射文件命名 类名.hbm.xml        <class name=”包名.类名” table=””>           <id name=”” column=””>             <generator class=”uuid,assigned,identity,increment,native,sequence”/>              </id>             <property name=”” column=”” not-null=”tru” type=”” length=”” />            <property name=”” column=”” not-null=”tru” type=”” length=”” />        </class> 3、关联关系的配置      分别为一对多关系、多对一关系、多对多关系、一对一关旭    Customer的类中:    一对多    Private Set<Linkman> linkmans = new HashSet<Linkman>(0);    Customer.hbm.xml文件中    <set name=” linkmans” cascade=”” inverse=””  fetch=”join|select” lazy=”true|false|extra”>       <key column=”外键字段名”/>      <one-to-many class=” Linkman” />    </set>    Cascade取值:all,save-update,delete,delete-orphan, delete-orphan-all    Inverse取值:true,false,默认为false    Cascade与inverse的区别?    1.  cascade代表父子项操作时的级联关系    2.  inverse代表控制权交给谁管理,true代表控制权交给对方管理    3.  inverse一般 设置为true,交给多方维护,这样可以提高效率    fetch的特点:fetch=”join”时lazy失效,同时它采用迫切左外连接实现的查询    它可以解决noSession问题     Fetch=select,它将采用多条sql语句的形式进行查询,发出sql的时机由lazy来决定,想立即发出sql就用lazy=”false”,希望在加载这个记录时才出现sql语句,就让lazy=”true|extra”    多对一的配置:    Linkman.java中配置:    Private Customer customer;    Linkman.hbm.xml文件    <many-to-one name=”customer” class=” Customer”  column=”外键字段名”></ many-to-one>    多对多的配置:    SysUser与SysRole用户与角色    SysUser.java    Private Set<SysRole> sysRoles = new HashSet<SysRole>(0);    SysUser.hbm.xml文件    <set name=”” table=”” inverse=”true”>         <key column=”关联到自身的来自中间表的外键”/>         <many-to-many class=” SysRole” column=” 关联到SysRole来自中间表的外键”/>    </set>
2 DAO模式
1.编写BaseDao<T>接口2.编写实现类BaseDaoImplPublic BaseDaoImpl<T> extends HibernateDaoSupport implements BaseDao<T>{   Class clz;  Public BaseDaoImpl(){         Type type = this.getClass().getGenericSuperClass();         ParameterizedType pt = (ParameterizedType)type;         clz = (Class)Pt.getActualArgumentsType()[0]; }   Public List<Customer> findAll(){      return this.getHibernateTemplate().find(“from    ”+clz.getName());  }}Class CustomerDaoImpl extends BaseDaoImpl<Customer> implements CustomerDao{}getHibernateTemplate().find()内部的本质是什么执行的?Session session = sessionFactory.openSession();AOP:横向插入事务开启的代码Query query = Session.createQuery(“from “+clz.getName());Query.list();AOP: 横向插入事务提交或回滚的代码Hibernate实现数据检索的5种方式get/load   加载时使用对象的OID(Object Identity Qualified  对象的唯一标识)QBC  Query By Criteria          Criteria c = session.createCriteria(Customer.class);HQL     Query query = session.createQuery(“”);对象导航  前提:先配置好对象之间的关联关系  Set<linkman> linkmans = customer.getLinkmans();SQL   :SQLQuery query = session.createSQLQuery(“sql”).addEntity(Customer.class);面试:get/load加载数据的区别?1.  get立即加载,load延迟加载2.  load加载的对象为代理对象,get加载的是真实对象3.  load加载失败会出现异常,而get加载失败返回null4.  get加载时就会出现sql语句,而load只会调用属性时才会真正加载(才会有sql)5.  load方法也可以实现与get方法相同的效果:第一种方法只要在相应的映射文件中找到class结点,添加一个lazy=”false”   第二种方法:在PO定义时加上final结论,加载数据失败时,load总是会抛出异常
3 Hibernate一级缓存
一级缓存:它是与session关联在一起的,如果session不存在了,一级缓存也就不存在了。    一级缓存的内部结构:    Hashtable,就是key-value对。    结于持久态的对象,没有调用update()方法,也会实现更新操作?因为它会根据一级缓存中的快照区与真实对象进行比较,如果有更新,就会在事务提交时,将更新后的结果刷出到数据库中。(tx.commit();默认就会调用session.flush();)    一级缓存中常用的操作方法:    clear();清空一级缓存    evict(Object obj)在一级缓存中清空指定的对象    flush()可以做到一级缓存中数据与数据库中数据的同步更新    refresh()再次将数据库中的数据查询出来,填充一级缓存

4 struts2的封装数据的方式

1.获取参数   ServletActionContext.getRequest.getParameter(“custId”);2解耦合方式获取参数   ActionContext.getContext().getParameters().get(“custId”)[0];3.属性驱动来实现参数封装(params拦截器)  Customer/customerAction_find?age=10;CustomerAction类中Private int age;Public void setAge(int age){   This.age =age;}Customer/customerAction_find?customer.age=10;private Customer customer;//生成它的setter与getter4.模型 驱动:(modelDriven拦截器)1.模型驱动要求实现一个接口:ModelDriven<Customer>,同时还要重写getModel(),这个方法要求返回一个已存在的对象。

5 值栈

1.什么是值栈?它是一个用于保存数据的容器,它本身只是一个叫做ValueStack接口,它的实现类是OgnlValueStack.2.如何得到ValueStack实例? ValueStack vs1 =  ActionContext.getContext().getValueStack(); ValueStack vs2 =  request.getAttribute(“struts.valueStack”);针对同一次请求,不管用上面的哪个方法,获取的都是同一个对象。每次请求时,valueStack都是一个新的对象,action对象也是一个新的对象3.ValueStack的内部结构root  :类型 CompoundRoot  而CompoundRoot又继承了ArrayList父类context:类型 OgnlContext ,而OgnlContext又实现Map接口默认操作值栈都是在操作root4.为什么EL表达式也能访问值栈?  用到RequestWrapper对request进行包装,在包装类中可以找到一个getAttribute()而这个方法首先是在request域中找数据,如果没有就会找valueStack.request = prepare.wrapRequest(request);
0 0