03【Response、ServletContext】

news2024/11/26 14:37:02

文章目录

  • 03【Response、ServletContext】
  • 一、HTTP响应概述
    • 1.1 什么是HTTP响应:
    • 1.2 响应信息的组成:
      • 1.2.1 响应行
      • 1.2.2 响应头
      • 1.2.3 响应体
    • 1.3 Http协议小结
  • 二、HttpServletResponse对象
    • 2.1 设置响应行
      • 2.2.1 设置响应状态码
      • 2.2.2 常见响应码
        • 1)404状态码
        • 2)405状态码
        • 3)500状态码
    • 2.3 设置响应头
      • 2.3.1 Refresh
      • 2.3.2 Location
      • 2.3.3 Content-Disposition
      • 2.3.4 Content-Type
    • 3.3 设置响应体
  • 三、ServletContext上下文对象
    • 3.1 ServletContext简介
    • 3.2 ServletContext的作用
      • 3.2.1 获取当前工程的资源文件
        • 1)访问WEB-INF下的资源访问
        • 2) 得到指定资源的真实地址
      • 3.2.2 获取作用域对象的值
        • 1)上下文域的作用范围:
        • 2)统计登录人数小案例
      • 3.2.3 配置全局参数
      • 3.2.4 获得MIME类型
      • 3.2.5 ServletRegistration注册器
        • 1)获取注册的Servlet信息
        • 2)ServletRegistration注册器

03【Response、ServletContext】

一、HTTP响应概述

1.1 什么是HTTP响应:

我们之前学习过HTTP协议,一个完整的HTTP报文分为HTTP请求报文和HTTP响应报文;一个完整的HTTP响应报文中封装了服务器端响应给浏览器的数据,我们学习HTTP响应就是学习HTTP协议中,到底封装了什么数据响应给浏览器;

1.2 响应信息的组成:

一个完整的HTTP响应报文由三个部分组成:响应行,响应头,响应体

  • 编写一个Servlet:
package com.dfbz.response;

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;

@WebServlet("/demo01")
public class Demo01Servlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.getWriter().write("hello~");
    }
}

发送请求:http://localhost:8080/demo01


  • 打开浏览器按F12,Network—>Headers;查看响应行/响应头:

在这里插入图片描述

  • 响应体:

在这里插入图片描述

Tips:如果是文字,显示文字,如果是图片或音频,视频数据,响应体就是一些二进制的数据

1.2.1 响应行

一个完整的响应行由三个组成部分:协议和版本、响应状态码、状态信息

  • 示例:
HTTP/1.1 200 OK
  • HTTP/1.1:协议和版本
  • 200:响应状态码
  • OK:响应的状态信息

响应状态码分为1xx、2xx、3xx、4xx、5xx,我们可以通过响应的状态码得知请求之后服务器端做的处理,常用于定位错误等

下列是五种状态码的大致含义:

状态码含义
1xx指示信息;表示请求已接收,继续处理。
2xx成功;表示请求已被成功接收、理解、接受。
3xx重定向;要完成请求必须进行更进一步的操作。
4xx客户端错误;请求有语法错误或请求无法实现。
5xx服务器端错误;服务器未能实现合法的请求。

下列是一些常见状态码的具体含义:

状态码含义
200正确的从服务器得到响应的数据
302表示页面重定向
304使用的是本地缓存,并没有从服务器上再次下载网页
400请求参数错误
404找不到服务器上指定的资源
405如果客户端使用GET/POST方法提交,而服务器端没有doGet/doPost方法,就会出现405错误
415服务器无法处理请求附带的媒体格式(无法识别请求中携带的参数)
500服务器出现内部错误,一般是Servlet中的代码有错误

HTTP响应状态码大全:http://tools.jb51.net/table/http_status_code

1.2.2 响应头

响应头由各种键值组成,响应头是固定的,值是可以变的。

响应头信息说明
Location: http://www.10086.cn重定向要跳转到的地址
Server:apache tomcat访问的服务器名字
Content-Encoding: gzip服务器压缩格式,如果服务器端数据量比较大的时候,首先会将数据进行压缩,这就是指定它的压缩格式。浏览器得到服务器发送过来的数据,浏览器根据这个格式进行解压。
Content-Length: 80响应的长度
Content-Type: text/html; charset=utf-8服务器发送过来的数据类型和字符集
Refresh: 1;url=/response/hello.html表示1秒以后,跳转到/response/hello.html页面
Content-Disposition: attachment; filename=hello.zipContent-Disposition: 内容的处理方式
attachment:以附件的方式下载
filename:下载时候的文件名,不建议使用汉字,汉字有乱码 将服务器上的数据以附件的方式下载
Date: Fri, 05 Feb 2021 01:17:00 GMT告诉浏览器,服务器响应时间
expires: Mon, 08 Feb 2021 02:27:18 GMT告诉浏览器回送的资源缓存多长时间。如果是-1或者0,表示不缓存

