嗨玩手游网

接口测试遇到500报错?别慌,你的头部可能有点问题

问题:接口的入参、地址、请求方式都设置对了,但是请求仍返回500,报系统错误是为啥?

在日常进行接口测试过程中,我们都知道一个完整的接口HTTP请求一般包括四大部分:请求信息头、请求体、响应信息头、响应体、请求方式(post/get等)。在进行测试时我们比较关心的是请求入参,也就是请求体的信息,从而忽略了请求信息头的重要性。若是未正确定义信息头,会导致接口请求失败。

本文主要带大家简单了解下信息头的作用。Jmeter提供了HTTP Header Manager信息头管理器,用于定义规范客户端和服务端之间HTTP接口请求的默认规范。

注意:HTTP 的请求方式有 8 种,但是我们在实际应用中常用的也就是 get 和 post,其他请求方式也都可以通过这两种方式间接的来实现。

常用的标准

常用的HTTP接口请求头字段有如下:

l Accept

设置接受的内容类型

l User-Agent

用户代理的字符串值,一般用于告诉服务器客户端使用的操作系统/浏览器的名称和版本等信息

l Content-Type

设置请求体的MIME类型(适用POST和PUT请求),告诉客户端实际返回的内容的内容类型,常用application/json;charset=UTF-8,定义接口响应返回的数据是json格式,编码格式是UTF-8。

l Content-Length

设置请求体的字节长度

l Accept-Encoding

设置接受的编码格式

l Accept-Language

设置接受的语言

l Origin

标识跨域资源请求(请求服务端设置Access-Control-Allow-Origin响应字段)

l Referer

设置前一个页面的地址,并且前一个页面中的连接指向当前请求,意思就是如果当前请求是在A页面中发送的,那么referer就是A页面的url地址

l Cookie

Cookie是远程服务端返回的识别用户身份信息,该信息存储在客户端,客户端每次进行操作时,会通过HTTP协议和服务器端进行Cookie的交互,验证身份信息正确才可交互成功(大多数需要登录后操作的接口上面会比较常见)。

l Set-Cookie

设置HTTP Cookie,用来存储一些用户信息以便让服务器辨别用户身份的,一般是服务端返回的用户身份信息(大多数需要登录的接口上面会比较常见)

......

Header信息获取方式

接口的信息头到底定义了哪些内容,可以通过以下渠道获得:

1. 开发提供接口文档

2. 通过抓包工具charles抓取查看Request的Headers

下图为方式2,通过抓包工具查看到的某接口的请求信息头(Request-Headers)

实践

目标:某系统登录接口已定义响应数据(Response)返回的格式是json格式,使用jmeter的HTTP Request、HTTP Header Manager成功实现登录。

配置

菜单路径

配置内容:

从抓包工具charles上可获取到接口需要定义Content-Type:application/json;charset=UTF-8(响应数据为json格式,编码方式为UTF-8)

未定义信息头

下图中POST方式的登录接口未设置HTTP Header Manager,运行jmeter脚本发起接口请求时默认Content-Type:text/plain(纯文本格式),所以请求会报错,返回状态码500。

正确定义信息头

正确定义信息头:Content-Type:application/json

信息头配置正确后,运行jmeter脚本接口请求成功,返回状态码200。

其他常见的媒体格式

text/html :HTML格式

text/plain :纯文本格式

text/xml :XML格式

application/xhtml+xml :XHTML格式

application/xml:XML数据格式

application/json:JSON数据格式

......

本文仅分享由于请求信息头(Headers)未定义而引起的错误码500,不排除其他原因引起。

SpringBoot 中统一响应格式及统一异常处理,你应该这样做

在我们开发SpringBoot后端服务时,一般需要给前端统一响应格式,方便前端调试及配置错误提示等等。这篇文章讲讲实际工作中统一响应格式及统一异常处理是如何做的。

一、统一响应基础类

在项目中对应工具类或Vo层来创建我们的统一响应类

ResponseResult:

java复制代码import com.fasterxml.jackson.annotation.JsonInclude;import com.zhang.enums.AppHttpCodeEnum;import java.io.Serializable;@JsonInclude(JsonInclude.Include.NON_NULL)public class ResponseResult<T> implements Serializable { private Integer code; private String msg; private T data; public ResponseResult() { thisde = AppHttpCodeEnum.SUCCESS.getCode(); this.msg = AppHttpCodeEnum.SUCCESS.getMsg(); } public ResponseResult(Integer code, T data) { thisde = code; this.data = data; } public ResponseResult(Integer code, String msg, T data) { thisde = code; this.msg = msg; this.data = data; } public ResponseResult(Integer code, String msg) { thisde = code; this.msg = msg; } public static ResponseResult errorResult(int code, String msg) { ResponseResult result = new ResponseResult(); return result.error(code, msg); } public static ResponseResult okResult() { ResponseResult result = new ResponseResult(); return result; } public static ResponseResult okResult(int code, String msg) { ResponseResult result = new ResponseResult(); return result.ok(code, null, msg); } public static ResponseResult okResult(Object data) { ResponseResult result = setAppHttpCodeEnum(AppHttpCodeEnum.SUCCESS, AppHttpCodeEnum.SUCCESS.getMsg()); if (data != null) { result.setData(data); } return result; } public static ResponseResult errorResult(AppHttpCodeEnum enums) { return setAppHttpCodeEnum(enums, enums.getMsg()); } public static ResponseResult errorResult(AppHttpCodeEnum enums, String msg) { return setAppHttpCodeEnum(enums, msg); } public static ResponseResult setAppHttpCodeEnum(AppHttpCodeEnum enums) { return okResult(enums.getCode(), enums.getMsg()); } private static ResponseResult setAppHttpCodeEnum(AppHttpCodeEnum enums, String msg) { return okResult(enums.getCode(), msg); } public ResponseResult<?> error(Integer code, String msg) { thisde = code; this.msg = msg; return this; } public ResponseResult<?> ok(Integer code, T data) { thisde = code; this.data = data; return this; } public ResponseResult<?> ok(Integer code, T data, String msg) { thisde = code; this.data = data; this.msg = msg; return this; } public ResponseResult<?> ok(T data) { this.data = data; return this; } public Integer getCode() { return code; } public void setCode(Integer code) { thisde = code; } public String getMsg() { return msg; } public void setMsg(String msg) { this.msg = msg; } public T getData() { return data; } public void setData(T data) { this.data = data; }}

