SpringMVC项目的执行流程:
|--在请求到达真实处理器之前会先被DispatcherServlet核心处理器进行拦截
|--由核心处理器调用HandlerMapping映射器将拦截下来的请求路径按需求映射给我们自定义的处理器
|--由核心处理器调用HandlerAdapter适配器将拦截下来的请求参数按需求映射给我们自定义的处理器
|--实际处理器处理结果将返回给DispatcherServlet核心处理器
|--接收到处理结果后DispatcherServlet处理器将对视图层做出响应(此过程会由ViewResolver解析器进行干预)
SpringMVC中的域对象:
|--传统Servlet中的域对象(request、session、servletContext)
|--用法同传统web项目中一致
|--ModelAndView域对象:用于传递数据信息与视图信息
|--通过addObject("XX",YY)绑定数据信息
|--XX用于设置所绑定数据在域中的属性名
|--YY为需要绑定的数据
|--通过setViewName("XX")绑定视图信息
|--XX为需要跳转的视图路径
|--注意ModelAndView域对象在进行请求转发时的用法同传统域对象
|--注意ModelAndView域对象在进行重定向跳转时会将绑定的数据信息以明文的方式拼接在路径背后
|--注意ModelAndView域对象必须作为处理器的返回值时其各种设置才能生效
|--Model域对象:用于传递数据信息
|--通过addObject("XX",YY)绑定数据信息
|--XX用于设置所绑定数据在域中的属性名
|--YY为需要绑定的数据
|--注意Model域对象在进行请求转发时的用法同传统域对象
|--注意Model域对象在进行重定向跳转时会将绑定的数据信息以明文的方式拼接在路径背后
|--可以理解为Model域对象就是为了解决ModelAndView域对象必须作为返回值才能生效的鸡肋性而存在
创建SpringMVC项目的流程:
|--确保当前是web工程环境
|--添加相关依赖
|--如spring-context依赖、spring-webmvc依赖、servlet-api依赖等
|--创建并编写springmvc配置文件(约束同spring配置文件)
|--在配置文件中添加包扫描
|--在配置文件中添加<mvc:annotation-driven/>注解驱动,表明采用处理器的注解式开发
|--注意这是处理器中能进行各种注解式开发的前提(例如 @RequestMapping、 @ResponseBody、 @DateTimeFormat、 @RequestParam等)
|--在配置文件中根据需求决定是否添加视图解析器(即ViewResolver)
|--在web.xml配置文件中注册springMVC框架,即注册DispatcherServlet核心处理器,具体格式如下
|--<servlet>
<servlet-name>XX</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:YY</param-value>
</init-param>
<servlet>
<servlet-mapping>
<servlet-name>XX</servlet-name>
<url-pattern>ZZ</url-pattern>
<servlet-mapping>
|--XX为DispatcherServlet类的别名
|--YY为springmvc配置文件的路径(默认从类的根路径下开始检索)
|--ZZ为需要拦截的路径
|--可以将设置初始化参数的步骤理解为将映射器、解析器、处理器的配置写在一个配置文件中,然后通过contextConfigLocation属性关联以减少耦合度
|--因为DispatcherServlet类是底层已经实现的类,故我们无法通过注解的方式完成注册
|--可以将DispatcherServlet核心处理器简单理解为一个web项目中的servlet
|--在处理器类中以处理函数的形式编写功能
SpringMVC中的适配器(HandlerAdapter):
|--为处理函数提供默认参数支持,常用的如下
|--HttpServletRequest对象
|--通过setAttribute()、getAttribute()存取数据
|--HttpServletResponse对象
|--通过setAttribute()、getAttribute()存取数据
|--HttpSession对象
|--通过setAttribute()、getAttribute()存取数据
|--Model对象
|--通过addAttribute()、getAttribute()存取数据
|--Map对象
|--通过put()、get()存取数据
|--ModelMap对象
|--通过addAttribute()、getAttribute()存取数据
|--接收请求中的参数并为处理函数的形参列表赋值
|--处理函数中用多个参数接收前台传递的数据(非注解式)
|--确保前台提交参数的字段名和处理函数形参列表中的参数名一样
|--适配器会为我们自动匹配赋值并完成类型转换
|--处理函数中用多个参数接收前台传递的数据( @RequestParam注解式)
|--在后台处理函数形参列表每个参数前需要添加 @RequestParam("XX")注解
|--XX为前台提交参数的字段名
|--适配器会为我们自动匹配赋值并完成类型转换
|--处理函数中用多个参数接收前台传递的数据( @PathVariable注解式,也称为restful风格)
|--前台所传递的参数必须以/XX的形式拼接在请求路径中
|--XX为前台需要提交的数据
|--处理函数需要在对应的 @RequestMapping注解中通过在路径中拼接/{XX}的方式进行接收
|--XX为用于接收参数的自定义别名
|--处理函数形参列表每个参数前需要添加 @PathVariable("XX")注解
|--XX为接收参数时的自定义别名
|--适配器会为我们自动匹配赋值并完成类型转换
|--注意由于该请求参数需要拼接在路径中,故这种方式只适用于get请求
|--处理函数中用一个对象接收前台传递的数据
|--确保前台提交参数的字段名和该对象中的成员属性名能匹配的上
|--适配器会为我们自动匹配赋值,完成类型转换并封装出对象
|--注意无论是提供默认参数支持还是接收请求参数并赋值,都是先调用参数列表中参数的空参构造创建对象,再通过set注入的方式完成赋值
SpringMVC中的处理器:
|--SpringMVC中可以可以有多个处理器类,每个类中可以有多个处理函数,通过这些函数完成功能的运作,具体格式如下
|--在处理函数上方通过 @RequestMapping(value="XX",method=YY)注解绑定路径
|--XX为需要绑定的路径
|--YY指定该函数只接收特定类型的请求,可选RequestMethod.GET或RequestMethod.POST
|--可以理解为每一个处理函数都是传统web项目中的一个servlet
|--注意该处理器类必须作为bean纳入spring的管理
|--注意该处理器类不需要再通过 @WebServlet注解进行声明
|--可以理解为注册了springmvc的核心处理器后,相当于将servlet对象的构建交给了spring,故不需要我们自己再做标识
|--注意RequestMapping也可以同时加在处理器类上解决不同类中同名函数访问的问题
|--相当于加了一级虚拟路径
SpringMVC中的视图解析器(ViewResolver):
|--视图解析用于干预和处理我们所返回的路径请求,具体格式如下
|--<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!--拼接前缀-->
<property name="prefix" value="XX"/>
<!--拼接后缀-->
<property name="suffix" value="YY"/>
</bean>
|--XX为跳转路径需要拼接的前缀
|--YY为跳转路径需要拼接的后缀
|--可以理解为视图解析器就是为了简化我们路径的书写,有了前缀后缀的概念后我们以后只需写跳转文件的名字即可
SpringMVC框架对WEB-INF文件夹的支持:
|--所有位于WEB-INF文件夹中的资源均不能直接访问到,必须通过处理函数的请求转发进行访问
SpringMVC中的请求转发与重定向:
|--请求转发
|--在返回的路径字符串中添加forward:作为前缀,框架会自动屏蔽解析器,将我们输入的字符串直接作为路径转发
|--重定向
|--在返回的路径字符串中添加redirect:作为前缀,框架会自动屏蔽解析器,将我们输入的字符串直接作为路径重定向
|--注意由解析器进行跳转的路径均为请求转发
SpringMVC中对中文编码的支持:
|--SpringMVC框架已经为我们内置了一个编码过滤器类,我们只需要在web.xml中进行配置即可,具体格式如下
|--<filter>
<filter-name>XX</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>forceRequestEncoding</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>forceResponseEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>XX</filter-name>
<filter-pattern>YY</filter-pattern>
</filter-mapping>
|--XX用于自定义该过滤器的别名
|--YY用于设置该过滤器需要拦截的路径
SpringMVC中处理函数的返回值类型:
|--字符串类型
|--框架会自动调用视图解析器为其拼接前缀和后缀,得到一个路径并进行跳转
|--ModelandView对象
|--框架会自动读取该对象中包含的视图信息并进行请求转发
|--视图信息通过对象调用setViewName()方法进行设置
|--void类型
|--框架会在执行完函数体后跳到默认路径中
|--默认路径为当前访问路径去除后缀后的路径
|--注意如果在函数体中手动进行了重定向或者请求转发,则不会再触发默认路径的跳转
SpringMVC中对ajax请求的支持:
|--准备支持环境
|--添加jackson-databind依赖
|--添加jackson-annotations依赖
|--添加jackson-core依赖
|--在处理函数的上方添加 @ResponseBody注解,表明当前处理的请求是一个ajax请求
|--此时若处理函数返回的是字符串类型或基本类型数据,框架都会将内容作为字符串格式响应给前端
|--注意如果存在中文乱码问题需要在响应前设置编码格式
|--此时若处理函数返回的是一个对象类型,框架会自动将其转换成JSON字符串响应给ajax的回调函数
|--此时若处理函数返回的是void类型,则不会发送任何页面跳转
|--实际开发中我们通常很少采用字符串的返回格式,如果需要返回字符串也会封装成对象的形式进行返回
|--可以理解为这是为了尽可能减少对浏览器编码格式的修改
SpringMVC对静态资源文件的三种支持方案:
|--方案一:配置默认处理器处理静态资源,具体格式如下
|--<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>XX</url-pattern>
</servlet-mapping>
|--XX为需要交给默认处理器处理的资源路径
|--这种方式得以解决是因为默认处理器的优先级要高于SpringMVC的核心处理器
|--方案二:给核心处理器配置静态资源的访问权限,具体格式如下
|--<mvc:resources mapping="XX" location="YY"/>
|--XX为需要放行的静态资源请求路径
|--YY用于指定该静态资源请求路径所能访问的位置
|--方案三:将核心处理器处理不了的所有请求,都交给默认处理器,具体格式如下
|--<mvc:default-servlet-handler/>
SpringMVC对拦截器的支持:
|--实现方式
|--方式一:继承HandlerInterceptorAdapter类并重写其方法
|--方式二:实现HandlerInterceptorAdapter接口并重写其方法
|--注意无论通过哪种方式实现都需要在SpringMVC的配置文件中进行注册,具体格式如下
|--<mvc:interceptors>
<mvc:interceptor>
<!--配置需要进行拦截的路径-->
<mvc:mapping path="XX"/>
<!--配置可以进行放行的路径-->
<mvc:exclude-mapping path="YY"/>
<!--配置具体的拦截器实现类-->
<bean class="ZZ"/>
</mvc:interceptor>
</mvc:interceptors>
|--XX为需要拦截的请求路径
|--YY为需要放行的请求路径
|--ZZ为拦截器实现类的全限定类名
|--拦截时机(每个时机即对应我们继承或实现时重写的方法)
|--preHandle():在请求被处理之前进行的一系列操作
|--注意由于该方法是位于处理器接到请求之前,故返回的是布尔值,如果为true则放行,为false则拦截
|--postHandle():在请求一处理完且还未响应时进行的一些列操作(故此时机的操作有可能改变响应结果)
|--afterCompletion():请求响应完成之后进行的一系列操作(一般为清理对象,关闭资源等)
|--可以将SpringMVC中的拦截器理解为传统web项目中过滤器
SpringMVC框架对文件上传的支持:
|--前提准备
|--添加commons-fileupload依赖
|--设置提交方式为post提交
|--设置提交数据的编码格式为enctype="multipart/form-data"
|--在配置文件中注册文件上传解析器,具体格式如下
|--<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="maxUploadSize" value="XX"/>
<property name="defaultEncoding" value="YY"/>
</bean>
|--XX用于设置所上传文件的最大尺寸,不做设置的话默认为long的最大长度
|--YY用于设置文件上传的编码格式,不做设置的话默认为utf-8
|--注意id名称固定且不可省略
|--具体操作
|--在处理函数的形参列表中使用MultipartFile对象接收所上传的文件
|--使用MultipartFile对象调用一系列方法操作文件,常用方法如下
|--getName():获取提交时文件所对应的key值
|--getOriginalFilename():获取文件带后缀名的名字
|--transferTo(XX):将文件写入指定的位置
|--XX为File对象,用于设置存入位置
|--可以理解为transferTo方法就是对传统web项目中使用输入输出流存储文件的封装
SpringMVC框架对文件下载的支持:
|--将处理函数的返回类型设置为ResponseEntity<byte[]>
|--在处理函数中设置响应头对象,通知浏览器开启下载器,具体格式如下
|--new HttpHeaders().setContentDispositionFormData("attachment",new String("XX".getBytes(),"ISO-8859-1"))
|--XX为自定义的文件下载名字
|--注意通过字符串构造方法设置名字是因为我们需要将其设置成浏览器能识别的编码格式
|--调用FileUtils工具类中的方法将文件转换为字节数组,具体格式如下
|--FileUtils.readFileToByteArray(XX)
|--XX为需要下载的文件对象
|--将文件字节数组、响应头对象、响应状态码作为参数构建ResponseEntity<byte[]>对象并返回,具体格式如下
|--return new ResponseEntity<byte[]>(XX, YY, HttpStatus.OK)
|--XX为需要下载文件的字节数组
|--YY为响应头对象
SpringMVC框架对mybatis分页插件的支持:
|--引入pagehelper依赖
|--在spring配置文件中添加分页插件,具体格式如下
|--<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="XX"/>
<property name="plugins">
<array>
<bean class="com.github.pagehelper.PageInterceptor">
<property name="properties">
<value>
offsetAsPageNum=true
<!--开启自动查询总条数功能-->
rowBoundsWithCount=true
<!--表示如果请求页为0的话则不执行分页插件-->
pageSizeZero=true
<!--开启修正功能,即若请求页数小于0强制改为首页,大于总页数强制改为最后一页-->
reasonable=true
</value>
</property>
</bean>
</array>
</property>
</bean>
|--XX为数据源bean的别名
|--在需要进行分页的方法前开启分页工具,具体格式如下
|--PageHelper.startPage(XX,YY,ZZ);
|--XX用于设置当前页
|--YY用于设置页面步长
|--ZZ用于设置导航栏一次展示页数,不做设置的话默认为8
|--注意分页开启代码和需要进行分页的方法之间必须紧密相连,不得穿插其他代码片段
|--在需要页面详细信息的地方通过new PageInfo<>(XX)得到页面对象并通过该对象调用各种属性得到页面详情
|--XX为执行了分页的方法的返回值(一般为集合)
|--常用属性
|--pageNum:当前页
|--pageSize:步长
|--pageSize:步长
|--pages:总页数
|--prePage:上一页页码
|--nextPage:下一页页码
|--isFristPage:是否是第一页
|--isLastPage:是否是最后一页
|--hasPreviousPage:是否有上一页
|--hasNextPage:是否有下一页
|--navigatePages:导航页码数
|--navigatepageNums:所有导航页号
|--navigateFirstPage:导航第一页
|--navigateLastPage:导航最后一页
|--firstPage:第一页
|--lastPage:最后一页
|--list:所查询的数据库数据
|--分页过程简单概述
|--分页插件会对紧邻着的下一个查询方法进行干预,得到除了查询结果外的所有页面数据并封装成对象
|--这时我们再手动将查询结果放入该对象,便可以得到一个含有页面所有信息的对象
SpringMVC中对日期的处理:
|--针对日期提交的处理
|--方式一(局部处理)
|--在处理函数的用于接收日期参数的类型前添加 @DateTimeFormat(pattern="yyyy-MM-dd")注解
|--该注解可以将接收到的字符串类型解析成日期类型
|--注意如果日期类型是处理函数参数列表中参数的一个成员变量,则应该在该成员变量或其对应的set方法上添加DateTimeFormat注解
|--方式二(全局处理)
|--通过 @InitBinder注解注册一个适用与全局的日期格式转换器,具体格式如下
|-- @InitBinder
public void XX(WebDataBinder dataBinder){
dataBinder.registerCustomEditor(YY,ZZ(KK,true))
}
|--XX为自定义转换器名
|--YY为需要使用该转换器的类型(如果为日期类则写Date.class)
|--ZZ为转换类型所使用的工具(如果为日期类则写CustomDateEditor)
|--KK为工具类中需要用到的对象(如果为日期类的话可以写日期格式刷对象,如SimpleDateFormat对象)
|--针对日期显示的处理
|--方式一(在业务层进行处理)
|--直接在业务层转换成字符串类型再往下传
|--方式二(在视图层使用jstl格式标签库进行处理)
|--格式为<XX:formatDate value="YY" pattern="yyyy-MM-dd">
|--XX为jstl格式库的别名
|--YY为需要进行格式化的数据
|--注意使用jstl标签库需要导入jstl相关依赖并在jsp页面中通过taglib指令进行引入
|--方式三(针对JSON类型的响应)
|--在该对象日期类型的成员变量get方法上添加 @JsonFormat(pattern="yyyy-MM-dd")注解
|--因为json调用属性时会自动调用其对应的get方法进行读取