Tomcat
基础
Tomcat是什么;是服务器软件,是在靶场中发射子弹的枪。
一个可以发布到tomcat/webapp中的目录结构。
- static
- js:
.js
- img:
.png
.jpg
- css:
.css
- js:
- page:
.html
- WEB-INF(受保护的资源目录)
- classes:字节码根路径
- lib:依赖jar包存放路径
- web.xml:项目的配置文件
| static和page是属于视图相关的文件,可以随意编排。
部署项目的两种方式
-
直接扔到webapps
-
放到其他目录,在\Tomcat 10.1\conf\Catalina\localhost添加配置
如果部署的项目文件夹为app,则添加如下配置
app.xml
<Context path="/app" docBase="D:\myWebApp\app" /> # path为应用上下文路径,即为url的路径,一般与项目文件名保持一致 # docBase为应用的地址
要访问tomcat原有的管理项目,需要先设置tomcat密码。
在/cnf/tomcat-users.xml文件中添加如下代码:
<role rolename="admin-gui"/>
<role rolename="admin-script"/>
<role rolename="manager-gui"/>
<role rolename="manager-script"/>
<role rolename="manager-jmx"/>
<role rolename="manager-status"/>
<user username="admin" password="admin" roles="manager-gui,manager-script,manager-jmx,manager-status,admin-script,admin-gui"/>
访问http://localhost:8080/manager/html,输入admin/admin
idea开发javaweb工程
-
建立Tomcat和idea关联
-
使用idea创建javaweb工程,在web工程中开发代码
首先配置JDK,模块,引用的库,Artifacts
-
如果使用了Servlet,模块中需要添加Tomcat依赖
-
使用idea将工程构建成一个可以发布的app
当缺少WEB目录时,可以通过下面的方式添加
-
使用idea将构建好的app部署到tomcat中启动运行
idea运行javaweb工程的原理
| 疑问:为什么在idea中运行javaweb工程后,在对应的tomcat的workapp目录下并没有应用文件?
idea为了避免污染硬盘中的tomcat目录,没有直接把应用文件放到workapp中,而是根据需要部署的web应用,创建了一套配置文件,让tomcat根据那个配置文件进行运行。
继续打开 conf/Catalina/localhost
中的 demo_war_exploded.xml
,有下面的代码,配置了web应用的上下文路径和项目文件位置
<Context path="/demo_war_exploded" docBase="C:\Users\Timothy\Documents\WeChat Files\wxid_b7e193fz08w512\FileStorage\File\2024-09\知校聚合支付接口(demo是PC端扫码跳转)\java\demo\out\artifacts\demo_war_exploded" />
Servlet
Servlet简介
Servlet是什么?
静态资源与动态资源:预先生成好的资源;服务器接受用户请求参数,动态生成的资源。
Servlet:能够处理客户请求并做出响应的一套Java技术标准,即Java代码生成动态资源的标准。
Servlet运行在服务端,所以只能在Web项目中开发,且在Tomcat这样的服务容器中运行。
Servlet运行流程?
用户请求 -> Tomcat -> Servlet -> Java类(Controller,Service,Mapper,DAO)
Servlet开发流程
基本流程
-
创建javaweb项目,同时将tomcat作为项目依赖
-
重写service方法,service(HttpServletRequest req, HttpServletResponse resp),定义业务处理代码
public class UserServlet extends HttpServlet { @Override protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // 1.获取请求参数,只要是kv形式(无论在请求头还是请求体),都可以通过getParameter方法获取 String username = req.getParameter("username"); // 2.执行业务代码 String info = "Yes"; if("atguigu".equals(username)) { info = "No"; } // 3.响应数据 resp.setContentType("text/html"); // 设置响应头 PrintWriter writer = resp.getWriter(); writer.write(info); } }
-
在web.xml中,配置Servlet的访问路径【可以直接用注解
@WebServlet("/userName")
替换】
注意事项:
- 如何导入
servlet-api
依赖
- 通过在Web资源目录下新建lib文件夹,把依赖放进去
- 通过Project Settings-Modules-Dependency指定
Tomcat 10.1
自动导入了jsp-api
和servlet-api
依赖
Tomcat 10.1在哪里配置的?见“idea开发javaweb工程”中的第一步配置。
两种方式有什么区别?
区别在于是否会把依赖存放在打好的war包中。lib方式会把servlet依赖放到war包,另一种方式由于scope是provided
,表示只会在编码时导入,不会放到war包。
如果不放到war包,程序怎么用servlet-api
呢?
tomcat中部署的所有war包共享当前tomcat的lib库中的依赖。【所以自己导入后反而有可能由于冲突报错】
- 怎么指定响应头的
Content-type
字段。
-
对于静态资源,tomcat的
web.xml
维护了请求的静态文件的扩展名与响应头Content-type
字段的对应关系。比如请求的是xxx.html
文件,则Content-type
为text/html -
对Servlet,默认的
Content-type
是html,如果数据需要作为其他类型解析,则要手动设置。具体设置的类型可以参考web.xml
Servlet生命周期
生命周期 | 执行者 | 时机 |
---|---|---|
实例化 | 构造器 | 第一次请求/服务启动 |
【load-on-startup 】 |
||
初始化 | init | 构造完毕 |
接受请求,处理请求 | service | 每次请求 |
销毁 | destory | 关闭服务 |
Servlet在Tomcat中是单例的,所以不建议在其中修改变量值。
DefaultServlet
Tomcat中提供了一个DefaultServlet
用来返回静态资源。
当所有Servlet都无法匹配到路径时,DefaultServlet
会接手,将其视为请求静态资源,然后把对应文件的内容放到请求体,并填充请求头的Content-type
字段,进行返回。
配置文件:web.xml
Servlet继承结构
Servlet-GeneticServlet-HttpServlet-自定义的Servlet。
在自定义Servlet中,可以重写service方法,也可以只重写doXXX方法。
ServletContex:属于应用域,单例的,用于在不同Servlet之间做沟通。
请求转发与重定向
请求转发
- 对客户端透明
- 目标资源只能是项目内的资源,不能是外部资源
- 目标资源可以是servlet动态资源,也可以是html等静态资源
- 目标资源可以是WEB-INF下的受保护资源,这也是访问受保护资源的唯一方式
@WebServlet("/servletA")
public class ServletA extends HttpServlet { @Override protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("ServletA执行了"); // 请求转发给ServletB // 1.获得请求转发器 RequestDispatcher requestDispatcher = req.getRequestDispatcher("servletB"); // 2.做出转发动作 requestDispatcher.forward(req, resp); // (也可以转发给视图资源) // req.getRequestDispatcher("a.html").forward(req, resp); // (转发到 WEB-INF 目录下的资源,访问WEB-INF下受保护资源的唯一访问方式) // req.getRequestDispatcher("WEB_INF/b.html").forward(req, resp); }
}
响应重定向
- 客户端行为,客户端发送多次请求
- 目标资源可以是外部资源
- 目标资源可以是servlet动态资源,也可以是html等静态资源
- 目标资源不能是WEB-INF下的受保护资源,这也是访问受保护资源的唯一方式
@WebServlet("/servlet1")
public class Servlet1 extends HttpServlet { @Override protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("servlet1运行了"); // 等价于 resp.setStatus(302); resp.setHeader("location", "servlet2"); resp.sendRedirect("servlet2"); // 外部资源 // resp.sendRedirect("http://baidu.com"); }
}
总结
客户端透明 | 内部资源 | WEB-INF | 外部资源 | |
---|---|---|---|---|
请求转发 | √ | √ | √ | × |
响应重定向 | × | √ | × | √ |
实现页面跳转时,优先使用重定向。