[spring-projects/spring-boot]Spring 反应式、本机和 Hateoas 的 EntityModel 实例化问题

2024-05-08 603 views
0

你好,

这是我的配置:Springboot版本3.1.1(反应式),原生一代,MacOS ARM-M1,OpenJDK运行时环境GraalVM 17.0.7+8.1

编译时一切正常gradle bootJar

当我使用本机模式 ( gradle nativeCompile) 进行编译并运行应用程序时,我得到以下堆栈跟踪。

完整源代码可在此处获取:https://github.com/operrin/native-hateoas

谢谢

2023-06-24T11:38:49.087+02:00 ERROR 36501 --- [ctor-http-nio-2] a.w.r.e.AbstractErrorWebExceptionHandler : [7d988f12-1]  500 Server Error for HTTP GET "/intervenants"

org.springframework.core.codec.EncodingException: JSON encoding error: Error creating bean with name 'org.springframework.hateoas.EntityModel$MapSuppressingUnwrappingSerializer': Failed to instantiate [org.springframework.hateoas.EntityModel$MapSuppressingUnwrappingSerializer]: No default constructor found
    at org.springframework.http.codec.json.AbstractJackson2Encoder.encodeValue(AbstractJackson2Encoder.java:259) ~[intervenant-service:6.0.10]
    Suppressed: reactor.core.publisher.FluxOnAssembly$OnAssemblyException:
Error has been observed at the following site(s):
    *__checkpoint ⇢ Handler org.miage.intervenantservice.boundary.IntervenantRouter$$Lambda$33f6ea66eb22970ddf524a223f0b6a228e9aeae3@2155835a [DispatcherHandler]
    *__checkpoint ⇢ HTTP GET "/intervenants" [ExceptionHandlingWebHandler]
