04-返回值处理器

准备对象

java 复制代码
@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {
    private String name;
    private int age;
}

准备FreeMarker视图解析器

java 复制代码
@Configuration
public class WebConfig {

    @Bean
    public FreeMarkerConfigurer freeMarkerConfigurer() {
        FreeMarkerConfigurer freeMarkerConfigurer = new FreeMarkerConfigurer();
        freeMarkerConfigurer.setDefaultEncoding("UTF-8");
        freeMarkerConfigurer.setTemplateLoaderPath("classpath:templates");
        return freeMarkerConfigurer;
    }

    @Bean
    public FreeMarkerViewResolver freeMarkerViewResolver(FreeMarkerConfigurer freeMarkerConfigurer) {
        // Spring初始化FreeMarkerView时,会要求Web环境  这里去掉此制约
        FreeMarkerViewResolver freeMarkerViewResolver = new FreeMarkerViewResolver() {
            public AbstractUrlBasedView instantiateView() {
                FreeMarkerView freeMarkerView = new FreeMarkerView() {
                    @Override
                    protected boolean isContextRequired() {
                        return false;
                    }
                };
                freeMarkerView.setConfiguration(freeMarkerConfigurer.getConfiguration());
                return freeMarkerView;
            }
        };
        freeMarkerViewResolver.setContentType("text/html;charset=utf-8");
        freeMarkerViewResolver.setPrefix("/");
        freeMarkerViewResolver.setSuffix(".ftl");
        freeMarkerViewResolver.setExposeSpringMacroHelpers(false);
        return freeMarkerViewResolver;
    }

}

准备控制器

java 复制代码
@Slf4j
static class Controller {

    public ModelAndView test1() {
        log.warn("test1()");
        // 添加视图名
        ModelAndView modelAndView = new ModelAndView("view1");
        // 添加模型名
        modelAndView.addObject("name", "张三");
        return modelAndView;
    }

    public String test2() {
        log.warn("test2()");
        // 返回视图名   只有视图 没有模型数据
        return "view2";
    }

    @ModelAttribute
    // 没有视图 默认将请求路径当作视图名
    //@RequestMapping("/test3")
    public User test3() {
        log.warn("test3()");
        // 只有模型数据  没有视图
        return new User("李四", 20);
    }
    
    public User test4() {
        log.warn("test4()");
        // 只有模型数据  没有视图
        return new User("王五", 30);
    }
    
    public HttpEntity<User> test5() {
        log.warn("test5()");
        return new HttpEntity<>(new User("赵六", 40));
    }

    public HttpHeaders test6() {
        log.warn("test6()");
        HttpHeaders httpHeaders = new HttpHeaders();
        httpHeaders.add("Content-Type", "text/html");
        return httpHeaders;
    }

    @ResponseBody
    public User test7() {
        log.warn("test7()");
        return new User("钱七", 50);
    }

}

准备返回值处理器组合

java 复制代码
private static HandlerMethodReturnValueHandlerComposite returnValueHandlerComposite() {
    MappingJackson2HttpMessageConverter jackson2HttpMessageConverter = new MappingJackson2HttpMessageConverter();
    HandlerMethodReturnValueHandlerComposite returnValueHandlerComposite = new HandlerMethodReturnValueHandlerComposite();
    returnValueHandlerComposite.addHandlers(CollUtil.newArrayList(
            // 返回值:ModelAndView    test1
            new ModelAndViewMethodReturnValueHandler(),
            // 返回值字符串:视图名    test2
            new ViewNameMethodReturnValueHandler(),
            // 返回模型数据  带@ModelAttribute注解   test3
            new ServletModelAttributeMethodProcessor(false),
            // 返回值:HttpEntity    test5
            new HttpEntityMethodProcessor(CollUtil.newArrayList(jackson2HttpMessageConverter)),
            // 返回值:HttpHeaders   test6
            new HttpHeadersReturnValueHandler(),
            // 返回值json: 带@ResponseBody注解   test7
            new RequestResponseBodyMethodProcessor(CollUtil.newArrayList(jackson2HttpMessageConverter)),
            // 返回模型数据  不带@ModelAttribute注解   test4
            new ServletModelAttributeMethodProcessor(true)
    ));
    return returnValueHandlerComposite;
}

