写谷歌浏览器插件的时候怎么获取到newwork中的请求的response信息_web请求和常用对象(终)|乐字节...

大家好,欢迎来到乐字节小乐的Java技术分享园地

回顾上篇内容:

乐字节:web请求和常用对象(续)|乐字节​zhuanlan.zhihu.com

一、Session

1. 介绍

HttpSession对象是 javax.servlet.http.HttpSession 的实例,该接口并不像 HttpServletRequest 或 HttpServletResponse 还存在一个父接口,该接口只是一个纯粹的接口。这因为 session 本身就属于 HTTP 协议的范畴。

对于服务器而言,每一个连接到它的客户端都是一个 session,servlet 容器使用此接口创建 HTTP 客户端和 HTTP 服务器之间的会话。会话将保留指定的时间段,跨多个连接或来自用户的页面请求。一个会话通常对应于一个用户,该用户可能多次访问一个站点。可以通过此接口查看和操作有关某个会话的信息,比如会话标识符、创建时间和最后一次访问时间。在整个 session 中,最重要的就是属性的操作。

69a6a4d5687ff42310759fa69a896c6a.png

session 无论客户端还是服务器端都可以感知到,若重新打开一个新的浏览器,则无法取得之前设置的 session,因为每一个 session 只保存在当前的浏览器当中,并在相关的页面取得。

2. Session 的作用

Session 的作用就是为了标识一次会话,或者说确认一个用户;并且在一次会话(一个用户的多次请求)期间共享数据。我们可以通过 req.getSession()方法,来获取当前会话的 session 对象。

676e54d11505642d83e9bcdfcdaf8e8a.png

3. 标识会话 JSESSIONID

Session 既然是为了标识一次会话,那么此次会话就应该有一个唯一的标志,这个标志就是 sessionId。

每当一次请求到达服务器,如果开启了会话(访问了 session),服务器第一步会查看是否从客户端回传一个名为 JSESSION 的 cookie,如果没有则认为这是一次新的会话,会创建 一个新的 session 对象,并用唯一的 sessionId 为此次会话做一个标志。如果有 JESSIONID 这 个cookie回传,服务器则会根据JSESSIONID这个值去查看是否含有id为JSESSION值的session 对象,如果没有则认为是一个新的会话,重新创建一个新的 session 对象,并标志此次会话; 如果找到了相应的 session 对象,则认为是之前标志过的一次会话,返回该 session 对象,数据达到共享。

这里提到一个叫做 JSESSION 的 cookie,这是一个比较特殊的 cookie,当用户请求服务器时,如果访问了 session,则服务器会创建一个名为 JSESSION,值为获取到的 session(无论是获取到的还是新创建的)的 sessionId 的 cookie 对象,并添加到 response 对象中,响应给客户端,有效时间为关闭浏览器。

所以 Session 的底层依赖 Cookie 来实现。

4. 作为域对象

Session 用来表示一次会话,在一次会话中数据是可以共享的,这时 session 作为域对象存在,可以通过 setAttribute(name,value);方法向域对象中添加数据,通过getAttribute(name) 从域对象中获取数据,通过 removeAttribute(name)从域对象中移除数据。

3e236a22eeebdb2e2668cfe206ba0526.png

数据存储在 session 域对象中,当 session 对象不存在了,或者是两个不同的 session 对 象时,数据也就不能共享了。这就不得不谈到 session 的生命周期。

5. Session 的销毁

1) 默认时间到期

当客户端第一次请求 servlet 并且操作 session 时,session 对象生成,Tomcat 中 session 默认的存活时间为 30min,即你不操作界面的时间,一旦有操作,session 会重新计时。那么 session的默认事件可以改么?答案是肯定的。可以在Tomcat中的web.xml文件中进行修改。 如下图:

a23da8c12c79772d00c281c63edc49c3.png

2) 自己设定到期时间

