基于原生Servlet使用模板引擎Thymeleaf访问界面

news2024/11/15 23:19:34

我们常在Spring Boot项目中使用Thymeleaf模板引擎,今天突发奇想,尝试原生Servlet访问!

说做就做

搭建完整的WEB项目

其中的大部分依赖都是后续报错 追加进来的

在这里插入图片描述

导入依赖 thymeleaf-3.0.11.RELEASE.jar
在这里插入图片描述

第一次访问

访问地址: http://localhost:8080/ThymeleafTest/test

java.lang.NoClassDefFoundError: org/slf4j/LoggerFactory
java.lang.ClassNotFoundException: org.slf4j.LoggerFactory

classNotFoundException异常通常是由于虚拟机(例如Java虚拟机)无法找到所需的类而引起的。这种情况可能发生在以下几种情况下:

  1. 缺少类文件:如果要加载的类文件不存在或不可访问,就会抛出ClassNotFoundException异常。请确保类文件存在于正确的位置,并且具有正确的权限。

  2. 类路径问题:虚拟机通过类路径来查找类文件。如果类路径配置不正确,虚拟机就无法找到所需的类。请检查类路径设置,并确保包含所需类的路径。

  3. 类名错误:还可能是由于类名错误导致的。请确保使用完整的类名(包括包名)来引用类,并且拼写没有错误。

  4. 类加载器问题:在某些情况下,自定义的类加载器可能无法找到所需的类。请确保使用正确的类加载器加载所需的类。

总结起来,ClassNotFoundException异常主要是由于缺少类文件、类路径配置问题、类名错误或类加载器问题引起的。


解决方案

目前预计缺少了相关依赖 ,总之少了谁就去maven中下载谁

第二次访问

加入slf4j-api-2.0.7.jar slf4j-log4j12-1.7.25

java.lang.NoClassDefFoundError: 
Could not initialize class org.thymeleaf.templateresolver.ServletContextTemplateResolver

第三次访问

java.lang.ClassNotFoundException: ognl.PropertyAccessor

此时可以访问指定Servlet

在这里插入图片描述

ognl.PropertyAccessor 异常是由于 OGNL(Object-Graph Navigation Language)表达式无法访问或操作指定对象的属性而引发的。OGNL 是一种用于在 Java 中访问对象属性的表达式语言。

通常,这种异常的原因可能是以下几种情况之一:

  1. 属性不存在:如果尝试访问的属性在对象中不存在,那么 OGNL 将引发此异常。请确保属性名称正确且存在于对象中。

  2. 访问权限限制:如果属性具有私有或受保护的访问修饰符,并且没有提供相应的访问方法(getter/setter),那么 OGNL 将无法访问该属性。在这种情况下,您可以尝试添加 getter 和 setter 方法,或者使用其他方法来访问该属性。

  3. 对象为空:如果尝试操作的对象为 null,那么 OGNL 将引发此异常。在使用 OGNL 之前,请确保对象不为空。

  4. OGNL 表达式错误:如果提供的 OGNL 表达式存在语法错误或不正确的格式,那么 OGNL 将无法解析它并引发异常。请仔细检查您的 OGNL 表达式是否正确。

第四次访问

加入ognl-3.1.12.jar

java.lang.NoClassDefFoundError: Could not initialize class ognl.OgnlRuntime

Could not initialize class ognl.OgnlRuntime 异常通常发生在使用 OGNL(Object-Graph Navigation Language)表达式语言时。它表示无法初始化 OGNL 运行时类。

Could not initialize class ognl.OgnlRuntime 异常的产生原因可能有以下几种:

  1. 缺少 OGNL 库:确保项目中包含了正确的 OGNL 库。如果使用 Maven 等构建工具,可以检查项目的依赖配置。
  2. 版本不匹配:如果项目依赖的 OGNL 版本与其他依赖项冲突,可能会导致初始化异常。需要确保版本兼容性,并解决依赖冲突。
  3. 类路径问题:如果运行时无法找到 OGNL 的类或配置文件,可能会导致初始化异常。检查类路径配置,并确认相关文件是否存在于正确的位置。
  4. 其他原因:除了上述原因外,还可能是由于环境配置、类加载顺序等因素导致的初始化异常。可以尝试重启应用程序或重新部署相关组件,以解决潜在的配置问题。

