Java-Servlet技术入门笔记-2

本文涉及的产品
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
全局流量管理 GTM,标准版 1个月
云解析 DNS,旗舰版 1个月
简介: 三、ServletContext类1、什么是ServletContext代表整个web工程,可以与程序的容器(Tomcat服务器)通信

三、ServletContext类

1、什么是ServletContext

代表整个web工程,可以与程序的容器(Tomcat服务器)通信

1.ServletContext是一个接口,它表示Servlet上下文对象

2.一个web工程,只有一个ServletContext对象实例

  ServletConfig对象取决于有多少个Servlet程序(一一对应,只能访问到配置文件中属于自己      的配置信息)

   但ServletContext对象还能访问配置文件中上下文参数

3.ServletContext对象是一个域对象

4.ServletContext对象是在web工程部署启动的时候创建,在web工程停止的时候销毁

什么是域对象


域对象指的是可以像Map一样存取数据的对象


这里的域指的是存取数据的操作范围——整个web工程


存数据
取数据 删除数据
Map put() get() remove()
域对象 setAttribute() getAttribute() removeAttribute()

2、获取ServletContext对象的方法

1.通过HttpServletRequest对象获取

  • request.getServletContext();

2.通过HttpServlet获取

  • this.getServletContext();

3.通过servletConfig对象获取

  • servletConfig.getServletContext();
@WebServlet("/getcontext")
public class GetContextServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //通过HttpServlet获取
        ServletContext servletContext1 = this.getServletContext();
        //通过HttpServletRequest req对象获取
        ServletContext servletContext2 = req.getServletContext();
        //通过servletConfig对象获取
        ServletContext servletContext3 = this.getServletConfig().getServletContext();
        System.out.println(servletContext1);
        System.out.println(servletContext2);
        System.out.println(servletContext3);
    }
}

3、ServletContext类的四大作用

1.获取web.xml中配置的上下文参数context-param

2.获取当前工程路径,格式:/工程路径

3.获取工程部署在服务器硬盘上的绝对路径

4.像Map一样存取数据

1)获取信息

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
    <!--新增部分-->
    <!--context-param是上下文参数(它属于整个web工程),可以配置多组-->
    <context-param>
        <param-name>username</param-name>
        <param-value>context</param-value>
    </context-param>
    <context-param>
        <param-name>password</param-name>
        <param-value>root</param-value>
    </context-param>
    <!--新增部分-->
    <servlet>
        <servlet-name>HelloServlet</servlet-name>
        <servlet-class>com.first.cyh.HelloServlet</servlet-class>
        <init-param>
            <param-name>username</param-name>
            <param-value>root</param-value>
        </init-param>
        <init-param>
            <param-name>url</param-name>
            <param-value>jdbc:mysql//localhost/test</param-value>
        </init-param>
    </servlet>
    <servlet-mapping>
        <servlet-name>HelloServlet</servlet-name>
        <url-pattern>/hello</url-pattern>
    </servlet-mapping>
</web-app>
public class ContextServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //获取配置文件中的上下文参数
        ServletContext context = getServletConfig().getServletContext();
        System.out.println(context.getInitParameter("username"));
        System.out.println(context.getInitParameter("password"));
        //获取当前的工程路径,格式:/工程路径
        System.out.println(context.getContextPath());
        //获取工程部署后在服务器硬盘的绝对路径
        /*
          getRealPath()返回一个给定虚拟路径的真实路径
          这个斜杆表示站点的根,也就是获取网站的根目录,即工程部署路径
            而/css就是表示该路径下的css文件夹
         */
        System.out.println(context.getRealPath("/"));
        System.out.println(context.getRealPath("/css"));
        System.out.println(context.getRealPath("/jpg"));
    }
}

上述程序执行后会返回


context

root

/myfirst

E:\eclipse-workspace\Javaweb-servlet\out\artifacts\Javaweb_servlet_war_exploded

E:\eclipse-workspace\Javaweb-servlet\out\artifacts\Javaweb_servlet_war_exploded\css

E:\eclipse-workspace\Javaweb-servlet\out\artifacts\Javaweb_servlet_war_exploded\jpg