当然除了以上的修改方式外,我们也可以在程序中自己设定 session 的生命周期,通过session.setMaxInactiveInterval(int);来设定 session 的最大不活动时间,单位为秒。

23fb915098f1e8d461be455c80db1651.png

当然我们也可以通过 getMaxInactiveInterval();方法来查看当前 Session 对象的最大不活动时间。

3) 立刻失效

或者我们也可以通过 session.invalidate();方法让 session 立刻失效

37187cf2938d442f0c7dd628e2890b8a.png

4) 关闭浏览器

从前面的 JESSION 可知道,session 的底层依赖 cookie 实现,并且该 cookie 的有效时间为关闭浏览器,从而 session 在浏览器关闭时也相当于失效了(因为没有 JSESSION 再与之对应)。

5) 关闭服务器

当非正常关闭服务器时,session 销毁;当正常关闭服务器时,Session 将被序列化到磁盘上,在工作空间 work 目录下的 SESSION.ser 文件中,下次启动服务时,自动加载到内存。

Session 失效则意味着此次会话结束,数据共享结束。

二、ServletContext 对象

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

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

1. ServletContext对象的获取

获取 ServletContext 对象的途径有很多例如通过 request 对象可以

aa2aa43eb45467bce99a5c673148ef83.png

通过 session 可以

aa2aa43eb45467bce99a5c673148ef83.png

通过servletConfig可以,在 Servlet 标准中提供了获取 ServletConfig 的方法

ed48c5c2105a1da391c286e5c780d6a5.png

本身Servlet标准后期的实现类中也提供了直接获取 ServletContext 的方法

ac5652f1f981eaa11d8c3b3d5d4651e6.png

2. 作为域对象

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

c6d065842edd03de5b59782dbaa4381d.png

到此了解了ServletContext的常用方法,后期使用到更多方法,查阅API即可。

三、文件上传下载

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

1. 文件上传

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

1) 前台页面

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

07e514a21eb99badfd5e8d197bedf976.png

6) 后台 commons-fileupload 的使用

首先需要导入第三方jar包,http://commons.apache.org/ 下 载 commons-io 和 commons-fileupload 两个jar的资源。解压并导入到项目中。 commons-fileupload.jar 是文件上传的核心包 commons-io.jar 是 filefupload 的依赖包,同时又是一个工具包。

2c354dbc4065b65261f1b50736273269.png

介绍一下使用到的几个核心类

DiskFileItemFactory – 设置磁盘空间,保存临时文件。只是一个工具类 ServletFileUpload – 文件上传的核心类,此类接收 request,并解析 ServletFileUpload.parseRequest(request); – List 解析 request

1、 创建一个 DiskFileItemFactory 工厂类,并制定临时文件和大小

2、 创建 ServletFileUpload 核心类,接收临时文件,做请求的转换

3、 通过 ServletFileUpload 类转换原始请求,得到 FileItem 集合

4、 遍历集合中的各个元素并处理

5、 判断每个元素是否是普通表单项,如果是则按照普通表单项处理

6、 如果不是普通表单项,则是文件,通过处理的方式进行处理(上传)

