2.2.1 Spring MVC的主要组件
- 前端控制器 DispatcherServlet(不需要程序员开发)作用:接收请求、响应结果,相当于转发器,有了DispatcherServlet 就减少了其它组件之间 的耦合度。
- 处理器映射器HandlerMapping(不需要程序员开发) 作用:根据请求的URL来查找Handler
- 处理器适配器HandlerAdapter注意:在编写Handler的时候要按照HandlerAdapter要求的规则去编写,这样适配器 HandlerAdapter才可以正确的去执行Handler。
- 处理器Handler(需要程序员开发)
- 视图解析器 ViewResolver(不需要程序员开发) 作用:进行视图的解析,根据视图逻辑名解析成真正的视图(view)
- 视图View(需要程序员开发jsp) View是一个接口, 它的实现类支持不同的视图类型(jsp,freemarker,pdf等等)
2.2.2 简单介绍下SpringMVC执行流程
- 用户发送请求至前端控制器DispatcherServlet
- DispatcherServlet收到请求后,调用HandlerMapping处理器映射器,请求获取Handle
- 处理器映射器根据请求url找到具体的处理器,生成处理器对象及处理器拦截器 , 组成一个处理器链 , 一并返回给DispatcherServlet
- DispatcherServlet 调用 HandlerAdapter处理器适配器;
- HandlerAdapter 经过适配调用具体处理器(Handler,也叫后端控制器)
- Handler执行完成返回ModelAndView
- HandlerAdapter将Handler执行结果ModelAndView返回给DispatcherServlet
- DispatcherServlet将ModelAndView传给ViewResolver视图解析器进行解析
- ViewResolver解析后返回具体View
- DispatcherServlet对View进行渲染视图(即将模型数据填充至视图中)
- DispatcherServlet响应用户
2.2.3 Spring MVC常用的注解有哪些
- @RequestMapping:用于处理请求 url 映射的注解,可用于类或方法上
- @RequestBody:注解实现接收http请求的json数据,将json转换为java对象
- @ResponseBody:注解实现将conreoller方法返回对象转化为json对象响应给客户
- @Controller:控制器的注解,表示是表现层,不能用用别的注解代替
- @RestController : 组合注解 @Conntroller + @ResponseBody
- @PathVariable : 接收请求路径中的参数
- @RequestParam : 接收请求参数
- @RequestHeader : 接收请求头数据
- @ExceptionHandler : 用于全局异常处理器, 指定补货具体类型的异常
- @ControllerAdvice: 主要用来处理全局数据,一般搭配@ExceptionHandler使用 , 进行异常处理
- @RestControllerAdvice : 组合注解@ControllerAdvice + @ResponseBody
- @CookieValue : 获取请求中指定名称的cookie值
- @SessionAttribute : 获取带session中属性值
- @CrossOrigin : 设置CROS跨域访问
2.2.4 SpringMVC怎么样设置重定向和转发?
实现转发 :
- 控制器直接返回视图名称
/**
* 指定逻辑视图名,经过视图解析器解析为jsp物理路径:/WEB-INF/pages/success.jsp
*/
@RequestMapping("/str")
public String respStr(){
System.out.println("aaaaaaaaaaaa");
return "success";
}
- 使用
forward
关键字
@RequestMapping("/forward")
public String forward(User user,HttpSession session) throws ServletException, IOException {
//将数据保存到session中
session.setAttribute("logined", user);
return "forward:/WEB-INF/pages/success.jsp";
}
- 使用
request
请求对象实现转发
@RequestMapping("/str")
public void respStr(User user, HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {
System.out.println("aaaaaaaaaaaa");
request.setAttribute("logined",user);
request.getRequestDispatcher("/WEB-INF/pages/success.jsp").forward(request,response);
}
实现重定向 :
- 使用
redirect
关键字
@RequestMapping("/redirect")
public String redirect(User user,HttpSession session) throws ServletException, IOException {
//将数据保存到session中
session.setAttribute("logined", user);
return "redirect:/index.jsp";
}
- 使用
response
对象实现重定向
@RequestMapping("/void")
public void respStr(User user, HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {
//业务操作...
response.sendRedirect(request.getContextPath()+"/index.jsp");
}
2.2.5 拦截器和过滤器的区别
拦截器和过滤器都可以对请求进行拦截,都可以体现例如权限的检查、日志的记录等功能。但是有不同之处:
- 使用范围不同:拦截器是在SpringMVC提供的 , 拦截的是SpringMVC的控制器 , 而filter是Servlet规范规定的,是Servlet容器支持的 , 拦截的是所有的web资源
- 执行顺序不同:过滤器只能在web项目中使用,它的执行顺序是由web.xml文件中的配置决定的;而拦截器可以在任何Java类中使用,它的执行顺序是由Spring容器管理的
2.2.6 你们项目中异常是怎么控制的 ?
我们会根据不同的异常情况定义异常类 , 异常类实现RuntimeException接口 , 然后在需要进行异常处理的位置对外抛出对应异常
在项目中定义全局异常处理类 , 使用@ControllerAdvice + @ExceptionHandler 捕获指定异常 , 处理异常 , 向客户端响应提示信息
package com.heima.common.exception;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.common.enums.AppHttpCodeEnum;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
@ControllerAdvice //控制器增强类
@Slf4j
public class ExceptionCatch {
/**
* 处理不可控异常
* @param e
* @return
*/
@ExceptionHandler(Exception.class)
@ResponseBody
public ResponseResult exception(Exception e){
e.printStackTrace();
log.error("catch exception:{}",e.getMessage());
return ResponseResult.errorResult(AppHttpCodeEnum.SERVER_ERROR);
}
/**
* 处理可控异常 自定义异常
* @param e
* @return
*/
@ExceptionHandler(CustomException.class)
@ResponseBody
public ResponseResult exception(CustomException e){
log.error("catch exception:{}",e);
return ResponseResult.errorResult(e.getAppHttpCodeEnum());
}
}