而为什么获得的路径为什么和我们项目创建的路径不一样,在我的另一篇博文(web工程部署路径与getServletConfig().getRealPath()_得过且过的勇者y的博客-CSDN博客中详细讲解了

为什么需要获取工程存放路径呢?

因为项目在本地开发后,项目中的文件路径写的是本地的路径。然而当项目部署到其他设备后,物理地址发生改变,就会导致文件找不到而报错。

2)存取数据

public class ContextServlet1 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //GenericServlet获取获取ServletContext对象的方式,等同于getServletConfig().getServletContext()
        ServletContext servletContext = getServletContext();
        System.out.println("保存之前Context1中获取域数据key1的值是:" + servletContext.getAttribute("key1"));
 public class ContextServlet2 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        ServletContext servletContext = getServletContext();
        System.out.println("Context2中获取域数据key1的值是:" + servletContext.getAttribute("key1"));
    }
}
       //存数据
        servletContext.setAttribute("key1","value1");
        //取数据
        System.out.println("Context1中获取域数据key1的值是:" + servletContext.getAttribute("key1"));
    }
}
public class ContextServlet2 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        ServletContext servletContext = getServletContext();
        System.out.println("Context2中获取域数据key1的值是:" + servletContext.getAttribute("key1"));
    }
}
public class ContextServlet2 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        ServletContext servletContext = getServletContext();
        System.out.println("Context2中获取域数据key1的值是:" + servletContext.getAttribute("key1"));
    }
}

以下为两次访问ContextServlet1输出的结果(没有重新部署)


保存之前Context1中获取域数据key1的值是:null

Context1中获取域数据key1的值是:value1


保存之前Context1中获取域数据key1的值是:value1

Context1中获取域数据key1的值是:value1


重新部署后再次访问ContextServlet1输出的结果


保存之前Context1中获取域数据key1的值是:null

Context1中获取域数据key1的值是:value1


这是因为ServletContext对象是在web工程部署启动的时候创建,在web工程停止的时候销毁,所以没有重新部署的话key1在set之后就一直存在,所以第二次及以后访问时都会有保存之前Context1中获取域数据key1的值是:value1,而重新部署之后第一次访问就又是null


而前文中的getInitParameter()获取的数据是保存在xml文件中的,故一直存在


总结


setAttribute方式存参数相当于把数据存在内存中,工程停止时消失,而xml方式存参数则是持久化到硬盘中


getInitParameter获得的是xml方式存储的参数


getAttribute获得的是setAttribute方式存储的参数


而当我们已经访问完ContextServlet1后再访问ContextServlet2,会输出


Context2中获取域数据key1的值是:value1


这是因为一个web工程,只有一个ServletContext对象实例,两个Servlet程序中的servletContext其实是相同的,如果我们在两个程序中都输出servletContext这个对象,值是相同的


所以当第一个Servlet程序设置完key1参数后,第二个自然也可以使用它

3)获取MIME类型

MIME类型是在互联网通信过程中定义的一种文件数据类型,格式为:大类型/小类型,如text/html,image/jpg

用处:响应头中content-type需要返回响应体的数据类型,这时候就要获取我们返回的数据的MIME类型

获取方法:通过文件后缀名在tomcat配置文件(tomcat的conf目录下的web.xml)中寻找对应的MIME类型(因为context对象可以与tomcat进行通信)

@WebServlet("/getmime")
public class GetMime extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ServletContext servletContext = this.getServletContext();
        //定义文件名
        String filename = "a.jpg";
        //通过文件名的后缀获取对应MIME类型
        String mimeType = servletContext.getMimeType(filename);
        System.out.println(mimeType);
    }
}

返回image/jpeg

四、HttpServletRequest类

1、作用

每次只要有请求进入Tomcat服务器,Tomcat服务器就会把请求过来的Http协议信息解析封装好到Request对象中,然后传递到service方法(doGet和doPost)中给我们使用。我们可以通过HttpServletRequest对象,获得到所有请求的信息

2、常用方法

getRequestURI():获取请求的资源路径

getRequestURL():获取请求的统一资源定位符(绝对路径)

