欢迎访问 生活随笔!

ag凯发k8国际

当前位置: ag凯发k8国际 > 前端技术 > javascript >内容正文

javascript

boot返回码规范 spring-ag凯发k8国际

发布时间:2024/10/12 javascript 30 豆豆
ag凯发k8国际 收集整理的这篇文章主要介绍了 boot返回码规范 spring_springboot 系列 web 篇之自定义返回 http code 的 n 种姿势 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

200105-springboot 系列 web 篇之自定义返回 http code 的 n 种姿势

虽然 http 的提供了一整套完整、定义明确的状态码,但实际的业务支持中,后端并不总会遵守这套规则,更多的是在返回结果中,加一个 code 字段来自定义业务状态,即便是后端 5xx 了,返回给前端的 http code 依然是 200

那么如果我想遵守 http 的规范,不同的 case 返回不同的 http code 在 spring 中可以做呢?

本文将介绍四种设置返回的 http code 的方式

  • @responsestatus 注解方式
  • httpservletresponse#senderror
  • httpservletresponse#setstatus
  • responseentity

i. 返回 http code 的 n 种姿势

0. 环境

进入正文之前,先创建一个 springboot 项目,本文示例所有版本为 spring-boot.2.1.2.release

(需要测试的小伙伴,本机创建一个 maven 项目,在pom.xml文件中,拷贝下面的配置即可)

org.springframework.boot spring-boot-starter-parent 2.2.1.releaseutf-8utf-81.8org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-maven-plugin spring-snapshotsspring snapshotshttps://repo.spring.io/libs-snapshot-localtruespring-milestonesspring milestoneshttps://repo.spring.io/libs-milestone-localfalsespring-releasesspring releaseshttps://repo.spring.io/libs-release-localfalse

下面所有的方法都放在 errorcoderest 这个类中

@restcontroller@requestmapping(path = "code")public class errorcoderest {}

1. responsestatus 使用姿势

通过注解@responsestatus,来指定返回的 http code, 一般来说,使用它有两种姿势,一个是直接加在方法上,一个是加在异常类上

a. 装饰方法

直接在方法上添加注解,并制定对应的 code

/** * 注解方式,只支持标准http状态码 * * @return */@getmapping("ano")@responsestatus(code = httpstatus.bad_request, reason = "请求参数异常!")public string ano() { return "{"code": 400, "msg": "bad request!"}";}

实测一下,返回结果如下

➜ ~ curl 'http://127.0.0.1:8080/code/ano' -ihttp/1.1 400content-type: application/json;charset=utf-8transfer-encoding: chunkeddate: sun, 05 jan 2020 01:29:04 gmtconnection: close{"timestamp":"2020-01-05t01:29:04.673 0000","status":400,"error":"bad request","message":"请求参数异常!","path":"/code/ano"}%

当我们发起请求时,返回的状态码为 400,返回的数据为 springboot 默认的错误信息格式

虽然上面这种使用姿势可以设置 http code,但是这种使用姿势有什么意义呢?

如果看过 web 系列教程中的:springboot 系列教程 web 篇之全局异常处理 可能就会有一些映象,配合@exceptionhandler来根据异常返回对应的状态码

一个推荐的使用姿势,下面表示当你的业务逻辑中出现数组越界时,返回 500 的状态码以及完整的堆栈信息

@responsebody@exceptionhandler(value = arrayindexoutofboundsexception.class)@responsestatus(httpstatus.internal_server_error)public string handlearrayindexoutbounds(httpservletrequest request, httpservletresponse response, arrayindexoutofboundsexception e) throws ioexception { log.info("array index out conf!"); return "aryindexoutofbounds: " getthrowablestackinfo(e);}

b. 装饰异常类

另外一种使用姿势就是直接装饰在异常类上,然后当你的业务代码中,抛出特定的异常类,返回的 httpcode 就会设置为注解中的值

/** * 异常类 注解方式,只支持标准http状态码 * * @return */@getmapping("exception/500")public string serverexception() { throw new serverexception("内部异常哦");}@getmapping("exception/400")public string clientexception() { throw new clientexception("客户端异常哦");}@responsestatus(code = httpstatus.internal_server_error, reason = "服务器失联了,请到月球上呼叫试试~~")public static class serverexception extends runtimeexception { public serverexception(string message) { super(message); }}@responsestatus(code = httpstatus.bad_request, reason = "老哥,你的请求有问题~~")public static class clientexception extends runtimeexception { public clientexception(string message) { super(message); }}

测试结果如下,在异常类上添加注解的方式,优点在于不需要配合@exceptionhandler写额外的逻辑了;缺点则在于需要定义很多的自定义异常类型

➜ ~ curl 'http://127.0.0.1:8080/code/exception/400' -ihttp/1.1 400content-type: application/json;charset=utf-8transfer-encoding: chunkeddate: sun, 05 jan 2020 01:37:07 gmtconnection: close{"timestamp":"2020-01-05t01:37:07.662 0000","status":400,"error":"bad request","message":"老哥,你的请求有问题~~","path":"/code/exception/400"}%➜ ~ curl 'http://127.0.0.1:8080/code/exception/500' -ihttp/1.1 500content-type: application/json;charset=utf-8transfer-encoding: chunkeddate: sun, 05 jan 2020 01:37:09 gmtconnection: close{"timestamp":"2020-01-05t01:37:09.389 0000","status":500,"error":"internal server error","message":"服务器失联了,请到月球上呼叫试试~~","path":"/code/exception/500"}%

