




已阅读5页,还剩45页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
系统架构介绍1 简介本项目采用Maven来构建和管理。通过Spring MVC分离了控制器、模型对象、分派器以及处理程序对象的角色,这种分离让它们更容易进行制定。持久层框架用的Mybatis,支持普通SQL查询,存储过程和高级映射。Shrio提供了认证、授权、加密和会话管理等功能。easyUi是一组基于jQuery的UI插件集合,帮助web开发者更轻松的打造出功能丰富并且美观的UI界面。2 框架及工具介绍2.1 MavenMaven是一个项目管理和整合的工具。Maven为开发者提供了一套完整的构建生命周期框架。开发团队基本不用花多少时间就能自动完成工程的基础构建配置,因为Maven使用了一个标准的目录结构和一个默认的构建生命周期。在创建报告、检查、构建和测试自动配置时,Maven可以让开发者的工作变得更简单。2.1.1 核心概念介绍 pompom是指project object Model。pom是一个xml,在Maven里为pom.xml。是Maven工作的基础,在执行task或者goal时,Maven会去项目根目录下读取pom.xml获得需要的配置信息。pom文件中包含了项目的信息和Maven build项目所需的配置信息,通常有项目信息(如版本、成员)、项目的依赖、插件和goal、build选项等等。pom是可以继承的,通常对于一个大型的项目或是多个module的情况,子模块的pom需要指定父模块的pom。pom文件中节点含义如下:1 project:pom文件的顶级元素;2 modelVersion:所使用的object model版本,为了确保稳定的使用,这个元素是强制性的。除非Maven开发者升级模板,否则不需要修改;3 groupId:项目创建团体或组织的唯一标志符,通常是域名倒写,如groupIdorg.apache.Maven.plugins就是为所有Maven插件预留的;4 artifactId:项目artifact唯一的基地址名;5 packaging:打包的方式,如jar、war、ear等等。默认为jar。这个不仅表示项目最终产生何种后缀的文件,也表示build过程使用什么样的lifecycle;6 version:版本,通常能看见为类似0.0.1-SNAPSHOT,其中SNAPSHOT表示项目开发中,为开发版本;7 name:项目的展现名,在Maven生成的文档中使用;8 url:地址,在Maven生成的文档中使用;9 description:项目的描述,在Maven生成的文档中使用;10 dependencies:依赖,在子节点dependencies中添加具体依赖的groupId artifactId和version;11 build:build配置;12 parent:父pom;其中groupId:artifactId:version唯一确定了一个artifact Artifact一个项目将要产生的文件,可以是jar文件,源文件,二进制文件,war文件,甚至是pom文件。每个artifact都由groupId:artifactId:version组成的标识符唯一识别。需要被使用(依赖)的artifact都要放在仓库(见Repository)中。 RepositoriesRepositories是用来存储Artifact的。如果说我们的项目产生的Artifact是一个个小工具,那么Repositories就是一个仓库,里面有我们自己创建的工具,也可以储存别人造的工具,我们在项目中需要使用某种工具时,在pom中声明dependency,编译代码时就会根据dependency去下载工具(Artifact),供自己使用。对于自己的项目完成后可以通过mvn install命令将项目放到仓库(Repositories)中。任何一个工具都有唯一的坐标,Maven根据这个坐标定义了构件在仓库中的唯一存储路径,Maven在仓库中的存储路径解读:1.基于groupId准备路径,将句点分隔符转成路径分隔符,就是将 . 转换成 / ; example:org.testng -org/testng2.基于artifactId准备路径,将artifactId连接到后面:org/testng/testng3.使用version准备路径,将version连接到后面:org/testng/testng/5.84.将artifactId于version以分隔符连字号连接到后面:org/testng/testng/5.8/tesng-5.8.jarMaven的仓库只有两大类:1.本地仓库 2.远程仓库:1 本地仓库,顾名思义,就是Maven在本地存储构件的地方。(注:Maven的本地仓库,在安装Maven后并不会创建,它是在第一次执行Maven命令的时候才被创建。)Maven本地仓库的默认位置:无论是Windows还是Linux,在用户的目录下都有一个.m2/repository/的仓库目录,这就是Maven仓库的默认位置。如果要更改Maven默认的本地仓库的位置:这里要引入一个新的元素:localRepository,它是存在于Maven的settings.xml文件中。更改配置用户范围的本地仓库:先在/.m2/目录下创建settings.xml文件,然后在/.m2/settings.xml,设置localRepository元素的值为想要的仓库地址这时候,Maven的本地仓库地址就变成了D:toolsapache-maven-3.2.5respo。(注:此时配置的Maven的本地仓库是属于用户范围的。)2 远程仓库远程仓库最核心的是中央仓库,中央仓库是默认的远程仓库,Maven在安装的时候,自带的就是中央仓库的配置。在Maven的聚合与继承中我们说过,所有的Maven项目都会继承超级pom,具体的说,包含了下面配置的pom我们就称之为超级pom中央仓库包含了绝大多数流行的开源Java构件,以及源码、作者信息、SCM、信息、许可证信息等。一般来说,简单的Java项目依赖的构件都可以在这里下载到。私服是一种特殊的远程仓库,它是架设在局域网内的仓库服务,私服代理广域网上的远程仓库,供局域网内的Maven用户使用。当Maven需要下载构件的时候,它从私服请求,如果私服上不存在该构件,则从外部的远程仓库下载,缓存在私服上之后,再为Maven的下载请求提供服务。我们还可以把一些无法从外部仓库下载到的构件上传到私服上。2.1.2 Maven实际应用构建maven项目在eclipse下构建maven项目,该项目由多个子模块组成。1 创建一个父项目NEW -project-maven-maven Project,点击下一步,进入new maven Project的Select project name and location界面,什么也不做,直接下一步到Select an Archetype界面。在这个界面中选择maven-Archetype-site-simple,然后选择下一步,进入选择Enter a group id for the artifact的界面,在group id 和artifact id中输入你的group和artifact名称。我用的分别是com.ai和MvnTest,选择完成。这时会在eclipse中生成一个项目,项目名是MvnTest。此时MvnTest的pom文件如下所示:2 创建子项目2.1 将项目MvnTest中的src文件删除。(可有可无,主要看个人需要)2.2 选中项目MvnTest,点击右键,选择NEW -project-maven-maven Module,点击下一步,在出现的界面中输入子模块的名称sMod1,点击下一步,出现Select an Archetype界面。这时选择maven-Archetype-site-quickStart或者maven-Archetype- webapp(构建web层时使用),然后选择完成,即生成子项目sMod1。这时MvnTest的pom文件就变成了这样(和上面的比只是多了个modules标签):这时构建MvnTest的子项目完成,构建其他的子项目和此类似。在构建第二个子项目sMod2时可能在MvnTest中没有及时出现,这时只要把MvnTest项目刷新下就可以了。3 eclipse引入Maven子模块选中项目MvnTest,点击右键,选择import-Exsiting Maven Projects点击下一步,选中需要引入的子模块,点finish,引入成功。添加JAR包到本地仓库首先,到 /这个网,在搜索栏中输入你要搜索的JAR包的关键字来搜索,下面直接贴图:以spring-context-support-3.1.0.RELEASE.jar 为例,在 上图中已经给出这个 jar 包的 groupId,artifactId,version信息,手动安装的时候这些信息不要改,否则Maven项目移植的话,jar包下载就会失败。顺便把这信息帖下面,方便对照:把这段话帖到pom.xml文件后,Maven工程就会自动下载jar包。对于一些自己编写的jar包,我们也可以通过命令上传至服务器共享使用:Maven 安装 JAR 包的命令是:例如:我下载的这个 jar 包是放到了 D:mvn 目录(D:mvnspring-context-support-3.1.0.RELEASE.jar),那么我在cmd中敲入的命令就应该是:mvninstall:install-file-Dfile=D:mvnspring-context-support-3.1.0.RELEASE.jar-DgroupId=org.springframework -DartifactId=spring-context-support-Dversion=3.1.0.RELEASE-Dpackaging=jar回车,显示安装成功:2.2 Spring MVCSpring MVC属于SpringFrameWork的后续产品,已经融合在Spring Web Flow里面。Spring 框架提供了构建 Web 应用程序的全功能 MVC 模块。使用 Spring 可插入的 MVC 架构,可以选择是使用内置的 Spring Web 框架还可以是 Struts 这样的 Web 框架。通过策略接口,Spring 框架是高度可配置的,而且包含多种视图技术,例如 JavaServer Pages(JSP)技术、Velocity、Tiles、iText 和 POI。Spring MVC 框架并不知道使用的视图,所以不会强迫您只使用 JSP 技术。Spring MVC 分离了控制器、模型对象、分派器以及处理程序对象的角色,这种分离让它们更容易进行定制。2.2.1核心架构核心架构的具体流程步骤如下:1首先用户发送请求DispatcherServlet,前端控制器收到请求后自己不进行处理,而是委托给其他的解析器进行处理,作为统一访问点,进行全局的流程控制;2 DispatcherServletHandlerMapping, HandlerMapping将会把请求映射为HandlerExecutionChain对象(包含一个Handler处理器(页面控制器)对象、多个HandlerInterceptor拦截器)对象,通过这种策略模式,很容易添加新的映射策略;3 DispatcherServletHandlerAdapter,HandlerAdapter将会把处理器包装为适配器,从而支持多种类型的处理器,即适配器设计模式的应用,从而很容易支持很多类型的处理器;4 HandlerAdapter处理器功能处理方法的调用,HandlerAdapter将会根据适配的结果调用真正的处理器的功能处理方法,完成功能处理;并返回一个ModelAndView对象(包含模型数据、逻辑视图名);5 ModelAndView的逻辑视图名 ViewResolver, ViewResolver将把逻辑视图名解析为具体的View,通过这种策略模式,很容易更换其他视图技术;6 View渲染,View会根据传进来的Model模型数据进行渲染,此处的Model实际是一个Map数据结构,因此很容易支持其他视图技术;7返回控制权给DispatcherServlet,由DispatcherServlet返回响应给用户,到此一个流程结束。架构图对应的DispatcherServlet核心代码如下:2.2.2 Spring MVC实际应用 Spring MVC配置SpringMVC是一个基于DispatcherServlet的MVC框架,每一个请求最先访问的都是DispatcherServlet,DispatcherServlet负责转发每一个Request请求给相应的Handler,Handler处理以后再返回相应的视图(View)和模型(Model),返回的视图和模型都可以不指定,即可以只返回Model或只返回View或都不返回。在使用注解的SpringMVC中,处理器Handler是基于Controller和RequestMapping这两个注解的,Controller声明一个处理器类,RequestMapping声明对应请求的映射关系,这样就可以提供一个非常灵活的匹配和处理方式。DispatcherServlet是继承自HttpServlet的,既然SpringMVC是基于DispatcherServlet的,那么我们先来配置一下DispatcherServlet,好让它能够管理我们希望它管理的内容。DispatcherServlet是在web.xml文件中声明的。上面声明了一个名为sprigmvc的DispatcherServlet,该Servlet将处理所有请求。在初始化DispatcherServlet的时候,SpringMVC默认会到/WEB-INF目录下寻找一个叫servlet-name-servlet.xml的配置文件,来初始化里面的bean对象,该文件中对应的bean对象会覆盖spring配置文件中声明的同名的bean对象。如上面的就会在/WEB-INF目录下寻找一个叫springmvc-servlet.xml的文件;当然也可以在Servlet中声明配置文件的位置,那就是通过Servlet的初始化参数来设置contextConfigLocation参数的值。DispatcherServlet会利用一些特殊的bean来处理Request请求和生成相应的视图返回。关于视图的返回,Controller只负责传回来一个值,然后到底返回的是什么视图,是由视图解析器控制的,在jsp中常用的视图解析器是InternalResourceViewResovler,它会要求一个前缀和一个后缀。在上述视图解析器中,如果Controller返回的是test/index,那么通过视图解析器解析之后的视图就是/WEB-INF/views/test/index.jsp。要使用注解的SpringMVC需要在SpringMVC的配置文件中进行声明,具体方式为先引入mvc命名空间,然后利用进行声明。spring Web MVC框架提供了org.springframework.web.filter.CharacterEncodingFilter用于解决POST方式造成的中文乱码问题,具体配置如下:注解说明SpringMVC中四个基本注解:Component、RepositoryService、Controller。看字面含义,很容易却别出其中三个:Controller控制层,就是我们的action层;Service业务逻辑层,就是我们的service或者manager层;Repository持久层,就是我们常说的DAO层;而Component(字面意思就是组件),它在你确定不了事哪一个层的时候使用。其实,这四个注解的效果都是一样的,spring都会把它们当做需要注入的Bean加载在上下文中;但是在项目中,却建议你严格按照除Componen的其余三个注解的含义使用在项目中。这对分层结构的web架构很有好处。在SpringMVC中Controller不需要继承什么类,也不需要实现什么接口,一切使用了Controller进行标记的类都是Controller有了Controller之后,那么到底是怎样请求一个Controller具体的方法的呢,那是通过RequestMapping来标记的,RequestMapping可以标记在类上面,也可以标记在方法上,当方法上和类上都标记了RequestMapping的时候,那么对应的方法对应的Url就是类上的加方法上的,如下面的index方法,其对应的URL应为类上的/test加上index方法上的/index,所以应为/test/index,所以当请求/test/index的时候就会访问CustHealthyController的index方法。加在类上的RequestMapping不是必须的,当Controller类上加上了RequestMapping的时候,那么Controller方法上的RequestMapping就是相对于类上的RequestMapping而言的,也就是前面说的请求映射的时候是类上的地址加方法上的地址,而当Controller类上没有加RequestMapping的时候,方法上的RequestMapping就是绝对路径了。在上面的代码中,如果index方法上没有RequestMapping注解,而只有CustHealthyController类上有,且该类只有一个方法的时候,直接请求类上的URL就会调用里面的方法,即直接请求/custHthy的时候就会调用index方法。在RequestMapping中还可以指定一个属性method,其主要对应的值有RequestMethod.GET和RequestMethod.POST,利用该属性可以严格的控制某一方法只能被标记的请求路径对应的请求方法才能访问,如指定method的值为GET,则表示只有通过GET方式才能访问该方法,默认是都可以访问。RequestMapping中的URL映射还支持通配符*,如:在RequestMapping中还有一个属性params,可以通过该属性指定请求参数中必须包含某一参数,或必须不包含某一参数,或某参数的值必须是什么,以此来缩小指定的映射范围。在上面示例中,只有当请求/custHthy/index并且请求参数param1的值为value1的时候才能访问到对应的index方法。如果params的值为param1,则表示请求参数只要包含param1就可以了,至于它的值是什么无所谓;如果params的值为!param1,则表示请求参数必须不包含param1才可以。RequestMapping中还可以使用header来缩小映射范围,如:在SpringMVC中常用的注解还有PathVariable,RequestParam,PathVariable标记在方法的参数上,利用它标记的参数可以利用请求路径传值,看下面一个例子:在该例子中,blogId是被PathVariable标记为请求路径变量的,如果请求的是/custHthy/comment/1.do的时候就表示blogId的值为1,PathVariable在进行赋值的时候如果像上面那样没有指定后面接的变量是对应URL中的哪个变量时默认是从URL中取跟后面接的变量名相同的变量,如上面示例中的PathVariable int blogId,没有指明要获取URL中的哪个变量,这个时候就默认取URL中的blogId变量对应的值赋给方法参数中的blogId,那如果方法参数的名称跟RequestMapping中定义的访问路径中的变量名不一样,或者我要利用PathVariable明确指定后面接的方法参数是对应于URL中的哪个变量时,可以像下面这样做,在PathVariable中给定一个value=blogId(只有一个参数的时候value是可以省略的)值明确指定方法参数中的id变量是对应请求路径定义中的blogId变量的。同样RequestParam也是用来给参数传值的,但是它是从头request的参数里面取值,相当于request.getParameter(参数名)方法。它的取值规则跟PathVariable是一样的,当没有指定的时候,默认是从request中取名称跟后面接的变量名同名的参数值,当要明确从request中取一个参数的时候使用RequestParam(参数名),如下所示:ResponseBody作用:该注解用于将Controller的方法返回的对象,通过适当的HttpMessageConverter转换为指定格式后,写入到Response对象的body数据区。使用时机:返回的数据不是html标签的页面,而是其他某种格式的数据时(如json、xml等)使用。拦截器Interceptor的使用SpringMVC 中的Interceptor 拦截器也是相当重要和相当有用的,它的主要作用是拦截用户的请求并进行相应的处理。比如通过它来进行权限验证,或者是来判断用户是否登陆,或者是像12306 那样子判断当前时间是否是购票时间。 一、定义Interceptor实现类 SpringMVC 中的Interceptor 拦截请求是通过HandlerInterceptor 来实现的。在SpringMVC 中定义一个Interceptor 非常简单,主要有两种方式,第一种方式是要定义的Interceptor类要实现了Spring的HandlerInterceptor 接口,或者是这个类继承实现了HandlerInterceptor 接口的类,比如Spring 已经提供的实现了HandlerInterceptor 接口的抽象类HandlerInterceptorAdapter ;第二种方式是实现Spring的WebRequestInterceptor接口,或者是继承实现了WebRequestInterceptor的类。 (一)实现HandlerInterceptor接口 HandlerInterceptor 接口中定义了三个方法,我们就是通过这三个方法来对用户的请求进行拦截处理的。 (1 )preHandle (HttpServletRequest request, HttpServletResponse response, Object handle) 方法,顾名思义,该方法将在请求处理之前进行调用。SpringMVC 中的Interceptor 是链式的调用的,在一个应用中或者说是在一个请求中可以同时存在多个Interceptor 。每个Interceptor 的调用会依据它的声明顺序依次执行,而且最先执行的都是Interceptor 中的preHandle 方法,所以可以在这个方法中进行一些前置初始化操作或者是对当前请求的一个预处理,也可以在这个方法中进行一些判断来决定请求是否要继续进行下去。该方法的返回值是布尔值Boolean 类型的,当它返回为false 时,表示请求结束,后续的Interceptor 和Controller 都不会再执行;当返回值为true 时就会继续调用下一个Interceptor 的preHandle 方法,如果已经是最后一个Interceptor 的时候就会是调用当前请求的Controller 方法。 (2 )postHandle (HttpServletRequest request, HttpServletResponse response, Object handle, ModelAndView modelAndView) 方法,由preHandle 方法的解释我们知道这个方法包括后面要说到的afterCompletion 方法都只能是在当前所属的Interceptor 的preHandle 方法的返回值为true 时才能被调用。postHandle 方法,顾名思义就是在当前请求进行处理之后,也就是Controller 方法调用之后执行,但是它会在DispatcherServlet 进行视图返回渲染之前被调用,所以我们可以在这个方法中对Controller 处理之后的ModelAndView 对象进行操作。postHandle 方法被调用的方向跟preHandle 是相反的,也就是说先声明的Interceptor 的postHandle 方法反而会后执行,这和Struts2 里面的Interceptor 的执行过程有点类型。Struts2 里面的Interceptor 的执行过程也是链式的,只是在Struts2 里面需要手动调用ActionInvocation 的invoke 方法来触发对下一个Interceptor 或者是Action 的调用,然后每一个Interceptor 中在invoke 方法调用之前的内容都是按照声明顺序执行的,而invoke 方法之后的内容就是反向的。 (3 )afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handle, Exception ex) 方法,该方法也是需要当前对应的Interceptor 的preHandle 方法的返回值为true 时才会执行。顾名思义,该方法将在整个请求结束之后,也就是在DispatcherServlet 渲染了对应的视图之后执行。这个方法的主要作用是用于进行资源清理工作的。 下面是一个简单的代码说明:(二)实现WebRequestInterceptor 接口WebRequestInterceptor 中也定义了三个方法,我们也是通过这三个方法来实现拦截的。这三个方法都传递了同一个参数WebRequest ,那么这个WebRequest 是什么呢?这个WebRequest 是Spring 定义的一个接口,它里面的方法定义都基本跟HttpServletRequest 一样,在WebRequestInterceptor 中对WebRequest 进行的所有操作都将同步到HttpServletRequest 中,然后在当前请求中一直传递。(1 )preHandle(WebRequest request) 方法。该方法将在请求处理之前进行调用,也就是说会在Controller 方法调用之前被调用。这个方法跟HandlerInterceptor 中的preHandle 是不同的,主要区别在于该方法的返回值是void ,也就是没有返回值,所以我们一般主要用它来进行资源的准备工作,比如我们在使用Hibernate 的时候可以在这个方法中准备一个Hibernate 的Session 对象,然后利用WebRequest 的setAttribute(name, value, scope) 把它放到WebRequest 的属性中。这里可以说说这个setAttribute 方法的第三个参数scope ,该参数是一个Integer 类型的。在WebRequest 的父层接口RequestAttributes 中对它定义了三个常量:SCOPE_REQUEST :它的值是0 ,代表只有在request 中可以访问。SCOPE_SESSION :它的值是1 ,如果环境允许的话它代表的是一个局部的隔离的session,否则就代表普通的session,并且在该session范围内可以访问。SCOPE_GLOBAL_SESSION :它的值是2 ,如果环境允许的话,它代表的是一个全局共享的session,否则就代表普通的session,并且在该session 范围内可以访问。(2 )postHandle(WebRequest request, ModelMap model) 方法。该方法将在请求处理之后,也就是在Controller 方法调用之后被调用,但是会在视图返回被渲染之前被调用,所以可以在这个方法里面通过改变数据模型ModelMap 来改变数据的展示。该方法有两个参数,WebRequest 对象是用于传递整个请求数据的,比如在preHandle 中准备的数据都可以通过WebRequest 来传递和访问;ModelMap 就是Controller 处理之后返回的Model 对象,我们可以通过改变它的属性来改变返回的Model 模型。(3 )afterCompletion(WebRequest request, Exception ex) 方法。该方法会在整个请求处理完成,也就是在视图返回并被渲染之后执行。所以在该方法中可以进行资源的释放操作。而WebRequest 参数就可以把我们在preHandle 中准备的资源传递到这里进行释放。Exception 参数表示的是当前请求的异常对象,如果在Controller 中抛出的异常已经被Spring 的异常处理器给处理了的话,那么这个异常对象就是是null 。下面是一个简单的代码说明: 二、把定义的拦截器类加到SpringMVC的拦截体系中 (一) 在SpringMVC的配置文件中加上支持MVC的schema 声明事例:这样在SpringMVC的配置文件中就可以使用mvc标签了,mvc标签中有一个mvc:interceptors是用于声明SpringMVC的拦截器的。(二)使用mvc:interceptors标签来声明需要加入到SpringMVC拦截器链中的拦截器由上面的示例可以看出可以利用mvc:interceptors标签声明一系列的拦截器,然后它们就可以形成一个拦截器链,拦截器的执行顺序是按声明的先后顺序执行的,先声明的拦截器中的preHandle方法会先执行,然而它的postHandle方法和afterCompletion方法却会后执行。 在mvc:interceptors标签下声明interceptor主要有两种方式: (1)直接定义一个Interceptor实现类的bean对象。使用这种方式声明的Interceptor拦截器将会对所有的请求进行拦截。 (2)使用mvc:interceptor标签进行声明。使用这种方式进行声明的Interceptor可以通过mvc:mapping子标签来定义需要进行拦截的请求路径。 经过上述两步之后,定义的拦截器就会发生作用对特定的请求进行拦截了。 过滤器Filter的使用SpringMVC框架是一个成熟的优秀java web开发框架,学习研究框架设计有助于我们更好的理解和掌握spring MVC,设计和写出更符合的结构和代码。过滤器放在web资源之前,可以在请求抵达它所应用的web资源(可以是一个Servlet、一个Jsp页面,甚至是一个HTML页面)之前截获进入的请求,并且在它返回到客户之前截获输出请求。Filter:用来拦截请求,处于客户端与被请求资源之间,目的是重用代码。Filter链,在web.xml中哪个先配置,哪个就先调用。在Filter中也可以配置一些初始化参数。Filter 有如下几个用处 :1在HttpServletRequest 到达Servlet 之前,拦截客户的HttpServletRequest 。2根据需要检查HttpServletRequest ,也可以修改HttpServletRequest 头和数据。3在HttpServletResponse 到达客户端之前,拦截HttpServletResponse 。4根据需要检查HttpServletResponse ,可以修改HttpServletResponse 头和数据。创建一个 Filter 只需两个步骤:(1)创建Filter 处理类: 创建Filter 必须实现javax.servlet.Filter 接口,在该接口中定义了三个方法。 void init(FilterConfig config): 用于完成Filter 的初始化。 void destroy(): 用于Filter销毁前,完成某些资源的回收。 void doFilter(ServletRequest request, ServletResponse response,FilterChain chain): 实现过滤功能,该方法就是对每个请求及响应增加的额外处理。过滤器Filter也具有生命周期:init()-doFilter()-destroy(),由部署文件中的filter元素驱动。(2) 在web.xml 文件中配置Filter。参照编码过滤器示例来查看怎么实现的:首先配置在web.xml文件里的规则如下其中,filter-class 为过滤器Filter类,init-prama为注入的set参数,Filter-mapping中的url-pattern为过滤的url类型。其核心代码为:其中filterChain为过滤器链,表示执行完这个过滤器之后接着执行下一个过滤器。2.3 MybatisMybatis是支持定制化SQL、存储过程以及高级映射的优秀的持久层框架。Mybatis避免了几乎所有的JDBC代码和手工设置参数以及抽取结果集。Mybatis使用简单的XML或注解来配置和映射基本体,将接口和Java的POJOs(PlainOldJavaObjects,普通的Java对象)映射成数据库中的记录。2.3.1核心架构Mybatis的整个的执行流程图:原理详解:Mybatis应用程序根据XML配置文件创建SqlSessionFactory,SqlSessionFactory在根据配置,配置来源于两个地方,一处是配置文件,一处是Java代码的注解,获取一个SqlSession。SqlSession包含了执行sql所需要的所有方法,可以通过SqlSession实例直接运行映射的sql语句,完成对数据的增删改查和事务提交等,用完之后关闭SqlSession。2.3.2 Mybatis实际应用 Mybatis配置首先,我们需要Mybatis-Spring的jar包,Mybatis的所有操作都是基于一个SqlSession的,而SqlSession是由SqlSessionFactory来产生的,SqlSessionFactory又是由SqlSessionFactoryBuilder来生成的。但是Mybatis-Spring是基于SqlSessionFactoryBean的。在使用Mybatis-Spring的时候,我们也需要SqlSession,而且这个SqlSession是内嵌在程序中的,一般不需要我们直接访问。SqlSession也是由SqlSessionFactory来产生的,但是Mybatis-Spring给我们封装了一个SqlSessionFactoryBean,在这个bean里面还是通过SqlSessionFactoryBuilder来建立对应的SqlSessionFactory,进而获取到对应的SqlSession。通过SqlSessionFactoryBean我们可以通过对其指定一些属性来提供Mybatis的一些配置信息。所以接下来我们需要在Spring的applicationContext配置文件中定义一个SqlSessionFactoryBean。在定义SqlSessionFactoryBean的时候,dataSource属性是必须指定的,它表示用于连接数据库的数据源。当然,我们也可以指定一些其他的属性,下面简单列举几个:mapperLocations:它表示我们的Mapper文件存放的位置,当我们的Mapper文件跟对应的Mapper接口处于同一位置的时候可以不用指定该属性的值。configLocation:用于指定Mybatis的配置文件位置。如果指定了该属性,那么会以该配置文件的内容作为配置信息构建对应的SqlSessionFactoryBuilder,但是后续属性指定的内容会覆盖该配置文件里面指定的对应内容。typeAliases:数组类型,用来指定别名的。指定了这个属性后,Mybatis会把这个类型的短名称作为这个类型的别名,前提是该类上没有标注Alias注解,否则将使用该注解对应的值作为此种类型的别名。如下图: Mapping与Dao结合使用1 DAO层:配置从哪个mapping文件获取sql,这里的“CustHthy”与mapping文件的namespace一致对应起来之后,Dao层的方法就可以通过mapping文件中的sql做增删改查等操作; Mapping文件设置公共sql其它sql语句可以通过include来引用使用LIKE模糊查询有两种方法,建议用第一种 一, 二,下面我们看看# 和 $ 区别,为什么要用第一种1.#将传入的数据都当成一个字符串,会对自动传入的数据加一个双引号。如:order by #user_id#,如果传入的值是111,那么解析成sql时的值为order by 111, 如果传入的值是id,则解析成的sql为order by id.2. $将传入的数据直接显示生成在sql中。如:order by $user_id$,如果传入的值是111,那么解析成sql时的值为order by user_id, 如果传入的值是id,则解析成的sql为order by id.3. #方式能够很大程度防止sql注入。4.$方式无法防止Sql注入。5.$方式一般用于传入数据库对象,例如传入表名.。6.一般能用#的就别用$。Mybatis排序时用order by动态参数时需要注意,用$而不是#。字符串替换默认情况下,使用#格式的语法会导致Mybatis创建预处理语句属性并以它为背景设置安全的值(比如?)。这样做很安全,很迅速也是首选做法,有时你只是想直接在SQL语句中插入一个不改变的字符串。比如,像ORDER BY,你可以这样来使用:ORDER BY $columnName,这里Mybatis不会修改或转义字符串。重要:接受从用户输出的内容并提供给语句中不变的字符串,这样做是不安全的。这会导致潜在的SQL注入攻击,因此你不应该允许用户输入这些字段,或者通常自行转义并检查。所以在注重安全的情况下 我们用第一种,防止sql注入。分支判断Mybatis的分支判断是通过choose,when,otherwise来实现的: Mybatis如何防止SQL注入#xxx,使用的是PreparedStatement,会有类型转换,所以比较安全;$xxx,使用字符串拼接,可以SQL注入;like查询不小心会有漏动,正确写法如下:Mysql: select * from t_user where name like concat(%, #name, %) Oracle: select * from t_user where name like % | #name | % SQLServer: select * from t_user where name like % + #name + %关于上述结论可以在xml中验证1 select * from test where id = #id随便传个id执行后可以在日志中看到如下结果select * from test where id = ?原理是采用了jdbc中的PreparedStatement,PreparedStatement是我们很熟悉的Statement的子类,它的对象包含了编译好的sql语句。这种“准备好”的方式不仅能提高安全性,而且在多次执行一个sql时,能够提高效率,原因是sql已编译好,再次执行时无需再编译。2 select * from test order by $list随便传个参数例如id执行后可以在日志中看到如下结果select * from test order by id这种是字符串拼接的,存在sql注入隐患在Mybatis中,“$xxx”这样格式的参数会直接参与sql编译,从而不能避免注入攻击。但涉及到动态表名和列名时,只能使用“$xxx”这样的参数格式,所以,这样的参数需要我们在代码中手工进行处理来防止注入。所以尽量用#这种方式传参数,如果用到了$方式要手动过滤sql注入2.4 shiroApache Shiro是一个强大易用的Java安全框架,提供了认证、授权、加密和会话管理等功能: 认证 - 用户身份识别,常被称为用户“登录”; 授权 - 访问控制; 密码加密 - 保护或隐藏数据防止被偷窥; 会话管理 - 每用户相关的时间敏感的状态;缓存 - 比如用户登录后,其用户信息、拥有的角色/权限不必每次去查,这样可以提高效率。Shiro不会去维护用户、维护权限;这些需要我们自己去设计/提供;然后通过相应的接口注入给Shiro即可。2.4.1核心架构首先,来了解一下Shiro的三个核心组件:Subject, Securi
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 人工智能助手在办公的应用案例
- 企业团队建设资金管理办法
- 脑病科病例分析与诊断要点
- 科学七年级上册易错题深度解析
- 物流运输服务合同协议
- 科技创新项目的管理策略与实施细节
- 产品代理合作合同样式5篇
- 2025国考阿拉善盟韩语翻译岗位行测高频考点及答案
- 2025国考白城市卫生监督岗位行测模拟题及答案
- 2025国考赤峰市机关事务岗位申论预测卷及答案
- 托班服务协议书标准版5篇
- 安全应急预案编制培训课件
- 青少年社会化实践教育模式研究
- 智能测绘课件
- 2025至2030中国乳房重建和隆胸行业发展趋势分析与未来投资战略咨询研究报告
- 2025年70周岁以上老年人换长久驾照三力测试题库(含答案)
- AMZ123《2025上半年跨境电商行业报告》
- 数据赋能打造精准教学新模式
- 家庭教育指导服务行业:2025年家庭教育市场消费者行为分析报告
- 苏州加装电梯协议书范本
- 大单元教学设计课件讲解
评论
0/150
提交评论