处理返回值(打印要渲染的视图)

java 复制代码
@SneakyThrows
private static void renderValue(ModelAndViewContainer modelAndViewContainer, ServletWebRequest servletWebRequest,
                                AnnotationConfigApplicationContext applicationContext) {

    try {
        log.warn("=========>渲染视图内容");
        HttpServletRequest request = servletWebRequest.getRequest();
        MockHttpServletResponse response = (MockHttpServletResponse) servletWebRequest.getResponse();
        String viewName = modelAndViewContainer.getViewName();
        if (StrUtil.isBlank(viewName)) {
            viewName = ((String) request.getAttribute(UrlPathHelper.PATH_ATTRIBUTE));
            modelAndViewContainer.setViewName(viewName);
            log.warn("没有获取到视图名,获取默认视图:{}", viewName);
        }
        if (!modelAndViewContainer.isRequestHandled()) {
            // 获取 View
            FreeMarkerViewResolver freeMarkerViewResolver = applicationContext.getBean(FreeMarkerViewResolver.class);
            View view = freeMarkerViewResolver.resolveViewName(viewName, RequestContextUtils.getLocale(request));
            view.render(modelAndViewContainer.getModel(), request, response);
        }
        for (String headerName : response.getHeaderNames()) {
            System.out.println(headerName + "=" + response.getHeaders(headerName));
        }
        System.out.println(new String(response.getContentAsByteArray(), StandardCharsets.UTF_8));

        } catch (Exception e) {
            // 处理渲染异常
            e.printStackTrace(); // 这里需要根据实际情况处理异常
        }
}

测试返回值处理器

test1(ModelAndViewMethodReturnValueHandler)

java 复制代码
AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext(WebConfig.class);
// 只探讨返回值处理器  所有测试方法都不带参数
Method method = Controller.class.getMethod("test1");
Controller controller = new Controller();
// 得到返回值
Object returnValue = method.invoke(controller);
// 拿到返回值类型
HandlerMethod handlerMethod = new HandlerMethod(controller, method);
MethodParameter returnType = handlerMethod.getReturnType();
// 模型视图容器
ModelAndViewContainer modelAndViewContainer = new ModelAndViewContainer();
// 模拟请求
MockHttpServletRequest request = new MockHttpServletRequest();
MockHttpServletResponse response = new MockHttpServletResponse();
ServletWebRequest servletWebRequest = new ServletWebRequest(request, response);
// 返回值处理器
HandlerMethodReturnValueHandlerComposite returnValueHandlerComposite = returnValueHandlerComposite();
if (returnValueHandlerComposite.supportsReturnType(returnType)) {
    returnValueHandlerComposite.handleReturnValue(
            returnValue, returnType, modelAndViewContainer, servletWebRequest
    );
    System.out.println(modelAndViewContainer.getModel());
    System.out.println(modelAndViewContainer.getViewName());
    renderValue(modelAndViewContainer, servletWebRequest, annotationConfigApplicationContext);
}

test2(ViewNameMethodReturnValueHandler)

java 复制代码
AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext(WebConfig.class);
// 只探讨返回值处理器  所有测试方法都不带参数
Method method = Controller.class.getMethod("test2");
Controller controller = new Controller();
// 得到返回值
Object returnValue = method.invoke(controller);
// 拿到返回值类型
HandlerMethod handlerMethod = new HandlerMethod(controller, method);
MethodParameter returnType = handlerMethod.getReturnType();
// 模型视图容器
ModelAndViewContainer modelAndViewContainer = new ModelAndViewContainer();
// 模拟请求
MockHttpServletRequest request = new MockHttpServletRequest();
MockHttpServletResponse response = new MockHttpServletResponse();
ServletWebRequest servletWebRequest = new ServletWebRequest(request, response);
// 返回值处理器
HandlerMethodReturnValueHandlerComposite returnValueHandlerComposite = returnValueHandlerComposite();
if (returnValueHandlerComposite.supportsReturnType(returnType)) {
    returnValueHandlerComposite.handleReturnValue(
            returnValue, returnType, modelAndViewContainer, servletWebRequest
    );
    System.out.println(modelAndViewContainer.getModel());
    System.out.println(modelAndViewContainer.getViewName());
    renderValue(modelAndViewContainer, servletWebRequest, annotationConfigApplicationContext);
}