第五次访问

切换OGNL 版本 ognl-3.0.6.jar

java.lang.ClassNotFoundException: javassist.ClassPool

ClassNotFoundException: javassist.ClassPool 的原因是在运行时找不到 javassist.ClassPool 类。

这可能是由以下几种情况引起的:

  1. 缺少相关的依赖库:javassist 是一个字节码操作库,如果你的项目中没有正确引入 javassist 的相关依赖库,就会导致找不到该类。你可以通过在项目中添加正确的依赖来解决这个问题,比如使用 Maven 或 Gradle 来管理依赖。

  2. 依赖版本不兼容:如果你的项目中使用的 javassist 版本与其他依赖库存在冲突,也可能导致找不到该类。你可以尝试升级或降级 javassist 的版本,或者解决其他依赖库的版本冲突。

  3. 类路径配置错误:如果你的项目中没有正确配置类路径,虽然你已经添加了正确的依赖,但 JVM 仍然无法找到该类。你可以检查你的类路径配置是否正确,并确保 javassist 类所在的 JAR 文件或目录已经包含在类路径中。

  4. 编译错误:如果你是在运行程序时出现该异常,而不是在编译时,那么有可能是因为你的代码在编译时找不到 javassist 类。这可能是因为你在编译时没有包含 javassist 的相关依赖或者编译选项配置错误。你可以检查你的编译配置,并确保 javassist 的依赖被正确引入。

第六次访问

加入javassist-3.29.2-GA.jar

java.lang.ClassNotFoundException: org.attoparser.IMarkupParser
  • org.attoparser.IMarkupParser是一个解析器接口,它定义了在解析HTML、XML或其他标记语言时所需的方法。具体来说,它提供了解析标记文本的能力,并将其转换为相应的数据结构或事件。
  • IMarkupParser的主要作用是将标记文本转换为可供程序处理的结构化数据,以便进一步的处理或展示。

通过实现IMarkupParser接口,开发人员可以自定义标记解析器以满足特定的需求。这个接口定义了一系列方法,如startElement、endElement、characters等,用于处理标记的开始、结束以及标记中的字符内容。

第七次访问

加入attoparser-2.0.7.RELEASE.jar

java.lang.ClassNotFoundException: org.unbescape.html.HtmlEscape

在这里插入图片描述
终于看到一丝希望

org.unbescape.html.HtmlEscape 是一个 Java 库,它提供了用于转义 HTML 字符实体的方法。在编写 Web 应用程序时,我们经常需要将特殊字符(如<, >, &, ", ’等)转义为对应的 HTML 实体,以确保这些字符在网页上正确显示,而不会被解释为 HTML 代码。HtmlEscape 类提供了一组静态方法,用于将文本中的特殊字符转义为对应的 HTML 实体,以便在 HTML 页面中正确显示。这个库是为了方便开发人员处理 HTML 相关操作而设计的。

第八次访问

加入attoparser-2.0.7.RELEASE.jar

在这里插入图片描述

拨开云雾见天日,守得云开见月明


项目源码请参考下方

  • web.xml配置
	<!-- 在上下文参数中配置视图前缀和视图后缀 -->
  	<!-- ①添加thymeleaf的jar包  ②在web.xml文件中添加配置 -->
	<context-param>
	    <param-name>view-prefix</param-name>
	    <param-value>/WEB-INF/view/</param-value> <!--前缀-->
	</context-param>
	<context-param>
	    <param-name>view-suffix</param-name> <!--后缀-->
	    <param-value>.html</param-value>
	</context-param>
  • index.html界面放在webapp目录下
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	<a href="test">初步测试Thymeleaf</a>
</body>
</html>
  • hello.html 界面放在/WEB-INF/view/目录下
<!-- 我们需要使用thymeleaf,需要在html文件中导入我们的命名空间约束,方便提示。 官方文档的#3中看一下把命名空间拿过来 -->
<html xmlns:th="http://www.thymeleaf.org">
  <head>
    <title>目标界面</title>
 
  </head>
  <body>
  	<!-- 在界面展示数据 -->
   	<h1 th:text="${festival}">这里要显示一个动态的festival</h1>
   	
	<!--th:text 表示转义 -->
	<div th:text="${msg}"> hello thymeleaf</div>
	<!--th:utext 表示不转义 -->
	<div th:utext="${msg}"> hello thymeleaf</div>
	
	<hr>
	
	<!--遍历集-->
	<!--th:each每次遍历都会生成当前这个标签:官网-->
	<h2 th:each="users:${user}" th:text="${users}"></h2>
	
	<!--行列写法 不建议-->
	<!--<h2 th:each="users:${user}">[[ ${users} ]] </h2>-->
	
  </body>
</html>
  • ViewBaseServlet.java 视图解析器
package com.yc.thymeleaf.controller;

import org.thymeleaf.TemplateEngine;
import org.thymeleaf.context.WebContext;
import org.thymeleaf.templatemode.TemplateMode;
import org.thymeleaf.templateresolver.ServletContextTemplateResolver;
 
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
 
/**
 * 在HTML页面上,加载Java内存中的数据的过程我们称为渲染(render);thymeleaf是用来帮助视图渲染的技术。
 * company 源辰信息
 * @author 梦凝哲雪
 * @date 2023年8月21日
 * @version 1.0
 * Email 1198865589@qq.com
 */
public class ViewBaseServlet extends HttpServlet {
 
	private static final long serialVersionUID = 1L;
	
	private TemplateEngine templateEngine;
 
    @Override
    public void init() throws ServletException {
 
        // 1.获取ServletContext对象
        ServletContext servletContext = this.getServletContext();
 
        // 2.创建Thymeleaf解析器对象
        ServletContextTemplateResolver templateResolver = new ServletContextTemplateResolver(servletContext);
 
        // 3.给解析器对象设置参数
        // ①HTML是默认模式,明确设置是为了代码更容易理解
        templateResolver.setTemplateMode(TemplateMode.HTML);
 
        // ②设置前缀
        String viewPrefix = servletContext.getInitParameter("view-prefix");
 
        templateResolver.setPrefix(viewPrefix);
 
        // ③设置后缀
        String viewSuffix = servletContext.getInitParameter("view-suffix");
 
        templateResolver.setSuffix(viewSuffix);
 
        // ④设置缓存过期时间(毫秒)
        templateResolver.setCacheTTLMs(60000L);
 
        // ⑤设置是否缓存
        templateResolver.setCacheable(true);
 
        // ⑥设置服务器端编码方式
        templateResolver.setCharacterEncoding("utf-8");
 
        // 4.创建模板引擎对象
        templateEngine = new TemplateEngine();
 
        // 5.给模板引擎对象设置模板解析器
        templateEngine.setTemplateResolver(templateResolver);
 
    }
 
    protected void processTemplate(String templateName, HttpServletRequest req, HttpServletResponse resp) throws IOException {
        // 1.设置响应体内容类型和字符集
        resp.setContentType("text/html;charset=UTF-8");
        resp.setCharacterEncoding("utf-8");
    	
        // 2.创建WebContext对象 创建Thymeleaf的上下文对象,此对象用来存储数据
        WebContext webContext = new WebContext(req, resp, getServletContext());
        
        // 3.处理模板数据
        templateEngine.process(templateName, webContext, resp.getWriter());
    }
}
  • HelloWorldController.java 请求交互的控制层
package com.yc.thymeleaf.controller;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.thymeleaf.context.WebContext;

@WebServlet("/test")
public class HelloWorldController extends ViewBaseServlet{

	private static final long serialVersionUID = 1L;

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doGet(request, response);
    }
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    	 System.out.println(666);
    	// 请求中设计相关参数
        request.setAttribute("festival","七夕快乐");
        request.setAttribute("msg", "<h1>first  thymeleaf page!!</h1>");
        request.setAttribute("users",  List.of("张三", "李四", "王五", "赵六"));
        // 请求转发跳转到/WEB-INF/view/target.html
        processTemplate("hello", request, response);
    }
}
  • 最终效果

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/909212.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

