微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

使用 Thymeleaf 在 Spring Webflux 中使用 Blockhound 的异常

如何解决使用 Thymeleaf 在 Spring Webflux 中使用 Blockhound 的异常

在我的 Spring Boot 应用程序中为生产启用 Blockhound 时,每当我尝试处理从 thymeleaf 返回视图的请求时,blockhound 都会抛出异常(可能是由于从磁盘读取模板文件时发生阻塞):

异常:

reactor.blockhound.BlockingOperationError: Blocking call! java.io.RandomAccessFile#readBytes
at java.base/java.io.RandomAccessFile.readBytes(RandomAccessFile.java) ~[na:na]
at java.base/java.io.RandomAccessFile.read(RandomAccessFile.java:406) ~[na:na]
at java.base/java.io.RandomAccessFile.readFully(RandomAccessFile.java:470) ~[na:na]
at java.base/java.util.zip.ZipFile$Source.readFullyAt(ZipFile.java:1304) ~[na:na]
at java.base/java.util.zip.ZipFile$ZipFileInputStream.initDataOffset(ZipFile.java:998) ~[na:na]
at java.base/java.util.zip.ZipFile$ZipFileInputStream.read(ZipFile.java:1013) ~[na:na]
at java.base/java.util.zip.ZipFile$ZipFileInflaterInputStream.fill(ZipFile.java:468) ~[na:na]
at java.base/java.util.zip.InflaterInputStream.read(InflaterInputStream.java:159) ~[na:na]
at java.base/java.io.FilterInputStream.read(FilterInputStream.java:133) ~[na:na]
at java.base/java.io.FilterInputStream.read(FilterInputStream.java:107) ~[na:na]
at java.base/java.util.Properties$LineReader.readLine(Properties.java:499) ~[na:na]
at java.base/java.util.Properties.load0(Properties.java:415) ~[na:na]
at java.base/java.util.Properties.load(Properties.java:404) ~[na:na]
at org.springframework.web.util.HtmlCharacterEntityReferences.<init>(HtmlCharacterEntityReferences.java:75) ~[spring-web-5.3.3.jar:5.3.3]
at org.springframework.web.util.HtmlUtils.<clinit>(HtmlUtils.java:46) ~[spring-web-5.3.3.jar:5.3.3]
at org.springframework.boot.autoconfigure.web.reactive.error.AbstractErrorWebExceptionHandler.htmlEscape(AbstractErrorWebExceptionHandler.java:295) ~[spring-boot-autoconfigure-2.4.2.jar:2.4.2]
at org.springframework.boot.autoconfigure.web.reactive.error.AbstractErrorWebExceptionHandler.renderDefaultErrorView(AbstractErrorWebExceptionHandler.java:282) ~[spring-boot-autoconfigure-2.4.2.jar:2.4.2]
at org.springframework.boot.autoconfigure.web.reactive.error.DefaultErrorWebExceptionHandler.renderErrorView(DefaultErrorWebExceptionHandler.java:141) ~[spring-boot-autoconfigure-2.4.2.jar:2.4.2]
at org.springframework.boot.autoconfigure.web.reactive.error.AbstractErrorWebExceptionHandler.lambda$handle$0(AbstractErrorWebExceptionHandler.java:326) ~[spring-boot-autoconfigure-2.4.2.jar:2.4.2]
at reactor.core.publisher.MonoFlatMap$FlatMapMain.onNext(MonoFlatMap.java:125) ~[reactor-core-3.4.2.jar:3.4.2]
at reactor.core.publisher.FluxSwitchIfEmpty$SwitchIfEmptySubscriber.onNext(FluxSwitchIfEmpty.java:73) ~[reactor-core-3.4.2.jar:3.4.2]
at reactor.core.publisher.MonoNext$NextSubscriber.onNext(MonoNext.java:82) ~[reactor-core-3.4.2.jar:3.4.2]
at reactor.core.publisher.FluxConcatArray$ConcatArraySubscriber.onNext(FluxConcatArray.java:177) ~[reactor-core-3.4.2.jar:3.4.2]
at reactor.core.publisher.Operators$Scalarsubscription.request(Operators.java:2359) ~[reactor-core-3.4.2.jar:3.4.2]
at reactor.core.publisher.Operators$MultiSubscriptionSubscriber.set(Operators.java:2167) ~[reactor-core-3.4.2.jar:3.4.2]
at reactor.core.publisher.Operators$MultiSubscriptionSubscriber.onSubscribe(Operators.java:2041) ~[reactor-core-3.4.2.jar:3.4.2]
at reactor.core.publisher.MonoJust.subscribe(MonoJust.java:54) ~[reactor-core-3.4.2.jar:3.4.2]
at reactor.core.publisher.Mono.subscribe(Mono.java:4046) ~[reactor-core-3.4.2.jar:3.4.2]
at reactor.core.publisher.FluxConcatArray$ConcatArraySubscriber.onComplete(FluxConcatArray.java:208) ~[reactor-core-3.4.2.jar:3.4.2]
at reactor.core.publisher.FluxConcatArray.subscribe(FluxConcatArray.java:80) ~[reactor-core-3.4.2.jar:3.4.2]
at reactor.core.publisher.Mono.subscribe(Mono.java:4046) ~[reactor-core-3.4.2.jar:3.4.2]
at reactor.core.publisher.FluxOnErrorResume$ResumeSubscriber.onError(FluxOnErrorResume.java:103) ~[reactor-core-3.4.2.jar:3.4.2]
at reactor.core.publisher.FluxOnErrorResume$ResumeSubscriber.onError(FluxOnErrorResume.java:106) ~[reactor-core-3.4.2.jar:3.4.2]
at reactor.core.publisher.FluxOnAssembly$OnAssemblySubscriber.onError(FluxOnAssembly.java:392) ~[reactor-core-3.4.2.jar:3.4.2]
at reactor.core.publisher.Operators.error(Operators.java:196) ~[reactor-core-3.4.2.jar:3.4.2]
at reactor.core.publisher.MonoError.subscribe(MonoError.java:52) ~[reactor-core-3.4.2.jar:3.4.2]
at reactor.core.publisher.Mono.subscribe(Mono.java:4046) ~[reactor-core-3.4.2.jar:3.4.2]
at reactor.core.publisher.FluxOnErrorResume$ResumeSubscriber.onError(FluxOnErrorResume.java:103) ~[reactor-core-3.4.2.jar:3.4.2]
at reactor.core.publisher.FluxOnAssembly$OnAssemblySubscriber.onError(FluxOnAssembly.java:392) ~[reactor-core-3.4.2.jar:3.4.2]
at reactor.core.publisher.MonoFlatMap$FlatMapMain.secondError(MonoFlatMap.java:192) ~[reactor-core-3.4.2.jar:3.4.2]
at reactor.core.publisher.MonoFlatMap$FlatMapInner.onError(MonoFlatMap.java:259) ~[reactor-core-3.4.2.jar:3.4.2]
at reactor.core.publisher.FluxOnErrorResume$ResumeSubscriber.onError(FluxOnErrorResume.java:106) ~[reactor-core-3.4.2.jar:3.4.2]
at reactor.core.publisher.Operators.error(Operators.java:196) ~[reactor-core-3.4.2.jar:3.4.2]
at reactor.core.publisher.FluxFlatMap.trySubscribeScalarMap(FluxFlatMap.java:134) ~[reactor-core-3.4.2.jar:3.4.2]
at reactor.core.publisher.MonoFlatMap.subscribeOrReturn(MonoFlatMap.java:53) ~[reactor-core-3.4.2.jar:3.4.2]
at reactor.core.publisher.Mono.subscribe(Mono.java:4031) ~[reactor-core-3.4.2.jar:3.4.2]
at reactor.core.publisher.FluxOnErrorResume$ResumeSubscriber.onError(FluxOnErrorResume.java:103) ~[reactor-core-3.4.2.jar:3.4.2]
at reactor.core.publisher.FluxOnAssembly$OnAssemblySubscriber.onError(FluxOnAssembly.java:392) ~[reactor-core-3.4.2.jar:3.4.2]
at reactor.core.publisher.MonoFlatMap$FlatMapMain.secondError(MonoFlatMap.java:192) ~[reactor-core-3.4.2.jar:3.4.2]
at reactor.core.publisher.MonoFlatMap$FlatMapInner.onError(MonoFlatMap.java:259) ~[reactor-core-3.4.2.jar:3.4.2]
at reactor.core.publisher.MonoFlatMap$FlatMapMain.onNext(MonoFlatMap.java:129) ~[reactor-core-3.4.2.jar:3.4.2]
at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.onNext(FluxMapFuseable.java:127) ~[reactor-core-3.4.2.jar:3.4.2]
at reactor.core.publisher.Operators$MonoSubscriber.complete(Operators.java:1789) ~[reactor-core-3.4.2.jar:3.4.2]
at reactor.core.publisher.MonoCollectList$MonoCollectListSubscriber.onComplete(MonoCollectList.java:128) ~[reactor-core-3.4.2.jar:3.4.2]
at reactor.core.publisher.FluxConcatMap$ConcatMapImmediate.drain(FluxConcatMap.java:366) ~[reactor-core-3.4.2.jar:3.4.2]
at reactor.core.publisher.FluxConcatMap$ConcatMapImmediate.onSubscribe(FluxConcatMap.java:218) ~[reactor-core-3.4.2.jar:3.4.2]
at reactor.core.publisher.FluxIterable.subscribe(FluxIterable.java:164) ~[reactor-core-3.4.2.jar:3.4.2]
at reactor.core.publisher.FluxIterable.subscribe(FluxIterable.java:86) ~[reactor-core-3.4.2.jar:3.4.2]
at reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:64) ~[reactor-core-3.4.2.jar:3.4.2]
at reactor.core.publisher.MonoFlatMap$FlatMapMain.onNext(MonoFlatMap.java:157) ~[reactor-core-3.4.2.jar:3.4.2]
at reactor.core.publisher.FluxSwitchIfEmpty$SwitchIfEmptySubscriber.onNext(FluxSwitchIfEmpty.java:73) ~[reactor-core-3.4.2.jar:3.4.2]
at reactor.core.publisher.Operators$Scalarsubscription.request(Operators.java:2359) ~[reactor-core-3.4.2.jar:3.4.2]
at reactor.core.publisher.Operators$MultiSubscriptionSubscriber.set(Operators.java:2167) ~[reactor-core-3.4.2.jar:3.4.2]
at reactor.core.publisher.Operators$MultiSubscriptionSubscriber.onSubscribe(Operators.java:2041) ~[reactor-core-3.4.2.jar:3.4.2]
at reactor.core.publisher.MonoJust.subscribe(MonoJust.java:54) ~[reactor-core-3.4.2.jar:3.4.2]
at reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:64) ~[reactor-core-3.4.2.jar:3.4.2]
at reactor.core.publisher.MonoFlatMap$FlatMapMain.onNext(MonoFlatMap.java:157) ~[reactor-core-3.4.2.jar:3.4.2]
at reactor.core.publisher.Operators$MonoSubscriber.complete(Operators.java:1789) ~[reactor-core-3.4.2.jar:3.4.2]
at reactor.core.publisher.MonoFlatMap$FlatMapInner.onNext(MonoFlatMap.java:249) ~[reactor-core-3.4.2.jar:3.4.2]
at reactor.core.publisher.FluxOnErrorResume$ResumeSubscriber.onNext(FluxOnErrorResume.java:79) ~[reactor-core-3.4.2.jar:3.4.2]
at reactor.core.publisher.FluxPeekFuseable$PeekFuseableSubscriber.onNext(FluxPeekFuseable.java:210) ~[reactor-core-3.4.2.jar:3.4.2]
at reactor.core.publisher.FluxPeekFuseable$PeekFuseableSubscriber.onNext(FluxPeekFuseable.java:210) ~[reactor-core-3.4.2.jar:3.4.2]
at reactor.core.publisher.Operators$MonoSubscriber.complete(Operators.java:1789) ~[reactor-core-3.4.2.jar:3.4.2]
at reactor.core.publisher.MonoIgnoreThen$ThenAcceptInner.onNext(MonoIgnoreThen.java:305) ~[reactor-core-3.4.2.jar:3.4.2]
at reactor.core.publisher.Operators$MonoSubscriber.complete(Operators.java:1789) ~[reactor-core-3.4.2.jar:3.4.2]
at reactor.core.publisher.MonoFlatMap$FlatMapMain.onNext(MonoFlatMap.java:151) ~[reactor-core-3.4.2.jar:3.4.2]
at reactor.core.publisher.Operators$MonoSubscriber.complete(Operators.java:1789) ~[reactor-core-3.4.2.jar:3.4.2]
at reactor.core.publisher.MonoZip$ZipCoordinator.signal(MonoZip.java:251) ~[reactor-core-3.4.2.jar:3.4.2]
at reactor.core.publisher.MonoZip$ZipInner.onNext(MonoZip.java:336) ~[reactor-core-3.4.2.jar:3.4.2]
at reactor.core.publisher.MonopeekTerminal$MonoTerminalPeekSubscriber.onNext(MonopeekTerminal.java:180) ~[reactor-core-3.4.2.jar:3.4.2]
at reactor.core.publisher.Operators$Scalarsubscription.request(Operators.java:2359) ~[reactor-core-3.4.2.jar:3.4.2]
at reactor.core.publisher.MonopeekTerminal$MonoTerminalPeekSubscriber.request(MonopeekTerminal.java:139) ~[reactor-core-3.4.2.jar:3.4.2]
at reactor.core.publisher.MonoZip$ZipInner.onSubscribe(MonoZip.java:325) ~[reactor-core-3.4.2.jar:3.4.2]
at reactor.core.publisher.MonopeekTerminal$MonoTerminalPeekSubscriber.onSubscribe(MonopeekTerminal.java:152) ~[reactor-core-3.4.2.jar:3.4.2]
at reactor.core.publisher.MonoJust.subscribe(MonoJust.java:54) ~[reactor-core-3.4.2.jar:3.4.2]
at reactor.core.publisher.Mono.subscribe(Mono.java:4046) ~[reactor-core-3.4.2.jar:3.4.2]
at reactor.core.publisher.MonoZip.subscribe(MonoZip.java:128) ~[reactor-core-3.4.2.jar:3.4.2]
at reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:64) ~[reactor-core-3.4.2.jar:3.4.2]
at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:52) ~[reactor-core-3.4.2.jar:3.4.2]
at reactor.core.publisher.MonoIgnoreThen$ThenIgnoreMain.drain(MonoIgnoreThen.java:154) ~[reactor-core-3.4.2.jar:3.4.2]
at reactor.core.publisher.MonoIgnoreThen.subscribe(MonoIgnoreThen.java:56) ~[reactor-core-3.4.2.jar:3.4.2]
at reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:64) ~[reactor-core-3.4.2.jar:3.4.2]
at reactor.core.publisher.MonoFlatMap$FlatMapMain.onNext(MonoFlatMap.java:157) ~[reactor-core-3.4.2.jar:3.4.2]
at reactor.core.publisher.FluxSwitchIfEmpty$SwitchIfEmptySubscriber.onNext(FluxSwitchIfEmpty.java:73) ~[reactor-core-3.4.2.jar:3.4.2]
at reactor.core.publisher.MonoNext$NextSubscriber.onNext(MonoNext.java:82) ~[reactor-core-3.4.2.jar:3.4.2]
at reactor.core.publisher.FluxConcatMap$ConcatMapImmediate.innerNext(FluxConcatMap.java:281) ~[reactor-core-3.4.2.jar:3.4.2]
at reactor.core.publisher.FluxConcatMap$ConcatMapInner.onNext(FluxConcatMap.java:860) ~[reactor-core-3.4.2.jar:3.4.2]
at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.onNext(FluxMapFuseable.java:127) ~[reactor-core-3.4.2.jar:3.4.2]
at reactor.core.publisher.MonopeekTerminal$MonoTerminalPeekSubscriber.onNext(MonopeekTerminal.java:180) ~[reactor-core-3.4.2.jar:3.4.2]
at reactor.core.publisher.Operators$Scalarsubscription.request(Operators.java:2359) ~[reactor-core-3.4.2.jar:3.4.2]
at reactor.core.publisher.MonopeekTerminal$MonoTerminalPeekSubscriber.request(MonopeekTerminal.java:139) ~[reactor-core-3.4.2.jar:3.4.2]
at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.request(FluxMapFuseable.java:169) ~[reactor-core-3.4.2.jar:3.4.2]
at reactor.core.publisher.Operators$MultiSubscriptionSubscriber.set(Operators.java:2167) ~[reactor-core-3.4.2.jar:3.4.2]
at reactor.core.publisher.Operators$MultiSubscriptionSubscriber.onSubscribe(Operators.java:2041) ~[reactor-core-3.4.2.jar:3.4.2]
at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.onSubscribe(FluxMapFuseable.java:96) ~[reactor-core-3.4.2.jar:3.4.2]
at reactor.core.publisher.MonopeekTerminal$MonoTerminalPeekSubscriber.onSubscribe(MonopeekTerminal.java:152) ~[reactor-core-3.4.2.jar:3.4.2]
at reactor.core.publisher.MonoJust.subscribe(MonoJust.java:54) ~[reactor-core-3.4.2.jar:3.4.2]
at reactor.core.publisher.Mono.subscribe(Mono.java:4046) ~[reactor-core-3.4.2.jar:3.4.2]
at reactor.core.publisher.FluxConcatMap$ConcatMapImmediate.drain(FluxConcatMap.java:448) ~[reactor-core-3.4.2.jar:3.4.2]
at reactor.core.publisher.FluxConcatMap$ConcatMapImmediate.onSubscribe(FluxConcatMap.java:218) ~[reactor-core-3.4.2.jar:3.4.2]
at reactor.core.publisher.FluxIterable.subscribe(FluxIterable.java:164) ~[reactor-core-3.4.2.jar:3.4.2]
at reactor.core.publisher.FluxIterable.subscribe(FluxIterable.java:86) ~[reactor-core-3.4.2.jar:3.4.2]
at reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:64) ~[reactor-core-3.4.2.jar:3.4.2]
at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:52) ~[reactor-core-3.4.2.jar:3.4.2]
at reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:64) ~[reactor-core-3.4.2.jar:3.4.2]
at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:52) ~[reactor-core-3.4.2.jar:3.4.2]
at reactor.core.publisher.Mono.subscribe(Mono.java:4046) ~[reactor-core-3.4.2.jar:3.4.2]
at reactor.core.publisher.MonoIgnoreThen$ThenIgnoreMain.drain(MonoIgnoreThen.java:173) ~[reactor-core-3.4.2.jar:3.4.2]
at reactor.core.publisher.MonoIgnoreThen.subscribe(MonoIgnoreThen.java:56) ~[reactor-core-3.4.2.jar:3.4.2]
at reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:64) ~[reactor-core-3.4.2.jar:3.4.2]
at reactor.netty.http.server.HttpServer$HttpServerHandle.onStateChange(HttpServer.java:860) ~[reactor-netty-http-1.0.3.jar:1.0.3]
at reactor.netty.ReactorNetty$CompositeConnectionObserver.onStateChange(ReactorNetty.java:638) ~[reactor-netty-core-1.0.3.jar:1.0.3]
at reactor.netty.transport.ServerTransport$Childobserver.onStateChange(ServerTransport.java:475) ~[reactor-netty-core-1.0.3.jar:1.0.3]
at reactor.netty.http.server.HttpServerOperations.onInboundNext(HttpServerOperations.java:525) ~[reactor-netty-http-1.0.3.jar:1.0.3]
at reactor.netty.channel.ChannelOperationsHandler.channelRead(ChannelOperationsHandler.java:94) ~[reactor-netty-core-1.0.3.jar:1.0.3]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379) ~[netty-transport-4.1.58.Final.jar:4.1.58.Final]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365) ~[netty-transport-4.1.58.Final.jar:4.1.58.Final]
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357) ~[netty-transport-4.1.58.Final.jar:4.1.58.Final]
at reactor.netty.http.server.HttpTrafficHandler.channelRead(HttpTrafficHandler.java:209) ~[reactor-netty-http-1.0.3.jar:1.0.3]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379) ~[netty-transport-4.1.58.Final.jar:4.1.58.Final]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365) ~[netty-transport-4.1.58.Final.jar:4.1.58.Final]
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357) ~[netty-transport-4.1.58.Final.jar:4.1.58.Final]
at io.netty.channel.CombinedChannelDuplexHandler$DelegatingChannelHandlerContext.fireChannelRead(CombinedChannelDuplexHandler.java:436) ~[netty-transport-4.1.58.Final.jar:4.1.58.Final]
at io.netty.handler.codec.BytetoMessageDecoder.fireChannelRead(BytetoMessageDecoder.java:324) ~[netty-codec-4.1.58.Final.jar:4.1.58.Final]
at io.netty.handler.codec.BytetoMessageDecoder.channelRead(BytetoMessageDecoder.java:296) ~[netty-codec-4.1.58.Final.jar:4.1.58.Final]
at io.netty.channel.CombinedChannelDuplexHandler.channelRead(CombinedChannelDuplexHandler.java:251) ~[netty-transport-4.1.58.Final.jar:4.1.58.Final]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379) ~[netty-transport-4.1.58.Final.jar:4.1.58.Final]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365) ~[netty-transport-4.1.58.Final.jar:4.1.58.Final]
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357) ~[netty-transport-4.1.58.Final.jar:4.1.58.Final]
at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1410) ~[netty-transport-4.1.58.Final.jar:4.1.58.Final]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379) ~[netty-transport-4.1.58.Final.jar:4.1.58.Final]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365) ~[netty-transport-4.1.58.Final.jar:4.1.58.Final]
at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:919) ~[netty-transport-4.1.58.Final.jar:4.1.58.Final]
at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:166) ~[netty-transport-4.1.58.Final.jar:4.1.58.Final]
at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:719) ~[netty-transport-4.1.58.Final.jar:4.1.58.Final]
at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:655) ~[netty-transport-4.1.58.Final.jar:4.1.58.Final]
at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:581) ~[netty-transport-4.1.58.Final.jar:4.1.58.Final]
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:493) ~[netty-transport-4.1.58.Final.jar:4.1.58.Final]
at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:989) ~[netty-common-4.1.58.Final.jar:4.1.58.Final]
at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74) ~[netty-common-4.1.58.Final.jar:4.1.58.Final]
at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30) ~[netty-common-4.1.58.Final.jar:4.1.58.Final]
at java.base/java.lang.Thread.run(Thread.java:834) ~[na:na]

