关于tomcat,我对其的影响仅仅停留在它是一个服务器,可以部署项目在上面的印象上。本次带着什么是tomcat,它是干什么的这样的疑问来学习了tomcat,感受颇深,记录一下学习心得。还有解决配置java环境变量的详细方法
目录
1)catalina.{yyyy-MM-dd}.log tomcat
1.tomcat基本介绍
Tomcat是 Apache软件基金会(Apache Software Foundation) 的Jakarta项目中的一个核心项目,由Apache、Sun和其他公司及个人共同开发完成。Tomcat服务器是一个免费开源的web应用服务器,属于轻量级应用服务器,在中小型和并发访问用户不是很多的场合被普遍使用,是开发和调试JSP程序的首选。
Tomcat和IIS(微软公司提供的基于运行Microsoft Windows的互联网基本服务) 等服务器一样,具有处理HTML页面的功能,另外它还是一个Servlet和JSP容器,独立的Servlet容器除了Tomcat外,web应用服务器还有jetty,weblogic,websphere,undertow等。
ps:有时我们会将web叫做web服务器,实际上tomcat更准确的叫法是应用服务器。web服务器主要是指专门来处理html,css,图片等静态资源的服务器,必要apache服务器。
2.目录结构及作用
tomcat(apache-tomcat-9.0.50)目录结构如下图所示
2.1 backup
此目录为备份目录,如果你不是很清楚backup文件夹中都有什么内容的话,最好不要直接删除,否则会导致重要文件丢失,如果你不需要这些备份文件的话,那就可以直接删除了。
2.2 bin
bin目录是主要用来存放tomcat命令的目录,里面主要有两种类型的文件,一种是以.bat为拓展名的文件,一种是以.sh为拓展名的文件。其中.bat的文件是在windows平台的命令,.sh的文件是用于linux平台的命令。
1)setclasspath
用于设置Java环境变量,如JAVA_HOME,JRE_HOME
2)catalina
该文件也是用来配置环境的,如CATALINA_HOME,及tomcat的安装路径,我们可以在此目录设置Java的启动参数,如最大最小堆空间大小
3)startup
用来给启动tomcat,当双击startup后,tomcat启动,读取catalina脚本配置启动环境,catalina 又会调用setclasspath脚本,用来设置jdk需要的环境变量,如果系统没有定义JAVA_HOME环境变量,则在会报错退出
4)shutdown
用于停止tomcat服务
startup.bat点击一闪而过解决方法(根本解决手段)
原因1:java环境变量出错
通过win+r打开命令控制符,通过cd指令直到打开tomcat文件夹,运行startup.bat
我的tomcat放在了d盘programFiles中,打开方式如下:
d: -> cd programFiles -> cd apache-tomcat-9.0.50 -> cd bin -> startup.bat
(如下图所示,下图为未配置环境变量)
首先看jdk在哪 在cmd中使用 java -verbose (java空格-verbose)查看jdk所在目录
如下图所示
去文件夹查看jdk检查是否存在jre目录
如果不存在即重新去下载jdk如果存在继续以下操作
win10系统右键此电脑点击属性,在关于页面往下滑找到相关设置中的高级系统设置
win11系统打开设置,在系统/系统信息高级系统设置里设置里找到环境变量
查看系统变量下是否存在JAVA_HOME、CLASSPATH,Path中是否存在%JAVA_HOME%,如果不存在新建变量
变量名:JAVA_HOME 值:jdk所在路径
变量名:CLASSPATH 值:.,%JAVA_HOME%\lib\dt.jar,tools.jar; (.,不能省略)
选中Path点击编辑在变量值中添加如下两个值放在最前面(推荐),最后不要忘记点击确定
这时候再点击startup.bat启动
如下图所示,即服务器启动成功
原因2:别处tomcat直接复制过来使用
检查以上环境变量是否配置成功,如果是从别处copy进来的tomcat这时候大概率还是无法运行,需要再conf中的server.xml右键编辑滑到最底部查看是否存在Context标签,最简单粗暴的办法就是直接删除所有的context(不要误删host标签否则会报错)
2.3 conf
该目录主要用来存放tomcat的配置文件, 重要的配置文件如下
1)server.xml
用于配置端口号,虚拟主机,默认加载项目,请求编码等等,是tomcat中最常使用的配置文件
2)web.xml
为所有的部署在该tomcat下的web应用通用的配置,与每个web应用的web.xml配合使用。例如DefaultServlet,就算系统中没有配置任何的servlet,tomcat依然可以处理html,js,css等静态资源的请求,就是这个servelt起的作用。
此外,这是总web.xml文件,当你修改的是tomcat服务器目录中的总web.xml文件,拿也就等于将所有web项目中的.xml文件修改了。其中JspServlet就是当请求jsp页面时,则会用到这个servlet。session过期时间配置session-timeout参数,也是在这个web.xml中配置的
3)catalina.policy
这个是tomcat安全相关的配置文件,主要使用安全策略文件可以在tomcat启动是附上 -security
4)catalina.properties
安全配置,类加载设置,不需扫描的类,字符缓存等配置
ps:properties是政策的意思
5)context.xml
所有在tomcat中发布的应用都会使用的公用配置,例如:发布的web应用的描述文件的位置及名称,及session持久化配置等。
注:如果是在该目录下配置session持久化,那么就对所有web项目有效,如果是在一个web项目中配置session持久化,那么就只对该web项目有效
6)tomcat-users.xml
tomcat的角色(授权用户)配置文件,用于访问tomcat管理应用程序时的安全性设置,用server.xml中引用的默认的用户数据库域(UserDatabase Realm)使用它,所有的凭据都是默认被注释的
7)tomcat-users.xsd
定义了 tomcat-users.xml 所使用到的标签,即tomcat-user.xml 的结构定义文件
2.4 lib
lib目录下存放所有的部署在tomcat中的web应用公用的jar包
2.5 logs
用于保存tomcat运行时的日志数据
1)catalina.{yyyy-MM-dd}.log tomcat
自己的运行日志
2)localhost.{yyyy-MM-dd}.log
应用初始化日志,包含tomcat的启动和暂停时的运行日志,没有catalina.{yyyy-MM-dd}.log记录的全,只包含一部分
3)localhost_access_log.{yyyy-MM-dd}.txt
tomcat访问(access)日志,包括请求时间,资源,返回的状态码
4)manager.{yyyy-MM-dd}.log
是tomcat管理控制台应用的专有日志
在Linux系统中,tomcat将日志记入catalina.out文件,可以使用 tail -f catalina.out 进行跟踪。
2.6 temp
存放tomcat在运行期间产生的临时文件,可以清空该目录的文件,但不能删除该目录,否则可能会引发不可预知的错误
2.7 webapps
tomcat默认的项目部署目录,在默认情况下,如果要发布应用可以直接将应用的war包放入该目录即可完成发布,也可以直接发布未压缩的目录,但要求该目录需要符合web应用规范。
- doc tomcat文档
- examples tomcat自带的web应用示例
- host-manager tomcat主机管理应用程序
- manager tomcat的管理应用程序
- ROOT 如果项目部署为ROOT,则在地址栏直接输入:http://ip:port/ 就可以访问,即不用输入应用名
2.8 work
用来部署应用中由jsp文件生成的java文件和编译之后的class文件,可以删除,删除后可以迫使tomcat重新生成jsp对用的java和class文件。
2.9 其他文件
- LICENSE tomcat开源许可文件
- NOTICE tomcat说明文件
- RELEASE-NOTES 版本说明文件
- README.md 即 README.txt tomcat帮助文件
3.session持久化
即在关闭或重启服务器、网页后session中的数据仍然一直存在
1)主要配置文件
session持久化主要是在context.xml文件中进行配置的,context.xml文件可以出现在两个位置上,其作用域不同,配置方式一致:
- tomcat安装目录\conf 目录中的context.xml配置文件,该文件中的配置对部署在该tomcat中的所用应用都有效
- 所开发的web应用的META-INFO目录中,创建一个context.xml配置文件,放在此处的配置,只对所属的web应用有效
<?xml version="1.0" encoding="UTF-8"?>
<Context>
<!--
maxIdleSwap: 自上次访问session以来,session数据应被保存到stroe中的时间间隔,该值应该大于等于maxIdleBackup参数的值
maxIdleBackup: 自上次访问会话后,会话有资格保留到会话存储区之前的时间间隔(秒),-1为默认值,表示禁用
saveOnRestart: 重启是是否持久化session
maxActiveSession:session总数大于该参数设置的值时,会将超出部分空闲的session换出
-->
<Manager className="org.apache.catalina.session.PersistentManager" saveOnRestart="true" maxIdleBackup="1" maxIdleSwap="1">
<Store className="org.apache.catalina.session.FileStore" directory="d:/aaa" />
</Manager>
</Context>
xml中属性的详细描述
maxIdleSwap: 自上次访问session以来,session数据应被保存到stroe中的时间间隔,该值应该大于等于maxIdleBackup参数的值
maxIdleBackup: 自上次访问会话后,会话有资格保留到会话存储区之前的时间间隔(秒),-1为默认值,表示禁用
saveOnRestart: 重启是是否持久化session
maxActiveSession:session总数大于该参数设置的值时,会将超出部分空闲的session换出
2)操作示例:
创建web工程
加入tomcat依赖
创建一个Customer实体bean,之后会将该bean放入session,注意:因为session需要进行持久化,所以该bean需要实现两个接口,分别为:HttpSessionActivationListener,Serializable,创建一个servlet,在用户访问该servlet时,将Customer存入session,已测试持久化
在webapp下的META_INF文件夹下建立一个文件Context.xml
Customer
public class Customer implements HttpSessionActivationListener, Serializable {
private String id;
private String name;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public void sessionDidActivate(HttpSessionEvent event) {
String name = ((Customer)event.getSession().getAttribute("cust")).getName();
System.out.println("钝化之后 = " + name);
}
@Override
public void sessionWillPassivate(HttpSessionEvent event) {
String name = ((Customer)event.getSession().getAttribute("cust")).getName();
System.out.println("钝化之前 = " + name);
}
@Override
public String toString() {
return "Custom [hljs-string" style="color: #d69d85; line-height: 160%; box-sizing: content-box;">", name=" + name + "]";
}
}
Servlet
@WebServlet("/login")
public class LoginServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
Object cust_obj = req.getSession().getAttribute("cust");
if(Objects.isNull(cust_obj)) {
Customer cust = new Customer();
cust.setId("cust_001");
cust.setName("张三");
System.out.println("将客户信息放入session");
req.getSession().setAttribute("cust", cust);
} else {
System.out.println("客户信息已经放入session");
String name = ((Customer)req.getSession().getAttribute("cust")).getName();
System.out.println("从session获取客户信息,name = " + name);
}
}
}
将web应用部署,运行之后访问servlet,查看指定的目录中是否有session的持久化数据,重新启动web,看session是否会从持久化数据中恢复