1.2.3 响应体

响应体就是服务器发送给浏览器的数据,这个数据可以是任何格式,如响应一个html,响应一张图片,一个音频等任意文件

编写一个Servlet,给客户端响应一张图片:

package com.dfbz.response;

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

/**
 * @author lscl
 * @version 1.0
 * @intro:
 */
@WebServlet("/demo02")
public class Demo02Servlet extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        // 去磁盘上读取一个文件
        FileInputStream fis = new FileInputStream("D:/000.png");

        // 获取与前端的输出流
        ServletOutputStream out = resp.getOutputStream();

        int data;
        while ((data=fis.read())!=-1){
            out.write(data);
        }
        fis.close();
        out.close();
    }
}

访问:http://localhost:8080/demo02

在这里插入图片描述

Tips:此时后端响应的是一张图片

1.3 Http协议小结

  • Http请求
    • 请求行
      • 提交的方式
      • 请求的地址
      • 采用的协议和版本
    • 请求头
      • host
      • connection
      • referer
      • content-type
      • Cookie
      • Accept
    • 请求体(GET提交方式没有请求体)
  • Http响应
    • 响应行
      • 采用的协议
      • 状态码
        • 200
        • 302
        • 304
        • 404
        • 405
        • 500
      • 响应的状态信息
    • 响应头
      • Refresh
      • Content-Disposition
      • ContentType
      • set-cookie
    • 响应体

二、HttpServletResponse对象

HttpServletResponse是JavaEE中用来封装HTTP响应报文的对象,我们可以通过改对象获取HTTP响应报文中响应行,响应头,响应体的详细数据;

2.1 设置响应行

2.2.1 设置响应状态码

  • void setStatus(int status):设置响应状态码

示例代码:

package com.dfbz.response;

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;

@WebServlet("/demo03")
public class Demo01 extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 设置响应的状态码
        response.setStatus(222);
    }
}

访问:http://localhost:8080/demo03

在这里插入图片描述

2.2.2 常见响应码

1)404状态码

  • 404的含义:找不到指定的资源
404常见的情况描述
地址栏错误地址栏打错,区分大小写。
web.xml配置问题如果web.xml中出现配置信息,会导致整个项目启动失败,所有的资源都找不到。
项目未部署项目没有部署到服务器
访问WEB-INF/web/WEB-INF/下面资源是受保护,不能直接访问。

在这里插入图片描述

总结:404就是资源找不到

2)405状态码

  • 405的含义:如果客户端使用GET/POST方法提交,而服务器端没有doGet/doPost方法,就会出现405错误

提供一个Servlet:

405简单的来说就是找不到对应的方法;Get方式—>doGet方法,Post方式—>doPost方法

package com.dfbz.response;

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;

/**
 * @author lscl
 * @version 1.0
 * @intro:
 */
@WebServlet("/demo04")
public class Demo04Servlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.getWriter().write("hello~");
    }
}

访问:http://localhost:8080/demo04

在这里插入图片描述

3)500状态码

  • 500状态码含义:服务器出现异常后没有即使处理抛给WEB服务器(Tomcat)处理将默认响应500状态码;

示例代码:

package com.dfbz.response;

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;

/**
 * @author lscl
 * @version 1.0
 * @intro:
 */
@WebServlet("/demo05")
public class Demo05Servlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        int i = 1 / 0;
    }
}

访问:http://localhost:8080/demo05

在这里插入图片描述

2.3 设置响应头

  • 响应头相关方法:
响应头的方法描述
void setHeader(String name, String value)设置响应头,指定名字和值
void setContentType(String type)设置响应的内容类型,功能上与 setHeader(“content-type”, “值”) 相同

2.3.1 Refresh

示例一:过3秒浏览器去请求另一个网站

  • 开发步骤:
  1. 创建一个Servlet

  2. 调用setHeader,设置消息头("refresh","3;url=http://www.jd.com"

  3. 调用setStatus,设置响应状态码200,可选。

  • 代码:
package com.dfbz.response;

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;

/**
 * 案例: 3秒后跳转到另一个网站
 */
@WebServlet("/demo06")
public class Demo06Servlet extends HttpServlet {

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        // 设置响应类型和响应的编码
        response.setContentType("text/html;charset=utf-8");

        PrintWriter out = response.getWriter();
        out.print("过3秒以后跳转到京东首页");

        // 设置响应头
        response.setHeader("refresh", "3;url=https://www.jd.com");
    }
}

