1 mvc: annotation-driven 标签

1.1 关于 mvc: annotation-driven 作用

[1]、 <mvc:annotation-driven /> 会自动向容器中注册如下组件,并且会代替之前默认的组件:

  • HandlerMapping :请求映射,负责根据用户请求 url 找到要执行的 Handler
    • RequestMappingHandlerMapping :支持@RequestMapping 注解
    • BeanNameUrlHandlerMapping :将 controller 类的名字映射为请求 url
  • HandlerAdapter : 处理器适配器,用于请求处理,通过 HandlerAdapter 对处理器进行执行
    • RequestMappingHandlerAdapter :处理@Controller 和@RequestMapping 注解的处理器
    • HttpRequestHandlerAdapter :处理继承了 HttpRequestHandler 创建的处理器
    • SimpleControllerHandlerAdapter :处理继承自 Controller 接口的处理器
  • ExceptionResolver :处理异常的解析器
    • ExceptionHandlerExceptionResolver
    • ResponseStatusExceptionResolver
    • DefaultHandlerExceptionResolver

<mvc:annotation-driven /> 最主要的作用是配置两个最常用的组件 RequestMappingHandlerMappingRequestMappingHandlerAdapter

  • RequestMappingHandlerMappingHandlerMapping 的实现类,它会在容器启动的时候,扫描容器内的 bean, 解析带有@RequestMapping 注解的方法,并将其解析为 url 和 handlerMethod 键值对方式注册到请求映射表中。
  • RequestMappingHandlerAdapter HandlerAdapter 的实现类,它是处理请求的适配器,说白了,就是确定调用哪个类的哪个方法,并且构造方法参数,返回值。

<mvc:annotation-driven/> 是告知 Spring 容器,我们启用注解驱动,支持 @RequestMapping 注解,这样我们就可以使用 @RequestMapping 来配置处理器。

<context:component-scan/> 标签是告诉 Spring 容器来扫描指定包下的类,并注册被 @Component@Controller@Service@Repository 等注解标记的组件相似。

② 还将提供以下支持:

  • 支持使用 ConversionService 实例对表单参数进行类型转换
  • 支持使用 @NumberFormat@DateTimeFormat 注解完成数据类型的格式化
  • 支持使用 @Valid 注解对 JavaBean 实例进行 JSR 303 验证
  • 支持使用 @RequestBody@ResponseBody 注解

1.2 mvc: annotation-driven 在什么时候必须配置

[1]、直接配置响应的页面:无需经过控制器来执行结果;但会导致其他请求路径失效,需要配置 mvc:annotation-driven 标签

<mvc:view-controller path="/success" view-name="success"/>

[2]、RESTful-CRUD 操作,删除时,通过 jQuery 执行 delete 请求时,找不到静态资源,需要配置 mvc:annotation-driven 标签

<mvc:default-servlet-handler /> 将在 SpringMVC 上下文中定义一个 DefaultServletHttpRequestHandler,它会对进入 DispatcherServlet 的请求进行筛查,如果发现是没有经过映射的请求,就将该请求交由 WEB 应用服务器默认的 Servlet 处理,如果不是静态资源的请求,才由 DispatcherServlet 继续处理。

[3]、配置类型转换器服务时,需要指定转换器服务引用

<mvc:annotation-driven conversion-service=“conversionService”/> 会将自定义的 ConversionService 注册到 Spring MVC 的上下文中

[4]、后面完成 JSR 303 数据验证,也需要配置

1.3 关于 mvc: annotation-driven 配合使用的几种情况

**[1]、既没有配置 <mvc:default-servlet-handler /> 也没有配置 <mvc:annotation-driven /> **

结果:动态资源像 @RequestMapping 映射的资源能访问,静态资源 (. Html,. Js,. Img) 不能访问

这里用到的是默认的注解请求映射—— DefaultAnnotationHandlerMapping,它里面有一个 handlerMap 里面包含了映射,所以动态的能访问。静态不能访问,就是因为里面没有保存静态资源映射。

image

**[2]、配置了 <mvc:default-servlet-handler /> 但没有配置 <mvc:annotation-driven /> **

结果:可以加载静态资源,动态资源不行。

可以发现 DefaultAnnotationHandlerMapping 没有了,所以不能存储那些请求信息了。

image

**[3]、既配置了 <mvc:default-servlet-handler /> 又配置 <mvc:annotation-driven /> **

结果:动态资源和静态资源都能访问

2 mvc: view-controller 标签

mvc:view-controller 标签的作用可以让我们在 Controller 类中少写一点代码,我们只需在 XML 中配置一下请求即可即可,其实我感觉没什么卵用,还不如直接在 Controller 中写呢!

那么它是怎么来使用的呢?假设有下面这样一个 handler 方法:

@RequestMapping("/hello")
public String hello() {
    return "success";
}

这个方法内部没有做任何处理,仅仅是把一个 URL 地址”/hello”映射到视图”success”。此时我们就可以使用 mvc:view-controller 标签来简化一下。

<mvc:view-controller path="/hello" view-name="success"/>
<mvc:annotation-driven/>

标签内部的两个属性介绍如下:

  • path=”/hello” 就是你访问的路径(相当于 RequestMapping (“/hello”)
  • view-name=”success” 就是你要跳转的视图页面(如 success. jsp,相当于 return “success” ) 配置了这个后对于 /success 请求就会直接交给 dispatcherServlet 处理,然后使用 ViewResolver 进行解析。

上面配置的是请求转发,还可以配置重定向请求:

@RequestMapping("/index")
public String index(){
    return "redirect:success.jsp";//注意这里访问不是WEB-INF下面的JSP
}

mvc: view-controller 来代替:

<mvc: view-controller path="/hello" view-name="redirect: success. jsp"/>
<mvc: annotation-driven/>

最后注意事项:

  • 使用了这个标签后必须配置 <mvc:annotation-driven />,否则会造成所有的@Controller 注解无法解析,导致 404 错误。
  • 如果请求存在处理器, 则这个标签对应的请求处理将不起作用。因为请求是先去找处理器处理, 如果找不到才会去找这个标签配置。

参考链接: