WireMock自定义响应调用badRequest()返回422而非400的问题排查
WireMock请求过滤器返回422而非预期400错误的排查
在自定义WireMock请求过滤器类中,预期触发条件时返回400 Bad Request错误,但实际收到的是422 Unprocessable Entity错误。即便调用了ResponseDefinition.badRequest()方法,依然抛出422错误,想确认这是WireMock的预期行为还是代码实现有遗漏。
自定义请求过滤器代码
import java.io.UnsupportedEncodingException; import java.util.ArrayList; import java.util.List; import org.apache.commons.codec.binary.Base64; import org.springframework.stereotype.Component; import com.example.wiremock.errorhandler.BadRequestError; import com.example.wiremock.errorhandler.MockError; import com.example.wiremock.errorhandler.MockErrorResponse; import com.example.wiremock.luukuresponse.LuukkuBasicInfoResponse; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; import com.github.tomakehurst.wiremock.common.Errors; import com.github.tomakehurst.wiremock.common.Errors.Error; import com.github.tomakehurst.wiremock.common.Errors.Error.Source; import com.github.tomakehurst.wiremock.common.Json; import com.github.tomakehurst.wiremock.extension.requestfilter.RequestFilterAction; import com.github.tomakehurst.wiremock.extension.requestfilter.StubRequestFilter; import com.github.tomakehurst.wiremock.http.HttpHeader; import com.github.tomakehurst.wiremock.http.Request; import com.github.tomakehurst.wiremock.http.ResponseDefinition; @Component public class BasicAuthRequestFilter extends StubRequestFilter { public String decodeJwt(String token) throws UnsupportedEncodingException { String payload = token.split("\\.")[1]; return new String(Base64.decodeBase64(payload), "UTF-8"); } @Override public RequestFilterAction filter(Request request){ if (request.header("Authorization").firstValue().matches("Bearer [a-zA-Z0-9&._-]{1,}")) { String authtoken = request.header("Authorization").firstValue(); ObjectMapper objectMapper = new ObjectMapper(); objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES); String str; try { String pattern = "^\\S{4}75-\\S{4}$"; str = decodeJwt(authtoken); Token token = objectMapper.readValue(str, Token.class); String test = token.getRepresentation().getId(); if(test.matches(pattern)) { Error error = new Error(400, null, "response", null); List<Error> listOfErros = new ArrayList<>(); listOfErros.add(error); Errors errorList = new Errors(listOfErros); return RequestFilterAction.stopWith(ResponseDefinition.badRequest(errorList)); } } catch (UnsupportedEncodingException | JsonProcessingException e) { e.printStackTrace(); } return RequestFilterAction.continueWith(request); } return null; } @Override public String getName() { return "Authorization"; } }
实际错误表现
Postman请求返回截图显示响应状态码为422 Unprocessable Entity,而非预期的400。
问题原因
核心问题在于你使用了WireMock内置的Errors/Error类构建响应体。WireMock内部有预设逻辑:当响应体为Errors类型时,会自动将状态码覆盖为422 Unprocessable Entity,这会直接冲掉你通过badRequest()设置的400状态码,属于框架的内置行为。
解决方案
不要使用WireMock自带的错误类,改用你代码中已经导入的自定义错误DTO(比如BadRequestError/MockError),手动构建响应并指定状态码:
修改后的核心代码片段
if(test.matches(pattern)) { // 用自定义错误类构建响应内容 MockError mockError = new MockError(400, "response", null); List<MockError> errorList = new ArrayList<>(); errorList.add(mockError); BadRequestError badRequestError = new BadRequestError(errorList); ObjectMapper objectMapper = new ObjectMapper(); String errorJson; try { errorJson = objectMapper.writeValueAsString(badRequestError); } catch (JsonProcessingException e) { e.printStackTrace(); // 序列化失败时的兜底响应 errorJson = "{\"errors\": [{\"status\": 400, \"source\": \"response\"}]}"; } // 手动构建响应,明确指定400状态码 ResponseDefinition responseDefinition = new ResponseDefinitionBuilder() .withStatus(400) .withHeader("Content-Type", "application/json") .withBody(errorJson) .build(); return RequestFilterAction.stopWith(responseDefinition); }
额外注意事项
- 先判断
Authorization请求头是否存在,再调用firstValue(),避免空指针异常 - JWT解码逻辑未处理无效格式(比如token分割后不足3段),需要补充异常捕获
Token类未在代码中导入,需补充对应的import语句
内容的提问来源于stack exchange,提问作者Shruti Mishra
相关产品推荐
相关产品推荐

