Netty 和 Spring Boot 3 中 getRequestURI 为 null

问题描述 投票:0回答:3

在百里香叶< 3.1 I used below expression to get the request URI.

th:classappend="${#arrays.contains(urls, #httpServletRequest.getRequestURI()) ? 'active' : ''}"

它一直有效,直到最近我升级到了 Spring Boot 3.0,它拉动了 Thymeleaf 3.1。我收到此异常:

[THYMELEAF][parallel-2] Exception processing template "index": Exception evaluating SpringEL expression: "#arrays.contains(urls, #servletServerHttpRequest.getRequestURI()) ? 'active' : ''" (template: "fragments/header" - line 185, col 6)

Caused by: org.springframework.expression.spel.SpelEvaluationException: EL1011E: Method call: Attempted to call method getRequestURI() on null context object

既然我在 Spring Boot 3.0 中使用 Netty 而不是 Tomcat,现在有什么替代方案?我无法从这里弄清楚这一点。

作为解决方法,现在为了解决这个问题,我正在使用:

@GetMapping ("/")
String homePage(Model model) {
    model.addAttribute("pagename", "home");
    return "index";
}

th:classappend="${pagename == 'home' ? 'active' : ''}"
spring spring-boot thymeleaf spring-thymeleaf
3个回答
11
投票

在 Thymeleaf 3.0 中,提供了访问权限:

HttpServletRequest

#request :直接访问与当前请求关联的 javax.servlet.http.HttpServletRequest 对象。 参考

这已在 3.1.0 中从 Thymeleaf 中删除。以下是文档中的等效部分:请求/会话属性等的 Web 上下文命名空间。


“3.1 中的新增功能”文档没有具体提及

HttpServletRequest
,但确实提到删除所有“基于 web-API 的表达式实用程序对象”。

#request、#response、#session 和 #servletContext 在 Thymeleaf 3.1 中不再可用于表达式。

Spring Boot 3.0.0 使用 Thymeleaf 3.1.0(如您所述)。


该怎么办?

查看相关GitHub问题:升级到SpringBoot3后推荐的方法 - 属性

具体:

出于安全原因,这些对象不能直接在 Thymeleaf 3.1 的模板中使用。使这些信息可供模板使用的推荐方法是将模板真正需要的特定信息添加为上下文变量(Spring 中的模型属性)。

示例:

model.addAttribute("servletPath", request.getServletPath();

这与您在解决方法中已经采取的基本方法相同。


另请参阅:删除基于 Web-API 的表达式实用程序对象


2
投票

添加@andrewJames 答案,

如果你在很多页面中使用

request.getServletPath()
,那么在这种情况下,在
@ModelAttribute
类中使用Spring的
@ControllerAdvice
注解会更方便。它将为应用程序中的所有控制器注册此
@ModelAttribute
方法。示例:

@ControllerAdvice
public class GlobalController {

  @ModelAttribute("servletPath")
  String getRequestServletPath(HttpServletRequest request) {
    return request.getServletPath();
  }
}

最后在任何页面中,您可以使用以下方式访问:

${servletPath}

0
投票

使用 Thymeleaf 3.1.2 我解决了类似的问题,将 HttpServletRequest 添加到我的路由中

@RequestMapping("/route")
public String route(Model model, HttpServletRequest request) {
    model.addAttribute("currentUri", request.getRequestURI());
    return "view";
}

在页面中您可以引用 currentUri 属性例如

th:attr="aria-expanded=${currentUri == '/users' ? 'true' : 'false'}"
© www.soinside.com 2019 - 2024. All rights reserved.