SSH前言第1章系统架构所谓系统架构是指,整合应用系统程序大的结构。经常提到的系统结构有两种:三层架构与MVC。这两种结构既有区别,又有联系。但这两种结构的使用,均是为了降低系统模块间的耦合度。1.1三层架构三层架构是指:视图层View、服务层Service,与持久层Dao。它们分别完成不同的功能。View层:用于接收用户提交请求的代码在这里编写。Service层:系统的业务逻辑主要在这里完成。Dao层:直接操作数据库的代码在这里编写。为了更好的降低各层间的耦合度,在三层架构程序设计中,采用面向抽象编程。即上层对下层的调用,是通过接口实现的。而下层对上层的真正服务提供者,是下层接口的实现类。服务标准(接口)是相同的,服务提供者(实现类)可以更换。这就实现了层间解耦合。1.2MVCMVC,即Model模型、View视图,及Controller控制器。View:视图,为用户提供使用界面,与用户直接进行交互。Model:模型,承载数据,并对用户提交请求进行计算的模块。其分为两类,一类称为数据承载Bean,一类称为业务处理Bean。所谓数据承载Bean是指实体类,专门用户承载业务数据的,如Student、User等。而业务处理Bean则是指Service或Dao对象,专门用于处理用户提交请求的。Controller:控制器,用于将用户请求转发给相应的Model进行处理,并根据Model的计算结果向用户提供相应响应。MVC架构程序的工作流程是这样的:(1)用户通过View页面向服务端提出请求,可以是表单请求、超链接请求、AJAX请求等(2)服务端Controller控制器接收到请求后对请求进行解析,找到相应的Model对用户请求进行处理(3)Model处理后,将处理结果再交给Controller(4)Controller在接到处理结果后,根据处理结果找到要作为向客户端发回的响应View页面。页面经渲染(数据填充)后,再发送给客户端。1.3MVC与三层架构的关系MVC与三层架构很相似,但它们并不一样。1.4SSH与三层架构的关系SSH,即Struts2、Spring与Hibernate三个框架。它们在三层架构中所处的位置是不同的,即它们在三层架构中的功能各不相同,各司其职。Struts2:作为View层的实现者,完成用户的请求接收功能。Struts2的Action作为整个应用的控制器,完成用户请求的转发及对用户的响应。Hibernate:作为Dao层的实现者,完成对数据库的增、删、改、查功能。Spring:以整个应用大管家的身份出现。整个应用中所有Bean的生命周期行为,均由Spring来管理。即整个应用中所有对象的创建、初始化、销毁,及对象间关联关系的维护,均由Spring进行管理。第2章环境设置2.1MyEclipse环境设置MyEclipse的相关属性设置,一般在Window/Preferences下。2.1.1字体设置2.1.2workspace字符集设置2.1.3JDK更换设置2.1.4默认编译器设置2.1.5Tomcat服务器设置2.1.6XML中没有自动提示功能对于xml配置文件,若当前主机连着互联网,那么,原则上在编写xml配置文件时,使用ALT+?,可出现自动提示。但,有时由于网速等原因,或根本就没有联网,没有自动提示。此时,可通过在MyEclipse中进行相关设置,使自动提示出现。下面以Struts2中核心配置文件struts.xml的自动提示为例进行描述。xml配置文件中的文件头中指定的是该xml文件的约束。该约束默认情况下,会从互联网上查找相应的dtd或xsd约束文件。约束文件中规定了该类型的xml文件中可以包含的标签,及标签的写书顺序等。Struts2的约束文件struts-2.3.dtd的部分内容如下:只有当前MyEclipse能够找到相应的约束文件,才可以根据约束文件给出自动提示。若当前系统没有连网,或网速有问题,则自动提示将会出问题。此时可通过指定让该URI不到互联网上查询约束文件,而从本地查找。所以,解决自动提示问题,首先要有约束文件。Struts2的约束文件struts-2.3.dtd在Struts2的核心Jar包中。将该文件从Jar包中拷贝出来,放到任意位置。然后,在MyEclipse中进行设置:(1)拷贝xml文件头的约束URL(2)WindowPreferences(3)输入xml搜索(4)指定URL对应的本地文件2.2Tomcat设置2.2.1Tomcat启动环境设置为了使Tomcat能够在命令行启动,即不是在MyEclipse下启动。则必须要在环境变量中设置JAVA_HOME与CATALINA_HOME。而这些变量的设置是在“我的电脑”上右击,选择“属性”,再按如下操作。(1)设置JAVA_HOME设置JAVA_HOME,其值指定JDK的安装主目录。(2)设置CATALINA_HOME以相同的方式设置CATALINA_HOME,其值设置为Tomcat的主目录。(3)在path变量中添加bin目录在“系统变量”的Path变量中添加Tomcat的主目录下的bin目录,为了能在命令行的任意位置可以直接运行Tomcat的启动命令startup.bat。直接双击Path变量,在“变量值”的最后,添加如下内容即可。当然,“系统变量”的Path变量中添加JDK主目录下的bin目录,是为了能在命令行的任意位置可以直接运行java、javac等命令。不过,若要在命令行直接运行javac命令,还需要在系统环境变量中添加一个名为classpath的变量,指定运行的.class文件的位置。一般设置其值仅为一个点号,表示要运行的.class文件就在当前目录。2.2.2设置Tomcat默认字符集为了解决GET提交时的中文乱码问题,可在Tomcat中作如下设置:打开Tomcat安装目录下的conf中的server.xml文件,在如下位置添加URIEncoding=“UTF-8”。2.2.3设置管理应用的登录用户名与密码为了方便测试时对项目的访问,可通过Tomcat的应用管理窗口“ManagerApp”进行访问管理。设置内容在点击如下按钮后,点取消,可看到提示设置登录用户名与密码的方法。所以,打Tomcat安装目录下的conf中的tomcat-users.xml文件,在最后添加如下内容,将用户名与密码均设置为1。第3章代理模式代理模式是指,为其他对象提供一种代理以控制对这个对象的访问。在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户类和目标对象之间起到中介的作用。百度百科《代理模式》换句话说,使用代理对象,是为了在不修改目标对象的基础上,增强主业务逻辑。客户类真正的想要访问的对象是目标对象,但客户类真正可以访问的对象是代理对象。客户类对目标对象的访问是通过访问代理对象来实现的。当然,代理类与目标类要实现同一个接口。以生活中的“代理律师”为例来理解“代理模式”。打官司是件非常麻烦的过程:案件调查取证、查找法律条文、起草法律文书、法庭辩论、签署法律文件、申请法院执行……但打官司的人只关心法宣判结果。此时,打官司的人就可聘请“代理律师”来完成整个打官司的所有事务。当事人只需与代理律师签订了“全权委托协议”,那么整个打官司的过程,当事人均可不出现。聘请代理律师时以下几点需要特别说明:(1)当事人与代理律师是在为同一件事情努力。(2)法院所有的具体事务都是通过代理律师完成。(3)在法院需要当事人完成某些工作时,代理律师会通知当事人,并为其出谋划策,即增强当事人。对于代理模式,需要注意以下几点:(1)代理类和目标类要实现同一个接口,即业务接口。(2)客户类对目标类的调用均是通过代理类完成的。(3)代理类的执行既执行了对目标类的增强业务逻辑,又调用了目标类的主业务逻辑。根据代理关系建立的时间不同,可以将代理分为两类:静态代理与动态代理。就好比当事人与律师之间的关系一样,也分为法律顾问与代理律师两类。3.1静态代理3.1.1概念静态代理是指,代理类在程序运行前就已经定义好,其与目标类的关系在程序运行前就已经确立。静态代理类似于企业与企业的法律顾问间的关系。法律顾问与企业的代理关系,并不是在“官司”发生后才建立的,而是之前就确立好的一种关系。3.1.2代理实现与解析静态代理实现转账:----proxy_static(1)定义业务接口IAccountService,其中含有抽象方法transfer()。(2)定义目标类AccountServiceImpl,该类实现了业务接口。在对接口方法的实现上,只实现主业务逻辑转账即可。这个方法称为目标方法。(3)定义代理类AccountProxy。这个类要实现IAccount接口。并且该代理类要将接口对象作为一个成员变量,还要定义一个带参的构造器,这个参数为接口对象。目的是,将目标对象引入代理类,以便代理类调用目标类的目标方法。(4)定义客户类Client。在客户类中首先要创建目标对象,再创建代理对象,并使用目标对象对其进行初始化。然后由代理对象来调用执行业务方法。3.2JDK动态代理动态代理是指,程序在整个运行过程中根本就不存在目标类的代理类,目标对象的代理对象只是由代理生成工具(如代理工厂类)在程序运行时由JVM根据反射等机制动态生成的。代理对象与目标对象的代理关系在程序运行时才确立。对比静态代理,静态代理是指在程序运行前就已经定义好了目标类的代理类。代理类与目标类的代理关系在程序运行之前就确立了。3.2.1概念动态代理类似于普通当事人与聘请的律师间的关系。律师是在“官司”发生后,才由当事人聘请的。即代理关系是在“官司”发生后才确立的。动态代理的实现方式常用的有两种:使用JDK的Proxy,与通过CGLIB生成代理。通过JDK的java.lang.reflect.Proxy类实现动态代理,会使用其静态方法newProxyInstance(),依据目标对象、业务接口及业务增强逻辑三者,自动生成一个动态代理对象。publicstaticnewProxyInstance(ClassLoaderloader,Class?[]interfaces,InvocationHandlerhandler)loader:目标类的类加载器,通过目标对象的反射可获取interfaces:目标类实现的接口数组,通过目标对象的反射可获取handler:业务增强逻辑,需要再定义。InvocationHandler是个接口,其具体介绍如下:实现了InvocationHandler接口的类用于加强目标类的主业务逻辑。这个接口中有一个方法invoke(),具体加强的代码逻辑就是定义在该方法中的。程序调用主业务逻辑时,会自动调用invoke()方法。invoke()方法的介绍如下:publicObjectinvoke(Objectproxy,Methodmethod,Object[]args)proxy:代表生成的代理对象method:代表目标方法args:代表目标方法的参数由于该方法是由代理对象自动调用的,所以这三个参数的值不用程序员给出。第二个参数为Method类对象,该类有一个方法也叫invoke(),可以调用目标类的目标方法。这两个invoke()方法,虽然同名,但无关。publicObjectinvoke(Objectobj,Object...args)obj:表示目标对象args:表示目标方法参数,就是其上一层invoke方法的第三个参数该方法的作用是:调用执行obj对象所属类的方法,这个方法由其调用者Method对象确定。在代码中,一般的写法为method.invoke(target,args);其中,method为上一层invoke方法的第二个参数。这样,即可调用了目标类的目标方法。3.2.2代理实现与解析动态代理实现转账:----proxy_dynamic(1)定义业务接口IAccounSevice,其中含有抽象方法transfer()。(2)定义目标类