回顾
nginx 基本使用
- 启动 nginx ./nginx
- nginx 配置文件中,修改 web 资源位置
- 重新加载配置文件 ./nginx -s reload
- 停止 nginx ./nginx -s stop
tomcat 基本使用
- 它与 nginx 的不同
- tomcat 静态+动态
- nginx 性能高
- 启动 tomcat bin/startup
- 启动时黑窗口一闪而过 JAVA_HOME
- 启动出现异常信息 logs
- 查找端口占用,杀死进程
- address already in use…
- window, netstat -ano | findstr 8080 管理员 taskkill /F /PID pid
- linux netstat -tlnp | grep 8080 kill -9 pid
- 乱码问题
- conf/logging.properties Console utf-8 => gbk
- 停止 tomcat bin/shutdown
- 如何访问 tomcat,地址格式是怎样的
- http://localhost:8080/虚拟目录
- 如何修改 tomcat 默认端口
- conf/server.xml 中 <Connector port=8080
- 部署项目
- 方式1 - 把项目放入 webapps 目录下, war 放入 webapps 目录下(*)
- 方式2 - conf/server.xml <Context path="/虚拟目录" docBase=“项目实际在磁盘的位置”
- 方式3 - conf/Catalina/localhost 新建xml文件,文件名就是虚拟目录 内容是<Context docBase=“项目实际在磁盘的位置”
- idea 集成 tomcat
- 如何配置虚拟目录
- 如何修改端口
- 如何配置浏览器
- 如何让页面改动立刻生效
今日内容
linux 安装 tomcat
1. http 协议(*)
- 超文本传输协议
- 客户端
- 2.0 , 只要连接了服务器也会向客户端推送信息
- 基于 tcp/ip
请求格式(*)
GET 资源地址?参数名1=值1&参数名2=值2 HTTP/1.1
key1: 值1
key2: 值2
空行
POST 资源地址 HTTP/1.1
key1: 值1
key2: 值2
空行
参数名1=值1&参数名2=值2
请求头
Host: 请求的主机 (必须的)
User-Agent: 客户端的类型
响应格式(*)
HTTP/1.1 状态码 状态码文字
key1: 值1
key2: 值2
空行
资源内容
状态码
200 成功
404 资源不存在
500 服务器代码异常
响应头
Content-Type: text/html text/xml image/png image/jpeg ... 指定了响应资源的内容类型
Content-length: 响应资源的长度(单位是字节)
2. servlet
idea 部署项目的问题
- 项目的发布格式和存储位置
- 静态资源拷贝后无效问题
- 多个项目问题
- 项目失效问题
servlet 入门(*)
- 服务器端的小程序 server applet, 处理请求和应答 service
步骤
1) 编写 servlet
* 实现 Servlet 接口
* 继承 GenericServlet
* 继承 HttpServlet
2)编写配置文件 web.xml - 给 servlet 配置了资源路径 (url-pattern)
web - 资源目录
|- WEB-INF 并不能直接访问
|- lib 项目依赖的 jar 包
|- classes 放置jar编译后的类文件
|- web.xml 核心配置文件
3) 通过浏览器访问
http://ip地址:端口/虚拟目录/servlet 资源路径
入门案例简化 - 不需要配置 web.xml 而是通过 @WebServlet 来为其指定资源路径
@WebServlet(urlPatterns = "/my") // 给servlet 提供一个资源路径
public class MyServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("进入了servlet");
resp.getWriter().print("<h1>hello</h1>");
}
}
servlet 执行流程(*)
xml 方式
- 根据浏览器输入的路径,第一步先通过虚拟目录匹配到你的应用程序(就是项目)
- 第二步再根据资源路径,匹配到
<url-pattern>
中的路径 - 第三步根据
<url-pattern>
对应的 servlet 名字,找到 servlet 的类 - 第四步,创建 servlet 并初始化(没配置 load-on-startup 的情况)
- 第五步,调用 servlet 的 service 方法,处理请求和响应,将响应返回给浏览器
注解方式
- 根据浏览器输入的路径,第一步先通过虚拟目录匹配到你的应用程序(就是项目)
- 第二步再根据资源路径,匹配到 @WebServlet 中的 urlPatterns 的路径
- 第三步,创建 servlet 并初始化(没配置 load-on-startup 的情况)
- 第四步,调用 servlet 的 service 方法,处理请求和响应,将响应返回给浏览器
get 与 post 请求(*)
- 地址栏直接输入是 get 请求
- 超链接点击是 get 请求
- 表单提交是根据表单的 method 属性决定是 get 还是 post 请求
重写了 doGet 或 doPost 时,不要调用 父类的 doGet 和 doPost 否则会出现 405 错误
servlet 继承体系
servlet 生命周期(*)
- 对象创建和初始化(init)只调用一次
- 是tomcat 服务器创建 servlet 对象,初始化等方法的调用也是 tomcat 来完成的
- doGet 或 doPost (会执行多次)
- 销毁 (destroy) 只调用一次
<load-on-startup>1</load-on-startup>
可以控制servlet 的创建时机- 饿汉
- 懒汉
servlet 线程安全(把结论记住)
- 原因是 servlet 只有一个对象,如果多个线程都来访问同一个对象,就有可能发生线程安全问题
- 解决方法1,不用成员变量,而是使用局部变量(是各个线程私有)推荐!
- 解决方法2,有共享变量,有读写,需要用锁保护 synchronized (最坏选择)
- 还有一种情况,有共享变量,但共享变量是【只读的(包括内容)】,这时也没有线程安全问题
servlet 路径映射(*)
- /资源路径 - 精确匹配
- /前缀/* - 前缀匹配
- *.后缀 - 后缀匹配
<url-pattern>/a/b/c/test/*</url-pattern> <!-- servlet1 -->
<url-pattern>*.do</url-pattern> <!-- servlet2 -->
/test/a.do
/a/b/c/test/1
/a/b/c/test/2
/a/b/c/test/3
默认 servlet
-
路径是
/
- 最低的优先级 servlet,其它的 servlet 都匹配不到时,才会找 默认 servlet -
再找不到就 404
-
tomcat 提供的默认servlet 的功能是处理静态资源(html,css, js, 图片), 如果自己提供了一个路径为 / 的 servlet 那么就会影响静态资源的访问