2.3.2 Location

示例二:使用location进行页面跳转(重定向)

Tips:Location必须搭配302状态一起使用,否则将不能重定向

  • 302的含义:进行页面重定向
package com.dfbz.response;

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;

// 实现页面的重定向
@WebServlet("/demo07")
public class Demo07Servlet extends HttpServlet {
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 设置响应头 需要搭配状态码一起使用
        response.setHeader("location", "http://www.jd.com");
        // 设置状态码为302
        response.setStatus(302);

        //专门重定向方法
//        response.sendRedirect("http://www.jd.com");
    }
}

访问:http://localhost:8080/demo07

在这里插入图片描述

Tips:302代表该资源发生了重定向行为;

2.3.3 Content-Disposition

Content-disposition 是 MIME 协议的扩展,设置客户端如何显示附加的文件。Content-disposition可以设置用户请求所得的内容为一个文件的时候提供一个默认的文件名,文件直接在浏览器上显示或者在访问时弹出文件下载对话框。

  • Content-Disposition响应头有两个参数:
    • inline:直接在页面显示(这也是大部分浏览器的默认值)
    • attachment:以附件形式下载
package com.dfbz.response;

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

@WebServlet("/demo08")
public class Demo08Servlet extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        // 设置Content-Disposition响应头
//        resp.setHeader("Content-Disposition","inline");           // 直接在页面显示
//        resp.setHeader("Content-Disposition","attachment");        // 以附件形式下载
        // resp.setHeader("Content-Disposition","attachment;filename=abc.png");     // 以附件形式下载,顺便设置文件名

        // 如果是中文记得要编码
        resp.setHeader("Content-Disposition","attachment;filename=图片.png");
        
        // 使用输入流关联一个磁盘文件
        FileInputStream fis = new FileInputStream("D:/000.png");

        // 获取与前端的输出流
        ServletOutputStream out = resp.getOutputStream();

        int data;

        while ((data = fis.read()) != -1) {
            out.write(data);
        }

        fis.close();
        out.close();
    }
}
  • URL编码有关的方法如下:
URL编码有关的方法描述
java.net.URLEncoder.encode(字符串, “utf-8”)对字符串进行utf-8编码
java.net.URLDecoder.decode(字符串, “utf-8”)对字符串进行utf-8解码
package com.dfbz.demo;

import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;

/**
 * @author lscl
 * @version 1.0
 * @intro:
 */
public class TestCode {
    public static void main(String[] args) throws UnsupportedEncodingException {
        String str = "图片";
        System.out.println(str);
        //编码
        String encode = URLEncoder.encode(str, "utf-8");
        System.out.println(encode);
        //解码
        String decode = URLDecoder.decode(encode, "utf-8");
        System.out.println(decode);
    }
}

2.3.4 Content-Type

Content-Type响应头用于告诉客户端,服务器将要响应什么数据格式给前端,前端按照这个数据类型进行解析;

  • 常见的响应类型:
text/htmlHTML格式
Content-Type类型说明
text/plain纯文本格式
text/xmlXML格式
image/gifgif图片格式
image/jpegjpg图片格式
image/pngpng图片格式
application/xhtml+xmlXHTML格式
application/xmlXML数据格式
application/jsonJSON数据格式
application/pdfpdf格式
application/mswordWord文档格式
application/octet-stream二进制流数据(如常见的文件下载)
application/x-www-form-urlencoded表单中默认的encType,form表单数据被编码为key/value格式发送到服务器(表单默认的提交数据的格式)

Content-Type对照表:https://tool.oschina.net/commons/

由于后期Content-Type响应头用的太多了,因此HttpServletResponse对象提供setContentType()方法单独来设置Content-Type响应头,当然也可以使用setHeader()方法来设置Content-Type响应头;

示例:

package com.dfbz.response;

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;

@WebServlet("/demo09")
public class Demo09Servlet extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        resp.getWriter().write("abc<h1>hello</h1>");
    }
}

访问:http://localhost:8080/demo09

在这里插入图片描述

设置响应头:

package com.dfbz.response;

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;

@WebServlet("/demo09")
public class Demo09Servlet extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

//        resp.setContentType("text/html;charset=utf8");
        resp.setHeader("Content-Type","text/html;charset=utf8");        // 等价于上面

        resp.getWriter().write("abc<h1>hello</h1>");
    }
}

访问:http://localhost:8080/demo09

在这里插入图片描述

3.3 设置响应体

响应体的方法描述
OutputStream getOutputStream()字节输出流,如果从服务器上返回是二进制数据,使用字节输出流。 也可以返回字符。
PrintWriter getWriter()字符输出流,如果从服务器上返回的是字符数据,文字之类。