Application.java

 @SpringBootApplication
 public class Application implements CommandLineRunner {
     public static void main(String[] args) {
         BlockHound.install();
         SpringApplication.run(Application.class,args);
    }
 }

pom.xml 依赖

 <dependencyManagement>
     <dependencies>
        <dependency>
           <groupId>org.springframework.cloud</groupId>
           <artifactId>spring-cloud-dependencies</artifactId>
           <version>2020.0.1</version>
           <type>pom</type>
           <scope>import</scope>
        </dependency>

        <dependency>
           <groupId>org.springframework.boot</groupId>
           <artifactId>spring-boot-dependencies</artifactId>
           <version>2.4.2</version>
           <type>pom</type>
           <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

<dependencies>
    <dependency>
        <groupId>io.springfox</groupId>
        <artifactId>springfox-boot-starter</artifactId>
        <version>3.0.0</version>
    </dependency>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>${lombok.version}</version>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-webflux</artifactId>
    </dependency>

            <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-thymeleaf</artifactId>
    </dependency>

    <!--
    <dependency>
        <groupId>org.thymeleaf</groupId>
        <artifactId>thymeleaf-Spring5</artifactId>
    </dependency>
    -->

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-validation</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-mongodb-reactive</artifactId>
    </dependency>

    <!-- https://mvnrepository.com/artifact/io.projectreactor.tools/blockhound -->
    <dependency>
        <groupId>io.projectreactor.tools</groupId>
        <artifactId>blockhound</artifactId>
        <version>1.0.6.RELEASE</version>
    </dependency>

    <!-- Test -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
    </dependency>
