踩坑-Tomcat(servlet)在启动(加载)是执行两次
不知道大家在使用Tomcat
时,有没有遇到过运行或者启动项目时,页面被执行了两次的问题。
可能发生过,但是你没有发现。
首先看一下问题是怎么样的。
问题演示
这是一段jsp
代码,说实话这玩意有点老了,不懂jsp
的请听我解释这一段代码。
我们定义一个全局变量
i
,i = 0
。我们定义一个无参无返回值方法,
void add()
,这个方法中使用i++
来自加。我们在下一句,
add()
调用这个方法。然后将
i
的值输出在页面。
我刚开始觉得答案肯定是1
,也必须是1
。
但是,当我运行起来发现。
????居然是2
?
我甚至怀疑是代码的问题......
于是我在add()
方法里面输出一下日志。
我发现,这不是之间将i
变成了2
,而是add()
方法被调用了两次!
可是代码里面明明只调用一次啊?
我去浏览器搜索相关案例,发现还真有几例,哈哈哈,浏览器万能。
经过一系列排查,发现是Tomcat
针对你的项目运行了两次。
原因
为什么会运行两次呢?
因为你的项目本来就放在
Tomcat
的默认webapp
目录下(tomcat在启动时肯定会加载1次),然后又在server.xml
中做了配置,为了达到访问根就可以访问你的项目(这样Tomcat
就又加载1次),结果,Tomcat就会加载两次。
你可能也并没有将项目放到webapp
目录下,但是你的IDEA工具给你了个项目映射,将你的项目映射到了webapp
下。
也可以这样说,Tomcat启动时,先加载
appBase
中配置的webapps
目录下的项目,然后再去加载docBase
中配置的项目,因为docBase
的相对路径(/xxx
)是在webapps
目录下,所以会被加载两次。
总的来说,就是Tomcat
的sever.xml
的配置做了一次无用功,导致运行了两次。
如何解决?
首先,我们有三种方法,我们一个个说。
先记住这两个是啥:
docBase
是web应用和本地路径,path
是Tomcat
访问这个应用的URL路径。
第一个方法
办法1、不要将 hello 应用放在
Tomat
的默认webapp
目录下,把它移出去,然后在server.xml
中修改docBase
的值为项目所在位置的绝对路径就可以了。
在Tomcat中的conf
目录中,在server.xml
中的,<host/>
节点中添加:
<Context path="项目的URL路径" docBase="Web应用和本地路径" debug="0" privileged="true">
</Context>
第二个方法
删除掉server.xml
中 Context
的手动配置,这样就不会加载两次,因为项目在webapp
下,所以在访问时,就只能是:http://ip:port/项目地址
这样来访问了。
如果说,你项目已经移入了
webapp
目录,但是还是一样,那你IDEA配置应该还是映射状态。
就像这样:
这样仍然处于映射状态,至于怎么配置请自行研究,我是直接去Tomcat
的bin
里面启动的。
第三个方法
在Tomcat
的conf
目录中,新建 Catalina
(注意大小写)\localhost
目录,在该目录中新建一个xml
文件,名字可以随意取,只要和当前文件中的文件名不重复就行了,该xml
文件的内容为:
<Context path="项目的URL路径" docBase="Web应用和本地路径" debug="0" privileged="true">
</Context>
尾述
jsp
是一个很老的技术,我不是特别喜欢,但是找到一个问题是对自己很好的一个提升,所以我觉得这个时间很值,尽管这个技术不是特别重要。
好的程序是改出来的,好的bug是找出来的。