Original Stack Trace:
        at org.springframework.http.codec.json.AbstractJackson2Encoder.encodeValue(AbstractJackson2Encoder.java:259) ~[intervenant-service:6.0.10]
        at org.springframework.http.codec.json.AbstractJackson2Encoder.lambda$encode$0(AbstractJackson2Encoder.java:158) ~[intervenant-service:6.0.10]
        at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.onNext(FluxMapFuseable.java:113) ~[na:na]
        at reactor.core.publisher.MonoFlatMap$FlatMapMain.secondComplete(MonoFlatMap.java:245) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.MonoFlatMap$FlatMapInner.onNext(MonoFlatMap.java:305) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.onNext(FluxMapFuseable.java:129) ~[na:na]
        at reactor.core.publisher.Operators$ScalarSubscription.request(Operators.java:2545) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.request(FluxMapFuseable.java:171) ~[na:na]
        at reactor.core.publisher.MonoFlatMap$FlatMapInner.onSubscribe(MonoFlatMap.java:291) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.onSubscribe(FluxMapFuseable.java:96) ~[na:na]
        at reactor.core.publisher.MonoJust.subscribe(MonoJust.java:55) ~[na:na]
        at reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:64) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.MonoFlatMap$FlatMapMain.onNext(MonoFlatMap.java:165) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.Operators$BaseFluxToMonoOperator.completePossiblyEmpty(Operators.java:2071) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.MonoCollectList$MonoCollectListSubscriber.onComplete(MonoCollectList.java:118) ~[na:na]
        at reactor.core.publisher.FluxFlatMap$FlatMapMain.checkTerminated(FluxFlatMap.java:847) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.FluxFlatMap$FlatMapMain.drainLoop(FluxFlatMap.java:609) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.FluxFlatMap$FlatMapMain.drain(FluxFlatMap.java:589) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.FluxFlatMap$FlatMapMain.onComplete(FluxFlatMap.java:466) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.FluxUsingWhen$UsingWhenSubscriber.deferredComplete(FluxUsingWhen.java:392) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.FluxUsingWhen$CommitInner.onComplete(FluxUsingWhen.java:527) ~[na:na]
        at reactor.core.publisher.Operators.complete(Operators.java:137) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.MonoEmpty.subscribe(MonoEmpty.java:46) ~[na:na]
        at reactor.core.publisher.Mono.subscribe(Mono.java:4495) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.FluxUsingWhen$UsingWhenSubscriber.onComplete(FluxUsingWhen.java:384) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.FluxConcatMapNoPrefetch$FluxConcatMapNoPrefetchSubscriber.onComplete(FluxConcatMapNoPrefetch.java:240) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.Operators$MultiSubscriptionSubscriber.onComplete(Operators.java:2205) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.FluxUsingWhen$UsingWhenSubscriber.deferredComplete(FluxUsingWhen.java:392) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.FluxUsingWhen$CommitInner.onComplete(FluxUsingWhen.java:527) ~[na:na]
        at reactor.core.publisher.Operators$MultiSubscriptionSubscriber.onComplete(Operators.java:2205) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.FluxPeek$PeekSubscriber.onComplete(FluxPeek.java:260) ~[na:na]
        at reactor.core.publisher.Operators$MultiSubscriptionSubscriber.onComplete(Operators.java:2205) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.MonoIgnoreThen$ThenIgnoreMain.onComplete(MonoIgnoreThen.java:209) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.MonoIgnoreThen$ThenIgnoreMain.onComplete(MonoIgnoreThen.java:209) ~[intervenant-service:3.5.7]
        at reactor.pool.SimpleDequePool.maybeRecycleAndDrain(SimpleDequePool.java:531) ~[intervenant-service:1.0.0]
        at reactor.pool.SimpleDequePool$QueuePoolRecyclerInner.onComplete(SimpleDequePool.java:761) ~[intervenant-service:1.0.0]
        at reactor.core.publisher.Operators.complete(Operators.java:137) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.MonoEmpty.subscribe(MonoEmpty.java:46) ~[na:na]
        at reactor.core.publisher.Mono.subscribe(Mono.java:4495) ~[intervenant-service:3.5.7]
        at reactor.pool.SimpleDequePool$QueuePoolRecyclerMono.subscribe(SimpleDequePool.java:873) ~[na:na]
        at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:53) ~[na:na]
        at reactor.core.publisher.MonoIgnoreThen$ThenIgnoreMain.subscribeNext(MonoIgnoreThen.java:240) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.MonoIgnoreThen$ThenIgnoreMain.onComplete(MonoIgnoreThen.java:203) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.FluxPeek$PeekSubscriber.onComplete(FluxPeek.java:260) ~[na:na]
        at reactor.core.publisher.Operators.complete(Operators.java:137) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.MonoEmpty.subscribe(MonoEmpty.java:46) ~[na:na]
        at reactor.core.publisher.Mono.subscribe(Mono.java:4495) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.MonoIgnoreThen$ThenIgnoreMain.subscribeNext(MonoIgnoreThen.java:263) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.MonoIgnoreThen.subscribe(MonoIgnoreThen.java:51) ~[na:na]
        at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:53) ~[na:na]
        at reactor.core.publisher.MonoIgnoreThen$ThenIgnoreMain.subscribeNext(MonoIgnoreThen.java:240) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.MonoIgnoreThen$ThenIgnoreMain.onComplete(MonoIgnoreThen.java:203) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.MonoIgnoreElements$IgnoreElementsSubscriber.onComplete(MonoIgnoreElements.java:89) ~[na:na]
        at reactor.core.publisher.FluxHandle$HandleSubscriber.onComplete(FluxHandle.java:223) ~[na:na]
        at reactor.core.publisher.FluxSwitchIfEmpty$SwitchIfEmptySubscriber.onComplete(FluxSwitchIfEmpty.java:85) ~[na:na]
        at reactor.core.publisher.MonoCallable$MonoCallableSubscription.request(MonoCallable.java:159) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.Operators$MultiSubscriptionSubscriber.set(Operators.java:2341) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.Operators$MultiSubscriptionSubscriber.onSubscribe(Operators.java:2215) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.MonoCallable.subscribe(MonoCallable.java:48) ~[na:na]
        at reactor.core.publisher.Mono.subscribe(Mono.java:4495) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.MonoIgnoreThen$ThenIgnoreMain.subscribeNext(MonoIgnoreThen.java:263) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.MonoIgnoreThen.subscribe(MonoIgnoreThen.java:51) ~[na:na]
        at reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:64) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:53) ~[na:na]
        at reactor.core.publisher.Mono.subscribe(Mono.java:4495) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.FluxOnErrorResume$ResumeSubscriber.onError(FluxOnErrorResume.java:103) ~[na:na]
        at reactor.core.publisher.MonoIgnoreElements$IgnoreElementsSubscriber.onError(MonoIgnoreElements.java:84) ~[na:na]
        at reactor.core.publisher.FluxMap$MapSubscriber.onError(FluxMap.java:134) ~[na:na]
        at reactor.core.publisher.FluxFilter$FilterSubscriber.onError(FluxFilter.java:157) ~[na:na]
        at reactor.core.publisher.FluxFilter$FilterConditionalSubscriber.onError(FluxFilter.java:291) ~[na:na]
        at reactor.core.publisher.FluxMap$MapConditionalSubscriber.onError(FluxMap.java:265) ~[na:na]
        at reactor.core.publisher.Operators.error(Operators.java:198) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.MonoError.subscribe(MonoError.java:53) ~[na:na]
        at reactor.core.publisher.MonoDeferContextual.subscribe(MonoDeferContextual.java:55) ~[na:na]
        at reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:64) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:53) ~[na:na]
        at reactor.core.publisher.Mono.subscribe(Mono.java:4495) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.FluxUsingWhen$UsingWhenSubscriber.onComplete(FluxUsingWhen.java:384) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.FluxFlatMap$FlatMapMain.checkTerminated(FluxFlatMap.java:847) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.FluxFlatMap$FlatMapMain.drainLoop(FluxFlatMap.java:609) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.FluxFlatMap$FlatMapMain.drain(FluxFlatMap.java:589) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.FluxFlatMap$FlatMapMain.onComplete(FluxFlatMap.java:466) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.FluxMap$MapSubscriber.onComplete(FluxMap.java:144) ~[na:na]
        at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.onComplete(FluxMapFuseable.java:152) ~[na:na]
        at reactor.core.publisher.FluxIterable$IterableSubscription.slowPath(FluxIterable.java:357) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.FluxIterable$IterableSubscription.request(FluxIterable.java:294) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.request(FluxMapFuseable.java:171) ~[na:na]
        at reactor.core.publisher.FluxMap$MapSubscriber.request(FluxMap.java:164) ~[na:na]
        at reactor.core.publisher.FluxFlatMap$FlatMapMain.onSubscribe(FluxFlatMap.java:371) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.FluxMap$MapSubscriber.onSubscribe(FluxMap.java:92) ~[na:na]
        at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.onSubscribe(FluxMapFuseable.java:96) ~[na:na]
        at reactor.core.publisher.FluxIterable.subscribe(FluxIterable.java:201) ~[na:na]
        at reactor.core.publisher.FluxIterable.subscribe(FluxIterable.java:83) ~[na:na]
        at reactor.core.publisher.Flux.subscribe(Flux.java:8773) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.FluxFlatMap.trySubscribeScalarMap(FluxFlatMap.java:200) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.FluxFlatMap.subscribeOrReturn(FluxFlatMap.java:93) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.Flux.subscribe(Flux.java:8759) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.FluxUsingWhen$ResourceSubscriber.onNext(FluxUsingWhen.java:195) ~[na:na]
        at reactor.core.publisher.FluxMap$MapSubscriber.onNext(FluxMap.java:122) ~[na:na]
        at reactor.core.publisher.FluxOnErrorResume$ResumeSubscriber.onNext(FluxOnErrorResume.java:79) ~[na:na]
        at reactor.core.publisher.FluxOnErrorResume$ResumeSubscriber.onNext(FluxOnErrorResume.java:79) ~[na:na]
        at reactor.core.publisher.FluxRetry$RetrySubscriber.onNext(FluxRetry.java:87) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.MonoFlatMap$FlatMapMain.secondComplete(MonoFlatMap.java:245) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.MonoFlatMap$FlatMapInner.onNext(MonoFlatMap.java:305) ~[intervenant-service:3.5.7]
        at io.r2dbc.pool.MonoDiscardOnCancel$MonoDiscardOnCancelSubscriber.onNext(MonoDiscardOnCancel.java:92) ~[na:na]
        at reactor.core.publisher.FluxOnErrorResume$ResumeSubscriber.onNext(FluxOnErrorResume.java:79) ~[na:na]
        at reactor.core.publisher.MonoIgnoreThen$ThenIgnoreMain.complete(MonoIgnoreThen.java:292) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.MonoIgnoreThen$ThenIgnoreMain.onNext(MonoIgnoreThen.java:187) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.MonoIgnoreThen$ThenIgnoreMain.subscribeNext(MonoIgnoreThen.java:236) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.MonoIgnoreThen$ThenIgnoreMain.onComplete(MonoIgnoreThen.java:203) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.MonoIgnoreElements$IgnoreElementsSubscriber.onComplete(MonoIgnoreElements.java:89) ~[na:na]
        at reactor.core.publisher.FluxHandle$HandleSubscriber.onComplete(FluxHandle.java:223) ~[na:na]
        at reactor.core.publisher.FluxSwitchIfEmpty$SwitchIfEmptySubscriber.onComplete(FluxSwitchIfEmpty.java:85) ~[na:na]
        at reactor.core.publisher.MonoCallable$MonoCallableSubscription.request(MonoCallable.java:159) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.Operators$MultiSubscriptionSubscriber.set(Operators.java:2341) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.Operators$MultiSubscriptionSubscriber.onSubscribe(Operators.java:2215) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.MonoCallable.subscribe(MonoCallable.java:48) ~[na:na]
        at reactor.core.publisher.Mono.subscribe(Mono.java:4495) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.MonoIgnoreThen$ThenIgnoreMain.subscribeNext(MonoIgnoreThen.java:263) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.MonoIgnoreThen.subscribe(MonoIgnoreThen.java:51) ~[na:na]
        at reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:64) ~[intervenant-service:3.5.7]
        at io.r2dbc.pool.MonoDiscardOnCancel.subscribe(MonoDiscardOnCancel.java:50) ~[na:na]
        at reactor.core.publisher.MonoFlatMap$FlatMapMain.onNext(MonoFlatMap.java:165) ~[intervenant-service:3.5.7]
        at reactor.pool.AbstractPool$Borrower.deliver(AbstractPool.java:467) ~[intervenant-service:1.0.0]
        at reactor.pool.SimpleDequePool.lambda$drainLoop$8(SimpleDequePool.java:368) ~[intervenant-service:1.0.0]
        at reactor.core.scheduler.ImmediateScheduler.schedule(ImmediateScheduler.java:52) ~[na:na]
        at reactor.pool.SimpleDequePool.drainLoop(SimpleDequePool.java:368) ~[intervenant-service:1.0.0]
        at reactor.pool.SimpleDequePool.pendingOffer(SimpleDequePool.java:598) ~[intervenant-service:1.0.0]
        at reactor.pool.SimpleDequePool.doAcquire(SimpleDequePool.java:294) ~[intervenant-service:1.0.0]
        at reactor.pool.AbstractPool$Borrower.request(AbstractPool.java:430) ~[intervenant-service:1.0.0]
        at reactor.core.publisher.MonoFlatMap$FlatMapMain.request(MonoFlatMap.java:194) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.Operators$MultiSubscriptionSubscriber.set(Operators.java:2341) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.Operators$MultiSubscriptionSubscriber.onSubscribe(Operators.java:2215) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.MonoFlatMap$FlatMapMain.onSubscribe(MonoFlatMap.java:117) ~[intervenant-service:3.5.7]
        at reactor.pool.SimpleDequePool$QueueBorrowerMono.subscribe(SimpleDequePool.java:716) ~[na:na]
        at reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:64) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:53) ~[na:na]
        at reactor.core.publisher.FluxRetry$RetrySubscriber.resubscribe(FluxRetry.java:117) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.MonoRetry.subscribeOrReturn(MonoRetry.java:50) ~[na:na]
        at reactor.core.publisher.Mono.subscribe(Mono.java:4480) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.FluxOnErrorResume$ResumeSubscriber.onError(FluxOnErrorResume.java:103) ~[na:na]
        at reactor.core.publisher.MonoFlatMap$FlatMapMain.onError(MonoFlatMap.java:180) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.FluxMap$MapSubscriber.onError(FluxMap.java:134) ~[na:na]
        at reactor.core.publisher.Operators.error(Operators.java:198) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.MonoError.subscribe(MonoError.java:53) ~[na:na]
        at reactor.core.publisher.MonoDeferContextual.subscribe(MonoDeferContextual.java:55) ~[na:na]
        at reactor.core.publisher.Mono.subscribe(Mono.java:4495) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.FluxUsingWhen.subscribe(FluxUsingWhen.java:104) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.Flux.subscribe(Flux.java:8773) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.FluxUsingWhen.subscribe(FluxUsingWhen.java:94) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.FluxFromMonoOperator.subscribe(FluxFromMonoOperator.java:83) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.FluxDeferContextual.subscribe(FluxDeferContextual.java:57) ~[na:na]
        at reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:64) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.MonoFlatMap$FlatMapMain.onNext(MonoFlatMap.java:165) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.onNext(FluxMapFuseable.java:129) ~[na:na]
        at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.onNext(FluxMapFuseable.java:129) ~[na:na]
        at reactor.core.publisher.Operators$ScalarSubscription.request(Operators.java:2545) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.request(FluxMapFuseable.java:171) ~[na:na]
        at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.request(FluxMapFuseable.java:171) ~[na:na]
        at reactor.core.publisher.MonoFlatMap$FlatMapMain.request(MonoFlatMap.java:194) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.MonoFlatMap$FlatMapInner.onSubscribe(MonoFlatMap.java:291) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.MonoFlatMap$FlatMapMain.onSubscribe(MonoFlatMap.java:117) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.onSubscribe(FluxMapFuseable.java:96) ~[na:na]
        at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.onSubscribe(FluxMapFuseable.java:96) ~[na:na]
        at reactor.core.publisher.MonoJust.subscribe(MonoJust.java:55) ~[na:na]
        at reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:64) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.MonoFlatMap$FlatMapMain.onNext(MonoFlatMap.java:165) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.FluxOnErrorResume$ResumeSubscriber.onNext(FluxOnErrorResume.java:79) ~[na:na]
        at reactor.core.publisher.FluxSwitchIfEmpty$SwitchIfEmptySubscriber.onNext(FluxSwitchIfEmpty.java:74) ~[na:na]
        at reactor.core.publisher.MonoNext$NextSubscriber.onNext(MonoNext.java:82) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.FluxConcatMapNoPrefetch$FluxConcatMapNoPrefetchSubscriber.innerNext(FluxConcatMapNoPrefetch.java:258) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.FluxConcatMap$ConcatMapInner.onNext(FluxConcatMap.java:863) ~[na:na]
        at reactor.core.publisher.FluxMap$MapSubscriber.onNext(FluxMap.java:122) ~[na:na]
        at reactor.core.publisher.FluxPeek$PeekSubscriber.onNext(FluxPeek.java:200) ~[na:na]
        at reactor.core.publisher.MonoNext$NextSubscriber.onNext(MonoNext.java:82) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.FluxConcatArray$ConcatArraySubscriber.onNext(FluxConcatArray.java:201) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.Operators$ScalarSubscription.request(Operators.java:2545) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.FluxConcatArray$ConcatArraySubscriber.request(FluxConcatArray.java:276) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.MonoNext$NextSubscriber.request(MonoNext.java:108) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.FluxPeek$PeekSubscriber.request(FluxPeek.java:138) ~[na:na]
        at reactor.core.publisher.FluxMap$MapSubscriber.request(FluxMap.java:164) ~[na:na]
        at reactor.core.publisher.Operators$MultiSubscriptionSubscriber.request(Operators.java:2305) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.FluxConcatMapNoPrefetch$FluxConcatMapNoPrefetchSubscriber.request(FluxConcatMapNoPrefetch.java:338) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.MonoNext$NextSubscriber.request(MonoNext.java:108) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.Operators$MultiSubscriptionSubscriber.set(Operators.java:2341) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.Operators$MultiSubscriptionSubscriber.onSubscribe(Operators.java:2215) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.MonoNext$NextSubscriber.onSubscribe(MonoNext.java:70) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.FluxConcatMapNoPrefetch$FluxConcatMapNoPrefetchSubscriber.onSubscribe(FluxConcatMapNoPrefetch.java:164) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.FluxIterable.subscribe(FluxIterable.java:201) ~[na:na]
        at reactor.core.publisher.FluxIterable.subscribe(FluxIterable.java:83) ~[na:na]
        at reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:64) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:53) ~[na:na]
        at reactor.core.publisher.Mono.subscribe(Mono.java:4495) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.MonoIgnoreThen$ThenIgnoreMain.subscribeNext(MonoIgnoreThen.java:263) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.MonoIgnoreThen.subscribe(MonoIgnoreThen.java:51) ~[na:na]
        at reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:64) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.MonoDeferContextual.subscribe(MonoDeferContextual.java:55) ~[na:na]
        at reactor.netty.http.server.HttpServer$HttpServerHandle.onStateChange(HttpServer.java:1006) ~[na:na]
        at reactor.netty.ReactorNetty$CompositeConnectionObserver.onStateChange(ReactorNetty.java:710) ~[na:na]
        at reactor.netty.transport.ServerTransport$ChildObserver.onStateChange(ServerTransport.java:481) ~[na:na]
        at reactor.netty.http.server.HttpServerOperations.onInboundNext(HttpServerOperations.java:621) ~[intervenant-service:1.1.8]
        at reactor.netty.channel.ChannelOperationsHandler.channelRead(ChannelOperationsHandler.java:113) ~[intervenant-service:1.1.8]
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:444) ~[intervenant-service:4.1.94.Final]
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420) ~[intervenant-service:4.1.94.Final]
        at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:412) ~[intervenant-service:4.1.94.Final]
        at reactor.netty.http.server.HttpTrafficHandler.channelRead(HttpTrafficHandler.java:230) ~[intervenant-service:1.1.8]
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:442) ~[intervenant-service:4.1.94.Final]
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420) ~[intervenant-service:4.1.94.Final]
        at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:412) ~[intervenant-service:4.1.94.Final]
        at io.netty.channel.CombinedChannelDuplexHandler$DelegatingChannelHandlerContext.fireChannelRead(CombinedChannelDuplexHandler.java:436) ~[intervenant-service:4.1.94.Final]
        at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:346) ~[intervenant-service:4.1.94.Final]
        at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:318) ~[intervenant-service:4.1.94.Final]
        at io.netty.channel.CombinedChannelDuplexHandler.channelRead(CombinedChannelDuplexHandler.java:251) ~[intervenant-service:4.1.94.Final]
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:442) ~[intervenant-service:4.1.94.Final]
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420) ~[intervenant-service:4.1.94.Final]
        at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:412) ~[intervenant-service:4.1.94.Final]
        at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1410) ~[intervenant-service:4.1.94.Final]
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:440) ~[intervenant-service:4.1.94.Final]
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420) ~[intervenant-service:4.1.94.Final]
        at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:919) ~[intervenant-service:4.1.94.Final]
        at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:166) ~[intervenant-service:4.1.94.Final]
        at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:788) ~[na:na]
        at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:724) ~[na:na]
        at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:650) ~[na:na]
        at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:562) ~[na:na]
        at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:997) ~[na:na]
        at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74) ~[na:na]
        at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30) ~[na:na]
        at java.base@17.0.7/java.lang.Thread.run(Thread.java:833) ~[intervenant-service:na]
        at org.graalvm.nativeimage.builder/com.oracle.svm.core.thread.PlatformThreads.threadStartRoutine(PlatformThreads.java:807) ~[intervenant-service:na]
        at org.graalvm.nativeimage.builder/com.oracle.svm.core.posix.thread.PosixPlatformThreads.pthreadStartRoutine(PosixPlatformThreads.java:210) ~[na:na]