</dependencies>

我还尝试了另一种配置:删除 spring boot thymeleaf 自动配置并自己声明 webflux 反应性 thymeleaf 视图解析器,但如果也不起作用:

pom.xml 中的更改:

<!--
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-thymeleaf</artifactId>
    </dependency>
    -->
    
    <dependency>
        <groupId>org.thymeleaf</groupId>
        <artifactId>thymeleaf-Spring5</artifactId>
    </dependency>
    

ViewConfiguration.java

@Setter
@Configuration
public class ViewConfiguration implements ApplicationContextAware,WebFluxConfigurer {

    ApplicationContext applicationContext;

    @Bean
    public ITemplateResolver thymeleafTemplateResolver() {
        final SpringResourceTemplateResolver resolver = new SpringResourceTemplateResolver();
        resolver.setApplicationContext(this.applicationContext);
        resolver.setPrefix("classpath:templates/");
        resolver.setSuffix(".html");
        resolver.setTemplateMode(TemplateMode.HTML);
        resolver.setCacheable(false);
        resolver.setCheckExistence(false);
        return resolver;
    }
    @Bean
    public ISpringWebFluxTemplateEngine thymeleafTemplateEngine() {
        SpringWebFluxTemplateEngine templateEngine = new SpringWebFluxTemplateEngine();
        templateEngine.setTemplateResolver(thymeleafTemplateResolver());
        return templateEngine;
    }
    @Bean
    public ThymeleafReactiveViewResolver thymeleafReactiveViewResolver() {
        ThymeleafReactiveViewResolver viewResolver = new ThymeleafReactiveViewResolver();
        viewResolver.setTemplateEngine(thymeleafTemplateEngine());
        return viewResolver;
    }
    @Override
    public void configureViewResolvers(ViewResolverRegistry registry) {
        registry.viewResolver(thymeleafReactiveViewResolver());
    }

}

我认为问题与百里香叶有关,因为当请求不涉及任何百里香叶模板(标准 REST API 调用)时,如果工作正常。

在这里遗漏了什么?

解决方法

Thymeleaf 似乎使用了传统的阻塞方式来加载它的模板文件。

替换

BlackHound.install()

BlockHound.builder()
  .allowBlockingCallsInside("org.thymeleaf.util.ClassLoaderUtils","loadResourceAsStream")
  .install()

至少对我有用。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。