Servlet的三大域对象是什么

ServletContext对象

每一个 web 应用都有且仅有一个ServletContext 对象,又称 Application 对象,从名称中可知,该对象是与应用程序相关的。在 WEB 容器启动的时候,会为每一个 WEB 应用程序创建一个对应的 ServletContext 对象。

该对象有两大作用,第一、作为域对象用来共享数据,此时数据在整个应用程序中共享; 第二、该对象中保存了当前应用程序相关信息。例如可以通过 getServerInfo() 方法获取当前服务器信息 ,getRealPath(String path) 获取资源的真实路径等。

ServletContext对象的获取

获取 ServletContext 对象的途径有很多。比如:

  1. 通过 request 对象获取
    ServletContext servletContext = request.getServletContext();
  2. 通过 session 对象获取
    ServletContext servletContext = request.getSession().getServletContext();
  3. 通过 servletConfig 对象获取,在 Servlet 标准中提供了 ServletConfig 方法
    ServletConfig servletConfig = getServletConfig();
    ServletContext servletContext = servletConfig.getServletContext();
  4. 直接获取,Servlet 类中提供了直接获取 ServletContext 对象的方法
    ServletContext servletContext = getServletContext();

常用方法

// 获取项目存放的真实路径
String realPath = request.getServletContext().getRealPath("/");
// 获取当前服务器的版本信息
String serverInfo = request.getServletContext().getServerInfo();

ServletContext域对象

ServletContext 也可当做域对象来使用,通过向 ServletContext 中存取数据,可以使得整个应用程序共享某些数据。当然不建议存放过多数据,因为 ServletContext 中的数据一旦存储进去没有手动移除将会一直保存。

// 获取ServletContext对象
ServletContext servletContext = request.getServletContext();
// 设置域对象
servletContext.setAttribute("name","zhangsan");
// 获取域对象
String name = (String) servletContext.getAttribute("name");
// 移除域对象
servletContext.removeAttribute("name");

Servlet的三大域对象

  1. request域对象
    在一次请求中有效。请求转发有效,重定向失效。
  2. session域对象
    在一次会话中有效。请求转发和重定向都有效,session销毁后失效。
  3. servletContext域对象
    在整个应用程序中有效。服务器关闭后失效。

文件上传和下载

在上网的时候我们常常遇到文件上传的情况,例如上传头像、上传资料等;当然除了上传,遇见下载的情况也很多,接下来看看我们 servlet 中怎么实现文件的上传和下载。

文件上传

文件上传涉及到前台页面的编写和后台服务器端代码的编写,前台发送文件,后台接收并保存文件,这才是一个完整的文件上传。

前台页面

在做文件上传的时候,会有一个上传文件的界面,首先我们需要一个表单,并且表单的请求方式为 POST;其次我们的 form 表单的 enctype 必须设为"multipart/form-data",即 enctype="multipart/form-data",意思是设置表单的类型为文件上传表单。默认情况下这个表单类型是 "application/x-www-form-urlencoded", 不能用于文件上传。只有使用了multipart/form-data 才能完整地传递文件数据。

<!--
    文件上传表单
        1. 表单提交类型 method="post"
        2. 表单类型 enctype="multipart/form-data"
        3. 表单元素类型  文件域设置name属性值
-->
<form method="post" action="uploadServlet" enctype="multipart/form-data">
    姓名:<input type="text" name="uname" > <br>
    文件:<input type="file" name="myfile" > <br>
    <button type="submit">提交</button>
</form>

后台实现

使用注解 @MultipartConfig 将一个 Servlet 标识为支持文件上传。 Servlet 将 multipart/form-data 的 POST 请求封装成 Part,通过 Part 对上传的文件进行操作。

package com.xxxx.servlet;
​
import javax.servlet.ServletException;
import javax.servlet.annotation.MultipartConfig;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.Part;
import java.io.IOException;
​
@WebServlet("/uploadServlet")
@MultipartConfig // 如果是文件上传表单,一定要加这个注解
public class UploadServlet extends HttpServlet {
​
    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 设置请求的编码格式
        request.setCharacterEncoding("UTF-8");
        // 获取普通表单项 (文本框)
        String uname = request.getParameter("uname"); // "uname"代表的是文本框的name属性值
        // 通过 getPart(name) 方法获取Part对象 (name代表的是页面中file文件域的name属性值)
        Part part = request.getPart("myfile");
        // 通过Part对象,获取上传的文件名
        String fileName = part.getSubmittedFileName();
        // 获取上传文件需要存放的路径 (得到项目存放的真实路径)
        String realPath = request.getServletContext().getRealPath("/");
        // 将文件上传到指定位置
        part.write(realPath + fileName);
    }
}

文件下载

文件下载,即将服务器上的资源下载(拷贝)到本地,我们可以通过两种方式下载。第一种是通过超链接本身的特性来下载;第二种是通过代码下载。

超链接下载

当我们在 HTML 或 JSP 页面中使用a标签时,原意是希望能够进行跳转,但当超链接遇到浏览器不识别的资源时会自动下载;当遇见浏览器能够直接显示的资源,浏览器就会默认显示出来,比如 txt、png、jpg 等。当然我们也可以通过 download 属性规定浏览器进行下载。但有些浏览器并不支持。

默认下载

<!-- 当超链接遇到浏览器不识别的资源时,会自动下载 -->
<a href="test.zip">超链接下载</a>

指定 download 属性下载

<!-- 当超链接遇到浏览器识别的资源时,默认不会下载。通过download属性可进行下载 -->
<a href="test.txt" download>超链接下载</a>

download 属性可以不写任何信息,会自动使用默认文件名。如果设置了download属性的值,则使用设置的值做为文件名。当用户打开浏览器点击链接的时候就会直接下载文件。

后台实现下载

实现步骤

  1. 需要通过 response.setContentType 方法设置 Content-type 头字段的值, 为浏览器无法使用某种方式或激活某个程序来处理的 MIME 类型,例 如 "application/octet-stream" 或 "application/x-msdownload" 等。
  2. 需要通过 response.setHeader 方法设置 Content-Disposition 头的值 为 "attachment;filename=文件名"
  3. 读取下载文件,调用 response.getOutputStream 方法向客户端写入附件内容。
package com.xxxx.servlet;
​
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
​
public class DownloadServlet extends HttpServlet {
    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 设置请求的编码
        request.setCharacterEncoding("UTF-8");
        // 获取文件下载路径
        String path = getServletContext().getRealPath("/");
        // 获取要下载的文件名
        String name = request.getParameter("fileName");
        // 通过路径得到file对象
        File file = new File(path + name);
        // 判断file对象是否存在,且是否是一个标准文件
        if (file.exists() && file.isFile()) {
            // 设置响应类型 (浏览器无法使用某种方式或激活某个程序来处理的类型)
            response.setContentType("application/x-msdownload");
            // 设置头信息
            response.setHeader("Content-Disposition", "attachment;filename=" + name);
            // 得到输入流
            InputStream is = new FileInputStream(file);
            // 得到输出流
            ServletOutputStream os = response.getOutputStream();
            // 定义byte数组
            byte[] car = new byte[1024];
            // 定义长度
            int len = 0;
            // 循环 输出
            while ((len = is.read(car)) != -1) {
                os.write(car, 0, len);
            }
            // 关闭流 释放资源
            os.close();
            is.close();
        } else {
            System.out.println("文件不存在,下载失败!");
        }
    }
}

 

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值