回答

8

使用 WebFlux.Fn 意味着方法签名中没有有关将序列化为 JSON 的类型的信息。您可以使用@RegisterReflectionForBinding来提供有关需要序列化为 json 的类型的信息。例如,添加@RegisterReflectionForBinding(EntityModel.class)getIntervenantById应该可以解决问题:

$ http :8082/intervenants 
HTTP/1.1 200 OK
Content-Length: 175
Content-Type: application/json

{
    "content": [
        {
            "id": "de7d9052-4961-4b4f-938a-3cd12cbe1f82",
            "links": [
                {}
            ],
            "nom": "Marchal"
        },
        {
            "id": "425e7701-02c6-4de3-9333-a2459eece1c8",
            "links": [
                {}
            ],
            "nom": "Dubois"
        }
    ],
    "links": [
        {}
    ]
}

$ http :8082/intervenants/de7d9052-4961-4b4f-938a-3cd12cbe1f82
HTTP/1.1 200 OK
Content-Length: 77
Content-Type: application/json

{
    "id": "de7d9052-4961-4b4f-938a-3cd12cbe1f82",
    "links": [
        {},
        {}
    ],
    "nom": "Marchal"
}
8

这将在 Spring HATEOAS 2.0.5、2.1.1 和 2.2 M1 中修复。即,它将包含在下一个 Spring Boot 3.x 错误修复版本中。已验证修复以使原始再现器正常工作。

