Tomcat 的 work 目录缓存导致的JSP页面图片更新问题

一、问题分析

1. 修改后重新部署没有变化

    笔者之前部署了一个后台管理项目,通过它来发布课程内容,其中有一个 JSP 课程页面,在该 JSP 页面里也引用了类文件 Constant.java 里的一个变量(ALIYUN_OSS_PATH),该变量的值是一个域名地址(static.aaa.com),在该 JSP 页面基于这个地址来加载和显示图片(static.aaa.com/x.png)。

# 在 jsp 页面获取 java 类的变量值
<c:set var="aliyun" value="<%=com.xxx.admin.common.Constants.ALIYUN_OSS_PATH%>"/>

    现在因为项目需要,在 Constant.java 文件里更改了这个该变量的值:

//修改前
//public static final String ALIYUN_OSS_PATH = "http://static.aaa.com/";
//修改后
public static final String ALIYUN_OSS_PATH = "http://static.bbb.com/";

    然后重新部署,但是却发现所有的图片都打不开了。但是在浏览器展示的页面上拷贝图片地址,发现与和之前的图片地址没有任何变化:static.aaa.com/x.png, 本来希望出现的变化是:static.bbb.com/x.png

    总之一句话,就是项目修改并重新部署后 JSP 页面的图片路径没有更新。

2. 图片无法正常显示分析

原先浏览器入口路径是 admin.aaa.com, 图片请求地址是:static.aaa.com/x.png ;

现在浏览器入口路径是 admin.bbb.com, 图片请求地址仍然是:static.aaa.com/x.png, 并没有变成我希望的修改后的 static.bbb.com.

    这里图片为什么之前能打开?现在重新部署后,路径没有变化为什么反而打不开呢?这个与部署后,进入网站后台入口地址发生了变化有关系:

    浏览器是通过 admin.aaa.com 进入后台管理,发起请求时,http 头的 referer url 路径就是入口路径:admin.aaa.com,这与 OSS 服务端设置的 referrer url 白名单一致,所以能正常打开图片。现在更新部署后,请求的图片路径没有变化,仍然是 static.aaa.com/x.png,但是管理后台的入口地址变更为: admin.bbb.com , 所以 header 头里带的 referer url 路径就变成 admin.bbb.com. 这个与 OSS 服务端设置的 refer url 白名单不一致,所以导致图片无法正常请求。

    通过 referer url 实现“访问控制”,其原理可以可以参考: <HTML页面跨域请求图片资源报错>

二、问题排查   

    一开始是怀疑浏览器的缓存导致,重新清理了浏览器的缓存重启浏览器,再次打开后台页面,仍然没有任何改变。

    问题进一步排除,继续去查看项目部署后台的文件,发现有更新的 java源文件,在编译后的 class 文件确实已经更新完毕。为什么 jsp 页面图片就是无法正常打开了。

    排除了以上问题后,开始怀疑在【服务端的Tomcat是否有类似浏览器一样的缓存】,经过查询后,定位到了 Tomcat 下的 WORK 目录。原来所有的 JSP 页面都会编译成 _jsp.java  和 _jsp.class 文件,存储在这个目录下,如果 jsp 发生了改变,tomcat 会重新编译,在前端请求时候将重新编译后的 _jsp.class 文件载入内存:

    现在问题明白了。因为我的 JSP 文件引用 java 类文件了的 oss 路径变量:

<c:set var="aliyun" value="<%=com.xxx.admin.common.Constants.ALIYUN_OSS_PATH%>"/>

    虽然我修了 java 源代文件里的 ALIYUN_OSS_PATH 变量的值后重新部署,但是 work 目录下的 JSP 文件本身没有进行任何修改,所以在重新部署后,JSP 不会重新编译,在发起请求时,tomcat 仍然调用的是之前缓存的 _jsp.class 文件,该文件里面 ALIYUN_OSS_PATH 值并没更新。所以图片加载地址就没有变化,仍然是之前的:static.aaa.com/x.png, 而不是更新后的 static.bbb.com/x.png

三、问题解决

方式1:

    清理 Tomcat 缓存,我们可以通过执行下面的命令:

rm -rf /path/to/tomcat/work/*

方式2:

    用 RD 命令删除整个目录,只需打开 tomcat/bin/startup.bat 文件,在开头加入:

rd/s/q "/Tomcat path/work/Catalina"

    这样每次启动Tomcat的时候就会先删除页面缓存了,不用担心页面修改后没被重新编译。

四、总结

    如果 JSP 的引用了 java 源代码里的变量。如果该变量的值发生了变化,在重新部署后,记得将Tomcat 下 work 目录里对应的 JSP 文件的缓存进行清理。

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

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

相关文章

使用ffmpeg实现音频静音修剪

1 silenceremove介绍 本文主要介绍在 FFmpeg 命令中使用 silenceremove filter 进行音频静音的修剪。 1.1 start_x参数 参数名说明取值范围默认值start_periods设置是否应在音频开头修剪音频。0 表示不应从一开始就修剪静音。当指定一个非 0 值时&#xff0c;它会修剪音频直…

2022-ECCV-Explaining Deepfake Detection by Analysing Image Matching

一、研究背景 1.大量工作将深度伪造检测作为一个二分类任务并取得了良好的性能。 2.理解模型如何在二分类标签的监督下学习伪造相关特征仍难是个艰巨的任务。 3.视觉概念&#xff1a;具有语义的人脸区域&#xff0c;如嘴、鼻子、眼睛。 二、研究目标 1.验证假设&#xff0c;并…

虹科分享 | 用Redis为LangChain定制AI代理——OpenGPTs

文章速览&#xff1a; OpenGPTs简介Redis在OpenGPTs中的作用在本地使用OpenGPTs在云端使用OpenGPTsRedis与LangChain赋能创新 OpenAI最近推出了OpenAI GPTs——一个构建定制化AI代理的无代码“应用商店”&#xff0c;随后LangChain开发了类似的开源工具OpenGPTs。OpenGPTs是一…

OpenCV——多分辨率LBP的计算方法

目录 一、算法原理1、原理概述2、参考文献 二、代码实现三、结果展示 OpenCV——多分辨率LBP的计算方法由CSDN点云侠原创&#xff0c;爬虫自重。如果你不是在点云侠的博客中看到该文章&#xff0c;那么此处便是不要脸的爬虫。 一、算法原理 1、原理概述 基本LBP算子虽然在早期…

Vue.js设计与实现阅读-2

Vue.js设计与实现阅读-2 1、前言2、框架设计的核心要素2、1 提升用户体验2、2 控制代码体积2、3 Tree-Shaking2、4 特性开关2、5 错误处理 1、前言 上一篇我们了解到了 命令式和声明式的区别&#xff0c;前者关注过程&#xff0c;后者关注结果了解了虚拟dom存在的意义&#x…

笔记软件内怎么查看文章字数 笔记查看字数的操作步骤

在记录生活点滴、工作要务时&#xff0c;你是否曾像我一样&#xff0c;为了知道写了多少字而犯愁&#xff1f;尤其是在需要精确控制字数时&#xff0c;那种焦虑感更是如影随形。 记得有一次&#xff0c;我为了一个项目报告苦思冥想&#xff0c;好不容易写了个初稿&#xff0c;…

Java--ListUtil工具类,实现将一个大列表,拆分成指定长度的子列表

文章目录 前言实现代码执行结果 前言 在项目中有时会出现列表很大&#xff0c;无法一次性批量操作&#xff0c;我们需要将列表分成指定大小的几个子列表&#xff0c;一份一份进行操作&#xff0c;本文提供这样的工具类实现这个需求。 实现代码 以下为代码实现&#xff1a; …

锂电池的电压和容量怎么计算?

锂电池组是由电池单体&#xff08;电芯&#xff09;通过串并联来组成 1、串联(S)增加电压&#xff0c;容量不变。 例如&#xff1a;1个磷酸铁锂电池的额定电压为3.2V&#xff0c;容量为4000mAH&#xff0c;将10个磷酸铁锂电芯串联&#xff0c;电池组电压&#xff1a;3.2v*10&a…

Spring Boot中加@Async和不加@Async有什么区别?设置核心线程数、设置最大线程数、设置队列容量是什么意思?直接在yml中配置线程池

在 Spring 中&#xff0c;Async 注解用于将方法标记为异步执行的方法。当使用 Async 注解时&#xff0c;该方法将在单独的线程中执行&#xff0c;而不会阻塞当前线程。这使得方法可以在后台执行&#xff0c;而不会影响主线程的执行。 在您提供的代码示例中&#xff0c;a1() 和…

【gpt4 8k 免费使用】Coze 是一款用来开发新一代 AI Chat Bot 的应用编辑平台

Coze 快速开始 | Coze Welcome to Coze Coze 是什么&#xff1f; Coze 是一款用来开发新一代 AI Chat Bot 的应用编辑平台&#xff0c;无论你是否有编程基础&#xff0c;都可以通过这个平台来快速创建各种类型的 Chat Bot&#xff0c;并将其发布到各类社交平台和通讯软件上。…

【C++】类和对象之匿名对象友元内部类

目录 一、匿名对象 1、基础格式 2、使用场景 二、友元 1、友元函数 2、友元类 三、内部类 1、概念 2、特性 四、拷贝对象时的一些编译器优化 1、函数传参 2、对象返回 一、匿名对象 1、基础格式 【注意】 &#x1f7e2;匿名对象的声明周期只有当前行&#xff0c;进入…

[计算机提升] 创建FTP共享

4.7 创建FTP共享 4.7.1 FTP介绍 在Windows系统中&#xff0c;FTP共享是一种用于在网络上进行文件传输的标准协议。它可以让用户通过FTP客户端程序访问并下载或上传文件&#xff0c;实现文件共享。 FTP共享的用途非常广泛&#xff0c;例如可以让多个用户共享文件、进行文件备份…

超越5大最先进的文本到视频系统!MagicVideo-V2:多阶段高保真视频生成框架(字节)

本项工作介绍了MagicVideo-V2&#xff0c;将文本到图像模型、视频运动生成器、参考图像embedding模块和帧内插模块集成到端到端的视频生成流程中。由于这些架构设计的好处&#xff0c;MagicVideo-V2能够生成具有极高保真度和流畅度的美观高分辨率视频。通过大规模用户评估&…

【设计模式-6】建造者模式的实现与框架中的应用

建造者模式又被成为生成器模式&#xff0c;是一种使用频率比较低&#xff0c;相对复杂的创建型模式&#xff0c;在很多源码框架中可以看到建造者的使用场景&#xff0c;稍后我们会在本文末尾展示几个框架的使用案例。  建造者模式所构造的对象通常是比较复杂而且庞大的&#x…

Day31 贪心算法 part01 理论基础 455.分发饼干 376.摆动序列 53.最大子序和

贪心算法 part01 理论基础 455.分发饼干 376.摆动序列 53.最大子序和 理论基础&#xff08;转载自代码随想录&#xff09; 什么是贪心 贪心的本质是选择每一阶段的局部最优&#xff0c;从而达到全局最优。 这么说有点抽象&#xff0c;来举一个例子&#xff1a; 例如&#…

Unity——VContainer的依赖注入

一、IOC控制反转和DI依赖倒置 1、IOC框架核心原理是依赖倒置原则 C#设计模式的六大原则 使用这种思想方式&#xff0c;可以让我们无需关心对象的生成方式&#xff0c;只需要告诉容器我需要的对象即可&#xff0c;而告诉容器我需要对象的方式就叫做DI&#xff08;依赖注入&…

企业级大数据安全架构(三)修改集群节点hostname

作者&#xff1a;楼高 在后续安装FreeIPA的过程中&#xff0c;要求机器名必须包含完整的域名信息。如果之前在Ambari集群节点上的机器名不符合这个要求&#xff0c;可以按照以下步骤在Ambari上修改所有节点的机器名&#xff1a; 1.部署节点说明 本次测试是三台 ambari 节点&…

【软件测试作业_TPshop商城】农业工程学院-测试需求分析与测试计划+自动化+性能+测试用例+报告软件缺陷+测试计划+单元测试+系统测试

1测试需求分析与测试计划 1.1 被测系统简介 1.2测试需求分析 1.2.1单元测试层面的测试需求分析 1.2.2系统测试层面的测试需求分析 1.3测试计划 1.31测试范围与任务 1.3.2 测试环境 1.3.3测试进度安排 测试用例的设计2 2.1单元测试层面的测试用例设计 2.2系统测试层面的测试用例…

linux部署apache服务部署静态网站

第一步&#xff1a;配置IP地址 第二步&#xff1a;创建挂载点 配置yum仓库 mkdir -p /media/cdrom 挂载 mount /dev/cdrom /media/cdrom 安装服务 安装yum源 启用httpd服务程序并将其加入到开机启动项中 建立网站数据保存目录&#xff0c;并创建首页文件 mkdir /home/wwwroo…