Spring Boot 3+Netty环境下Thymeleaf中getRequestURI为null的替代方案
问题原因与替代实现方案
问题根源
切换到Netty+Spring WebFlux的Reactive环境后,原有的#httpServletRequest是Servlet API相关对象,在非Servlet的Reactive环境中不存在,调用getRequestURI()时自然会出现空指针异常。Thymeleaf 3.1在Reactive环境下提供了对应的Reactive请求对象,而非依赖Servlet的HttpServletRequest。
替代实现方案
方案1:使用Thymeleaf Reactive内置对象直接获取路径
在WebFlux环境中,Thymeleaf提供了#requestServerHttpRequest对象来获取当前请求信息,用它的path()方法替代原有的getRequestURI()即可:
th:classappend="${#arrays.contains(urls, #requestServerHttpRequest.path()) ? 'active' : ''}"
方案2:全局注入当前请求路径(避免手动加pagename)
如果不想每个Controller都手动添加pagename,可以通过全局处理把当前请求路径注入到Model中,所有页面都能直接使用:
方式一:通过@ControllerAdvice实现
@ControllerAdvice public class GlobalRequestAdvice { @ModelAttribute public void addCurrentPath(ServerRequest request, Model model) { model.addAttribute("currentPath", request.path()); } }
然后在页面中直接使用注入的currentPath:
th:classappend="${#arrays.contains(urls, currentPath) ? 'active' : ''}"
方式二:通过WebFilter实现
@Component public class RequestPathFilter implements HandlerFilterFunction<ServerResponse, ServerResponse> { @Override public Mono<ServerResponse> filter(ServerRequest request, HandlerFunction<ServerResponse> next) { return next.handle(request) .contextWrite(context -> context.put("currentPath", request.path())); } }
页面中同样使用${currentPath}即可,效果和方式一一致。
方案3:保留临时方案(适合页面较少的场景)
如果项目页面不多,手动给每个Controller添加pagename的方式可以继续使用,但页面较多时会比较繁琐,推荐用上面的自动化方案。
内容的提问来源于stack exchange,提问作者Ajay Kumar
相关产品推荐
相关产品推荐