我们之前一直使用的是reponse的getWriter()方法,此方法返回一个字符打印输出流,默认指向的是来请求的客户端,使用该类可以很方便的向客户端写出文本数据,但是如果我们希望往客户端写出其他数据,如图片、视频、压缩包等,我们就需要使用response的getOutputStream()方法了;

  • 案例:服务器往客户端写回一张图片
package com.dfbz.response;

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

@WebServlet("/demo10")
public class Demo10Servlet extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        // 响应响应类型
        resp.setContentType("image/png");

        // 读取服务器本地的图片
        FileInputStream fis = new FileInputStream("D://000.png");

        // 获取一个字节输出流,该流指向的是客户端
        ServletOutputStream out = resp.getOutputStream();

        byte[] data = new byte[1024];

        int len;

        while ((len = fis.read(data)) != -1) {
            out.write(data, 0, len);
        }

        // 释放资源
        fis.close();
        out.close();
    }
}

三、ServletContext上下文对象

3.1 ServletContext简介

ServletContext官方叫servlet上下文。WEB容器在启动时,它会为每个WEB应用程序都创建一个对应的ServletContext对象,它代表当前web应用。而且工程内部的所有servlet都共享这个对象。

ServletContext:代表当前web应用

  • 回顾Servlet的继承结构

在这里插入图片描述

所有的HttpSerlvet都实现了ServletConfig接口,ServletConfig对象中维护了ServletContext对象的引用,开发人员在编写servlet时,可以通过ServletConfig.getServletContext方法获得ServletContext对象,由于一个WEB应用中的所有Servlet共享同一个ServletContext对象,因此Servlet对象之间可以通过ServletContext对象来实现通讯。

  • ServletContext getServletContext():获取ServletContext对象

在这里插入图片描述

3.2 ServletContext的作用

3.2.1 获取当前工程的资源文件

  • 相关的方法:
ServletContext的方法功能
InputStream getResourceAsStream(String path)得到web目录下的资源,转成一个输入流对象
String getRealPath(String path)web目录下的资源,得到它在服务器上部署的真实路径

1)访问WEB-INF下的资源访问

  • 示例:读取WEB-INF下面的图片文件显示在浏览器上

示例代码:

package com.dfbz.demo;

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.io.InputStream;
import java.io.OutputStream;

/**
 * @author lscl
 * @version 1.0
 * @intro:
 */
@WebServlet("/demo01")
public class Demo01_GetWebInfoResource extends HttpServlet {
    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        //得到上下文对象
        ServletContext application = getServletContext();

        //得到一个文件输入流
        InputStream in = application.getResourceAsStream("/WEB-INF/000.png");

        //得到一个输出流
        OutputStream out = response.getOutputStream();   //字节流

        //设置响应头
        response.setContentType("image/png");

        //输出到浏览器上
        byte[] buf = new byte[1024];

        int len;

        while ((len = in.read(buf)) != -1) {
            out.write(buf, 0, len);
        }
    }
}

2) 得到指定资源的真实地址

package com.dfbz.demo;

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.io.PrintWriter;

/**
 * @author lscl
 * @version 1.0
 * @intro:
 */
@WebServlet("/demo02")
public class Demo02_RealPath extends HttpServlet {
    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        // 得到上下文对象
        ServletContext application = getServletContext();

        // 得到某个资源的真实地址
        String realPath = application.getRealPath("/index.html");

        // 输出到浏览器
        response.setContentType("text/html;charset=utf-8");

        PrintWriter out = response.getWriter();

        out.print("真实地址是:" + realPath);
    }
}

在这里插入图片描述

问:资源文件如果不存在会怎么样?

  • 不会有影响,只是将项目部署的真实路径+我们的资源路径

在这里插入图片描述

Tips:项目中并没有/abc/demo/abca.html资源;

3.2.2 获取作用域对象的值

在这里插入图片描述

域对象的功能:在Servlet之间进行数据的共享;底层是一个Map对象,由键和值集合组成

1)上下文域的作用范围:

只有服务器没有关闭,所有的用户都可以访问,每个用户的每次请求都可以读取或修改上下文域中的数据。

  • 域对象相关方法:
ServeltContext的方法作用
void setAttribute(“键”,Object数据)向上下文域中添加键和值
Object getAttribute(“键”)从上下文域中得到值
void removeAttribute(“键”)删除上下文域中的键值对

2)统计登录人数小案例