里面还有用到一个响应的枚举类AppHttpCodeEnum,接下来我们创建这个枚举类

二、响应枚举类

AppHttpCodeEnum:

java复制代码public enum AppHttpCodeEnum { // 成功 SUCCESS(200, "操作成功"), // 登录 NEED_LOGIN(401, "需要登录后操作"), NO_OPERATOR_AUTH(403, "无权限操作"), SYSTEM_ERROR(500, "出现错误"), USERNAME_EXIST(501, "用户名已存在"), PHONENUMBER_EXIST(502, "手机号已存在"), EMAIL_EXIST(503, "邮箱已存在"), REQUIRE_USERNAME(504, "必需填写用户名"), CONTENT_NOT_NULL(506, "评论内容不能为空"), FILE_TYPE_ERROR(507, "文件类型错误"), USERNAME_NOT_NULL(508, "用户名不能为空"), NICKNAME_NOT_NULL(509, "昵称不能为空"), PASSWORD_NOT_NULL(510, "密码不能为空"), EMAIL_NOT_NULL(511, "邮箱不能为空"), NICKNAME_EXIST(512, "昵称已存在"), LOGIN_ERROR(505, "用户名或密码错误"); int code; String msg; AppHttpCodeEnum(int code, String errorMessage) { thisde = code; this.msg = errorMessage; } public int getCode() { return code; } public String getMsg() { return msg; }}

一般我们在这个枚举类中管理需要响应的错误code及msg

三、统一响应格式使用

在对应的controller或者service里面使用统一响应类

成功: ResponseResult.okResult()失败: ResponseResult.errorResult(AppHttpCodeEnum.SYSTEM_ERROR), 参数传入我们定义的响应枚举类四、统一异常处理1. 自定义异常

为什么我们需要自定义异常?因为在某些情况下,我们需要返回我们自定义的响应格式非常不方便,如在处理用户鉴权或token校验的时候,因为像这些部分我们一般都是在单独的工具类中去处理,这时候如果报错其实就可以抛出我们自定义的异常,交由我们全局的异常处理去统一返回响应。

在exception包下新建SystemException类SystemException继承RuntimeException

具体实现代码如下

exception.SystemException:

scala复制代码import com.jk.enums.AppHttpCodeEnum;public class SystemException extends RuntimeException{ private int code; private String msg; public int getCode() { return code; } public String getMsg() { return msg; } public SystemException(AppHttpCodeEnum appHttpCodeEnum) { super(appHttpCodeEnum.getMsg()); thisde = appHttpCodeEnum.getCode(); this.msg = appHttpCodeEnum.getMsg(); }}

目前只是自定义了异常,我们还需要对自定义的异常进行处理,返回统一的响应格式。

2.异常处理在handler.exception包下新建GlobalExceptionHandler处理类@RestControllerAdvice是组合注解,由@ControllerAdvice、@ResponseBody组成,标明是一个统一异常处理的类,并把返回结果封装在ResponseBody中@Slf4j是Lombok实现日志输出的注解@ExceptionHandler标明该方法处理哪些异常

具体代码实现如下:

handler.exception.GlobalExceptionHandler:

java复制代码import com.jk.enums.AppHttpCodeEnum;import com.jk.exception.SystemException;import com.jk.vo.ResponseResult;import lombok.extern.slf4j.Slf4j;import org.springframework.web.bind.annotation.ExceptionHandler;import org.springframework.web.bind.annotation.RestControllerAdvice;@RestControllerAdvice@Slf4jpublic class GlobalExceptionHandler { @ExceptionHandler(SystemException.class) public ResponseResult systemExceptionHandler(SystemException e) { log.error("出现了异常! {}", e); return ResponseResult.errorResult(e.getCode(), e.getMsg()); } @ExceptionHandler(Exception.class) public ResponseResult exceptionHandler(Exception e) { log.error("出现了异常! {}", e); return ResponseResult.errorResult(AppHttpCodeEnum.SYSTEM_ERROR.getCode(), e.getMessage()); }}

可以看到我们除了处理自定义异常SystemException外,还对Exception就是其他我们无法预料到的异常做了一个兜底。

3.自定义异常使用

在需要抛出异常的地方:

java复制代码throw new SystemException(AppHttpCodeEnum.LOGIN_ERROR);

前端接收到的响应是:

json复制代码{ "code": 505, "msg": "用户名或密码错误"}

这样就比接收到500错误也不知道错误原因好多了。

作者:JK凯链接:https://juejin/post/7226994337123549242

更多资讯
游戏推荐
更多+