我正在构建一个React SPA,并希望使用JSON与后端进行交互。当身份验证失败时,我希望能够以JSON的形式发送自定义错误消息。但是给出以下代码:
chart.getDatasetMeta(0)
出现以下错误:
.authenticationFailureHandler(((exchange, e) -> {
return Mono.fromRunnable(() -> {
ServerHttpResponse response = exchange.getExchange().getResponse();
response.setStatusCode(HttpStatus.OK);
response.getHeaders().setContentType(MediaType.APPLICATION_JSON);
DataBuffer buf = exchange.getExchange().getResponse().bufferFactory().wrap("{\"test\":\"tests\"}".getBytes(StandardCharsets.UTF_8));
response.writeWith(Mono.just(buf));
});
})
但是,如果我更改响应代码,它将反映在响应中,因此我知道代码已执行,但没有返回响应正文。
我需要更改什么才能在身份验证失败时发送回响应正文?
答案 0 :(得分:0)
我认为这可行:
.authenticationFailureHandler(((exchange, e) -> {
ServerHttpResponse response = exchange.getExchange().getResponse();
response.setStatusCode(HttpStatus.OK);
response.getHeaders().setContentType(MediaType.APPLICATION_JSON);
DataBuffer buf = exchange.getExchange().getResponse().bufferFactory().wrap("{\"test\":\"tests\"}".getBytes(StandardCharsets.UTF_8));
return response.writeWith(Mono.just(buf));
});
})
可能有比将JSON编写为String更好的方法,但是我认为这应该可行。
您的尝试没有用,因为Publisher
没有订阅返回的response.writeWith(Mono.just(buf))
。由于发布者很懒,因此不会在响应中写入任何内容。
答案 1 :(得分:0)
您还可以使用自定义的WebExceptionHandler和ErrorAttributes
.authenticationFailureHandler(webFilterExchange, exception) ->
customErrorWebExceptionHandler.handle(webFilterExchange.getExchange(), exception);
@Component
public class CustomErrorWebExceptionHandler extends AbstractErrorWebExceptionHandler {
public CustomErrorWebExceptionHandler(
final CustomErrorAttributes customAttributes,
final ResourceProperties resourceProperties,
final ObjectProvider<List<ViewResolver>> viewResolversProvider,
final ServerCodecConfigurer serverCodecConfigurer,
final ApplicationContext applicationContext
) {
super(customAttributes, resourceProperties, applicationContext);
this.setViewResolvers(viewResolversProvider.getIfAvailable(Collections::emptyList));
this.setMessageWriters(serverCodecConfigurer.getWriters());
this.setMessageReaders(serverCodecConfigurer.getReaders());
}
@Override
protected RouterFunction<ServerResponse> getRoutingFunction(final ErrorAttributes errorAttributes) {
if (errorAttributes instanceof CustomErrorAttributes) {
return RouterFunctions.route(RequestPredicates.all(),
(request) -> handleProblemDetail(request, (CustomErrorAttributes) errorAttributes)
);
}
throw new UnsupportedOperationException(errorAttributes.getClass().getName());
}
private Mono<ServerResponse> handleProblemDetail(final ServerRequest request, final CustomErrorAttributes error) {
final Map<String, Object> errorAttributes = error.getErrorAttributes(request, false);
return ServerResponse.status(Integer.parseInt(errorAttributes
.getOrDefault("status", "500").toString()))
.contentType(MediaType.APPLICATION_PROBLEM_JSON)
.body(Mono.just(errorAttributes), Map.class)
;
}
}
@Component
public class CustomErrorAttributes implements ErrorAttributes {
private static final String ERROR_ATTRIBUTE = CustomErrorAttributes.class.getName() + ".ERROR";
@Override
public Map<String, Object> getErrorAttributes(final ServerRequest request, final boolean includeStackTrace) {
final Throwable error = this.getError(request);
return somethingThatConvertsTheErrorToAMap(error);
}
@Override
public Throwable getError(final ServerRequest request) {
return (Throwable)request.attribute(ERROR_ATTRIBUTE).orElseThrow(() -> {
return new IllegalStateException("Missing exception attribute in ServerWebExchange");
});
}
@Override
public void storeErrorInformation(final Throwable error, final ServerWebExchange exchange) {
exchange.getAttributes().putIfAbsent(ERROR_ATTRIBUTE, error);
}
}