2

谢谢。为了完全正确,我必须添加以下注释: @RegisterReflectionForBinding({Link.class, EntityModel.class})

EntityModel.class避免 MapSuppressingUnwrappingSerializer 异常。并Link.class获取链接的正确值(否则,它们是空的)

0

我必须对您的示例项目发出什么请求才能触发缺少的元数据LinkHypermediaTypeAotProcessor实际上应该已经添加了该元数据,并且我们有 AOT 冒烟测试,显示链接在本机图像中正确呈现。 ?

2

当使用 编译时gradle bootJar,我发出请求http :8082/intervenants并得到:

HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 538

{
    "content": [
        {
            "id": "de7d9052-4961-4b4f-938a-3cd12cbe1f82",
            "nom": "Marchal",
            "prenom": "Thomas",
            "commune": "Nancy",
            "codepostal": "54000",
            "links": [
                {
                    "rel": "self",
                    "href": "http://localhost:8082/intervenants/de7d9052-4961-4b4f-938a-3cd12cbe1f82"
                }
            ]
        },
        {
            "id": "425e7701-02c6-4de3-9333-a2459eece1c8",
            "nom": "Dubois",
            "prenom": "Anne",
            "commune": "Grenoble",
            "codepostal": "38000",
            "links": [
                {
                    "rel": "self",
                    "href": "http://localhost:8082/intervenants/425e7701-02c6-4de3-9333-a2459eece1c8"
                }
            ]
        }
    ],
    "links": [
        {
            "rel": "collection",
            "href": "http://localhost:8082/intervenants"
        }
    ]
}

