【低效编码】一个@ResponseBody注解没加让我这个菜鸟原形毕露

【低效编码】一个@ResponseBody注解没加让我这个菜鸟原形毕露小问题暴露大知识点

大家好,又见面了,我是你们的朋友全栈君。

您好,我是码农飞哥,感谢您阅读本文!如果此文对您有所帮助,请毫不犹豫的一键三连吧。小伙伴们,有啥想看的,想问的,欢迎积极留言告诉我喔。
今天是5月12日,太阳依然比我起的更早一些。8点半闹铃准时响起来,一把将我从黄粱美梦中拉回到了现实中来,我猛地从床上弹起来(枕边没人,害,可怜人儿),急匆匆洗漱完,挂上工牌,背起小米双肩包,穿上那件心爱的格子衫,就开启了一天的搬砖之旅。
在这里插入图片描述

开心编码

事情是这样的,我在用SpringBoot框架搭建的项目上写了一个新增用户的接口,接口地址是/v1/user/test,代码如下所示(demo版,非生产代码),简单到不能再简单的一个接口,像这样的接口我都记不清自己已经写了多少个了。

@Controller
public class TestRespController { 
   
	//新增用户的接口
    @RequestMapping("/v1/user/test")
    public User addUser(String userName, String password) { 
   
        User user = new User();
        user.setUserName(userName);
        user.setPassword(password);
        return user;
    }
}

接口写好之后,我没有多想,就启动项目开始调试代码,我熟练的在chrome浏览器上输入了http://localhost:8080/v1/user/test 这个地址,然后点击回车,没想到的是页面上提示了一个404的错误。
在这里插入图片描述
这是怎么回事呢?我这接口地址没有错呀,为啥找不到接口呢?奇了怪了。我火急火燎的跑到控制台,看看有没有错误日志。让我很失望啥错误都没有输出,过滤器也准确的把我的输入的请求地址打印出来了。
在这里插入图片描述

苦苦寻找

为啥页面报了404的错误,而控制台没有任何错误输出呢?实在是有点诡异。问同事嘛,又不好意思,自己好歹是个高级开发工程师,404的问题都搞不定实在是说不过去。三十六计走为上,看看其他的正常的接口是怎么写的。然后,我找到了这样一个接口,这个接口是可以正常访问的,

    @ResponseBody
    @RequestMapping("/v1/user/test/update")
    public User updateUser(User user) { 
   
        boolean result = testNgService.updateUser(user);
        return result ? user : null;
    }

哦哦哦,我突然恍然大悟,原来是没有在接口上添加@ResponseBody 注解,我印象中这个注解可以将返回的对象序列化成json字符串,并放在响应体中,但是跟接口地址又有啥关系呢?。抱着试试看的态度,我在接口上加上了 @ResponseBody注解,代码就不列举了,太简单了不好意思列举。再次访问http://localhost:8080/v1/user/test 这个地址,接口可以正常返回数据了。
在这里插入图片描述
当然,如果该类下所有的接口都是返回application/json格式数据的接口,则可以直接将类上的**@Controller注解替换成 @RestController 注解。@RestController注解是一个组合注解是由@Controller注解和@ResponseBody注解组成**。

思考升华

至此,问题是解决了。但是,心中的小问号还萦绕在心头。

  1. 为啥页面报了404的错误,但是控制台没有错误日志呢?
  2. 为啥不加@ResponseBody注解接口会报404的错误呢?
    知道的小伙伴,可以在下方评论留言哦,并且直接略过下面的内容,因为你们太牛逼了。

有问题,咱们就解决问题,(而不是解决提出问题的人喔,哈哈哈哈)

1. 为啥页面报了404的错误,但是控制台没有错误日志呢?

为啥出现了404的异常,但是控制台没有错误的日志输出呢?这个就很奇怪了。这个问题是我们首先需要解决的,不然不知道具体的错误是啥,就很难定位到问题。根据已经掌握SpringMVC的知识:我们在页面输入一个url之后,请求首先会到DispatcherServlet。然后,DispatcherServlet会根据url去HandelMapping中找到能处理该请求的Handler。如果找不到的话则会报错404的错误,所以,猜测SpringBoot抛出的是NoHandlerFoundException这个异常,现在的问题就是为啥这个NoHandlerFoundException没输出呢?一番百度之后,我发现只需要在配置文件application.yml中添加如下配置即可:

spring:
  mvc:
# 允许抛出NoHandlerFoundException
    throw-exception-if-no-handler-found: true
# 禁用资源映射
  resources:
    add-mappings: false

加上这两个配置之后,在访问接口的话,控制台就会打印出如下的错误日志:我们看到在查找mapping时url就变成了 /v1/user/v1/user/test,不是我们期待的 /v1/user/test
在这里插入图片描述
说明:加上spring.resources.add-mappings=false 禁用资源映射之后,可以输出

