- mongodb - 在 MongoDB mapreduce 中,如何展平值对象?
- javascript - 对象传播与 Object.assign
- html - 输入类型 ="submit"Vs 按钮标签它们可以互换吗?
- sql - 使用 MongoDB 而不是 MS SQL Server 的优缺点
我目前正在尝试将文件从 Angular 4 前端上传到 Spring Webflux Controller 。 Controller 能够读取 @RequestPart 值,但会抛出 415 UnsupportedMediaTypeStatusException。
上传 Controller
@PostMapping( consumes = MediaType.MULTIPART_FORM_DATA_VALUE )
public Mono<Void> save(@RequestPart("file")MultipartFile file) {
log.info("Storing a new file. Recieved by Controller");
this.storageService.store(file);
return Mono.empty();
}
log.info() 方法没有执行,所以似乎在方法执行之前就抛出了错误。
错误信息
org.springframework.web.server.UnsupportedMediaTypeStatusException: Response status 415 with reason "Content type 'image/png' not supported"
at org.springframework.web.reactive.result.method.annotation.AbstractMessageReaderArgumentResolver.readBody(AbstractMessageReaderArgumentResolver.java:206) ~[spring-webflux-5.0.4.RELEASE.jar:5.0.4.RELEASE]
at org.springframework.web.reactive.result.method.annotation.AbstractMessageReaderArgumentResolver.readBody(AbstractMessageReaderArgumentResolver.java:124) ~[spring-webflux-5.0.4.RELEASE.jar:5.0.4.RELEASE]
at org.springframework.web.reactive.result.method.annotation.RequestPartMethodArgumentResolver.lambda$resolveArgument$0(RequestPartMethodArgumentResolver.java:99) ~[spring-webflux-5.0.4.RELEASE.jar:5.0.4.RELEASE]
at reactor.core.publisher.MonoFlatMap$FlatMapMain.onNext(MonoFlatMap.java:118) ~[reactor-core-3.1.5.RELEASE.jar:3.1.5.RELEASE]
at reactor.core.publisher.FluxOnAssembly$OnAssemblySubscriber.onNext(FluxOnAssembly.java:450) ~[reactor-core-3.1.5.RELEASE.jar:3.1.5.RELEASE]
at reactor.core.publisher.MonoNext$NextSubscriber.onNext(MonoNext.java:76) ~[reactor-core-3.1.5.RELEASE.jar:3.1.5.RELEASE]
at reactor.core.publisher.FluxOnAssembly$OnAssemblySubscriber.onNext(FluxOnAssembly.java:450) ~[reactor-core-3.1.5.RELEASE.jar:3.1.5.RELEASE]
at reactor.core.publisher.FluxSwitchIfEmpty$SwitchIfEmptySubscriber.onNext(FluxSwitchIfEmpty.java:67) ~[reactor-core-3.1.5.RELEASE.jar:3.1.5.RELEASE]
at reactor.core.publisher.FluxOnAssembly$OnAssemblySubscriber.onNext(FluxOnAssembly.java:450) ~[reactor-core-3.1.5.RELEASE.jar:3.1.5.RELEASE]
at reactor.core.publisher.FluxFlattenIterable$FlattenIterableSubscriber.drainAsync(FluxFlattenIterable.java:391) ~[reactor-core-3.1.5.RELEASE.jar:3.1.5.RELEASE]
at reactor.core.publisher.FluxFlattenIterable$FlattenIterableSubscriber.drain(FluxFlattenIterable.java:633) ~[reactor-core-3.1.5.RELEASE.jar:3.1.5.RELEASE]
at reactor.core.publisher.FluxFlattenIterable$FlattenIterableSubscriber.onNext(FluxFlattenIterable.java:238) ~[reactor-core-3.1.5.RELEASE.jar:3.1.5.RELEASE]
at reactor.core.publisher.FluxOnAssembly$OnAssemblySubscriber.onNext(FluxOnAssembly.java:450) ~[reactor-core-3.1.5.RELEASE.jar:3.1.5.RELEASE]
at reactor.core.publisher.FluxFilterFuseable$FilterFuseableSubscriber.onNext(FluxFilterFuseable.java:87) ~[reactor-core-3.1.5.RELEASE.jar:3.1.5.RELEASE]
at reactor.core.publisher.FluxOnAssembly$OnAssemblySubscriber.onNext(FluxOnAssembly.java:450) ~[reactor-core-3.1.5.RELEASE.jar:3.1.5.RELEASE]
at reactor.core.publisher.FluxReplay$SizeBoundReplayBuffer.replayFused(FluxReplay.java:865) ~[reactor-core-3.1.5.RELEASE.jar:3.1.5.RELEASE]
at reactor.core.publisher.FluxReplay$SizeBoundReplayBuffer.replay(FluxReplay.java:895) ~[reactor-core-3.1.5.RELEASE.jar:3.1.5.RELEASE]
at reactor.core.publisher.ReplayProcessor.onNext(ReplayProcessor.java:436) ~[reactor-core-3.1.5.RELEASE.jar:3.1.5.RELEASE]
at reactor.core.publisher.MonoProcessor.drainLoop(MonoProcessor.java:504) ~[reactor-core-3.1.5.RELEASE.jar:3.1.5.RELEASE]
at reactor.core.publisher.MonoProcessor.onNext(MonoProcessor.java:347) ~[reactor-core-3.1.5.RELEASE.jar:3.1.5.RELEASE]
at reactor.core.publisher.FluxOnAssembly$OnAssemblySubscriber.onNext(FluxOnAssembly.java:450) ~[reactor-core-3.1.5.RELEASE.jar:3.1.5.RELEASE]
at reactor.core.publisher.FluxSwitchIfEmpty$SwitchIfEmptySubscriber.onNext(FluxSwitchIfEmpty.java:67) ~[reactor-core-3.1.5.RELEASE.jar:3.1.5.RELEASE]
at reactor.core.publisher.FluxOnAssembly$OnAssemblySubscriber.onNext(FluxOnAssembly.java:450) ~[reactor-core-3.1.5.RELEASE.jar:3.1.5.RELEASE]
at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.onNext(FluxMapFuseable.java:115) ~[reactor-core-3.1.5.RELEASE.jar:3.1.5.RELEASE]
at reactor.core.publisher.FluxOnAssembly$OnAssemblySubscriber.onNext(FluxOnAssembly.java:450) ~[reactor-core-3.1.5.RELEASE.jar:3.1.5.RELEASE]
at reactor.core.publisher.Operators$MonoSubscriber.complete(Operators.java:1069) ~[reactor-core-3.1.5.RELEASE.jar:3.1.5.RELEASE]
at reactor.core.publisher.MonoCollect$CollectSubscriber.onComplete(MonoCollect.java:142) ~[reactor-core-3.1.5.RELEASE.jar:3.1.5.RELEASE]
at reactor.core.publisher.FluxOnAssembly$OnAssemblySubscriber.onComplete(FluxOnAssembly.java:460) ~[reactor-core-3.1.5.RELEASE.jar:3.1.5.RELEASE]
at reactor.core.publisher.FluxCreate$BaseSink.complete(FluxCreate.java:404) ~[reactor-core-3.1.5.RELEASE.jar:3.1.5.RELEASE]
at reactor.core.publisher.FluxCreate$BufferAsyncSink.drain(FluxCreate.java:712) ~[reactor-core-3.1.5.RELEASE.jar:3.1.5.RELEASE]
at reactor.core.publisher.FluxCreate$BufferAsyncSink.complete(FluxCreate.java:666) ~[reactor-core-3.1.5.RELEASE.jar:3.1.5.RELEASE]
at reactor.core.publisher.FluxCreate$SerializedSink.drainLoop(FluxCreate.java:221) ~[reactor-core-3.1.5.RELEASE.jar:3.1.5.RELEASE]
at reactor.core.publisher.FluxCreate$SerializedSink.drain(FluxCreate.java:192) ~[reactor-core-3.1.5.RELEASE.jar:3.1.5.RELEASE]
at reactor.core.publisher.FluxCreate$SerializedSink.complete(FluxCreate.java:187) ~[reactor-core-3.1.5.RELEASE.jar:3.1.5.RELEASE]
at org.springframework.http.codec.multipart.SynchronossPartHttpMessageReader$FluxSinkAdapterListener.onAllPartsFinished(SynchronossPartHttpMessageReader.java:215) ~[spring-web-5.0.4.RELEASE.jar:5.0.4.RELEASE]
at org.synchronoss.cloud.nio.multipart.NioMultipartParser.allPartsRead(NioMultipartParser.java:603) ~[nio-multipart-parser-1.1.0.jar:na]
at org.synchronoss.cloud.nio.multipart.NioMultipartParser.write(NioMultipartParser.java:449) ~[nio-multipart-parser-1.1.0.jar:na]
at org.synchronoss.cloud.nio.multipart.NioMultipartParser.write(NioMultipartParser.java:370) ~[nio-multipart-parser-1.1.0.jar:na]
at org.springframework.http.codec.multipart.SynchronossPartHttpMessageReader$SynchronossPartGenerator.lambda$accept$0(SynchronossPartHttpMessageReader.java:136) ~[spring-web-5.0.4.RELEASE.jar:5.0.4.RELEASE]
依赖 Spring Webflux 应该使用 org.synchronoss.cloud.nio.multipart 已加载,所以我不完全理解 Spring 抛出 415 错误的原因。
我在 Spring 中使用 WebClient 创建了一个测试
网络测试
@Test
public void sendValidFileSaveCorrectly() {
MockMultipartFile file = new MockMultipartFile("foo", "foo.txt",
MediaType.TEXT_PLAIN_VALUE, "Hello World".getBytes());
MultipartBodyBuilder builder = new MultipartBodyBuilder();
builder.part("file", file);
webClient.post()
.uri("/api/file")
.syncBody(builder.build())
.exchange()
.expectStatus().is2xxSuccessful();
}
我收到了一个新的 500 错误,而不是使用 MockMultipartFile 和此消息
I/O failure: org.springframework.core.codec.CodecException: Type definition error: [simple type, class java.io.ByteArrayInputStream]; nested exception is com.fasterxml.jackson.databind.exc.InvalidDefinitionException: No serializer found for class java.io.ByteArrayInputStream and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS) (through reference chain: org.springframework.mock.web.MockMultipartFile["inputStream"])
我想了解的是为什么 Spring 会抛出 Unsupported Media Type 异常,以及如何指示 Spring Webflux 忽略正在编写该响应的任何内容。
更新
尝试将 Controller 更改为使用 @RequestParams 和 @RequestBody 并得到相同的 415 错误。正在处理 Multipart 请求,但附件的 Content-Type 正在执行 415。
我继续向 Controller 添加了一个 ExceptionHandler 以 try catch UnsupportedMediaTypeStatusException。尽管我无法将文件传递给 ExceptionHandler,所以这不起作用。我可以为 UnsupportedMediaTypeStatusException 覆盖默认的 ExceptionHandler,但我希望尽可能避免这种情况。
如果有用,我将发布上传文件的 Angular 服务。但是,由于即使在测试中也会发生错误,所以我认为 Angular 没有问题。
upload.service.ts
post(file: File, fileName: string) {
const formData = new FormData();
formData.append('file', file, fileName);
let headers = new HttpHeaders();
headers = headers.delete('Content-Type');
this.http
.post(this.API_URL, formData, { headers: headers, reportProgress: true })
.subscribe();
}
最佳答案
请使用 @RequestPart("file") Mono<FilePart> file
或 @RequestPart("file") Flux<FilePart>
而不是 @RequestPart("file") MultipartFile file
.
@PostMapping(consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public Mono<Void> save(@RequestPart("file") Mono<FilePart> file) {
log.info("Storing a new file. Received by Controller");
this.storageService.store(file);
return Mono.empty();
}
关于java - 带有 MultipartFile 的 Spring Webflux 415,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49457761/
我希望缓存Mono(仅在成功的情况下),这是WebClient调用的结果。 通过阅读项目 react 堆插件文档,我觉得CacheMono不太适合,因为它也存储了我不想要的错误。 因此,我没有使用Ca
我用 webflux 与 网易和 jdbc ,所以我以下一种方式包装阻塞 jdbc 操作: static Mono fromOne(Callable blockingOperation) {
有人可以告诉我或使用 提供现成的 CRUD 示例吗? WebFlux、RScoket 和 Spring(或 SpringBoot) ? 我研究了 RSocket 文档, WebFlux ,也写了我的简
我正在通过代理连接使用ssl服务测试webclient,但是使用安全ssl连接时出现以下错误。 你知道是什么问题吗? 堆栈跟踪: {"timestamp":"2019-10-29T18:35:43.5
public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) { Flux body = exchange.
我创建了一个过滤器,我可以在其中访问有效负载的主体并对其执行一些逻辑(现在假设我记录主体)。在最后一步中,我返回了 Mono,但是当请求通过 Controller 继续发送到服务时,它会抛出请求正文丢
上次我在考虑在我们的应用程序中正确使用记录器。例如,我有一个返回用户流的 Controller ,但在日志中,我看到“获取用户”日志正在被另一个线程而不是处理管道上的线程记录,但这是一个好方法吗? @
我正在使用带有 Netty 的 Spring Webflux (2.0.3.RELEASE) 并尝试了解服务器和 Web 客户端如何使用线程。我用 WebClient 编写了一些带有 http 调用链
我面临一个问题。我正在使用 Spring Webflux 并行调用一些 API。如果任何子线程面临任何问题,它需要记录请求。现在的问题是,用于记录一个普通的 POJO 类,其中有一个静态方法通过 Ap
我试图用 JSP 配置 Spring WebFlux。我在 Spring WebFlux 中没有看到任何支持 JSTL View 的 View 类。这是否意味着我们不能使用 Spring WebFlu
我正在寻找一种在响应式(Reactive) API 中使用计划任务的方法。 我知道它使用线程池,所以它与 webflux 组件不太兼容。 你有同等的人来做这项工作吗? 非常感谢 萨维留 最佳答案 有几
我曾经调用 HttpServletRequest.getRemoteAddr() 来获取客户端 ip。 我想知道如何通过 ServerWebExchange 获得它。 我最好的猜测是: serve
我想使用 spring webflux 以 react 方式流式传输文件。 我的端点应该看起来更具体什么是对象的类型? @GetMapping("/file") Flux file() { /
我无法让我的响应式(Reactive)代码以一种常见的方式处理错误。理想的方式是使用可重用的组件,我可以将其作为依赖项添加到其他项目中。 过去,我们使用 @RestControllerAdvise 通
我们正在尝试对 Webflux 使用react。我们将 Jaegar 与 Istio 用于检测目的。 Jaegar 非常了解 Spring MVC 端点,但似乎对 WebFlux 根本不起作用。 我正
我是响应式(Reactive)编程和 Spring WebFlux 的新手。我想让我的 App 1 通过 Flux 发布 Server Sent 事件,我的 App 2 持续监听它。 我希望 Flux
我正在我的项目中尝试新的 ReactiveQuerydslPredicateExecutor 但我找不到 findAll(Predicate, Pageable) 的方法,就像我在 QueryDslP
我正在使用 Spring WebFlux webclient 进行 REST 调用。我已经在 3000 上配置了连接超时毫秒,相应地: WebClient webClient = WebClient.
我想测量使用 WebFlux 进行的一些异步调用的长度。我一直在阅读各种来源,据我所知,@Timed 注释与 AspectJ 一起工作,基本上只是在方法调用之前启动一个计时器,然后停止它。这显然不适用
我有一个 Reactor Kafka 应用程序,它无限期地使用来自主题的消息。我需要公开一个健康检查 REST 端点,它可以指示此过程的健康状况——主要是想知道 Kafka 接收器通量序列是否已终止,
我是一名优秀的程序员,十分优秀!