内容协商原理
已知可以将方法返回结果转换为不同的格式放进响应体中响应回页面,还是以转换json为例。
内容协商就是上面的找到springMvc支持的转换类型后再把这些支持的和请求自带的支持类型进行比较【协商】,最后将两方共同支持转换的类型的类型转换器放进一个数组里返回。
首先来到,writeWithMessageConverters方法里的这一行,他的名字就是获取可生产的媒体类型,就是springMvc支持的返回类型
List<MediaType> producibleTypes = getProducibleMediaTypes(request, valueType, targetType);
进入来到这个方法中
protected List<MediaType> getProducibleMediaTypes(
HttpServletRequest request, Class<?> valueClass, @Nullable Type targetType) {
//定义了一个空媒体类型的数组,再做一个判断不是空的就叫他变成空的
Set<MediaType> mediaTypes =
(Set<MediaType>) request.getAttribute(HandlerMapping.PRODUCIBLE_MEDIA_TYPES_ATTRIBUTE);
if (!CollectionUtils.isEmpty(mediaTypes)) {
return new ArrayList<>(mediaTypes);
}
//在定义了一个媒体类型的数组装协商结果【两方都支持的报文转换方式和转换器】
List<MediaType> result = new ArrayList<>();
//循环寻找当前的报文转换器那个能转换,总共十个报文转换器,在找到MappingJackson后面的都能支持转换方法返回结果
for (HttpMessageConverter<?> converter : this.messageConverters) {
if (converter instanceof GenericHttpMessageConverter && targetType != null) {
//在这里会进去看到,前面的转换器都会比较是不是自己的类型,然后support方法返回值,到了MappingJackson就是直接返回的true
if (((GenericHttpMessageConverter<?>) converter).canWrite(targetType, valueClass, null)) {
result.addAll(converter.getSupportedMediaTypes(valueClass));
}
}
else if (converter.canWrite(valueClass, null)) {
result.addAll(converter.getSupportedMediaTypes(valueClass));
}
}
return (result.isEmpty() ? Collections.singletonList(MediaType.ALL) : result);
}
找到的报文转换器结果,有两个是重复的,是因为两个MappingJackson对象都支持转换这两种数据类型
在找