Spring Web MVC内容协商机制详解

引言

在构建RESTful API时,客户端和服务器之间可能需要交换多种类型的数据。Spring Web MVC通过内容协商机制(Content Negotiation)来处理不同媒体类型的请求和响应。本文将详细解析Spring Web MVC中的内容协商机制,并提供实例代码。

内容协商策略接口(ContentNegotiationStrategy)

内容协商策略接口是Spring Web MVC中用于解决请求媒体类型的核心接口。该接口定义了一个方法resolveMediaTypes(),用于返回当前HTTP请求的媒体类型列表。

默认内容协商策略(Default ContentNegotiationStrategies)

Spring Web MVC默认注册了一些内容协商策略。以下是一个简单的控制器,用于打印默认注册的内容协商策略:

@Controller
public class MyController {
    @Autowired
    ApplicationContext context;

    @RequestMapping("/")
    @ResponseBody
    public String handleRequest() {
        Map<String, ContentNegotiationStrategy> map =
                BeanFactoryUtils.beansOfTypeIncludingAncestors(
                        context, ContentNegotiationStrategy.class,
                        true, false);
        map.forEach((k, v) -> System.out.printf("%s=%s%n",
                                              k, v.getClass().getSimpleName()));
        return "response";
    }
}

运行上述代码,访问http://localhost:8080/,服务器控制台将打印出默认的内容协商策略。

内容协商管理器(ContentNegotiationManager)

ContentNegotiationManager是确定请求所需媒体类型的中心类。它的resolveMediaTypes()方法并不直接解析媒体类型,而是委托给一系列配置的内容协商策略。

内容协商策略的顺序

内容协商策略按照特定的顺序应用。如果添加了更多的策略,它们的应用顺序将按照配置指定。

媒体类型匹配标准

ContentNegotiationManager如何应用底层策略呢?如果一个策略返回空结果或匹配所有媒体类型(即MediaType.ALL),则尝试下一个策略,直到找到更具体的媒体类型匹配。如果没有匹配,则返回空列表,调用者将其视为MediaType.ALL

匹配的媒体类型如何使用

ContentNegotiationManager的默认实例在配置时被注册为一个bean。以下是Spring MVC组件使用这个默认实例的方式:

RequestMappingHandlerMapping

RequestMappingHandlerMapping使用ContentNegotiationManager#resolveMediaTypes()匹配RequestMapping#producesRequestMapping#headers中指定的值,直到选择一个匹配。

RequestMappingHandlerAdapter

处理器返回对象到HTTP响应体的解析

RequestMappingHandlerAdapter使用ContentNegotiationManager#resolveMediaTypes()返回的媒体类型来选择一个合适的HttpMessageConverter。然后调用选定的HttpMessageConverterwriteInternal()方法,将处理器方法的返回值进行转换。

HTTP请求体到处理器方法参数的解析

基于请求的Content-Type头,选择一个合适的HttpMessageConverter,然后调用选定的HttpMessageConverterreadInternal()方法,将请求体转换为Java对象。

ResourceHandlerRegistry

它将内容协商策略应用于静态资源,包括图片、CSS文件等。

ViewResolverRegistry

它实际上将内容协商策略应用于ContentNegotiatingViewResolver,后者使用内容协商策略返回的媒体类型,在视图渲染时选择一个合适的视图。

ExceptionHandlerExceptionResolver

类似于RequestMappingHandlerAdapterExceptionHandlerExceptionResolver使用内容协商策略选择一个合适的HttpMessageConverter来准备响应(来自注解了@ExceptionHandler的方法)。

结语

在接下来的教程中,我们将探索如何自定义默认的内容协商策略,并提供一个编写自定义内容协商策略的示例。

示例项目

使用的依赖和技术:

  • spring-webmvc 4.3.9.RELEASE:Spring Web MVC。
  • javax.servlet-api 3.0.1:Java Servlet API。
  • junit 4.12:JUnit是一个Java的单元测试框架,由Erich Gamma和Kent Beck创建。
  • JDK 1.8
  • Maven 3.3.9
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值