SpringMVC
1、 SpringMVC简介
1) JavaEE体系结构包括四层,从上到下分别是应用层、Web层、业务层、持久层。
- Struts和SpringMVC是Web层的框架
- Spring是业务层的框架
- Hibernate和MyBatis是持久层的框架。
2) SpringMVC是一种基于Java,实现了Web MVC设计模式,请求驱动类型的轻量级Web框架,即使用了MVC架构模式的思想,将Web层进行职责解耦。
SpringMVC的处理流程如下——
- 前端控制器:是用户request上来的url分配给谁去处理。
作用:接收请求,响应结果,相当于转发器,是springmvc的核心,主要功能调度分配 。
- 处理映射器:接受到前端控制器的请求url找到相应的handler,也就是说找到对应的controller的方法。
例如:用户需要删除某条信息,通过(url)delete.action?id=1然后去controller找到void delete(String id)方法。
- 处理器适配器:执行handler,通过处理器适配器找到能执行handler的方法。
作用:按照特定规则(HandlerAdapter要求的规则)去执行Handler然后返回modeandview。
- 视图解析器:根据逻辑视图名生成真正的视图(在springmvc中使用View对象表示)。
作用:进行视图解析,根据逻辑视图名解析成真正的视图(view)。
- View视图:jsp页面,仅是数据展示,没有业务逻辑
2、 SpringMVC常用注解
@Controller
负责注册一个bean 到spring 上下文中
@RequestMapping
注解为控制器指定可以处理哪些 URL 请求
@RequestBody
该注解用于读取Request请求的body部分数据,使用系统默认配置的HttpMessageConverter进行解析,然后把相应的数据绑定到要返回的对象上 ,再把HttpMessageConverter返回的对象数据绑定到 controller中方法的参数上
@ResponseBody
该注解用于将Controller的方法返回的对象,通过适当的HttpMessageConverter转换为指定格式后,写入到Response对象的body数据区
@ModelAttribute
在方法定义上使用 @ModelAttribute 注解:Spring MVC 在调用目标处理方法前,会先逐个调用在方法级上标注了@ModelAttribute 的方法
在方法的入参前使用 @ModelAttribute 注解:可以从隐含对象中获取隐含的模型数据中获取对象,再将请求参数 –绑定到对象中,再传入入参将方法入参对象添加到模型中
@RequestParam
在处理方法入参处使用 @RequestParam 可以把请求参 数传递给请求方法
@PathVariable
绑定 URL 占位符到入参
@ExceptionHandler
注解到方法上,出现异常时会执行该方法
@ControllerAdvice
使一个Contoller成为全局的异常处理类,类中用@ExceptionHandler方法注解的方法可以处理所有Controller发生的异常
3、 SrpingMVC原理解析
SpringMVC的请求相应步骤如下:
1、用户向服务器发送请求,请求被Spring 前端控制Servelt DispatcherServlet捕获
2、DispatcherServlet对请求URL进行解析,得到请求资源标识符(URI)。然后根据该URI,调用HandlerMapping获得该Handler配置的所有相关的对象(包括Handler对象以及Handler对象对应的拦截器),最后以HandlerExecutionChain对象的形式返回
3、DispatcherServlet 根据获得的Handler,选择一个合适的HandlerAdapter。(附注:如果成功获得HandlerAdapter后,此时将开始执行拦截器的preHandler(...)方法)
4、提取Request中的模型数据,填充Handler入参,开始执行Handler(Controller)。 在填充Handler的入参过程中,根据你的配置,Spring将帮你做一些额外的工作
HttpMessageConveter: 将请求消息(如Json、xml等数据)转换成一个对象,将对象转换为指定的响应信息
1.数据转换:对请求消息进行数据转换。如String转换成Integer、Double等
2.数据根式化:对请求消息进行数据格式化。 如将字符串转换成格式化数字或格式化日期等
3.数据验证: 验证数据的有效性(长度、格式等),验证结果存储到BindingResult或Error中
5、Handler执行完成后,向DispatcherServlet 返回一个ModelAndView对象
6、根据返回的ModelAndView,选择一个适合的ViewResolver(必须是已经注册到Spring容器中的ViewResolver)返回给DispatcherServlet
7、ViewResolver 结合Model和View,来渲染视图
8、将渲染结果返回给客户端
4、 SpringMVC入门程序
1) 配置SpringMVC前端控制器,拦截所有请求
<servlet> <servlet-name>springmvc</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>namespace</param-name> <param-value>dispatcher-servlet</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>springmvc</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping>
在这个配置中,规定了 DispatcherServlet 的关联 XML 文件名称叫做 dispatcher-servlet。
注意,这里的路径是相对于web.xml来说的,也就是说,这个文件也在WEB-INF的根目录下。
所以,需要在WEB-INF的根目录下新建一个dispatcher-servlet.xml文件。
2) 编写dispatcher-servlet.xml,即配置SpringMVC分发器
<?xml version="1.0" encoding="UTF-8" ?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xmlns:util="http://www.springframework.org/schema/util" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd "> <!-- 开启注解模式驱动 --> <mvc:annotation-driven></mvc:annotation-driven> <!-- 扫包 --> <context:component-scan base-package="com.springmvc.*"></context:component-scan> <!-- 静态资源过滤 --> <mvc:resources location="/resources/" mapping="/resources/**"/> <!-- 视图渲染 jsp/freemaker/velocity--> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <!-- 制定页面存放的路径 --> <property name="prefix" value="/WEB-INF/pages/"></property> <!-- 文件的后缀 --> <property name="suffix" value=".jsp"></property> </bean> </beans>
根据配置,有三个需要注意的地方。
它会扫描 com.springmvc 包下所有的Java类,但凡是遇到有注解的,比如@Controller , @Service , @Autowired ,就会将它们加入到Spring的bean工厂里面去。
所有的静态资源文件,比如说 js , css , images 都需要放在/resources目录下,这个目录现在还没有建。
- 所有的展示页面,比如jsp文件,都需要放置在/WEB-INF/pages目录下,这个目录现在也没有建。
把对应的目录加上。
当我们项目一旦启动,springmvc就会扫描这三个包,将里面但凡是有注解的类都提取起来,放进Spring容器(或者说Spring的bean工厂),借由Spring容器来统一管理。这也就是你从来没有去new一个Controller的原因。
3) 导包
4)配置SpringBean工厂,applicationContext.xml文件
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:util="http://www.springframework.org/schema/util" xmlns:p="http://www.springframework.org/schema/p" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsd "> </beans>
5) 配置ViewController
为了保证安全性,我们前面将页面都放在WEB-INF目录下,WEB-INF目录下的任何资源都是无法直接通过浏览器的url地址去访问的。
现在,为了访问这个页面,我们需要用到SpringMVC的页面跳转机制。我们在Controller包下新建一个ViewController
package com.springmvc.controller; import javax.servlet.http.HttpServletRequest; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.servlet.ModelAndView; @Controller public class ViewController { @RequestMapping("/view") public ModelAndView view(HttpServletRequest request){ String path = request.getParameter("path") + ""; ModelAndView mav = new ModelAndView(); mav.setViewName(path); return mav; } }