test3(ServletModelAttributeMethodProcessor)

java 复制代码
AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext(WebConfig.class);
// 只探讨返回值处理器  所有测试方法都不带参数
Method method = Controller.class.getMethod("test3");
Controller controller = new Controller();
// 得到返回值
Object returnValue = method.invoke(controller);
// 拿到返回值类型
HandlerMethod handlerMethod = new HandlerMethod(controller, method);
MethodParameter returnType = handlerMethod.getReturnType();
// 模型视图容器
ModelAndViewContainer modelAndViewContainer = new ModelAndViewContainer();
// 模拟请求
MockHttpServletRequest request = new MockHttpServletRequest();
// 模拟将路径放入RequestAttribute中  模拟视图名字
request.setRequestURI("test3");
UrlPathHelper.defaultInstance.resolveAndCacheLookupPath(request);
MockHttpServletResponse response = new MockHttpServletResponse();
response.setContentType("text/html;charset=utf-8");
ServletWebRequest servletWebRequest = new ServletWebRequest(request, response);
// 返回值处理器
HandlerMethodReturnValueHandlerComposite returnValueHandlerComposite = returnValueHandlerComposite();
if (returnValueHandlerComposite.supportsReturnType(returnType)) {
    returnValueHandlerComposite.handleReturnValue(
            returnValue, returnType, modelAndViewContainer, servletWebRequest
    );
    System.out.println(modelAndViewContainer.getModel());
    System.out.println(modelAndViewContainer.getViewName());
    renderValue(modelAndViewContainer, servletWebRequest, annotationConfigApplicationContext);
}

test4(ServletModelAttributeMethodProcessor)

java 复制代码
AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext(WebConfig.class);
// 只探讨返回值处理器  所有测试方法都不带参数
Method method = Controller.class.getMethod("test4");
Controller controller = new Controller();
// 得到返回值
Object returnValue = method.invoke(controller);
// 拿到返回值类型
HandlerMethod handlerMethod = new HandlerMethod(controller, method);
MethodParameter returnType = handlerMethod.getReturnType();
// 模型视图容器
ModelAndViewContainer modelAndViewContainer = new ModelAndViewContainer();
// 模拟请求
MockHttpServletRequest request = new MockHttpServletRequest();
// 模拟将路径放入RequestAttribute中  模拟视图名字
request.setRequestURI("test4");
UrlPathHelper.defaultInstance.resolveAndCacheLookupPath(request);
MockHttpServletResponse response = new MockHttpServletResponse();
response.setContentType("text/html;charset=utf-8");
ServletWebRequest servletWebRequest = new ServletWebRequest(request, response);
// 返回值处理器
HandlerMethodReturnValueHandlerComposite returnValueHandlerComposite = returnValueHandlerComposite();
if (returnValueHandlerComposite.supportsReturnType(returnType)) {
    returnValueHandlerComposite.handleReturnValue(
            returnValue, returnType, modelAndViewContainer, servletWebRequest
    );
    System.out.println(modelAndViewContainer.getModel());
    System.out.println(modelAndViewContainer.getViewName());
    renderValue(modelAndViewContainer, servletWebRequest, annotationConfigApplicationContext);
}

test5(HttpEntityMethodProcessor)

java 复制代码
AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext(WebConfig.class);
// 只探讨返回值处理器  所有测试方法都不带参数
Method method = Controller.class.getMethod("test5");
Controller controller = new Controller();
// 得到返回值
Object returnValue = method.invoke(controller);
// 拿到返回值类型
HandlerMethod handlerMethod = new HandlerMethod(controller, method);
MethodParameter returnType = handlerMethod.getReturnType();
// 模型视图容器
ModelAndViewContainer modelAndViewContainer = new ModelAndViewContainer();
// 模拟请求
MockHttpServletRequest request = new MockHttpServletRequest();
MockHttpServletResponse response = new MockHttpServletResponse();
ServletWebRequest servletWebRequest = new ServletWebRequest(request, response);
// 返回值处理器
HandlerMethodReturnValueHandlerComposite returnValueHandlerComposite = returnValueHandlerComposite();
if (returnValueHandlerComposite.supportsReturnType(returnType)) {
    returnValueHandlerComposite.handleReturnValue(
            returnValue, returnType, modelAndViewContainer, servletWebRequest
    );
    System.out.println(modelAndViewContainer.getModel());
    System.out.println(modelAndViewContainer.getViewName());
    renderValue(modelAndViewContainer, servletWebRequest, annotationConfigApplicationContext);
}