原理:当第一次初始化登录Servlet时初始化count值为0,每一个用户登录成功后,取出count值+1再次存入到域对象,此域对象必须所有的servlet共享;

  • 开发步骤:

    • 1)在LoginServlet的init()方法中创建count=0,并且将值放入上下文域中.
    • 2)在登录成功的代码中从上下文域中取出count,并且加1,再更新上下文域中的值。
    • 3)跳转到另一个CountServlet,在另一个CountServlet中取出上下文域中的值,显示在页面上。
  • 登录的表单:

<!DOCTYPE html>
<html>
<head>
    <title>登录页面</title>
    <meta charset="UTF-8">
</head>
<body>
<h2>用户登录</h2>
<form action="login" method="post">
    用户名: <input type="text" name="username"/><hr>
    密码: <input type="password" name="password"/><hr/>
    <input type="submit" value="登录"/>
</form>
</body>
</html>
  • Demo03_LoginServlet:
package com.dfbz.demo;

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.io.PrintWriter;

/**
 * @author lscl
 * @version 1.0
 * @intro:
 */
@WebServlet("/login")
public class Demo03_LoginServlet extends HttpServlet {


    // 在初始化的方法中,向上下文域中放入一个初始值count = 0
    @Override
    public void init() throws ServletException {
        getServletContext().setAttribute("count", 0);
    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("text/html;charset=utf-8");
        PrintWriter out = response.getWriter();

        //得到上下文对象
        ServletContext application = getServletContext();

        // 1.登录判断用户名和密码是否正确
        String username = request.getParameter("username");
        String password = request.getParameter("password");

        if ("admin".equals(username) && "123".equals(password)) {
            // 2. 如果登录成功,将上下文域中的数据取出,加1,放回到上下文域中
            int count = (int) application.getAttribute("count");
            application.setAttribute("count", ++count);

            // 重定向到另一个Servlet显示登录人数
            response.sendRedirect("/count");
        }
        //登录失败
        else {
            out.print("<script>");
            out.print("alert('用户名或密码不正确');");
            out.print("location.href='/login.html';");
            out.print("</script>");
        }
    }
}
  • Demo04_CountServlet:
package com.dfbz.demo;

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;

/**
 * @author lscl
 * @version 1.0
 * @intro:
 */
@WebServlet("/count")
public class Demo04_CountServlet extends HttpServlet {

    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        response.setContentType("text/html;charset=utf-8");

        PrintWriter out = response.getWriter();

        // 从上下文域中取出数据,并且显示出来
        out.print("<h1>你是第" + getServletContext().getAttribute("count") + "个登录的用户</h1>");
    }
}

3.2.3 配置全局参数

我们知道ServletContext是随着容器的启动而创建,有的时候我们希望配置一些全局参数,让这些参数也随着容器的启动而初始化,这个时候我们可以在web.xml配置一些全局参数,如:让mysql的连接随着容器的创建而创建

配置web.xml:

<?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>
        <param-name>username</param-name>
        <param-value>root</param-value>
    </context-param>
    <context-param>
        <param-name>password</param-name>
        <param-value>admin</param-value>
    </context-param>
    <context-param>
        <param-name>url</param-name>
        <param-value>jdbc:mysql://localhost:3306/test</param-value>
    </context-param>
    <context-param>
        <param-name>driverClassName</param-name>
        <param-value>com.mysql.jdbc.Driver</param-value>
    </context-param>
</web-app>
  • Demo06_GetInitParams:读取全局参数
package com.dfbz.demo;

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;

/**
 * @author lscl
 * @version 1.0
 * @intro:
 */
@WebServlet("/demo06")
public class Demo06_GetInitParams extends HttpServlet {

    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        ServletContext app = getServletContext();

        // 使用getInitParameter方法获取全局参数
        Object username = app.getInitParameter("username");
        Object password = app.getInitParameter("password");
        Object url = app.getInitParameter("url");
        Object driverClassName = app.getInitParameter("driverClassName");

        response.getWriter().println("username: " + username);
        response.getWriter().println("password: " + password);
        response.getWriter().println("url: " + url);
        response.getWriter().println("driverClassName: " + driverClassName);
    }
}

访问:http://localhost:8080/demo06

在这里插入图片描述

3.2.4 获得MIME类型

MIME:全称Multipurpose Internet Mail Extensions,多功能Internet邮件扩充服务。它是一种多用途网际邮件扩充协议,在1992年最早应用于电子邮件系统,但后来也应用到浏览器。MIME类型就是设定某种扩展名的文件用一种应用程序来打开的方式类型,当该扩展名文件被访问的时候,浏览器会自动使用指定应用程序来打开。多用于指定一些客户端自定义的文件名,以及一些媒体文件打开方式。

Tips:MIME就是文件的媒体类型。浏览器可以根据它来区分文件,然后决定什么内容用什么形式来显示。

  • 常见文件的MIME类型:
文件拓展名MIMEType
pngimage/png
bmp\dibimage/bmp
jpg\jpeg\jpgimage/ipeg
gifimage/gif
mp3audio/mpeg
mp4\mpg4\m4v\mp4vvideo/mp4
jsapplication/javascript
pdfapplication/pdf
text\txttext/plan
jsonapplication/json
xmltext/xml

示例代码:

package com.dfbz.demo;

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;

/**
 * @author lscl
 * @version 1.0
 * @intro:
 */
@WebServlet("/demo07")
public class Demo07_GetMIMEType extends HttpServlet {

    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        // 获取上下文对象
        ServletContext app = getServletContext();

        // 设置响应的类型
        response.setContentType("text/html;charset=utf8");

        // image/ipeg
        response.getWriter().write("【a.jpg】--->【" + app.getMimeType("a.jpg") + "】<hr>");

        // image/png
        response.getWriter().write("【a.png】--->【" + app.getMimeType("a.png") + "】<hr>");

        // application/pdf
        response.getWriter().write("【a.pdf】--->【" + app.getMimeType("a.pdf") + "】<hr>");

        // null
        response.getWriter().write("【a.word】--->【" + app.getMimeType("a.word") + "】<hr>");

        // application/javascript
        response.getWriter().write("【a.js】--->【" + app.getMimeType("a.js") + "】<hr>");
    }
}

访问:http://localhost:8080/demo07

在这里插入图片描述

3.2.5 ServletRegistration注册器

ServletContext对象很大程度上代表了当前的WEB容器(或当前项目),我们可以获取当前WEB容器已经注册的Servlet信息;

1)获取注册的Servlet信息

  • Map<String, ? extends ServletRegistration> getServletRegistrations():获取当前WEB容器所有的注册器
  • ServletRegistration getServletRegistration(String var1):根据servlet的名称(默认是该servlet的全路径)获取指定的注册器

示例代码:

package com.dfbz.demo;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRegistration;
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;
import java.util.Map;

/**
 * @author lscl
 * @version 1.0
 * @intro:
 */
@WebServlet("/demo08")
public class Demo08_GetRegistrationServlet extends HttpServlet {

    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        // 设置响应类型
        response.setContentType("text/html;charset=utf8");

        // 获取与前端的字符输出流
        PrintWriter out = response.getWriter();

        // 获取上下文对象
        ServletContext app = getServletContext();

        // 获取当前WEB容器中注册的所有Servlet
        Map<String, ? extends ServletRegistration> registrationMap = app.getServletRegistrations();

        for (String servletName : registrationMap.keySet()) {
            out.println("【servletName】----【" + servletName + "】<hr>");
        }

        // 根据类的全路径获取指定的注册器
        ServletRegistration servletRegistration = app.getServletRegistration("com.dfbz.demo.Demo08_RegisterServlet");
        out.println("【Demo08_RegisterServlet的注册器】----【" + servletRegistration + "】<hr>");
    }
}

访问:http://localhost:8080/demo08

在这里插入图片描述

2)ServletRegistration注册器

ServletRegistration注册器用于获取Servlet的一系列信息;

  • 1)编写Servlet,ServletRegistration注册器使用获取Demo08Servlet的Mapping信息:
package com.dfbz.demo;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRegistration;
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;
import java.util.Collection;

/**
 * @author lscl
 * @version 1.0
 * @intro:
 */
@WebServlet("/demo09")
public class Demo09_GetRegistrationServlet extends HttpServlet {

    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 获取上下文对象
        ServletContext app = getServletContext();

        // 获取与客户端的字符输出流
        PrintWriter out = response.getWriter();

        // 根据类的全路径获取指定的注册器
        ServletRegistration registration = app.getServletRegistration("com.dfbz.demo.Demo08_GetRegistrationServlet");

        // 获取servlet的mapping映射
        Collection<String> mappings = registration.getMappings();

        for (String mapping : mappings) {
            out.println(mapping + "<hr>");
        }
    }
}

访问:http://localhost:8080/demo09

在这里插入图片描述

  • 2)使用注册器注册新的Mapping信息:
package com.dfbz.demo;

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

/**
 * @author lscl
 * @version 1.0
 * @intro:
 */
@WebServlet("/demo10")
public class Demo10_addMappingServlet extends HttpServlet {
    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        // 获取上下文对象
        ServletContext app = getServletContext();

        // 根据类的全路径获取指定的注册器
        ServletRegistration registration = app.getServletRegistration("com.dfbz.demo.Demo08_GetRegistrationServlet");

        // 新增servlet映射
        registration.addMapping("/demo08_1", "/demo08_2");
    }
}

访问:http://localhost:8080/demo10,再访问http://localhost:8080/demo09

