Spring Boot集成Thymeleaf实现无业务逻辑的页面跳转

Spring Boot集成Thymeleaf,默认情况下,前端的动态html页面放在resources/templates目录下,浏览器如果要访问这个目录下的页面,必须先发一个请求到Controller方法,由该方法返回一个页面的路径加名称前缀实现浏览器上展示动态页面

package com.zhutao.demo.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
@RequestMapping("/indexPage")
public class IndexController {
	
	@GetMapping
	public String toIndex() {
		return "index";
	}
}

如上,浏览器要访问resources/templates/index.html页面,必须先发请求http://ip:port/contextPath/indexPage。

如果templates下面有很多个动态页面,这么干是否觉得麻烦?能否通过http://ip:port/contextPath/index就能访问到templates/index.html界面?

Spring Boot提供了WebMvcConfigurer,该方法有个addViewControllers方法,可以实现这种想法

package com.zhutao.demo.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;


@Configuration
public class WebMvcConfigTemp implements WebMvcConfigurer {
	
	@Override
	public void addViewControllers(ViewControllerRegistry registry) {
		registry.addViewController("/index");
	}

}

这个效果类似下面的代码

package com.zhutao.demo.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
@RequestMapping
public class PageController {
	
	@GetMapping("/index")
	public String toIndex() {
		return "/index";
	}

}

但是如果有很多个页面,都通过registry注册,是否又显得很麻烦,能否更简单一点。

思路:在程序启动的时候,自动的读取templates目录下的html文件,通过registry注册,以下是实现,分两种情况考虑,第一本地开发环境运行时,可以通过文件系统读取所有的html文件;第二,通过运行jar包来启动程序,就不能再通过File读取所有的html文件,只能解析jar包来读取所有的html文件

package com.zhutao.demo.config;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;