链接是正确的。

使用@RegisterReflectionForBinding(EntityModel.class),当用 编译时gradle nativeCompile,我得到:

HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 290

{
    "content": [
        {
            "id": "de7d9052-4961-4b4f-938a-3cd12cbe1f82",
            "nom": "Marchal",
            "prenom": "Thomas",
            "commune": "Nancy",
            "codepostal": "54000",
            "links": [
                {}
            ]
        },
        {
            "id": "425e7701-02c6-4de3-9333-a2459eece1c8",
            "nom": "Dubois",
            "prenom": "Anne",
            "commune": "Grenoble",
            "codepostal": "38000",
            "links": [
                {}
            ]
        }
    ],
    "links": [
        {}
    ]
}

链接为空。

使用@RegisterReflectionForBinding({Link.class,EntityModel.class}),当用 编译时gradle nativeCompile,链接是正确的。

9

谢谢,我去看看。

3

您确定是Link,而不是Links(尾随 s)吗?看来问题是Links未注册反射和您的项目未使用正确的超媒体媒体类型而仅使用的组合application/json。这将导致EntityModel按原样渲染,因此我们为 HAL 等官方超媒体媒体类型设置的自定义 Jackson 指令将生效。我只能建议切换到其中一种,因为渲染任何内容,但官方不支持。

