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);
}
相关推荐
芒果披萨4 分钟前
El表达式和JSTL
java·el
duration~1 小时前
Maven随笔
java·maven
zmgst1 小时前
canal1.1.7使用canal-adapter进行mysql同步数据
java·数据库·mysql
跃ZHD1 小时前
前后端分离,Jackson,Long精度丢失
java
blammmp1 小时前
Java:数据结构-枚举
java·开发语言·数据结构
暗黑起源喵2 小时前
设计模式-工厂设计模式
java·开发语言·设计模式
WaaTong2 小时前
Java反射
java·开发语言·反射
九圣残炎2 小时前
【从零开始的LeetCode-算法】1456. 定长子串中元音的最大数目
java·算法·leetcode
wclass-zhengge2 小时前
Netty篇(入门编程)
java·linux·服务器
成富3 小时前
文本转SQL(Text-to-SQL),场景介绍与 Spring AI 实现
数据库·人工智能·sql·spring·oracle