在Spring-Webflux整合Thymeleaf时,出现Could not resolve view with name ‘xxxx' 问题。个人方法有问题可以打脸,不想看过程直接拉到最后,文中涉及webflux依赖版本为2.1.2
demo项目参考地址: 这是码云
在项目整合Thymeleaf时,无法识别view name问题,debug查找原因。
在 ServerResponseResultHandler做结果处理时会使用ViewResolverRegistry中注册的视图解析器,但是这个地方debug发现视图解析器是0个。
WebFluxConfigurationSupport涉及源码:
@Bean
public ServerResponseResultHandler serverResponseResultHandler() {
List resolvers = getViewResolverRegistry().getViewResolvers();
ServerResponseResultHandler handler = new ServerResponseResultHandler();
handler.setMessageWriters(serverCodecConfigurer().getWriters());
handler.setViewResolvers(resolvers);
return handler;
}
WebFluxConfigurationSupport -> ViewResolverRegistry.viewResolvers 是空的,下面就找这个resolverRegistry注册viewResovlers的地方。
WebFluxConfigurationSupport部分源码,此处是获取了视图解析器:
//此处注入视图结果处理器,其中会获取视图解析器并设置
@Bean
public ViewResolutionResultHandler viewResolutionResultHandler() {
ViewResolverRegistry registry = getViewResolverRegistry();
List resolvers = registry.getViewResolvers();
ViewResolutionResultHandler handler = new ViewResolutionResultHandler(
resolvers, webFluxContentTypeResolver(), webFluxAdapterRegistry());
handler.setDefaultViews(registry.getDefaultViews());
handler.setOrder(registry.getOrder());
return handler;
}
getViewResolverRegistry方法:里面有个调用配置视图解析器的方法configureViewResolvers
protected final ViewResolverRegistry getViewResolverRegistry() {
if (this.viewResolverRegistry == null) {
this.viewResolverRegistry = new ViewResolverRegistry(this.applicationContext);
configureViewResolvers(this.viewResolverRegistry);
}
return this.viewResolverRegistry;
}
configureViewResolvers方法:
/**
* Configure view resolution for supporting template engines.
* @see ViewResolverRegistry
*/
protected void configureViewResolvers(ViewResolverRegistry registry) {
//留给子类实现的
}
子类DelegatingWebFluxConfiguration实现了这个方法:
@Override
protected void configureViewResolvers(ViewResolverRegistry registry) {
this.configurers.configureViewResolvers(registry);
}
这个子类就是@EnableWebFlux中引入的一个配置类,他的源码:
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@Import(DelegatingWebFluxConfiguration.class)
public @interface EnableWebFlux {
}
DelegatingWebFluxConfiguration类继承自WebFluxConfigurationSupport并配置了一些webflux的很多处理器
DelegatingWebFluxConfiguration类中注入了所有实现WebFluxConfigurer的bean:
@Autowired(required = false)
public void setConfigurers(List configurers) {
if (!CollectionUtils.isEmpty(configurers)) {
this.configurers.addWebFluxConfigurers(configurers);
}
}
在DelegatingWebFluxConfiguration中有个全局变量WebFluxConfigurerComposite configurers,是聚合WebFlux配置类的一个代理类,这个代理类最终代理了所有实现了WebFluxConfigurer接口的类,并对常用组件做配置。
注入的bean最终被加到了WebFluxConfigurerComposite 中。所以只需要实现一个WebFluxConfigurer就可以对WebFluxConfigurer就可以对视图解析器进行配置,类似Spring-web中的WebMvcConfigurer。
下面具体配置类:解决找不到视图的问题
package tom.reactor.config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.reactive.config.ResourceHandlerRegistry;
import org.springframework.web.reactive.config.ViewResolverRegistry;
import org.springframework.web.reactive.config.WebFluxConfigurer;
import org.thymeleaf.spring5.view.reactive.ThymeleafReactiveViewResolver;
/**
* 提供了自定义配置WebFlux相关组件
* @author aisheishei
*/
@Configuration
public class WebFluxConfig implements WebFluxConfigurer {
//引入spring-boot-starter-thymeleaf自动会注入该bean
@Autowired
private ThymeleafReactiveViewResolver thymeleafReactiveViewResolver;
/**
* 加入thymeleaf试图解析器,不然找不到view name
* @param registry
*/
@Override
public void configureViewResolvers(ViewResolverRegistry registry) {
registry.viewResolver(thymeleafReactiveViewResolver);
}
/**
* 映射静态资源文件映射
* @param registry
*/
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/static/**")
//指向的是目录
.addResourceLocations("classpath:/static/");
}
}