什么是SpringMVC?
SpringMVC是Spring框架的一个模块,它是一种基于MVC设计模型的轻量级Web框架
什么是MVC设计模型?
MVC,Model View Controller,即模型视图控制器,它是一种软件设计典范。它将业务逻辑,数据和视图分离,在需要改进和定制界面时不需要修改业务逻辑代码,实现了代码解耦。
SpringMVC的执行流程?
- 用户向服务器发送一个请求,DispatcherServlet(前端控制器)接收到请求
- DispatcherServlet请求HandlerMapping(处理器映射器)根据URL和注解或xml配置去寻找对应的Handler(处理器)并返回给DispatcherServlet
- DispatcherServlet请求HandlerAdapter(处理器适配器)去执行对应的Handler
- Handler执行完毕后会返回一个ModelAndView对象给HandlerAdapter
- HandlerAdapter把ModelAndView返回给DispatcherServlet
- DispatcherServlet收到ModelAndView后,请求ViewResoler(视图解析器)对视图进行解析
- ViewResoler解析完后将视图结果返回给DispatcherServlet
- DispatcherServlet收到解析结果后,进行视图渲染,将ModelAndView中的Model数据填充到View视图中的request域中,生成最后的视图
- DispatcherServlet向用户返回结果
上述的Handler也就是我们常说的Controller
SpringMVC是Spirng框架的一部分,所以自然也拥有Spirng的特点,IOC(控制反转),DI(依赖注入),AOP(切面)等
IOC(Inversion of Control):控制反转。控制的是对象,反转的是对象的创建权和管理权。以前我们需要创建某个对象的依赖对象时,都需要自己new一个,这会使得代码耦合严重。现在将对象都交由Spirng容器管理,依赖对象何时产生,怎么产生,这与我们无关,Spring容器就像一个工厂,他会帮我们产生对象。那有了对象,怎么使用呢?那就用到了DI(依赖注入)。
DI(Dependency Injection):当我们需要使用依赖对象时,仅需将他通过注解或者xml的方式注入进来,我们就可以直接使用了。
AOP(面向切面编程):我们假设从DAO->Service->Controller是一个纵向的过程,那么AOP就可以看做是横向切入,比如在业务逻辑代码执行过程中横向切入一个日志打印。这可以看做是对业务功能的一个增强
请求转发与重定向
请求转发(forward):A将http请求在内部转给B处理,A和B必须是在同一服务器下,且客户端浏览器路径栏内仍显示第一次请求的路径,客户感知不到请求转发,浏览器只执行了一次请求
重定向(redirect):一种资源跳转方式。当浏览器给A资源发送http请求,A发现处理不了,此时会响应浏览器自己处理不了(发送302状态码),并让浏览器去访问B,这个B可以是本服务器,也可以是别的服务器。所以重定向是用户能够感知到的,且访问地址也发生了变化。浏览器一共发生了两次请求
SpringMVC中的常用注解:
@requestMapping(“/xxx”):用于处理请求url,注释于类或方法上。注释在类上表示该类的所有方法都以/xxx为父路径
@requestBody:实现接收http请求的json数据,将json数据转化为java对象
@responseBody:实现将controller方法返回对象转化为json对象响应
如何解决get和post请求乱码问题?
GET:修改Tomcat配置文件
POST:在web.xml中配置一个CharacterEncodingFilter过滤器,设置对应编码
SpringMVC拦截器:运用了AOP的原理,在controller处理请求之前进行处理。一般是通过实现HandlerInterceptor接口,并在web.xml文件中配置
接口中声明了三个方法:
preHandle():这个方法在Controller处理请求之前被调用,如果存在多个Interceptor,那么这些拦截器会根据声明顺序成链,在Controller处理请求之前依次调用这些拦截器的preHandle()方法。在这个方法中可以进行一些判断来决定请求是否要继续执行,或者对当前请求进行一些预处理。该方法的返回值为boolean类型,当返回true时,那就会继续执行下一个拦截器的preHandler(),若是最后一个拦截器,那么就让Controller处理请求,如果返回false,那么后面的拦截器和Controller都不会执行。
PostHandle():这个方法在Controller处理完请求之后,DispatcherServlet进行视图渲染之前被调用,所以我们可以在这个方法中对Controller返回的ModelAndView对象进行处理。PostHandle()被调用的方向和preHandle()是相反的,也就是当前拦截器声明的越靠前,这个方法执行的越靠后
AfterCompletion():在DispatcherServlet渲染完对应的视图后执行
注解:在这之前,xml备受青睐,因为他以低耦合的方式几乎完成了框架中的所有配置,但是随着项目越来越大,xml中的配置会越来越复杂,导致不方便维护,所以注解配置方式就产生了。注解的本质就是一个继承了Annotation接口的接口,其具体实现类是Java运行时生成的动态代理类。我们通过反射获取注解时,返回的是java运行时生成的动态代理类对象。通过代理类调用自定义注解的方法,最终会调用AnnotationInvocationHandler的invoke()方法。该方法会从memberValues这个Map中索引处对应的value值。
元注解:修饰注解的注解
@Target:注解的作用目标
@Retention:注解的生命周期
@Documented:注解是否应该被包含在JavaDoc文档中
@Inherited:是否允许子类继承该注解
SpringMVC的异常处理
我们可以不用自定义异常处理器,把异常交给Spring框架处理,我们只需要在web.xml文件中配置即可
@ControllerAdvice和@ExceptionHandler的区别
@ControllerAdvice:注释在类上,标志着一个类是全局异常处理类
@ExceptionHandler:注释在方法上,标志着一个方法是全局异常处理方法
SpringMVC的四种返回值类型
- ModelAndView
- Void:分为无返回值,请求转发,重定向
- String : 分为字符串,视图名称,请求转发,重定向
- JSON