o.s.web.servlet.PageNotFound             : No mapping for GET /v1/user/v1/user/test

springboot中的WebMvcAutoConfiguration类配置默认资源映射地址是 “/”

private static final String SERVLET_LOCATION = "/";

即使你的地址错误也会匹配到 /** 这个静态资源映射地址,就不会进入noHandlerFound方法,自然不会抛出NoHandlerFoundException了。
异常终于暴露出来了。接下来就是处理异常了。

2. 为啥不加@ResponseBody注解接口会报404的错误呢?

要想回答这个问题,还是要回到 @ResponseBody 注解的作用上面,一番苦苦的搜索之后,我终于发现了答案。@ResponseBody 注解的作用就是将Controller返回的对象通过适当的HttpMessageConverter转换为指定的格式,写入到Response对象的body数据区中返回给前端页面。如果没有加这个注解,只有@RequestMapping这个注解的话,则返回值通常解析为跳转路径,控制器返回的时候路径会变为(在当前路径的上一级路径上追加路径),然后返回的过程找不到对应的视图,导致404的错误。这只是理论,实际上是不是这样子的呢?还需要我们验证一下。

  1. 不加@ResponseBody则默认会返回一个视图,如下图所示,返回一个名为 /static/helloWorld.html的视图。
    @RequestMapping("/v1/user/test1")
    public String queryUserHtml2() { 
   
        return "/static/helloWorld.html";
    }

即会访问static目录下的helloWorld.html页面。
在这里插入图片描述
访问结果是:
在这里插入图片描述
页面可以正常的跳转,说明,不加上@ResponseBody注解确实会默认返回一个视图,这是正常的能找到页面的视图,如果返回一个不存在的视图会怎样呢?

    @RequestMapping("/v1/user/test2")
    public String queryUserHtml3() { 
   
        return "{\"code\":200}";
    }

打印出来的路径是 /v1/user/{“code”:200},即/v1/user/test2的上级路径 /v1/user+{“code”:200},说明上面的理论解释是没有问题的。

总结

本文从实际开发中一个很小的问题入手,层层分析问题的根源,知其然更要知其所以然。总之,一句话总结@ResponseBody注解的作用就是将返回的结果通过HttpMessageConverter 转换为指定格式并放在响应体中,没有它的话,SpringBoot会默认返回一个视图。

参考

@ResponseBody注解
解决springboot配置@ControllerAdvice不能捕获NoHandlerFoundException问题

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/140224.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

  • SpringMvc工作原理学习总结

    SpringMvc工作原理学习总结SpringMvc工作原理了解SpringMvc之前先看看Mvc的工作原理1、MVC工作原理M:Model(完成业务逻辑Service/dao/entity/)V:View(完成界面渲染jsp/html)C:Controller(控制器->类似于CPU接受请求->调用M->返回V)MVC工作原理图2、SpringMvc工作原理Spring和SpringMvc的关系:SpringMVC是一个MVC的开源框架,SpringMVC是Spring的一个

  • Origin2018安装教程「建议收藏」

    Origin2018安装教程「建议收藏」Origin是由OriginLab公司开发的一个科学绘图、数据分析软件,支持在MicrosoftWindows下运行,它能支持各种各样的2D/3D图形,其数据分析功能很强大,包括统计,信号处理,曲线拟合以及峰值分析。Origin中的曲线拟合是采用基于Levernberg-Marquardt算法(LMA)的非线性最小二乘法拟合,它强大的数据导入功能,支持多种格式的数据,包括ASCII、Excel、NITDM、DIADem、NetCDF、SPC等等。不仅如此,它的图形输出格式也多种多样,例如JPEG,

  • 史上最全的Linux常用命令汇总(超全面!超详细!)收藏这一篇就够了!

    这绝对是整理的最全面最详细最认真最适合用来当笔记的Linux终端命令汇总的文章了

  • 安装luajit_lua安卓

    安装luajit_lua安卓wgethttp://luajit.org/download/LuaJIT-2.0.5.tar.gztarxzvfLuaJIT-2.0.5.tar.gzcdLuaJIT-2.0.5mkdir~/luajit2makeprefix=/home/wang/luajit2sudomakeinstallluajit-v#SuccessfullyLuaJIT2.0.5…

  • XMl简单语法笔记

    XMl简单语法笔记

  • 越权访问漏洞总结

    越权访问漏洞总结一、平行越权攻击者请求操作(增删改查)某条数据时,web应用程序没有判断该条数据的所属人,或者在判断数据所属人时直接从用户提交的表单参数中获取,例如用户id等,导致攻击者可以自行修改参数,操作获取不属于自己的数据。测试方法:在发送请求时观察请求参数,尝试修改用户id或者其他参数验证是否能查看不属于自己的数据,进行增删改查,若成功则存在平行越权的漏洞。 二、纵向越权和平行越权相似…

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号