JavaWeb_day02_Tomcat&Servlet

JavaWeb_day02_Tomcat&Servlet

1.Tomcat
1.1系统结构

  • CS 结构:(Client Server) 客户端+服务器的方式
  • BS 结构:(Browser Server) 浏览器+服务器的方式

1.2Tomcat 配置文件

  • 主配置文件 server.xml

  • 8080 端口:tomcat 服务默认端口号。访问 url 地址后必须手动写 :8080

  • 80 端口:HTTP协议采用的端口号。访问 url 地址后不用写 :80

2.Servlet
2.1Servlet 介绍

  • Servlet 是运行在Java服务器端的程序,用于接收和响应来自客户端基于 HTTP 协议的请求

2.2Servlet 执行过程

  • 客户端浏览器 发起请求;
  • Tomcat服务器 解析请求地址(URL);找到对应的应用;
  • servlet_demo1 找到应用的web.xml
  • web.xml 解析请求资源地址(URI)找到应用的资源
    ServletDemo01 执行service方法,响应给客户端浏览器

2.3Servlet 实现方式

第一种

  • 实现 Servlet 接口,实现所有的抽象方法。该方式支持最大程度的自定义。

第二种

  • 继承 GenericServlet 抽象类,必须重写 service 方法,其他方法可选择重写。该方式让我们开发 Servlet变得简单。但是这种方式和 HTTP 协议无关。

第三种

  • 继承 HttpServlet 抽象类,需要重写 doGet 和 doPost 方法。该方式表示请求和响应都需要和 HTTP 协议相关。

2.4Servlet 线程安全问题

  • 由于 Servlet 采用的是单例模式,也就是整个应用中只有一个实例对象。所以我们需要分析这个唯一的实例对象中的类成员是否线程安全。

  • 模拟用户登录功能来查看 Servlet 线程是否安全。

  • 结论:一个浏览器代表一个线程,多个浏览器代表多个线程。按理说我们期望的应该是每个浏览器查看的都应该是自己的用户名。而现在的结果是浏览器中数据混乱。因此,我们可以认为 Servlet 是线程不安全的!

  • 解决:定义类成员要谨慎。如果是共用的,并且只会在初始化时赋值,其他时间都是获取的话,那么是没问题的。如果不是共用的,或者每次使用都有可能对其赋值,那就要考虑线程安全问题了,可以将其定义到
    doGet 或 doPost 方法内或者使用同步功能即可。

代码
package com.itheima.review;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

//模拟用户登录功能来查看 Servlet 线程是否安全
@WebServlet("/reviewDemo1")
public class reviewDemo1 extends HttpServlet {
    private String username;

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        synchronized (this) {
            username = req.getParameter("username");
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            resp.getWriter().print("welcome" + username);
        }

    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

2.5Servlet 映射方式
第一种

  • 具体名称的方式。访问的资源路径必须和映射配置完全相同。

第二种

  • / 开头 + 通配符的方式。只要符合目录结构即可,不用考虑结尾是什么。

第三种

  • 通配符 + 固定格式结尾的方式。只要符合固定结尾格式即可,不用考虑前面的路径。
  • 注意:优先级问题。越是具体的优先级越高,越是模糊通用的优先级越低。第一种 > 第二种 > 第三种。

2.6Servlet 多路径映射练习

  • 我们可以给一个 Servlet 配置多个访问映射,从而根据不同的请求路径来实现不同的功能。

场景分析:
如果访问的资源路径是 /vip 商品价格打9折。
如果访问的资源路径是 /vvip 商品价格打5折。
如果访问的资源路径是其他 商品价格不打折。

代码
package com.itheima.review;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

@WebServlet("/reviewDemo2/*")
public class reviewDemo2 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        int money = 1000;
        String name = req.getRequestURI();
        name = name.substring(name.lastIndexOf("/"));
        if ("/vip".equals(name)) {
            System.out.println((money * 0.9));
        } else if ("/vvip".equals(name)) {
            System.out.println(money * 0.5);
        } else {
            System.out.println(money);
        }
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

3.ServletConfig
3.1ServletConfig介绍

  • ServletConfig 是 Servlet 的配置参数对象,在 Servlet 的规范中,允许为每一个 Servlet都提供一些初始化的配置。所以,每个 Servlet 都有一个自己的 ServletConfig
  • 作用:在 Servlet 的初始化时,把一些配置信息传递给 Servlet
  • 生命周期:和 Servlet 相同

3.2ServletConfig 配置方式

  • <servlet>标签中,通过<init-param>标签来配置。有两个子标签。

  • <param-name>:代表初始化参数的 key。

  • <param-value>:代表初始化参数的 value。

3.3ServletConfig 常用方法

  • String getInitParameter(String name) 根据参数名称获取参数的值

  • Enumeration getInitParameterNames() 获取所有参数名称的枚举

  • String getServletName() 获取Servlet的名称

  • ServletContext getServletContext() 获取ServletContext对象

3.4ServletConfig 实现步骤

  • 定义一个类,继承 HttpServlet

  • 在成员位置,声明一个 ServletConfig 对象

  • 重写 init 方法,并为 ServletConfig 对象赋值

  • 重写 doGet 和 doPost 方法

  • 在 web.xml 文件中进行配置

  • 在 doGet 方法中获取初始化参数

  • 部署并启动项目

  • 通过浏览器测试

代码
package com.itheima.review;

import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Enumeration;

@WebServlet("/reviewDemo3")
public class reviewDemo3 extends HttpServlet {
    private ServletConfig config;

    @Override
    public void init(ServletConfig config) throws ServletException {
        this.config = config;
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String encodingValue = config.getInitParameter("encoding");
        System.out.println(encodingValue);

        String servletName = config.getServletName();
        System.out.println(servletName);

        ServletContext servletContext = config.getServletContext();
        System.out.println(servletContext);

        Object username = servletContext.getAttribute("username");
        System.out.println(username);

        Enumeration<String> initParameterNames = config.getInitParameterNames();
        while (initParameterNames.hasMoreElements()) {
            String name = initParameterNames.nextElement();
            String value = config.getInitParameter(name);
            System.out.println(name + "..." + value);
        }
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

4.ServletContext
4.1ServletContext介绍

  • ServletContext 是应用上下文对象(应用域对象)。每一个应用中只有一个 ServletContext 对象。
  • 作用:可以获得应用的全局初始化参数和达到 Servlet 之间的数据共享。
  • 生命周期:应用一加载则创建,应用被停止则销毁。

4.2ServletContext配置方式

  • ServletContext 并不属于某个 Servlet 的配置,而是针对于整个应用的配置,也叫全局的初始化参数。
  • <web-app>标签中,通过<context-param>标签来配置。有两个子标签。
  • <param-name>:代表全局初始化参数的 key。
  • <param-value>:代表全局初始化参数的 value。

4.3ServletContext 常用方法

  • String getInitParameter(String name) 根据名称获取全局配置的参数

  • String getContextPath() 获取当前应用的访问虚拟目录

  • String getRealPath(String path) 根据虚拟目录获取应用部署的磁盘绝对路径

  • void setAttribute(String name,Object value) 向应用域对象中存储数据

  • Object getAttribute(String name) 通过名称获取应用域对象中的数据

  • void removeAttribute(String name) 通过名称移除应用域对象中的数据

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值