概述

在这个简短的文章中,我们将学习如何使用Thymeleaf库在服务器端访问HTTP会话。目标是构建一个网页,包含一个用于发送姓名分析请求的表单,一个显示结果的部分,以及一个记录整个会话期间所有请求的面板。

为了简化示例,我们将使用Spring和Thymeleaf,因此我们将使用Thymeleaf Spring Standard方言。

2. Thymeleaf中的会话属性

会话信息存储在servlet上下文中,我们可以在模板级别或Spring Boot控制器内部访问这些信息。现在,我们将探讨两种访问会话信息的方法。

2.1. 在Thymeleaf模板中访问会话属性

在Thymeleaf中,我们有两个始终可用的基本对象:ctxlocale,它们前面带有#前缀。**#ctx基本对象提供了包含HTTP会话信息的servlet上下文访问权限**。因此,在模板中,我们可以使用表达式来访问会话:

#ctx.session

如果我们想以更简洁的方式访问会话,可以使用变量session,所以上述命令等同于:

session

现在,让我们看看在模板中,我们可以对会话实例做些什么。首先,我们可以获取会话中存在多少个属性

${#ctx.session.size()}

此外,我们可以检查会话是否为空

${#ctx.session.isEmpty()}

在模板中,我们不能使用containsKey方法检查某个属性是否注册在会话中

${#ctx.session.containsKey('lastAnalysis')}

这个方法总是返回true,因此我们应该检查会话属性是否为null

${#ctx.session.lastAnalysis}==null

最后,我们可以访问会话属性

${#ctx.session.foo}

2.2. 在Spring Boot控制器中访问会话属性

在控制器内部,Thymeleaf的IWebSession接口定义了访问会话信息的方法:

public interface IWebSession {
    public boolean exists();
    public boolean containsAttribute(String name);
    public int getAttributeCount();
    public Set<String> getAllAttributeNames();
    public Map<String,Object> getAttributeMap();
    public Object getAttributeValue(String name);
    public void setAttributeValue(String name,Object value);
    public void removeAttribute(String name);
}

在我们的示例中,我们将看到如何获取IWebSession接口的实例,并使用它来移除、获取和设置会话属性。虽然不会展示接口的所有方法,但足以说明其用法。

首先,从IServletWebExchange开始,它将提供IWebSession实例。然后,我们使用HttpServletRequestHttpServletResponseNameAnalysisController控制器请求中通过webApp属性构建IServletWebExchange实例。

让我们看看getIWebSession方法:

private IWebSession getIWebSession(HttpServletRequest request, HttpServletResponse response) {
    IServletWebExchange exchange = webApp.buildExchange(request, response);
    return exchange == null ? null : exchange.getSession();
}

现在,看看webApp属性的类型及其如何实例化:

private JakartaServletWebApplication webApp;

@Autowired
public NameAnalysisController(NameAnalysisService nameAnalysisService, SessionNameRequestFactory sessionNameRequestFactory, ServletContext servletContext) {
    super();
    ...
    this.webApp = JakartaServletWebApplication.buildApplication(servletContext);
}

在这里,我们可以看到webApp属性是一个JakartaServletWebApplication实例,它使用注入的ServletContext实例构建。至此,我们已经准备好访问会话信息了。

3. 项目设置

回顾一下我们的项目设置。这是一个Maven项目,有两个依赖项。第一个,spring-boot-starter-web,将导入所有使用Spring Boot进行Web开发所需的内容:

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

第二个,spring-boot-starter-thymeleaf,将导入所有启用Thymeleaf与Spring Boot协同工作的内容:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-thymeleaf</artifactId>
    <version>${spring.boot.starter.thymeleaf}</version>
</dependency>

3.1. Thymeleaf引擎配置

spring-boot-starter-thymeleaf依赖项将为我们配置一切,但在示例中,我们稍微调整一下SpringResourceTemplateResolver,设置模板模式、模板前缀和模板后缀:

@Autowired
public SpringWebConfig(SpringResourceTemplateResolver templateResolver) {
    super();

    templateResolver.setPrefix("/WEB-INF/templates/");
    templateResolver.setSuffix(".html");
    templateResolver.setTemplateMode(TemplateMode.HTML);
}

通过这些更改,解析器将对请求进行转换,添加前缀/WEB-INF/templates/和后缀.html. 所以,以下URL请求:

http://localhost:8080/name-analysis.html

将转换为以下模板路径:

WEB-INF/templates/name-analysis.html

4. 运行示例

为了确认一切正常运行,让我们在项目的根目录下使用命令行执行以下Maven命令:

mvn spring-boot:run

该命令将启动Tomcat服务器并嵌入应用。服务器监听8080端口,并在根上下文中发布示例应用。因此,访问基础页面的URL是:

http://localhost:8080

这个请求将显示如下:姓名分析基础

这里可以看到示例的三个不同部分。我们从“分析名称”面板开始,它没有访问任何会话信息,只使用暴露的nameRequest模型属性。

接下来是“已分析的名称”面板,它使用会话中的lastRequest属性显示姓名分析请求的结果。最后,面板“请求历史”也将访问会话中的requests属性信息。

5. 总结

在这篇文章中,我们了解了如何配置一个Maven项目以使用Spring + Thymeleaf。此外,我们专注于如何从Thymeleaf模板和Spring Boot服务器端访问HTTP会话信息。若想深入了解Thymeleaf的工作原理,请阅读从头开始使用Thymeleaf在Spring中的教程

如往常一样,本示例的完整代码可在GitHub上找到。