利用屏幕水印学习英语单词,无打扰英语单词学习

1、利用屏幕水印学习英语单词&#xff0c;不影响任何鼠标键盘操作&#xff0c;不影响工作 2、利用系统热键快速隐藏&#xff08;ALT1键 隐藏与显示&#xff09; 3、日积月累单词会有进步 4、软件下载地址: 免安装&#xff0c;代码未加密&#xff0c;安全的屏幕水印学习英语…

Linux学习之ftp安装、vsftpd安装和使用

ftp需要两个端口&#xff1a; 数据端口 命令端口 ftp有两种模式&#xff1a; 被动模式&#xff1a;建立命令连接之后&#xff0c;服务器等待客户端发起请求。 主动模式&#xff1a;建立命令连接之后&#xff0c;服务器主动向客户端发起数据连接&#xff0c;因为客户端可能有防火…

6-2 使用函数求素数和

分数 20 全屏浏览题目 切换布局 作者 张高燕 单位 浙大城市学院 本题要求实现一个判断素数的简单函数、以及利用该函数计算给定区间内素数和的函数。 素数就是只能被1和自身整除的正整数。注意&#xff1a;1不是素数&#xff0c;2是素数。 函数接口定义&#xff1a; int p…

相关变化率的例子

如图&#xff0c;不解释。 很多物理学上的物理量&#xff0c;直接使用微分和导数来定义&#xff0c;因此可以不加证明的直接使用这些物理量。 解&#xff1a; d l 2 , d w 3 dl 2, dw 3 dl2,dw3 v l 2 w 2 , d v − 2 l d l 2 w d w 2 l 2 w 2 − 2 12 2 2 5…

内网渗透神器CobaltStrike之内网信息收集(九)

收集域内信息 Windows命令 查看网关的ip地址, DNS的ip地址、域名等等&#xff1a;shell ipconfig /all 查看当前主机所在的域: shell net view /domain 查看当前域的主机列表: shell net view 查看指定域的主机列表: shell net view /domain:[domain] 若beacon用户是域控, 则…

数据同步工具比较:选择适合您业务需求的解决方案

在当今数字化时代&#xff0c;数据已经成为企业的核心资产。然而&#xff0c;随着业务的扩展和设备的增多&#xff0c;如何实现数据的高效管理和同步成为了一个亟待解决的问题。本文将介绍几种常见的数据同步工具&#xff0c;并对比它们的功能、性能和适用场景&#xff0c;帮助…

二、9.硬盘驱动程序

文件系统是运行在操作系统中的软件模块&#xff0c;是操作系统提供的一套管理磁盘文件读写的方法和数据组织、存储形式&#xff0c;因此&#xff0c;文件系统&#xff1d;数据结构&#xff0b;算法&#xff0c;哈哈&#xff0c;所以它是程序。它的管理对象是文件&#xff0c;管…

互斥锁的概念,与部分接口

何为互斥 一种对共享数据的保护&#xff0c;防止多线程同时访问共享资源的时&#xff0c;数据混乱的问题。在互斥期间&#xff0c;保证执行流由并行改为串行。任何时刻&#xff0c;互斥保证有且只有一个执行流进入临界区&#xff0c;访问临界资源&#xff0c;通常对临界资源起…

苍穹外卖 day2 反向代理和负载均衡配置的代码

为什么要整这些玩意 为了并发&#xff0c;为了容错&#xff0c;为了高可用 一 反向代理的代码 server{listen 80;server_name localhost;location /api/{proxy_pass http://localhost:8080/admin/; #反向代理} }**proxy_pass&#xff1a;**该指令是用来设置代理服务器的地址&…

1小时学会Python

1.Hello world 安装完Python之后,打开IDLE(Python GUI) ,该程序是Python语言解释器,你写的语句能够立即运行。 我们写下一句著名的程序语句: 并按回车,你就能看到这句被K&R引入到程序世界的名言。 在解释器中选择"File"--"New Window" 或快捷键 …