注意

  • responsestatus 注解的使用姿势,只支持标准的 http code(必须是枚举类org.springframework.http.httpstatus)

2. responseentity

这种使用姿势就比较简单了,方法的返回结果必须是responseentity,下面给出两个实际的 case

@getmapping("401")public responseentity _401() { return responseentity.status(httpstatus.unauthorized).body("{"code": 401, "msg": "未授权!"}");}@getmapping("451")public responseentity _451() { return responseentity.status(451).body("{"code": 451, "msg": "自定义异常!"}");}

实测结果

➜ ~ curl 'http://127.0.0.1:8080/code/401' -ihttp/1.1 401content-type: text/plain;charset=utf-8content-length: 34date: sun, 05 jan 2020 01:40:10 gmt{"code": 401, "msg": "未授权!"}➜ ~ curl 'http://127.0.0.1:8080/code/451' -ihttp/1.1 451content-type: text/plain;charset=utf-8content-length: 40date: sun, 05 jan 2020 01:40:19 gmt{"code": 451, "msg": "自定义异常!"}

从上面的使用实例上看,可以知道这种使用方式,不仅仅支持标准的 http code,也支持自定义的 code(如返回 code 451)

3. httpservletresponse

这种使用姿势则是直接操作httpservletresponse对象,手动录入返回的结果

a. setstatus

/** * response.setstatus 支持自定义http code,并可以返回结果 * * @param response * @return */@getmapping("525")public string _525(httpservletresponse response) { response.setstatus(525); return "{"code": 525, "msg": "自定义错误码 525!"}";}

输出结果

➜ ~ curl 'http://127.0.0.1:8080/code/525' -ihttp/1.1 525content-type: text/plain;charset=utf-8content-length: 47date: sun, 05 jan 2020 01:45:38 gmt{"code": 525, "msg": "自定义错误码 525!"}%

使用方式比较简单,直接设置 status 即可,支持自定义的 http code 返回

b. senderror

使用这种姿势的时候需要注意一下,只支持标准的 http code,而且 response body 中不会有你的业务返回数据,如

/** * send error 方式,只支持标准http状态码; 且不会带上返回的结果 * * @param response * @return * @throws ioexception */@getmapping("410")public string _410(httpservletresponse response) throws ioexception { response.senderror(410, "send 410"); return "{"code": 410, "msg": "gone 410!"}";}@getmapping("460")public string _460(httpservletresponse response) throws ioexception { response.senderror(460, "send 460"); return "{"code": 460, "msg": "gone 460!"}";}

输出结果

➜ ~ curl 'http://127.0.0.1:8080/code/410' -ihttp/1.1 410content-type: application/json;charset=utf-8transfer-encoding: chunkeddate: sun, 05 jan 2020 01:47:52 gmt{"timestamp":"2020-01-05t01:47:52.300 0000","status":410,"error":"gone","message":"send 410","path":"/code/410"}%➜ ~ curl 'http://127.0.0.1:8080/code/460' -ihttp/1.1 500content-type: application/json;charset=utf-8transfer-encoding: chunkeddate: sun, 05 jan 2020 01:47:54 gmtconnection: close{"timestamp":"2020-01-05t01:47:54.719 0000","status":460,"error":"http status 460","message":"send 460","path":"/code/460"}%

从上面的 case 也可以看出,当我们使用 send error 时,如果是标准的 http code,会设置对响应头;如果是自定义的不被识别的 code,那么返回的 http code 是 500

4, 小结

上面介绍了几种常见的设置响应 http code 的姿势,下面小结一下使用时的注意事项

responsestatus

  • 只支持标准的 http code
  • 装饰自定义异常类,使用时抛出对应的异常类,从而达到设置响应 code 的效果 缺点对非可控的异常类不可用
  • 结合@exceptionhandler,用来装饰方法

responseentity

形如:

return responseentity.status(451).body("{"code": 451, "msg": "自定义异常!"}");
  • 我个人感觉是最强大的使用姿势,就是写起来没有那么简洁
  • 支持自定义 code,支持设置 response body

httpservletresponse

  • setstatus: 设置响应 code,支持自定义 code,支持返回 response body
  • senderror: 只支持标准的 http code,如果传入自定义的 code,返回的 http code 会是 500

ii. 其他

项目源码

  • 工程:https://github.com/liuyueyi/spring-boot-demo[1]
  • 项目:https://github.com/liuyueyi/spring-boot-demo/blob/master/spring-boot/207-web-response[2]

1. 一灰灰 blog

尽信书则不如,以上内容,纯属一家之言,因个人能力有限,难免有疏漏和错误之处,如发现 bug 或者有更好的建议,欢迎批评指正,不吝感激

下面一灰灰的个人博客,记录所有学习和工作中的博文,欢迎大家前去逛逛

  • 一灰灰 blog 个人博客 https://blog.hhui.top[3]
  • 一灰灰 blog-spring 专题博客 http://spring.hhui.top[4]

总结

以上是ag凯发k8国际为你收集整理的boot返回码规范 spring_springboot 系列 web 篇之自定义返回 http code 的 n 种姿势的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得ag凯发k8国际网站内容还不错,欢迎将ag凯发k8国际推荐给好友。

  • 上一篇:
  • 下一篇:
网站地图