我需要在控制器中将请求体作为原始JSON字符串。我正在使用Spring WebFlux。如果我能够更改@PostMapper函数签名,那么使用"@RequestBody “获得原始JSON将非常容易。但是我不能这样做,因为它是自动生成的,并且会影响其他处理程序,"@RequestBody学生“也已经存在,我们不能有两个@RequestBody。
@RestController
public class StudentController {
@PostMapping("/student")
private void newStudent(@RequestBody Student student,
ServerWebExchange exchange) {
String rawStudent = ServerExchangeUtils.getRequestRawBody(exchange); //idealy like this
System.out.println(rawStudent);
}
}
我要找的是“交换”(GetRequestRaw)之类的东西
发布于 2022-04-29 14:51:00
我也有同样的问题,我不能改变信号,因为它是由openapi生成器生成的。
通过将主体缓存在WebFilter中的字符串中,我找到了一个解决方案:
@Slf4j
public class CachingBodyServerHttpRequestDecorator extends ServerHttpRequestDecorator {
private final StringBuilder cachedBody = new StringBuilder();
public CachingBodyServerHttpRequestDecorator(ServerHttpRequest delegate) {
super(delegate);
}
@Override
public Flux<DataBuffer> getBody() {
return super.getBody().doOnNext(this::cache);
}
@SneakyThrows
private void cache(DataBuffer buffer) {
cachedBody.append(UTF_8.decode(buffer.asByteBuffer()));
}
public String getCachedBody() {
return cachedBody.toString();
}
}
public final class CachingBodyServerWebExchangeDecorator extends ServerWebExchangeDecorator {
private final ServerHttpRequestDecorator requestDecorator;
public CachingBodyServerWebExchangeDecorator(ServerWebExchange delegate) {
super(delegate);
this.requestDecorator = new CachingBodyServerHttpRequestDecorator(delegate.getRequest());
}
@Override
public ServerHttpRequest getRequest() {
return requestDecorator;
}
}
@Component
@Slf4j
public class SetRequestBodyAttribute implements WebFilter {
private static ServerHttpRequestPredicate requestsToServe =
MethodServerHttpRequestPredicate.of(HttpMethod.POST)
.and(PathServerHttpRequestPredicate.of("/contacts/import"))
.or(MethodServerHttpRequestPredicate.of(HttpMethod.PATCH)
.and(PathServerHttpRequestPredicate.of("/contacts/{contact_id}")));
@Override
public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
if (requestsToServe.test(exchange.getRequest())) {
return chain.filter(new CachingBodyServerWebExchangeDecorator(exchange));
}
return chain.filter(exchange);
}
}
@UtilityClass
public class ServerHttpRequestUtils {
public Mono<String> getBodyAsString(ServerHttpRequest request) {
return Mono.just(((CachingBodyServerHttpRequestDecorator)exchange.getRequest()).getCachedBody())
}
}
public interface ServerHttpRequestPredicate {
boolean test(ServerHttpRequest request);
@NotNull
default ServerHttpRequestPredicate and(@NotNull ServerHttpRequestPredicate other) {
Objects.requireNonNull(other);
return (t) -> test(t) && other.test(t);
}
@NotNull
default ServerHttpRequestPredicate negate() {
return (t) -> !test(t);
}
@NotNull
default ServerHttpRequestPredicate or(@NotNull ServerHttpRequestPredicate other) {
Objects.requireNonNull(other);
return (t) -> test(t) || other.test(t);
}
}
@Value
public class PathServerHttpRequestPredicate implements ServerHttpRequestPredicate {
public static PathServerHttpRequestPredicate of(String path) {
return new PathServerHttpRequestPredicate(path);
}
PathPattern pathPattern;
public PathServerHttpRequestPredicate(String path) {
Assert.notNull(path, "path should not be null!");
this.pathPattern = PathPatternParser.defaultInstance.parse(path);
}
@Override
public boolean test(ServerHttpRequest request) {
PathContainer pathContainer = request.getPath().pathWithinApplication();
PathPattern.PathMatchInfo info = this.pathPattern.matchAndExtract(pathContainer);
return info != null;
}
}
@Value(staticConstructor = "of")
public class MethodServerHttpRequestPredicate implements ServerHttpRequestPredicate{
HttpMethod httpMethod;
public MethodServerHttpRequestPredicate(HttpMethod httpMethod) {
Assert.notNull(httpMethod, "httpMethod should not be null!");
this.httpMethod = httpMethod;
}
@Override
public boolean test(ServerHttpRequest request) {
return request.getMethod() == httpMethod;
}
}
在控制器处理程序中,我们可以将主体作为字符串获得,即使它是作为对象注入的。
Mono<String> bodyAsStringMono = ServerHttpRequestUtils .getBodyAsString(exchange);
https://stackoverflow.com/questions/70708196
复制相似问题