• 一个看似Circular view path的问题, 其实不是这个问题的问题


    Circular view path

    [dispatcherServlet] in context with path [/demo] threw exception [Circular view path [users]: would dispatch back to the current handler URL [/demo/users] again. Check your ViewResolver setup! (Hint: This may be the result of an unspecified view, due to default view name generation.)] with root cause
    javax.servlet.ServletException: Circular view path [users]: would dispatch back to the current handler URL [/demo/users] again. Check your ViewResolver setup! (Hint: This may be the result of an unspecified view, due to default view name generation.)
    at org.springframework.web.servlet.view.InternalResourceView.prepareForRendering(InternalResourceView.java:210)
    at org.springframework.web.servlet.view.InternalResourceView.renderMergedOutputModel(InternalResourceView.java:148)

    网上都是说什么使用@RestController和@ResponseBody, 然后我本生就是使用的@RestController

    各种百度,google,github都没有解决, 最后决定自己调式看看, 于是发现一个异常位置

    at org.springframework.web.servlet.view.InternalResourceView.prepareForRendering(InternalResourceView.java:210)
    
    • 1

    问题原因

    因为我使用@RestControllerAdvice对返回结果封装, 又使用了@ControllerAdvice进行了全局异常捕获

    问题主要出在返回封装的结果抛出了异常, 然后全局异常捕获处理, 就更不容易看到问题, 然而这个异常就影响了Servlet处理的流程, 导致报了这个循环视图的问题, 所以本质不是视图配置问题, 就是要解决最原始的异常即可解决问题

    我这里本质问题是一个类转换异常

    报错的代码位置

    org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor#writeWithMessageConverters

    else {
       ((HttpMessageConverter) converter).write(body, selectedMediaType, outputMessage);
    }
    
    • 1
    • 2
    • 3

    这里的StringHttpMessageConverter有点怪怪的, 为什么是String, 我返回的结果可是Json啊

    image-20221127231515687

    可以用的信息转换器

    image-20221127231711641

    经过计算测试发现, 只有第8和9个执行这个代码不会抛出异常

    image-20221127231938665

    是不是什么地方错误导致这个信息转换器使用错误呢?

    最后发现这个value其实不是我们的body, 而是我们封装数据格式中的一个data的数据结果. 所示被识别成了String.class, 也就导致了我们的Result->String出现CastClass的异常

    image-20221127232357296

    问题就出在285行, 执行这一行之前, 我们的body还是String, 执行之后就变成了Result类型了

    image-20221127232814121

    最后发现一处错误: 我的全局异常处理使用的注解是@ControllerAdvice但是, 统一封装返回结果使用的是@RestControllerAdvice

    应该统一使用@RestControllerAdvice注解, 改正后, 可以正常返回异常信息, 但是应该不返回异常才是, 问题还是没有得到根本解决]

    {
      "code": 500,
      "message": "class len.hgy.response.Result cannot be cast to class java.lang.String (len.hgy.response.Result is in unnamed module of loader 'app'; java.lang.String is in module java.base of loader 'bootstrap')",
      "data": null
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    这里应该返回处理的结果, 而不是返回一个类转换异常

    最终发现了问题

    String类型不能直接包装成对象类型, 这样就会出现上面的现象, 所以我们需要特殊处理下我们的统一包装类

    @Override
    public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType,
        Class<? extends HttpMessageConverter<?>> selectedConverterType, ServerHttpRequest request,
        ServerHttpResponse response) {
        // 提供一定的灵活度,如果body已经被包装了,就不进行包装
        if (body instanceof Result) {
            return body;
        }
        // String类型不能直接包装
        if (returnType.getGenericParameterType().equals(String.class)) {
            try {
                // 将数据包装在 ResultVo 里后转换为json串进行返回
                return JacksonUtils.mapper.writeValueAsString(Result.success(body));
            } catch (JsonProcessingException e) {
                throw new MyException(e.getMessage(), e);
            }
        }
    
        return Result.success(body);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    至此, 终于解决了一个错误报错提示问题

    [dispatcherServlet] in context with path [/demo] threw exception [Circular view path [users]: would dispatch back to the current handler URL [/demo/users] again. Check your ViewResolver setup! (Hint: This may be the result of an unspecified view, due to default view name generation.)] with root cause
    javax.servlet.ServletException: Circular view path [users]: would dispatch back to the current handler URL [/demo/users] again. Check your ViewResolver setup! (Hint: This may be the result of an unspecified view, due to default view name generation.)
    	at org.springframework.web.servlet.view.InternalResourceView.prepareForRendering(InternalResourceView.java:210)
    	at org.springframework.web.servlet.view.InternalResourceView.renderMergedOutputModel(InternalResourceView.java:148)
    
    • 1
    • 2
    • 3
    • 4

    问题和这个错误异常没有任何毛线的关系

    总结:

    如果我们遇到一个非常奇怪的问题, 网上可能很常见但是解决不了自己的问题, 或者网上基本没有这样的问题, 那肯定是我们有些细节除了问题, 要知道, 此时我们不管是如何网上找寻答案, 基本都是无用功, 我们不妨做如下两个选择, 一个是先放下这个问题, 后续可能会恍然大悟, 或者深入调式源码, 不然可能就真的是在浪费时间了

  • 相关阅读:
    Hadoop 推测执行
    webadi修改经历
    C. Monoblock
    快鲸智慧楼宇:助力商业地产快速实现数字化转型升级
    Netty深入浅出Java网络编程学习笔记(二) Netty进阶应用篇
    win server 2016 无法安转.net framework 3.5 问题
    第三章:JVM监控及诊断工具-GUI篇
    【定位问题】基于matlab chan算法、fang算法、taylor算法求解目标定位问题【含Matlab源码 2135期】
    网络编程
    nodejs+vue+python+PHP+微信小程序南七街道志愿者服务平台的设计与实现-计算机毕业设计推荐
  • 原文地址:https://blog.csdn.net/yin18827152962/article/details/128072505