HttpServletResponse 没有 return 正确的消息
HttpServletResponse didnt return proper message
public class ApiKeyFilter implements Filter {
private final Logger log = LoggerFactory.getLogger(ApiKeyFilter.class);
private final ApiKeyRepository apiKeyRepository;
private final SecurityModule securityModule;
private final JsonUtils jsonUtils;
@Autowired
public ApiKeyFilter(ApiKeyRepository apiKeyRepository, SecurityModule securityModule, JsonUtils jsonUtils) {
this.apiKeyRepository = apiKeyRepository;
this.securityModule = securityModule;
this.jsonUtils = jsonUtils;
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
//Convert request to httpRequest
RequestWrapper requestWrapper = new RequestWrapper((HttpServletRequest) servletRequest);
HttpServletResponse httpServletResponse = (HttpServletResponse)servletResponse;
String xApiKey = requestWrapper.getHeader("x-api-key");
String sortBodySign = requestWrapper.getHeader("sort-body-sign");
//BLABLABLA Logic
//Compare with client's API key
if (!apiKeyObject.getSignature().equalsIgnoreCase(Hex.toHexString(messageDigest))) {
log.error("Invalid signature, expected: {}, received: {}", Hex.toHexString(messageDigest), apiKeyObject.getSignature());
httpServletResponse.sendError(HttpServletResponse.SC_PRECONDITION_FAILED,
StatusCode.getStatusMessage(StatusCode.VERIFY_SIGNATURE_FAIL));
return;
}
} catch (RuntimeException ex){
log.error("Exception happened: {}", ex.getMessage());
httpServletResponse.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Internal Server Error");
return;
}
filterChain.doFilter(requestWrapper, servletResponse);
}
我是 spring 启动 httpServletResponse 的新手。我可以知道为什么我的 sendError 函数在我写的时候没有 return 错误消息。
这是响应消息:
{"timestamp":"2021-09-10T09:00:54.146+00:00","status":412,"error":"Precondition Failed"}
我也希望 return 将消息放入响应中。
示例:
{"timestamp":"2021-09-11T02:17:06.948+00:00","status":602,"error":"Http Status 602","message":"Invalid Authorization Signature"}
在您的 ApiKeyFilter
中,您应该只抛出自定义运行时异常 (InvalidAuthorizationSignatureException
)。
public class InvalidAuthorizationSignatureException extends RuntimeException {
public InvalidAuthorizationSignatureException(String errorMessage, Throwable err) {
super(errorMessage, err);
}
}
那么您需要一个 ExceptionHandler
用于设置 HTTP 状态和消息的异常。
@ControllerAdvice
public class CustomRestExceptionHandler extends ResponseEntityExceptionHandler {
@ExceptionHandler({ InvalidAuthorizationSignatureException.class })
public ResponseEntity<Object> handleInvalidAuthorizationSignature(InvalidAuthorizationSignatureException ex, WebRequest request) {
ApiError apiError = new ApiError(HttpStatus.SC_PRECONDITION_FAILED, StatusCode.getStatusMessage(StatusCode.VERIFY_SIGNATURE_FAIL), errors);
return new ResponseEntity<Object>(apiError, new HttpHeaders(), apiError.getStatus());
}
}
有关详细信息,请查看 https://www.baeldung.com/global-error-handler-in-a-spring-rest-api。
public class ApiKeyFilter implements Filter {
private final Logger log = LoggerFactory.getLogger(ApiKeyFilter.class);
private final ApiKeyRepository apiKeyRepository;
private final SecurityModule securityModule;
private final JsonUtils jsonUtils;
@Autowired
public ApiKeyFilter(ApiKeyRepository apiKeyRepository, SecurityModule securityModule, JsonUtils jsonUtils) {
this.apiKeyRepository = apiKeyRepository;
this.securityModule = securityModule;
this.jsonUtils = jsonUtils;
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
//Convert request to httpRequest
RequestWrapper requestWrapper = new RequestWrapper((HttpServletRequest) servletRequest);
HttpServletResponse httpServletResponse = (HttpServletResponse)servletResponse;
String xApiKey = requestWrapper.getHeader("x-api-key");
String sortBodySign = requestWrapper.getHeader("sort-body-sign");
//BLABLABLA Logic
//Compare with client's API key
if (!apiKeyObject.getSignature().equalsIgnoreCase(Hex.toHexString(messageDigest))) {
log.error("Invalid signature, expected: {}, received: {}", Hex.toHexString(messageDigest), apiKeyObject.getSignature());
httpServletResponse.sendError(HttpServletResponse.SC_PRECONDITION_FAILED,
StatusCode.getStatusMessage(StatusCode.VERIFY_SIGNATURE_FAIL));
return;
}
} catch (RuntimeException ex){
log.error("Exception happened: {}", ex.getMessage());
httpServletResponse.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Internal Server Error");
return;
}
filterChain.doFilter(requestWrapper, servletResponse);
}
我是 spring 启动 httpServletResponse 的新手。我可以知道为什么我的 sendError 函数在我写的时候没有 return 错误消息。 这是响应消息:
{"timestamp":"2021-09-10T09:00:54.146+00:00","status":412,"error":"Precondition Failed"}
我也希望 return 将消息放入响应中。
示例:
{"timestamp":"2021-09-11T02:17:06.948+00:00","status":602,"error":"Http Status 602","message":"Invalid Authorization Signature"}
在您的 ApiKeyFilter
中,您应该只抛出自定义运行时异常 (InvalidAuthorizationSignatureException
)。
public class InvalidAuthorizationSignatureException extends RuntimeException {
public InvalidAuthorizationSignatureException(String errorMessage, Throwable err) {
super(errorMessage, err);
}
}
那么您需要一个 ExceptionHandler
用于设置 HTTP 状态和消息的异常。
@ControllerAdvice
public class CustomRestExceptionHandler extends ResponseEntityExceptionHandler {
@ExceptionHandler({ InvalidAuthorizationSignatureException.class })
public ResponseEntity<Object> handleInvalidAuthorizationSignature(InvalidAuthorizationSignatureException ex, WebRequest request) {
ApiError apiError = new ApiError(HttpStatus.SC_PRECONDITION_FAILED, StatusCode.getStatusMessage(StatusCode.VERIFY_SIGNATURE_FAIL), errors);
return new ResponseEntity<Object>(apiError, new HttpHeaders(), apiError.getStatus());
}
}
有关详细信息,请查看 https://www.baeldung.com/global-error-handler-in-a-spring-rest-api。