getRemoteHost():获取客户端的IP地址

getHeader():获取请求头

getParameter():获取请求的参数

getParameterValues():获取请求的参数(多个值得时候使用)

getMethod():获取请求的方式(GET或POST)

setAttribute(key, value):设置域数据

getAttribute(key):获取域数据

getRequestDispatcher():获取请求转发对象

public class RequestAPIServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("URI-->" + req.getRequestURI());//URI-->/myfirst/req
        System.out.println("URL-->" + req.getRequestURL());//URL-->http://localhost:8080/myfirst/req
        //如果以localhost访问,则返回0:0:0:0:0:0:0:10:0:0:0:0:0:0:1
        //以127.0.0.1访问,则返回127.0.0.1
        //以真实ip访问,则返回真实ip
        System.out.println("HOST-->" + req.getRemoteHost());
        //HEADER-->Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.54 Safari/537.36 Edg/95.0.1020.30
        System.out.println("METHOD-->" + req.getMethod());//GET
        System.out.println("HEADER-->" + req.getHeader("User-Agent"));
    }
}
public class RequestGetParameter extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("用户名" + req.getParameter("username"));
        System.out.println("密码" + req.getParameter("password"));
        String[] hobbies = req.getParameterValues("hobby");
        try{
            System.out.println("兴趣爱好" + Arrays.asList(hobbies));
        }catch (Exception e){
            System.out.println(e.getStackTrace());
        }
    }
}

注意点


如果使用的是post请求,则需要设置字符集,否则在post请求参数是中文会出现乱码


req.setCharacterEncoding(“UTF-8”);


且此设置要在所有获取参数语句(不管会不会获取中文)的前面设置


只要有获取参数的语句在设置语句前面,不管这条语句会不会获取中文,都会导致设置失效,从而使那些在设置语句后的获取参数语句同样会乱码

3、请求转发

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-e8l4Ttgx-1636276443283)(C:\Users\Ken-Chy\Desktop\大二临时\00自学部分\后端\笔记\请求转发.png)]

public class Servlet1 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //查看请求的带来的数据
        String username = req.getParameter("username");
        System.out.println("servlet1中请求带来的数据:" + username);
        //处理业务
        //doSth
        username += "ahahha";
        System.out.println("业务1完成,username=" + username);
        //处理完业务,在request域中存储数据
        req.setAttribute("username",username);
        //询问servlet2的路径
        //请求转发必须以斜杆开始,表示http://ip:8080/工程名/
        RequestDispatcher requestDispatcher = req.getRequestDispatcher("/servlet2");
        //带着请求走向servlet
        requestDispatcher.forward(req,resp);
    }
}
public class Servlet2 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //查看请求带来的数据
        String username = request.getParameter("username");
        System.out.println("servlet2中请求带来的数据:" + username);
        //获取servlet1传入的数据
        Object obj = request.getAttribute("username");
        System.out.println("servlet1传入的数据:"+obj);
        //处理自己的业务
        System.out.println("业务处理完成");
    }
}

请求转发的特点

1.浏览器地址栏没有发生变化

2.它们是一次请求

3.它们共享Request域中的数据

4.可以转发到WEB-INF目录下

5.不可以访问工程以外的资源

4、base标签的作用

设置页面相对路径工作时参照的地址,href属性就是参数的地址值

应用场景

如果页面采用请求转发,跳转页面时地址不会发生改变,这时候在跳转到的页面中如果访问了设置成相对路径的地址,则会发生请求错误,因为如果没有设置base标签,默认相对地址会参照于当前浏览器的地址

5、web中’/‘的不同意义

在web中,’/'是一种绝对路径

如果被浏览器解析,得到的地址是:http://ip:port/

<a href="/"></a>

如果被服务器解析,得到的地址是:http://ip:port/工程路径

<url-pattern>/servlet1</url-pattern>

servletContext.getRealPath("/")

request.getRequestDispatcher("/")

特殊情况:response.sendRediect("/")是把斜杠发给浏览器解析,故得到的是http://ip:port/

