一.SpringMVC基本原理
1.基本概念
SpringMVC框架是围绕前端控制器DispatcherServlet这个类为核心运转的。DispatcherServlet最主要的功能就是拦截来自用户的请求,并将其分配给相应的类(这样的类被称为Handler)处理,并将处理结果返回给用户。
2.执行的详细流程:
(1)用户发送请求,被DispatcherServlet截取,准备分配
(2)DispatcherServlet对请求进行解析封装,调用HandlerMapping(处理器映射器) , 根据配置或者注解寻找所有相应的Handler类
(3)DispatcherServlet再将找到的类交给HandlerAdapter(处理器适配器),调用相应的处理方法来处理请求,返回处理器视图资源。
(4)DispatcherServlet将视图资源交由ViewResolver(视图解析器)处理解析,渲染视图,返回给客户。

3.三大基本组件
(1)HandlerMapping(处理器映射器)
HandlerMapping是请求映射处理器,其建立维护了请求与Controller的映射关系,也就是通过请求的url找到对应的逻辑处理单元(Controller),几种典型的HandlerMapping如下:
- RequestMappingUrlHandlerMapping : 发起请求后,RequestMappingUrlHandlerMapping匹配到RequestMapping注解中实际的url路径,从自身维护的map中根据url取出对应的方法,包装成HanderMethod对象,然后交给RequestMappinigHandlerAdapter,用于处理controller中实际的方法。即一个url映射到一个方法。
- BeanNameUrlHandlerMapping : 需要在spring-mvc.xml中配置BeanNameUrlHandlerMapping以及bean对应的Controller。Controller要实现AbstractController,并通过bean将url映射到对应的Controller。即一个url映射到一个Controller对象,调用
handleRequestInternal方法处理请求。- SimpleUrlHandlerMapping : 该类型的用法最灵活,既可以用于匹配静态资源、又可以简化controller等等。一般是通过直接查找url返回静态资源。
(2)HandlerAdapter (处理器适配器)
按照特定规则(HandlerAdapter要求的规则)对处理器Handler进行执行,拿到后端控制器返回的结果ModelAndView后将结果返回给前端控制器DispatcherServlet。
(3)ViewResolver(视图解析器)
主要负责将从DispatcherServlet中拿到的ModelAndView对象进行解析,生成View对象返回给DispatcherServlet。
二.SpringMVC 源码分析
SpringMVC组件原理分析详见 :
三.SpringMVC常用注解
1.@PathVariable(路径变量)
通过 @PathVariable 可以将访问路径URL 中的占位符参数绑定到控制器处理方法的入参中,占位符参数获取的方法有两种:
(1)使用@PathVariable("paramId") param 的方式依次绑定每个参数并取值。如果方法中的参数名与url中{}里面(占位符)的名字一样,则可以省略@PathVariable(“paramId”)中的paramId。
(2)使用@PathVariable Map<String,String>键值对的方式一次性获取所有的占位符参数值。
@RequestMapping("/user/{userId}/name/{username}",method = RequestMethod.GET)
public String getUser(@PathVariable("userId") Integer userId,
@PathVariable("username") String username,
@PathVariable Map<String,String> pv){
System.out.println("User Id : " + userId);
System.out.println("User name : " + username);
System.out.println("User : " + pv);
return "hello";
}2.@RequestHeader(请求头信息)
@RequestHeader注解用于将请求的头信息数据映射到功能处理方法的参数上。头信息获取的方法有两种:
(1)使用@RequestHeader("header-name") String param的方法获取请求头信息中相应的数据。
(2)使用@RequestHeader Map<String,String>的方法获取所有头信息的键值对集合。
@RequestMapping(“/header”)
public String getHeader(@RequestHeader("User-Agent") String agent,
@RequestHeader Map<String,String> headers){
System.out.println("User-Agent : " + agent);
System.out.println("Headers : " + headers);
return "success";
}3.RequestParam(请求参数)
@RequestParam主要用于将请求参数区域的数据映射到控制层方法的参数上,其使用语法如下:
语法:@RequestParam(value=”参数名”,required=”true/false”,defaultValue=””) value:参数名 required:是否包含该参数,默认为true,表示该请求路径中必须包含该参数,如果不包含就报错。 defaultValue:默认参数值,如果设置了该值,required=true将失效,自动为false,如果没有传该参数,就使用默认值
@RequestParam获取请求参数值的方式有两种,如下:
(1)使用@RequestParam("paramName") param 的方式依次绑定获取GET请求内的每个参数值。
(2)使用@RequestParam Map<String,String>或MultiValueMap<String,String>键值对获取所有的请求参数。
//URL: http://localhost:8080/user?age=18&inters=basketball&inters=game
@GetMapping(“/user”)
public String getUser(@RequestParam("age") Integer age,
@RequestParam("inters") List<String> inters,
@RequestParam MultiValueMap<String,String> params){
System.out.println("User-Age : " + age);
System.out.println("User-Inters : " + inters);
System.out.println("User-Params : " + params);
return "success";
}4.@RequestBody(获取请求体)
@RequestBody是作用在形参列表上,用于将前端请求体中发送过来的数据(xml 格式或者 json等)通过HttpMessageConverter消息转换器封装到形参上。
@RequestMapping("/login")
//将前端请求体中的数据取出封装到content
public String login(@RequestBody String content){
System.out.println(content);
return "success";
}
@RequestMapping("/login")
//将前端JSON数据格式,通过消息转换器封装到Java Bean(要求属性名对应相同)
public ResultVo login(@RequestBody Users users, HttpSession session){
ResultVo resultVo = userService.login(users,session);
return resultVo;
}注意:GET方式无请求体,所以使用@RequestBody接收数据时,前端不能使用GET方式提交数据,而是用POST方式进行提交。
5. @ResponseBody
@ResponseBody用于将Controller方法返回的对象数据,通过适当的HttpMessageConverter(转换器)转换为指定格式后,写入到Response对象的body数据区,一般在返回值不是某页面时使用,如返回json、xml等时使用。使用ResponseBody将会跳过视图处理的部分,直接返回数据(如我们前后端分离开发时,JSON数据的传输与处理)。
// 使用@ResponseBody注解进行标注,直接返回需要转换的对象
@ResponseBody
@RequestMapping("/login")
public ResultVo loginUser(@RequestBody User user) {
ResultVo result = userService.login(user);
return result;
}注意:spring-mvc.xml配置文件中<mvc:annotation-driven />开启之后,会给Spring容器初始化7个不同类型的数据格式转换器,每次请求SpringMVC会从List<HttpMessageConverter>中挑选一个来处理数据,遍历HttpMessageConverter集合,与数据获取可接受类型进行匹配。实际开发中,我们通常使用第三方的FastJson转换器来代替这七个成为默认转换器,解析和封装Json数据对象。
















