SpringBoot2.x系列教程:整合SpringMVC之内容协商视图解析器

我们在上一章节中,讲解了ContentNegotiating内容协商的使用及简单原理分析,上一章节主要是讲解内容协商在HttpMessage上的作用。

其实内容协商不仅仅可以作用在HttpMessage上,还可以作用在View视图上,本章节我讲解该内容。

一.内容协商视图解析器

1.概述

ContentNegotiatingViewResolver自己并不解析视图,而是委派给其他的视图处理器。

为了使这个解析器正常工作,order序号需要设置成比其他的视图处理器高的优先级(默认就是最高的)。

2. ContentNegotiatingViewResolver细节:

  • ContentNegotiationManager用于内容协商的策略可以手动设置指定,也可以通过FactoryBean自动生成;
  • viewResolvers默认是去容器内找到所有的,当然你也可以手动set进来;
  • 使用request的媒体类型,根据扩展名选择不同的view输出不同的格式;
  • 不是自己处理view,而是代理给不同的ViewResolver来处理不同的view;
  • 默认是支持Accept和后缀的协商方式的。并且还支持 逻辑视图名.后缀的视图解析方式;
  • 依据View.getContentType匹配MediaType来完成的最佳匹配。

二.ContentNegotiatingViewResolver使用

在默认情况下,Spring MVC并没有开启ContentNegotiatingViewResolver内容协商视图解析器,因此如果有同一接口资源,要用多视图展示的需求,我们是需要自己手动配置来实现的。

所以接下来我带大家,对同一个接口资源,返回多个View。

1. 需求介绍

我们要对同一个RESTful风格的URL,根据请求的不同,可以得到一个PDF视图,一个JSON视图,一个Html视图。

2. 创建web项目(略)

参照之前的案例,我们创建一个新的web项目,过程略去。

3. 创建View视图

3.1 创建PdfViewResolver类

package com.yyg.boot.resolver;

import org.springframework.http.MediaType;
import org.springframework.web.servlet.View;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.view.ContentNegotiatingViewResolver;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Map;

/**
 * @Description Description
 * @Author 一一哥Sun
 * @Date Created in 2020/3/22
 */
public class PdfViewResolver implements View {

    @Override
    public String getContentType() {
        return MediaType.APPLICATION_PDF_VALUE;
    }

    @Override
    public void render(Map<String, ?> model, HttpServletRequest request, HttpServletResponse response) throws Exception {
        response.getWriter().write("<html><body style='color:red'>This is [PDF] view</body></html>");
    }

}

3.2 创建ExcelViewResolver类

package com.yyg.boot.resolver;

import org.springframework.http.MediaType;
import org.springframework.web.servlet.View;
import org.springframework.web.servlet.view.ContentNegotiatingViewResolver;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Map;

/**
 * @Description Description
 * @Author 一一哥Sun
 * @Date Created in 2020/3/22
 */
public class ExcelViewResolver implements View {

    @Override
    public String getContentType() {
        return MediaType.APPLICATION_JSON_UTF8_VALUE;
    }

    @Override
    public void render(Map<String, ?> model, HttpServletRequest request, HttpServletResponse response) throws Exception {
        response.getWriter()
                .write("<html><body style='color:blue'>This is [JSON] view!</body></html>");
    }

}

3.3 创建HtmlViewResolver类

package com.yyg.boot.resolver;

import org.springframework.http.MediaType;
import org.springframework.web.servlet.View;
import org.springframework.web.servlet.view.ContentNegotiatingViewResolver;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Map;

/**
 * @Description Description
 * @Author 一一哥Sun
 * @Date Created in 2020/3/22
 */
public class HtmlViewResolver implements View {

    @Override
    public String getContentType() {
        return MediaType.TEXT_HTML_VALUE;
    }

    @Override
    public void render(Map<String, ?> model, HttpServletRequest request, HttpServletResponse response) throws Exception {
        response.getWriter()
                .write("<html><body style='color:green'>This is [HTML] view!</body></html>");
    }

}

4. 进行视图配置

将上面创建的视图注册到内容协调视图解析器中,开启Spring MVC在视图上对ContentNegotiation内容协商的支持。

package com.yyg.boot.config;

import com.yyg.boot.resolver.ExcelViewResolver;
import com.yyg.boot.resolver.HtmlViewResolver;
import com.yyg.boot.resolver.PdfViewResolver;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.web.servlet.View;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.ViewResolverRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.view.ContentNegotiatingViewResolver;
import org.springframework.web.servlet.view.InternalResourceViewResolver;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Locale;
import java.util.Map;

/**
 * @Description Description
 * @Author 一一哥Sun
 * @Date Created in 2020/3/22
 */
@Configuration
public class WebMvcConfig extends WebMvcConfigurationSupport {

    @Override
    public void configureViewResolvers(ViewResolverRegistry registry) {
        registry.enableContentNegotiation(new PdfViewResolver());
        registry.enableContentNegotiation(new ExcelViewResolver());
        registry.enableContentNegotiation(new HtmlViewResolver());

        // 上面三个注册方法必须在此方法之上执行
        registry.enableContentNegotiation(false);
    }

}

5. 创建Controller测试接口

package com.yyg.boot.web;

import lombok.extern.slf4j.Slf4j;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.util.MimeType;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.ResponseBody;

/**
 * @Description 内容协商视图解析器
 * @Author 一一哥Sun
 * @Date Created in 2020/3/21
 */
@Slf4j
@Controller
public class NegotiationController {

    @GetMapping(value = "/show/{type}")
    public String showUser(@PathVariable("type") String type) {
        log.warn("type={}", type);
        return "跟一一哥学习ContentNegotiatingViewResolver!";
    }

}

6. 启动程序,运行测试

我们在浏览器中输入地址:
http://localhost:8080/show/a.pdf
可以看到如下效果:

我们在浏览器中输入地址:
http://localhost:8080/show/a.json
可以看到如下效果:

我们在浏览器中输入地址:
http://localhost:8080/show/a.html
可以看到如下效果:

而在没有后缀名的情况下,以Accept的规则为准。

所以可见扩展名的规则优先级高于Accept,符合我们上一章节中的理论知识。若没有指定请求的扩展名,则Accept就会生效!

三.内容协调视图解析器工作原理图

发布了412 篇原创文章 · 获赞 262 · 访问量 90万+

猜你喜欢

转载自blog.csdn.net/GUDUzhongliang/article/details/105704996