我将继续并Links在 spring-projects/spring-hateoas#1981 (以及相应的后端口)的上下文中增强反射注册。但话又说回来,如果您愿意返回application/hal+json或任何其他受支持且正确指定的超媒体类型,您应该会看到此工作。

8

谢谢。它适用于Link.class.

关于MediaType,我只是尝试以下修改:

    @RegisterReflectionForBinding(EntityModel.class)
    public Mono<ServerResponse> getIntervenantById(ServerRequest request) {
        var collectionLink = Link.of(deleteIdInUri(request.uri().toString(), request.pathVariable("id")))
                .withRel("collection");
        var selfLink = Link.of(request.uri().toString()).withSelfRel();
        return this.is.getIntervenant(request.pathVariable("id"))
                .flatMap(r -> Mono.just(EntityModel.of(r, selfLink, collectionLink)))
                .flatMap(r -> ServerResponse.ok().contentType(MediaTypes.HAL_JSON).bodyValue(r))
                .switchIfEmpty(ServerResponse.notFound().build());
    }

结果是空链接。

2

抱歉,我仔细阅读了您的消息,并且我添加了配置类并使用了注释@EnableHypermediaSupport,并且链接正确呈现。

我很抱歉

4

不用道歉。这非常有帮助。我刚刚意识到 Spring HATEOAS 自动配置在 Web.fn 场景中未激活。我想知道是否应该使用位于 WebFlux 工件中的触发器类型来解决这个问题? /抄送@wilkinsona

6

重新阅读 #16020 中的对话后,我想我将继续将基本 Spring HATEOAS 类型的 AOT 反射提示生成与涵盖生成单个媒体类型的 Jackson 模型类型的生成分开。这样,即使用户不想使用正确的、受支持的超媒体类型,我们也可以让 HATEOAS 在 GraalVM 上开箱即用。即使我们不建议这样做,我认为合理的工作也比部分失败要好。

@EnableHypermediaSupport我还将在参考文档中提到需要明确使用WebFlux / Web.fn 设置。

7

为了结束这个问题,我更新了 spring-projects/spring-hateoas#1981 的修复,以确保所有基本的 HATEOAS 类型都注册为反射。也就是说,我仍然无法为您的 Web.fn 设置提供正确的 HAL 渲染。我得单独调查一下。