test6(HttpHeadersReturnValueHandler)

java 复制代码
AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext(WebConfig.class);
// 只探讨返回值处理器  所有测试方法都不带参数
Method method = Controller.class.getMethod("test6");
Controller controller = new Controller();
// 得到返回值
Object returnValue = method.invoke(controller);
// 拿到返回值类型
HandlerMethod handlerMethod = new HandlerMethod(controller, method);
MethodParameter returnType = handlerMethod.getReturnType();
// 模型视图容器
ModelAndViewContainer modelAndViewContainer = new ModelAndViewContainer();
// 模拟请求
MockHttpServletRequest request = new MockHttpServletRequest();
MockHttpServletResponse response = new MockHttpServletResponse();
ServletWebRequest servletWebRequest = new ServletWebRequest(request, response);
// 返回值处理器
HandlerMethodReturnValueHandlerComposite returnValueHandlerComposite = returnValueHandlerComposite();
if (returnValueHandlerComposite.supportsReturnType(returnType)) {
    returnValueHandlerComposite.handleReturnValue(
            returnValue, returnType, modelAndViewContainer, servletWebRequest
    );
    System.out.println(modelAndViewContainer.getModel());
    System.out.println(modelAndViewContainer.getViewName());
    renderValue(modelAndViewContainer, servletWebRequest, annotationConfigApplicationContext);
}

test7(RequestResponseBodyMethodProcessor)

java 复制代码
AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext(WebConfig.class);
// 只探讨返回值处理器  所有测试方法都不带参数
Method method = Controller.class.getMethod("test7");
Controller controller = new Controller();
// 得到返回值
Object returnValue = method.invoke(controller);
// 拿到返回值类型
HandlerMethod handlerMethod = new HandlerMethod(controller, method);
MethodParameter returnType = handlerMethod.getReturnType();
// 模型视图容器
ModelAndViewContainer modelAndViewContainer = new ModelAndViewContainer();
// 模拟请求
MockHttpServletRequest request = new MockHttpServletRequest();
MockHttpServletResponse response = new MockHttpServletResponse();
ServletWebRequest servletWebRequest = new ServletWebRequest(request, response);
// 返回值处理器
HandlerMethodReturnValueHandlerComposite returnValueHandlerComposite = returnValueHandlerComposite();
if (returnValueHandlerComposite.supportsReturnType(returnType)) {
    returnValueHandlerComposite.handleReturnValue(
            returnValue, returnType, modelAndViewContainer, servletWebRequest
    );
    System.out.println(modelAndViewContainer.getModel());
    System.out.println(modelAndViewContainer.getViewName());
    renderValue(modelAndViewContainer, servletWebRequest, annotationConfigApplicationContext);
}
相关推荐
计算机毕设指导6几秒前
基于 SpringBoot 的作业管理系统【附源码】
java·vue.js·spring boot·后端·mysql·spring·intellij-idea
Gu Gu Study2 分钟前
枚举与lambda表达式,枚举实现单例模式为什么是安全的,lambda表达式与函数式接口的小九九~
java·开发语言
Chris _data4 分钟前
二叉树oj题解析
java·数据结构
牙牙70510 分钟前
Centos7安装Jenkins脚本一键部署
java·servlet·jenkins
paopaokaka_luck17 分钟前
[371]基于springboot的高校实习管理系统
java·spring boot·后端
以后不吃煲仔饭30 分钟前
Java基础夯实——2.7 线程上下文切换
java·开发语言
进阶的架构师31 分钟前
2024年Java面试题及答案整理(1000+面试题附答案解析)
java·开发语言
The_Ticker36 分钟前
CFD平台如何接入实时行情源
java·大数据·数据库·人工智能·算法·区块链·软件工程
大数据编程之光1 小时前
Flink Standalone集群模式安装部署全攻略
java·大数据·开发语言·面试·flink
爪哇学长1 小时前
双指针算法详解:原理、应用场景及代码示例
java·数据结构·算法