相关文章
|
16天前
|
存储 监控 安全
单位网络监控软件:Java 技术驱动的高效网络监管体系构建
在数字化办公时代,构建基于Java技术的单位网络监控软件至关重要。该软件能精准监管单位网络活动,保障信息安全,提升工作效率。通过网络流量监测、访问控制及连接状态监控等模块,实现高效网络监管,确保网络稳定、安全、高效运行。
45 11
|
26天前
|
XML Java 编译器
Java注解的底层源码剖析与技术认识
Java注解(Annotation)是Java 5引入的一种新特性,它提供了一种在代码中添加元数据(Metadata)的方式。注解本身并不是代码的一部分,它们不会直接影响代码的执行,但可以在编译、类加载和运行时被读取和处理。注解为开发者提供了一种以非侵入性的方式为代码提供额外信息的手段,这些信息可以用于生成文档、编译时检查、运行时处理等。
60 7
|
8天前
|
移动开发 前端开发 Java
Java最新图形化界面开发技术——JavaFx教程(含UI控件用法介绍、属性绑定、事件监听、FXML)
JavaFX是Java的下一代图形用户界面工具包。JavaFX是一组图形和媒体API,我们可以用它们来创建和部署富客户端应用程序。 JavaFX允许开发人员快速构建丰富的跨平台应用程序,允许开发人员在单个编程接口中组合图形,动画和UI控件。本文详细介绍了JavaFx的常见用法,相信读完本教程你一定有所收获!
Java最新图形化界面开发技术——JavaFx教程(含UI控件用法介绍、属性绑定、事件监听、FXML)
|
1月前
|
Java 开发者 微服务
Spring Boot 入门:简化 Java Web 开发的强大工具
Spring Boot 是一个开源的 Java 基础框架,用于创建独立、生产级别的基于Spring框架的应用程序。它旨在简化Spring应用的初始搭建以及开发过程。
55 6
Spring Boot 入门:简化 Java Web 开发的强大工具
|
27天前
|
监控 架构师 Java
Java虚拟机调优的艺术:从入门到精通####
本文作为一篇深入浅出的技术指南,旨在为Java开发者揭示JVM调优的神秘面纱,通过剖析其背后的原理、分享实战经验与最佳实践,引领读者踏上从调优新手到高手的进阶之路。不同于传统的摘要概述,本文将以一场虚拟的对话形式,模拟一位经验丰富的架构师向初学者传授JVM调优的心法,激发学习兴趣,同时概括性地介绍文章将探讨的核心议题——性能监控、垃圾回收优化、内存管理及常见问题解决策略。 ####
|
29天前
|
安全 Java 编译器
Kotlin教程笔记(27) -Kotlin 与 Java 共存(二)
Kotlin教程笔记(27) -Kotlin 与 Java 共存(二)
|
29天前
|
Java 开发工具 Android开发
Kotlin教程笔记(26) -Kotlin 与 Java 共存(一)
Kotlin教程笔记(26) -Kotlin 与 Java 共存(一)
|
26天前
|
JavaScript 安全 Java
java版药品不良反应智能监测系统源码,采用SpringBoot、Vue、MySQL技术开发
基于B/S架构,采用Java、SpringBoot、Vue、MySQL等技术自主研发的ADR智能监测系统,适用于三甲医院,支持二次开发。该系统能自动监测全院患者药物不良反应,通过移动端和PC端实时反馈,提升用药安全。系统涵盖规则管理、监测报告、系统管理三大模块,确保精准、高效地处理ADR事件。
|
2月前
|
Java 编译器 Android开发
Kotlin教程笔记(28) -Kotlin 与 Java 混编
Kotlin教程笔记(28) -Kotlin 与 Java 混编
34 2
|
2月前
|
监控 前端开发 Java
【技术开发】接口管理平台要用什么技术栈?推荐:Java+Vue3+Docker+MySQL
该文档介绍了基于Java后端和Vue3前端构建的管理系统的技术栈及功能模块,涵盖管理后台的访问、登录、首页概览、API接口管理、接口权限设置、接口监控、计费管理、账号管理、应用管理、数据库配置、站点配置及管理员个人设置等内容,并提供了访问地址及操作指南。