04-返回值处理器

准备对象

@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {
    private String name;
    private int age;
}

准备FreeMarker视图解析器

@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;
    }

}

准备控制器

@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);
    }

}

准备返回值处理器组合

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;
}

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

@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)

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)

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)

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)

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)

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)

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)

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
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

层巅余落日

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值