如何通过振动判断设备健康度?以PreMaint设备数字化平台为例

在工业生产过程中&#xff0c;设备的健康状况直接关系到生产效率和安全。而振动分析作为一种重要的设备健康监测手段&#xff0c;可以通过监测设备的振动情况来判断其健康状况。本文将以PreMaint设备数字化平台为例&#xff0c;探讨如何通过振动分析来判断设备的健康度&#xf…

【javaweb】学习日记Day3 - Ajax 前后端分离开发 入门

目录 一、Ajax 1、简介 2、Axios &#xff08;没懂 暂留&#xff09; &#xff08;1&#xff09;请求方式别名 &#xff08;2&#xff09;发送get请求 &#xff08;3&#xff09;发送post请求 &#xff08;4&#xff09;案例 二、前端工程化 1、Vue项目-目录结构 2、…

IDEA中使用Docker插件构建镜像并推送至私服Harbor

一、开启Docker服务器的远程访问 1.1 开启2375远程访问 默认的dokcer是不支持远程访问的&#xff0c;需要加点配置&#xff0c;开启Docker的远程访问 # 首先查看docker配置文件所在位置 systemctl status docker# 会输出如下内容&#xff1a; ● docker.service - Docker Ap…

如何使用PHP实现多语言网站功能

如何使用PHP实现多语言网站功能 在全球化的今天&#xff0c;开发多语言网站成为了一个必要的需求。PHP作为一种常用的编程语言&#xff0c;可以很方便地实现多语言网站功能。本文将介绍如何使用PHP实现多语言网站功能&#xff0c;并提供相应的代码示例。 一、创建语言文件 首先…

系统集成项目管理工程师【中级】考证学习资料整理分享——第一章《信息化基础知识》,持续更新中........

系统集成项目管理工程师(中级)考证学习资料整理分享,持续更新中........ 第一章 《信息化基础知识》 一、信息与信息化 在充满前所未有的创新活力的同时,信息化正以更快地速度推进生产力的发展,围绕智能制造、云计算、网络空间、移动互联、工业互联、大数据、信息安全等领…

网络安全—黑客—自学笔记

想自学网络安全&#xff08;黑客技术&#xff09;首先你得了解什么是网络安全&#xff01;什么是黑客&#xff01; 网络安全可以基于攻击和防御视角来分类&#xff0c;我们经常听到的 “红队”、“渗透测试” 等就是研究攻击技术&#xff0c;而“蓝队”、“安全运营”、“安全…

多线程与高并发编程一

文章目录 一、故事背景二、知识点主要构成1、线程的概念2、启动方式2.1、继承Thread类 重写run方法2.2、实现Runnable接口 重写run方法2.3、实现Callable 重写call方法 配合FuterTask获取线程结果 3、常用方法start()方法&#xff1a;run()方法&#xff1a;sleep(long millis)方…

【HCIP】企业网三层架构实验

题目&#xff1a; 拓扑图 配置 LSW1 //链路聚合 [lsw3]interface Eth-Trunk 1 [lsw3-Eth-Trunk1]trunkport GigabitEthernet 0/0/3 0/0/4 [lsw3-Eth-Trunk1]q [lsw3]vlan batch 1 2 [lsw3]interface Eth-Trunk 1 [lsw3-Eth-Trunk1]port link-type trunk [lsw3-Eth-Trunk1]port…

docker中bridge、host、container、none四种网络模式简介

一.bridge模式 1.简介 2.演示 &#xff08;1&#xff09;运行两个容器&#xff0c;不指定网络模式情况下默认是bridge模式 &#xff08;2&#xff09;在主机中自动生成了两个veth设备 &#xff08;3&#xff09;查看两个容器的IP地址 &#xff08;4&#xff09;可以自定义…

基于图卷积网络的知识嵌入8.21

基于图卷积网络的知识嵌入 摘要介绍 摘要 近年来&#xff0c;围绕图卷积网络&#xff08;GCN&#xff09;这一主题出现了大量的文献。如何有效地利用复杂图中丰富的结构信息&#xff08;例如具有heterogeneous types of entities and relations(异构实体和关系类型) 的知识图谱…