public class UploadSource extends HttpServlet {
 protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
  // 设定编码,可以获取中文文件名
  req.setCharacterEncoding("UTF-8");
  // 获取tomcat下的upload目录的路径
  String path = getServletContext().getRealPath("/upload");
  // 临时文件目录
  String tempPath = getServletContext().getRealPath("/temp");
  // 检查我们是否有文件上传请求
  // boolean isMultipart = ServletFileUpload.isMultipartContent(req);
  // 1、声明DiskFileItemFactory工厂类,用于在指定磁盘上设置一个临时目录
  DiskFileItemFactory disk = new DiskFileItemFactory(1024 * 10, new File(tempPath));
  // 2、声明ServletFileUpload,接收上面的临时文件。也可以默认值
  ServletFileUpload up = new ServletFileUpload(disk);
  // 3、解析request
  try {
   List<FileItem> list = up.parseRequest(req);
   if (list.size() > 0) {
    for (FileItem file : list)
     // 判断是否是普通的表单项
     if (file.isFormField()) {
      String fieldName = file.getFieldName();
      // 中文乱码,此时还需要指定获取数据的编码方式
      // String value = file.getString();
      String value = file.getString("UTF-8");
      System.out.println(fieldName + "=" + value);
     } else { // 说明是一个文件
      // 获取文件本身的名称
      String fileName = file.getName();
      System.out.println(file.getFieldName());
      // 处理文件名称
      fileName = fileName.substring(fileName.lastIndexOf("") + 1);
      System.out.println("old Name : " + fileName);
      // 修改名称
      String extName = fileName.substring(fileName.lastIndexOf("."));
      String newName = UUID.randomUUID().toString().replace("-", "") + extName;
      // 保存新的名称,并写出到新文件中
      file.write(new File(path + "/" + newName));
      System.out.println("文件名是:" + fileName);
      System.out.println("文件大小是:" + file.getSize());
      file.delete();
     }
   }
  } catch (FileUploadException e) {
   e.printStackTrace();
  } catch (Exception e) {
   e.printStackTrace();
  }
 }
}

7. 文件下载

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

1) 超链接下载

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

默认下载

f8b2e1926087e88561b40e8b21e623cb.png

指定 download 属性下载

fd3bf980578dc4af91ee856b242453b7.png

这里,download 也可以不写任何信息,会自动使用默认文件名。这样当用户打开浏览 器点击链接的时候就会直接下载文件。

7) 后台实现下载

Step1:需要通过 HttpServletResponse.setContentType 方法设置 Content-type 头字段的值, 为浏览器无法使用某种方式或激活某个程序来处理的 MIME 类型,例 如 ”application/octet-stream” 或 ”application/x-msdownload” 等

Step2:需要通过 HttpServletResponse.setHeader 方法设置 Content-Disposition 头的值 为”attachment;filename=文件名”

Step3: 读取下载文件,调用HttpServletResponse.getOutputStream方法返回的OutputStream对象来向客户端写入附件内容。

public class DownloadServlet extends HttpServlet {
 private static final long serialVersionUID = 1L;
 
 protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
  req.setCharacterEncoding("UTF-8");
  // 获取文件下载路径
  String path = getServletContext().getRealPath("/") + "download/";
  String fileName = req.getParameter("filename");
  File file = new File(path + fileName);
  if (file.exists()) {
   // 设置相应类型 application/octet-stream
   resp.setContentType("application/x-msdownload");
   // 设置头信息
   resp.setHeader("Content-Disposition", "attachment;filename=" + fileName);
   InputStream is = new FileInputStream(file);
   ServletOutputStream os = resp.getOutputStream();
   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("文件不存在,下载失败!");
  }
 }
}

感谢阅读乐字节技术文章,请继续关注乐字节或添加君羊:⑧⑥⑧⑤零④零⑨⑨,更多Java技术文章奉上,下次小乐将为大家带来过滤器及监听器的详细讲解!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
回答: 根据提供的引用内容,你遇到了两个问题。第一个问题是安装vite后运行时报错:Cannot find module 'worker_threads'。根据引用的解决方案,这可能是因为你的node版本太低所导致的。你可以通过安装新的node版本来解决这个问题。***123 #### 引用[.reference_title] - *1* [安装vite报错:Cannot find module ‘worker_threads](https://blog.csdn.net/zxhzm_life/article/details/123159056)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}} ] [.reference_item] - *2* [springboot+vue前后端分离项目遇到的错误1ERROR Error: EPERM: operation not permitted, mkdir ‘D:\Node\...](https://blog.csdn.net/qq_54381475/article/details/129794877)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}} ] [.reference_item] - *3* [【Qualcomm sdx62】编译ERROR: lighttpd_1.4.59.bb:do_fetch) failed with exit code ‘1](https://blog.csdn.net/wgl307293845/article/details/123416448)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值