import javax.annotation.Resource;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ResourceLoader;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
	
	private static Logger logger = LoggerFactory.getLogger(WebMvcConfig.class);
	//默认值为classpath:/templates/,和springboot保持一致
	@Value("${spring.thymeleaf.prefix:classpath:/templates/}")
	private String prefix;
	//默认值为.html,和springboot保持一致
	@Value("${spring.thymeleaf.prefix:.html}")
	private String suffix;
	
	@Resource
	private ResourceLoader resourceLoader;
	
	@Override
	public void addViewControllers(ViewControllerRegistry registry) {
		String prefixName = prefix.substring("classpath:".length());
		if(prefixName.startsWith("/")) {
			prefixName = prefixName.substring(1);
		}
		if(prefixName.endsWith("/")) {
			prefixName = prefixName.substring(0,prefixName.length()-1);
		}
		org.springframework.core.io.Resource resource = resourceLoader.getResource(prefix);
		JarFile jarFile = null;
		try {
			String path = resource.getURL().getPath();
			//打成jar包后的场景
			if(path.indexOf(".jar!/BOOT-INF/classes!/"+prefixName+"/") != -1) {
				jarFile = new JarFile(path.substring("file:".length(),path.lastIndexOf("!/BOOT-INF/classes!")));
				Enumeration<JarEntry> jarEntries = jarFile.entries();
				while(jarEntries.hasMoreElements()) {
					JarEntry jarEntry = jarEntries.nextElement();
					String classPrefix = "BOOT-INF/classes/"+prefixName+"/";
					if(jarEntry.getName().startsWith(classPrefix) && jarEntry.getName().endsWith(suffix)) {
						String url = jarEntry.getName().substring(classPrefix.length()-1,jarEntry.getName().length() - suffix.length());
						registry.addViewController(url);
					}
				}
			} else {
				//本地开发环境的场景
				File prefixFile = resource.getFile();
				List<File> allHtmlFiles = htmlFiles(prefixFile);
				if(allHtmlFiles == null || allHtmlFiles.isEmpty()) {
					return;
				}
				int prefixFilePathLength = prefixFile.getPath().length();
				for(File e : allHtmlFiles) {
					String url = e.getPath().substring(prefixFilePathLength,e.getPath().length()-suffix.length());
					registry.addViewController(url);
				}
			}
		} catch (IOException e) {
			logger.error("自动将模板页面的路径映射为controller的url时异常",e);
		} finally {
			if(jarFile != null) {
				try {
					jarFile.close();
				} catch (IOException e) {
					logger.error("关闭jar文件时异常",e);
				}
			}
		}
	}
	
	private List<File> htmlFiles(File file) {
		File[] subFiles = file.listFiles();
		if(subFiles == null || subFiles.length == 0) {
			return new ArrayList<File>();
		}
		List<File> files = new ArrayList<>();
		for(File subFile : subFiles) {
			if(subFile.isFile()) {
				if(subFile.getName().toLowerCase().endsWith(suffix)) {
					files.add(subFile);
				}
			} else {
				List<File> fs = htmlFiles(subFile);
				if(fs != null && !fs.isEmpty()) {
					files.addAll(fs);
				}
			}
		}
		return files;
	}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,下面是一个简单的实现步骤: 1. 创建一个基于 Spring Boot 的 web 项目,可以使用 Spring Initializr 来快速生成项目模板。 2. 添加 Thymeleaf 依赖,可以在 pom.xml 文件中添加以下依赖: ``` <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> ``` 3. 在 src/main/resources/templates 目录下创建 login.html 文件,作为登录页面模板。 4. 在 src/main/resources/application.properties 文件中添加以下配置: ``` spring.thymeleaf.prefix=classpath:/templates/ spring.thymeleaf.suffix=.html ``` 这样 Spring Boot 就能自动找到 login.html 模板文件。 5. 在 src/main/java 目录下创建一个名为 LoginController 的控制器类,用于处理登录请求。代码如下: ``` @Controller public class LoginController { @GetMapping("/login") public String login() { return "login"; } @PostMapping("/login") public String doLogin(@RequestParam String username, @RequestParam String password, Model model) { if (username.equals("admin") && password.equals("123456")) { model.addAttribute("username", username); return "success"; } else { model.addAttribute("error", "用户名或密码错误"); return "login"; } } } ``` 这里的 login() 方法用于返回登录页面模板,doLogin() 方法用于处理登录请求,判断用户名和密码是否正确,如果正确则跳转到 success.html 页面,否则返回登录页面并显示错误信息。 6. 在 src/main/resources/templates 目录下创建 success.html 文件,作为登录成功后的页面模板。 ``` <!DOCTYPE html> <html xmlns:th="http://www.thymeleaf.org"> <head> <title>登录成功</title> </head> <body> <h1>欢迎,[[${username}]]!</h1> </body> </html> ``` 这里使用了 Thymeleaf 的表达式语法,将登录成功的用户名显示在页面上。 7. 在 src/main/resources/templates 目录下的 login.html 文件中添加以下代码: ``` <!DOCTYPE html> <html xmlns:th="http://www.thymeleaf.org"> <head> <title>登录</title> </head> <body> <h1>登录</h1> <form th:action="@{/login}" method="post"> <div> <label for="username">用户名:</label> <input type="text" id="username" name="username" required> </div> <div> <label for="password">密码:</label> <input type="password" id="password" name="password" required> </div> <div> <button type="submit">登录</button> </div> <div th:if="${error}"> <span style="color: red;">[[${error}]]</span> </div> </form> </body> </html> ``` 这里使用了 Thymeleaf 的表单绑定语法,将表单数据绑定到 doLogin() 方法的参数中。同时,如果登录失败,会显示错误信息。 8. 运行项目,访问 http://localhost:8080/login 即可看到登录页面。输入正确的用户名和密码,会跳转到登录成功页面。 以上就是一个简单的 Spring BootThymeleaf 整合的 webapp,希望能对你有所帮助。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值