在这里插入图片描述

此时使用http://localhost:800/demo08、http://localhost:800/demo08_1、http://localhost:800/demo08_2都可以访问到Demo08Servlet!


除此之外,注册器还可以帮助我们获取Servlet的其他信息:

  • String getClassName():获取该Servlet的全路径
  • String getName():获取该Servlet的名称

示例代码:

package com.dfbz.demo;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRegistration;
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;

/**
 * @author lscl
 * @version 1.0
 * @intro:
 */
@WebServlet("/demo11")
public class Demo11_RegistrationMethod extends HttpServlet {
    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        // 设置响应的类型
        response.setContentType("text/html;charset=utf8");

        // 获取与客户端的字符输出流
        PrintWriter out = response.getWriter();

        // 获取上下文对象
        ServletContext app = getServletContext();

        // 根据servlet的名称(默认为servlet的全路径)径获取指定的注册器
        ServletRegistration registration = app.getServletRegistration("com.dfbz.demo.Demo08_GetRegistrationServlet");

        // 获取servlet的全路径
        out.println("getClassName: " + registration.getClassName() + "<hr>");

        // 获取该servlet的名称
        out.println("getName: " + registration.getName() + "<hr>");
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/153807.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

入选IDC报告,美创科技数据安全管理平台实力领跑

近日&#xff0c;国际权威研究咨询机构IDC发布《中国数据安全基础设施管理平台市场洞察&#xff0c;2022》报告。本次报告对行业用户以及技术提供商深入访谈&#xff0c;挑选出具有代表性的数据安全基础设施管理平台产品和方案&#xff0c;美创数据安全管理平台入选&#xff0c…

软件测试---概念篇

本文主要介绍软件测试相关的一些基础概念.主要内容包括 : 什么是需求 什么是bug 什么是测试用例 开发模型和测试模型 配置管理和软件测试 一 : 什么是需求 满足用户期望或正式规定文档&#xff08;合同、标准、规范&#xff09;所具有的条件和权能&#xff0c;包含用户需求和软…

【Kubernetes 企业项目实战】02、基于 Prometheus 和 K8s 构建智能化监控告警系统(中)

目录 一、安装和配置 node-exporter 1.1 node-exporter介绍&#xff1f; 1.2 安装 node-exporter 二、Prometheus server 安装和配置 2.1 创建 sa 账号&#xff0c;对 sa 做 rbac 授权 2.2 创建 prometheus 数据存储目录 2.3 安装 Prometheus server 服务 &#xff08;…

Python再入手-03

又过了半年,已经完全忘了当时8月份的python工作了。这半年,先是跑合同,然后张罗出海,完了又搞了两次验收,还做了两次汇报,开了无数的会,忙坏了。 现在,得重新张罗电磁这档子事儿了。下面记录下最近的操作。 1 打开编程环境。 都忘了怎么打开环境了,翻一下以前的博客…

Ant Design使用

目录官网在项目中使用下载引入方法1:全部引入方法2:按需引入-手动加载方法3:按需引入-自动加载组件Anchor作用&#xff1a;用于跳转到页面指定位置案例1-基础使用案例2-添加偏移量案例3-指定容器总结官网 Ant Design官网 在项目中使用 在react中使用Ant Design 下载 使用如…

【无人机学习之Mission Planner】RTK/GPS Inject 学习

█ 【无人机学习之Mission Planner】RTK/GPS Inject 学习 █ 系列文章目录 提示&#xff1a;这里是收集了无人机的相关文章 【无人机学习】无人机基础知识【无人机学习】Mission Planner&#xff08;pc端&#xff09;和QGroundControl&#xff08;android端&#xff09;【无人…

P1102 A-B 数对

题目背景 出题是一件痛苦的事情&#xff01; 相同的题目看多了也会有审美疲劳&#xff0c;于是我舍弃了大家所熟悉的 AB Problem&#xff0c;改用 A-B 了哈哈&#xff01; 题目描述 给出一串正整数数列以及一个正整数 CC&#xff0c;要求计算出所有满足 A - B CA−BC 的数对的…

vb.net多功能白板(集成:绘图,编辑,批注,橡皮,图片处理,拍摄,裁剪,旋转等功能

根据上一次的自定义白板&#xff0c;我已经更新了很多内容了 这一次打算再细一点 初始化程序&#xff1a;所有的整体变量&#xff08;作者提醒&#xff0c;请不要直接照抄代码&#xff0c;可以和作者发的文件进行学习和参考 Public ListOfPen As New List(Of Bitmap)Public L…

ArcGIS如何进行自动矢量化操作

这里我们在网络上找一幅高中地理课本上看的等高线图给大家能进行操作演示。 等高线图 01 地理配准 1、定义投影 给数据框定义一个投影&#xff0c;右键Layers>Properties>Coordinate System>Projected Coordinate Systems>Gauss Kruger>Beijing1954> Be…

雅思经验总结(1)

听力技巧&#xff1a;听sections 3就是看你何时进入状态&#xff0c;还有审题&#xff0c;之后就是听but&#xff0c;其他的转折词什么yet because however什么都非常的少&#xff0c;最主要的还是but&#xff0c;注意bus之后的话&#xff0c;其余的什么细节题就是说还要听懂文…

Biome-BGC生态系统模型区域模拟

Biome-BGC是利用站点描述数据、气象数据和植被生理生态参数&#xff0c;模拟日尺度碳、水和氮通量的有效模型&#xff0c;其研究的空间尺度可以从点尺度扩展到陆地生态系统。在Biome-BGC模型中&#xff0c;对于碳的生物量积累&#xff0c;采用光合酶促反应机理模型计算出每天的…

Java面向对象进阶之static

目录static静态关键字static&#xff1a;修饰成员变量&#xff0c;内存机制static是什么、修饰成员变量的方法总结static修饰成员变量的内存原理static&#xff1a;修饰成员方法、内存机制static修饰成员方法的基本用法总结static修饰成员方法的内存原理static的注意事项static…

计算机组成原理习题二

计算机组成原理习题二 文章目录计算机组成原理习题二1、某指令系统的指令格式如下&#xff1a;答案&#xff1a;(1)152301Q1101 010011 000 001I10&#xff0c;I21&#xff0c;Z/C0&#xff0c;D/I0&#xff0c;故为变址寄存器2寻址&#xff0c;EA(I2)A063215301063516Q。 (4)…

大咖年终“讲” 维视教育李明睿——制造业转型升级下需要重新定义人才培养

数字化转型迫在眉睫建设应用型大学风潮正涌制造企业在推进智能制造和数字化转型进程中&#xff0c;衍生出大量人才需求。据人社部、工信部发布的《制造业人才发展规划指南》显示&#xff0c;中国制造业10大重点领域人才缺口2025年将接近3000万人&#xff0c;缺口率高达48&#…

流媒体基础-RTCP

1、RTCP的封装 RTP需要RTCP为其服务器质量提供保证&#xff0c;周期性发送 RTCP的主要功能是&#xff1a;服务质量的监视、反馈&#xff08;QoS&#xff09;、媒体间的同步&#xff08;Sync&#xff09;&#xff0c;以及多播组中成员的标识。在RTP会话期间&#xff0c;各参与者…

Lichee_RV学习系列---认识Lichee_RV、环境搭建和编译第一个程序

系列文章目录 文章目录系列文章目录前言一、认识Lichee RV1、D1-H 芯片2、Lichee RV开发板3、系统镜像二、Lichee RV 固件烧录1、要求基本硬件2、基本资料下载3、固件烧录在这里插入图片描述三、连接上开发板1、ADB方式连接a&#xff1a;ADB下载b&#xff1a;ADB连接c&#xff…

孙溟㠭篆刻《无有中无尽藏》

《无有中无尽藏》孙溟㠭篆刻 无一物中无尽藏&#xff0c;是说当“我执”袪除&#xff0c;仅余“真如”时&#xff0c;便可以理解“无尽藏”。虽然身上没有东西&#xff0c;但是其实世人身上藏了所有的东西。“无心”亦是有心&#xff0c;心中富足。所以当人祛除心中的偏执&…

自动语音识别(ASR)研究综述

自动语音识别ASR研究综述 一、语言识别基础知识 从语音系统识别构成来讲&#xff0c;一套完整的语音识别系统包括&#xff1a;预处理、特征提取、声学模型、语言模型、以及搜索算法等模块&#xff0c;具体结构示意图如下所示: 特征提取&#xff08;MFCC声学特征&#xff09…

Error handling response: TypeError: self.processResponse is not a function

问题背景 &#xff1a; 自己在搭建 Vue 初始模板架子的时候 &#xff0c; 解决完 router 路由的报错问题后 &#xff0c; 控制台还剩下一个显眼的 Error 红色 Bug &#xff0c; 不解决的话看着难受 &#xff0c; 盘它 &#xff01; 点击报错内容后进入 &#xff1a; Error h…

redis应用笔记

1.登录服务 在登陆服务中,如果将数据全部存储到tomcat中,当存在多个tomcat的时候,数据是无法同步的,这就导致了数据的共享问题: 1、每台服务器中都有完整的一份session数据&#xff0c;服务器压力过大。 2、session拷贝数据时&#xff0c;可能会出现延迟 解决办法就是采用redi…