ROC*_*CKY 1 spring spring-boot spring-web spring-webflux
我正在尝试使用 Webfilter 拦截 Spring Boot Webflux 应用程序(Spring boot 2.0.0.M7)中的所有请求,并检查“Authorization”标头是否存在。如果不存在,我想停止请求处理并发送自定义 HttpStatus 和自定义正文。自定义 HttpStatus 正在运行,但我无法将自定义消息写入 HTTP 正文。以下
import java.time.LocalDateTime;
import org.apache.commons.lang.SerializationUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.core.io.buffer.DefaultDataBufferFactory;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.web.reactive.function.client.WebClient;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.WebFilter;
import org.springframework.web.server.WebFilterChain;
import reactor.core.publisher.Mono;
import reactor.util.context.Context;
public class RequestContextFilter implements WebFilter{
Logger LOG = LoggerFactory.getLogger(RequestContextFilter.class);
@Autowired
private WebClient.Builder webclientBuilder;
@Override
public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
LOG.debug("Inside RequestContextFilter.."+ exchange);
String authorizationHeader = exchange.getRequest().getHeaders().getFirst(HttpHeaders.AUTHORIZATION);
if(authorizationHeader == null) {
exchange.getResponse().setStatusCode(HttpStatus.BAD_REQUEST);
ApiError apiError = new ApiError(HttpStatus.BAD_REQUEST);
apiError.setMessage("Missing Authorization Header");
apiError.setTimestamp(LocalDateTime.now());
// The below code of writing to body is NOT WORKING
exchange.getResponse().writeWith(Mono.just(new DefaultDataBufferFactory().wrap(SerializationUtils.serialize(apiError))));
return Mono.empty();
}
return chain.filter(exchange);
}
}
Run Code Online (Sandbox Code Playgroud)
ApiError.java 类只不过是我想包含在响应中的自定义对象。
public class ApiError implements Serializable{
private HttpStatus status;
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "dd-MM-yyyy hh:mm:ss")
private LocalDateTime timestamp;
private String message;
private String debugMessage;
private List<ApiSubError> subErrors;
public ApiError() {
timestamp = LocalDateTime.now();
}
public ApiError(HttpStatus status) {
this();
this.status = status;
}
public ApiError(HttpStatus status, Throwable ex) {
this();
this.status = status;
this.message = "Unexpected error";
this.debugMessage = ex.getLocalizedMessage();
}
public ApiError(HttpStatus status, String message, Throwable ex) {
this();
this.status = status;
this.message = message;
this.debugMessage = ex.getLocalizedMessage();
}
}
Run Code Online (Sandbox Code Playgroud)
我卷曲了端点,这个 Webfilter 确实有效,它发送了正确的 HttpStatus 代码 400,但没有 ApiError。
请求(无授权标头):
curl -X GET "http://localhost:8080/accounts"--verbose
Run Code Online (Sandbox Code Playgroud)
回复:
HTTP/1.1 400 Bad Request
content-length: 0
Run Code Online (Sandbox Code Playgroud)
状态有效并且正在调用过滤器但没有对象响应。在使用 jackson 将原始字节转换为 JSON 后,我确实尝试将字节写入 DataBufferFactory,但它不起作用。
+1 @bsamartins 所说的。
现在关于您的特定解决方案:该writeWith方法返回一个Publisher. 如果没有任何东西订阅它,那么什么都不会发生。你应该更换
exchange.getResponse().writeWith(Mono.just(new DefaultDataBufferFactory().wrap(SerializationUtils.serialize(apiError))));
return Mono.empty();
Run Code Online (Sandbox Code Playgroud)
和
return exchange.getResponse()
.writeWith(Mono.just(new DefaultDataBufferFactory().wrap(SerializationUtils.serialize(apiError))));
Run Code Online (Sandbox Code Playgroud)
有了这个更改,Spring WebFlux 将订阅返回的内容Publisher,您的代码将写入响应。
| 归档时间: |
|
| 查看次数: |
2090 次 |
| 最近记录: |