JavaWeb-HttpServletRequest请求域接口

文章目录

  • HttpServletRequest请求域接口
    • HttpServletRequest请求域接口简介
    • 关于请求域和应用域的区别
  • 请求域接口中的相关方法
    • 获取前端请求参数(getParameter系列方法)
    • 存储请求域名参数(Attribute系列方法)
    • 获取客户端的相关地址信息
    • 获取项目的根路径
  • 关于转发和重定向的细致剖析
    • 转发代码实现及相关问题
    • 重定向代码实现及相关问题

HttpServletRequest请求域接口

HttpServletRequest请求域接口简介

其实关于请求域这个词也蛮熟悉的, 因为我们之前学习过 应用域 这一概念, 应用域的生命周期很长, 伴随这服务器的启动和终止, 作用范围也很广, 对所有的处于当前 webapp 也就是 web 应用的所有Servlet对象都生效


  • HttpServletRequest 是位于jakarta.servlet.http.*包下面的一个接口

  • 继承了ServletRequest接口
    public interface HttpServletRequest extends ServletRequest

  • 之前我们学习过HTTP协议的相关内容, 这个对象中封装的其实就是网络传输的时候, 发送的HTTP请求(Request)中封装的相关参数内容信息

  • 实现这个接口是Tomcat服务器实现的, 传递对象封装参数也是Tomcat服务器完成好的内容, 我们作为Java程序员, 只需要学习获取其中封装的相关参数即可


关于请求域和应用域的区别

  • 生命周期不同, 应用域伴随着Tomcat的生命周期 而 请求域 只作用域这一次请求之内, 而且http协议的特点就是, 一次请求一次创建一次请求域对象
  • 而且在进行参数设定的时候, 尽量的去选择请求域的参数而不是应用域的参数, 因为小的域的对象占用的资源比较小

请求域接口中的相关方法

上面都说了, 请求域是封装了相关的http协议的参数信息, 所以必定提供了一些方法来让我们程序员获取到这些参数的信息…


获取前端请求参数(getParameter系列方法)

首先我们思考, 前端传递过来的参数应该采用什么数据结构来组织比较好

我们从下面的前端的页面中获取信息

<!DOCTYPE html>
<html lang='en'>
<head>
    <meta charset='UTF-8'>
    <meta name='viewport' content='width=device-width, initial-scale=1.0'>
    <title>个人信息</title>
</head>
<body>
    <h2>个人信息</h2>
    <form action="" method="get">
        姓名:<input type="text" name="name" value=""><br>
        年龄:<input type="text" name="age" value=""><br>
        性别:<input type="radio" name="sex" value="">
            <input type="radio" name="sex" value=""><br>
        爱好:<input type="checkbox" name="hobby" value="吃饭">
            <input type="checkbox" name="hobby" value="睡觉">
            <input type="checkbox" name="hobby" value="打游戏"><br>
        <input type="submit" value="提交">
    </form>
</body>
</html>

我们执行 http://127.0.0.1:8080/servlet08/test.html

在这里插入图片描述

我们对URL拆解如下(涉及URLEncoding)

在这里插入图片描述

我们可以发现, 前端向后端提交数据的格式其实并不是单纯的键值对的结构存储的, 因为如果是键值对结构存储的话, 一个key只能对应一个value, 但是复选框这种提交信息的结构, 一个key可以对应多个value信息

所以实际上, 我们的前端发来的数据存储格式是一个特殊的map集合

Map<String, String[]> map = new HashMap<>();

一个String类型的key可以对应一个String[] 数组, 也就是多个value(前端传递参数都是String类型)


上面是一个html页面, 其中包含test类型文本, 单选框, 复选框

在这里插入图片描述

上面的方法的解释:

  • String getParameter(String name): 根据key返回String数组中的第一个参数
  • String[] getParameterValues(String name): 根据key返回完整的String[]数组
  • Enumeration< String > getParameterNames(): 返回一个由所有key组成的集合
  • Map<String, String[]> getParameterMap(): 返回一个key和value组成的完整的集合

还拿我们上面写的那个html页面进行测试(设置一下传递的Servlet路径地址)
(注意, 我们下面的method其实写错了, 实际上是post请求)

在这里插入图片描述

Servlet对象的源码如下

import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

import java.io.*;
import java.util.Enumeration;
import java.util.Map;

@WebServlet(urlPatterns = "/getparameter")
public class GetParameterServlet extends HttpServlet {

    // 由于是form表单提交的数据, 我们尽量采用重写doPost的方式进行测试
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 最好还是设置一下字符集, 防止出现乱码
        response.setContentType("text/html;charset=UTF-8");
        PrintWriter out = response.getWriter();

        // 1. 使用getParameterMap获取整个的map形式参数集合
        out.print("<h3>使用getParameterMap获取整个集合</h3>");
        Map<String, String[]> parameterMap = request.getParameterMap();
        for(Map.Entry<String, String[]> entry : parameterMap.entrySet()){
            out.print(entry.getKey() + "=");
            for(String value : entry.getValue()){
                out.print(value + " ");
            }
        }
        out.print("<br>");
        out.print("====================================<br>");

        // 2. 使用getParameterNames获取整个参数集合的key
        out.print("<h3>使用getParameterNames获取整个集合中的key</h3>");
        Enumeration<String> parameterNames = request.getParameterNames();
        while(parameterNames.hasMoreElements()){
            String name = parameterNames.nextElement();
            out.print(name + " ");
        }
        out.print("<br>");
        out.print("====================================<br>");

        // 3. 使用getParameterValues, 根据key获取参数集合的value数组
        String[] hobbys = request.getParameterValues("hobby");
        out.print("hobby=");
        for(String hobby : hobbys){
            out.print(hobby + " ");
        }
        out.print("<br>");
        out.print("====================================<br>");

        // 4. 使用getParameter, 根据key获取到value数组中的第一个值
        String name = request.getParameter("name");
        out.print("name=" + name);
        out.print("<br>");
        out.print("====================================<br>");
    }
}

测试:

下面是form表单中提交的数据信息

在这里插入图片描述


下面是在浏览器中输出的内容

在这里插入图片描述


存储请求域名参数(Attribute系列方法)

Attribute 这个词其实我们很熟悉了, 因为之前学习ServletContext就出现过这个词, 也出现了和下面一模一样的一系列方法, 当时是设置应用域对象, 但是现在是设置请求域对象

在这里插入图片描述
在这里插入图片描述

  • void setAttribute(String name, Object o): 设置请求域参数
  • Object getAttribute(String name): 获取请求域参数
  • Enumeration< String > getAttributeNames(): 获取所有请求域的key组成的集合
  • void removeAttribute(String name): 移除 key 为参数的请求域信息

没啥可说的, 直接上测试代码

import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

import java.io.*;
import java.util.Enumeration;

// 使用注解来配置Servlet
@WebServlet("/attribute")
public class AttributeInfoServlet extends HttpServlet {

    // 重写doGet方法
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        response.setContentType("text/html");
        PrintWriter out = response.getWriter();

        // 1. 使用 void setAttribute(String name, Object o) 设置请求域参数
        request.setAttribute("name", "Jack");
        request.setAttribute("age", 18);

        // 2. 使用 Object getAttribute(String name) 获取请求域参数
        Object name = request.getAttribute("name");
        Object age = request.getAttribute("age");
        out.print("<h3>" + name + " " + age + "</h3>");

        out.print("<br>========================================<br>");

        // 3. 使用 Enumeration< String > getAttributeNames() 获取所有的请求域参数key集合
        Enumeration<String> attributeNames = request.getAttributeNames();
        while (attributeNames.hasMoreElements()) {
            String attributeName = attributeNames.nextElement();
            out.print("<h3>" + attributeName + "</h3>");
        }

        out.print("<br>========================================<br>");

        // 4. 使用 void removeAttribute(String name) 移除参数
        request.removeAttribute("name");
        Object name1 = request.getAttribute("name");
        out.print("<h3>" + name1 + "</h3>");
    }
}

测试结果如下

在这里插入图片描述

获取客户端的相关地址信息

我们需要掌握下面的三个获取地址相关信息的方法

  • getRemoteAddr(): 获取客户端主机IP
  • getRemotePort(): 获取客户端的应用端port(端口号)
  • getRemoteHost(): 获取客户端主机名称

下面是关于上面的三个方法的测试代码(我们直接给出)

import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

import java.io.*;


// 使用注解代替web.xml进行Servlet的配置
@WebServlet(urlPatterns = "/addr")
public class GetAddr extends HttpServlet {

    // 重写doGet方法

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

        // 设置返回的类型以及获取输出流信息
        response.setContentType("text/html");
        PrintWriter out = response.getWriter();

        // 1. 使用getRemoteAddr获取客户端的IP信息
        String remoteAddr = request.getRemoteAddr();
        out.print("<h3>客户端的IP地址为</h3><br>");
        out.print(remoteAddr);

        out.print("<br>=====================================");

        // 2. 使用getRemotePort获取客户端的端口号的信息
        int remotePort = request.getRemotePort();
        out.print("<h3>客户端的端口号为</h3><br>");
        out.print(remotePort);

        out.print("<br>======================================");

        // 3. 使用getRemoteHost获取客户端的主机名称
        String remoteHost = request.getRemoteHost();
        out.print("<h3>客户端的主机名号为</h3><br>");
        out.print(remoteHost);
        
    }
}

在浏览器上面访问这个资源, 可以得到下面的内容

在这里插入图片描述

注意我们的端口号其实不是固定的, 每一次请求的端口号都是在一个范围之内进行随机的, 因为我们的规范建议客户端的端口号设置为变化的, 服务器端的端口号设置为不变的…


获取项目的根路径

这个方法其实用的还是很多的, 因为我们在大量的场景中都需要动态获取根路径, 也就是项目路径, 我们在先前的内容中其实也提到过这个方法…

  • getContextPath(): 获取项目部署的路径…

测试就省略了, 主要是想说这个方法的作用非常的重要, 我们好多地方获取项目的路径都需要这个方法…


关于转发和重定向的细致剖析

首先要了解, 不管是转发和重定向, 其目的都是为了实现资源的跳转

也就是Java中有两种方式实现资源的跳转

  • 转发
  • 重定向

转发代码实现及相关问题

在这里插入图片描述
在这里插入图片描述

  • getRequestDispatch(String servletName): 通过给定的转发的ServletName地址获取一个分发器对象
  • forward(request, response): 把当前Servlet对象的请求响应对象作为参数传递到转发当中去, 从而实现位于同一个请求域的作用…

转发的代码实现

首先创建一个AServlet对象(相关注释都在代码中)

import bean.User;
import jakarta.servlet.RequestDispatcher;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

import java.io.*;

// 使用注解信息简化Servlet配置
// 我们把这个 AServlet 作为资源访问的入口, 然后对 BServlet进行资源的转发(所以二者本质上还是一次请求, 共享同一个请求域)
@WebServlet(urlPatterns = "/a")
public class AServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        // 因为要测试转发是不是在一次请求之内转发(也就是多个Servlet共享同一个request和response对象)
        // 我们设置相关的请求域参数(我们把用户定义在了另一个包当中, 等会我们复制代码就不展示User类了, 应该可以看懂)
        request.setAttribute("user", new User("huahua", "19", "zz"));

        // 获取分发器对象, 调用分发器对象的forward方法对这次请求进行转发
        RequestDispatcher requestDispatcher = request.getRequestDispatcher("/b");
        requestDispatcher.forward(request, response);
    }
}

创建一个BServlet对象作为AServlet的转发请求的地址

import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import bean.User;

import java.io.*;

// 使用注解简化Servlet配置
// 这个BServlet作为转发的接收方, 接收AServlet的转发
@WebServlet(urlPatterns = "/b")
public class BServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("text/html");
        PrintWriter out = response.getWriter();
        // 获取AServlet中的应用域的参数
        Object user = request.getAttribute("user");
        // 强制类型转化
        User us = (User) user;
        // 输出其中的信息内容
        out.print(us);
    }
}

在这里插入图片描述

我们现在在浏览器中访问AServlet的资源, 显然, 跳转到了BServlet中

  • 可以发现, 在A中设置的请求域参数, B中同样可以获取, 所以可以判定二者位于同一个请求域
  • 通过URL可以发现, 虽然资源跳转到了BServlet, 但是URL中的地址还是显示的AServlet的地址, 所以我们可以了解到, 其实转发是一种Tomcat服务器内部进行的资源跳转, 和浏览器无关(和重定向区分的重要依据)
  • 根据上面的提示, 我们可以了解到, 转发是同一次请求的转发, 也就是只能在一种方法当中之间进行转发, 全部都在doGet内部转发, 或者全部都在doPost请求中进行转发…

转发不可以在不同的方法之间完成跳转, 测试如下
假设我们把 BServlet中的 doGet 方法转换为 doPost 方法

在这里插入图片描述

其他代码完全不变, 此时再次向AServlet发送请求

在这里插入图片描述

会发现直接报错, 报错信息是 405 method not allowed

其实针对上述问题, 我们还是有解决方案的, 只需要在doGet方法内部调用doPost就可以避免这种问题

在这里插入图片描述

继续访问AServlet, 会发现程序还是可以正常执行
在这里插入图片描述


重定向代码实现及相关问题

和转发不同, 重定向调用的API位于response对象中

通过 response 对象调用 sendReDirect(/项目路径/Servlet路径)方法进行重定向

代码测试

CServlet如下

import bean.User;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

import java.io.*;

// 使用注解简化开发
@WebServlet(urlPatterns = "/c")
public class CServlet extends HttpServlet {

    // 重写doGet方法
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        // 在CServlet类中设置请求域参数, 然后在DServlet中获取这个请求域参数, 查看是否可以获取得到...
        request.setAttribute("user", new User("huahua", "19", "zz"));

        // 调用 sendRedirt 进行重定向操作(重定向要加上项目的地址), 重定向至DServlet
        response.sendRedirect(request.getContextPath() + "/d");
    }
}

DServlet

import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

import java.io.*;

// 使用注解简化开发
@WebServlet(urlPatterns = "/d")
public class DServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("text/html");
        PrintWriter out = response.getWriter();

        // 尝试接收CServlet中设置的请求域参数, 查看是不是可以获取到(其实本质是查看是不是一次请求)
        Object user = request.getAttribute("user");

        out.println(user == null ? "不是一个请求" : "是一个请求");
    }
}


向CServlet发送请求
在这里插入图片描述

获取响应结果如下

在这里插入图片描述

  • 很明显的看到URL中的资源明显的发生了改变

我们不妨抓个包看一看刚才发生了什么

会发现出现了两次请求…

在这里插入图片描述

第一次向CServlet发送了请求, 这是第一次的请求响应信息

在这里插入图片描述

可以发现, 响应时的状态码是 302 Found

在这里插入图片描述

也就是发生了重定向的操作

第二次请求是直接通过浏览器向DServlet发送了一个请求而不是Tomcat资源内部的跳转, 具体不再演示了


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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

IO多路复用实现并发服务器

一.select函数 select 的调用注意事项 在使用 select 函数时&#xff0c;需要注意以下几个关键点&#xff1a; 1. 参数的修改与拷贝 readfds 等参数是结果参数 &#xff1a; select 函数会直接修改传入的 fd_set&#xff08;如 readfds、writefds 和 exceptfds&#xf…

实现静态网络爬虫(入门篇)

一、了解基本概念以及信息 1.什么是爬虫 爬虫是一段自动抓取互联网信息的程序&#xff0c;可以从一个URL出发&#xff0c;访问它所关联的URL&#xff0c;提取我们所需要的数据。也就是说爬虫是自动访问互联网并提取数据的程序。 它可以将互联网上的数据为我所用&#xff0c;…

计算机网络——交换机

一、什么是交换机&#xff1f; 交换机&#xff08;Switch&#xff09;是局域网&#xff08;LAN&#xff09;中的核心设备&#xff0c;负责在 数据链路层&#xff08;OSI第二层&#xff09;高效转发数据帧。它像一位“智能交通警察”&#xff0c;根据设备的 MAC地址 精准引导数…

【SpringBoot】深入解析 Maven 的操作与配置

Maven 1.什么是Maven? Maven是一个项目管理工具&#xff0c;通过pom.xml文件的配置获取jar包&#xff0c;而不用手动去添加jar包&#xff1b; 2. 创建一个Maven项目 IDEA本身已经集成了Maven&#xff0c;我们可以直接使用&#xff0c;无需安装 以下截图的idea版本为&#xff…

MySQL的安装以及数据库的基本配置

MySQL的安装及配置 MySQL的下载 选择想要安装的版本&#xff0c;点击Download下载 Mysql官网下载地址&#xff1a;​ ​https://downloads.mysql.com/archives/installer/​​ MySQL的安装 选择是自定义安装&#xff0c;所以直接选择“Custom”&#xff0c;点击“Next”​ …

Manus AI : Agent 元年开启.pdf

Manus AI : Agent 元年开启.pdf 是由华泰证券出品的一份调研报告&#xff0c;共计23页。报告详细介绍了Manus AI 及 Agent&#xff0c;主要包括Manus AI 的功能、优势、技术能力&#xff0c;Agent 的概念、架构、应用场景&#xff0c;以及 AI Agent 的类型和相关案例&#xff0…

2.数据结构-栈和队列

数据结构-栈和队列 2.1栈2.1.1栈的表示和实现2.1.2栈的应用举例数制转换括号匹配检验迷宫给求解表达式求值 2.1.3链栈的表示和实现2.1.4栈与递归的实现遍历输出链表中各个结点的递归算法*Hanoi塔问题的递归算法 2.2队列2.2.1循环队列——队列的顺序表示和实现2.2.2链队——队列…

(十七) Nginx解析:架构设计、负载均衡实战与常见面试问题

什么是Nginx? Nginx 是一款高性能的 HTTP 服务器和反向代理服务器&#xff0c;同时支持 IMAP/POP3/SMTP 协议。其设计以高并发、低资源消耗为核心优势&#xff0c;广泛应用于负载均衡、静态资源服务和反向代理等场景。 一、Nginx 的核心优势 高并发处理能力采用异步非阻塞的…

Cpu100%问题(包括-线上docker服务以及Arthas方式进行处理)

&#x1f353; 简介&#xff1a;java系列技术分享(&#x1f449;持续更新中…&#x1f525;) &#x1f353; 初衷:一起学习、一起进步、坚持不懈 &#x1f353; 如果文章内容有误与您的想法不一致,欢迎大家在评论区指正&#x1f64f; &#x1f353; 希望这篇文章对你有所帮助,欢…

【大模型】WPS 接入 DeepSeek-R1详解,打造全能AI办公助手

目录 一、前言 二、WPS接入AI工具优势​​​​​​​ 三、WPS接入AI工具两种方式 3.1 手动配置的方式 3.2 Office AI助手 四、WPS手动配置方式接入AI大模型 4.1 安装VBA插件 4.1.1 下载VBA插件并安装 4.2 配置WPS 4.3 WPS集成VB 4.4 AI助手效果测试 4.5 配置模板文…

架构思维:高性能架构_01基础概念

文章目录 概述基础概念性能指标利特尔法则&#xff08;O T L&#xff09;系统优化策略1. 降低耗时&#xff08;L↓&#xff09;2. 增加容量&#xff08;O↑&#xff09;3. 增加时延&#xff08;L↑&#xff09; 场景化指标选择响应时间优先吞吐量/容量优先平衡策略 概述 一个…

解决stylelint对deep报错

报错如图 在.stylelintrc.json的rules中配置 "selector-pseudo-class-no-unknown": [true,{"ignorePseudoClasses": ["deep"]} ]

VScode 中文符号出现黄色方框的解决方法

VScode 中文符号出现黄色方框的解决方法 我的vscode的python多行注释中会将中文字符用黄色方框框处&#xff1a; 只需要打开设置搜索unicode&#xff0c;然后将这一项的勾选取消掉就可以了&#xff1a; 取消之后的效果如下&#xff1a; 另一种情况&#xff1a;中文显示出现黄色…

大模型架构记录2

一 应用场景 1.1 prompt 示例 1.2 自己搭建一个UI界面&#xff0c;调用接口 可以选用不同的模型&#xff0c;需要对应的API KEY 二 Agent 使用 2.1 构建GPT

深度学习实战车辆目标跟踪与计数

本文采用YOLOv8作为核心算法框架&#xff0c;结合PyQt5构建用户界面&#xff0c;使用Python3进行开发。YOLOv8以其高效的实时检测能力&#xff0c;在多个目标检测任务中展现出卓越性能。本研究针对车辆目标数据集进行训练和优化&#xff0c;该数据集包含丰富的车辆目标图像样本…

升级到Android Studio 2024.2.2 版本遇到的坑

一、上来就编译报错&#xff0c;大概率是因为选择了替换安装&#xff0c;本地配置文件出错 找到本地当前版本的配置文件&#xff0c;删掉&#xff0c;重启studio就好了&#xff1a; 1、打开终端 2、“cd /Users/用户名/Library/Application\ Support/Google” //到Google目录 …

Git - 补充工作中常用的一些命令

Git - 补充工作中常用的一些命令 1 一些场景1.1 场景11.2 场景21.3 场景31.4 场景41.5 场景51.6 场景61.7 场景71.8 场景81.9 场景91.10 场景101.11 场景111.12 场景121.13 场景131.14 场景141.15 场景15 2 git cherry-pick \<commit-hash\> 和 git checkout branch \-\-…

【网络安全工程】任务11:路由器配置与静态路由配置

目录 一、概念 二、路由器配置 三、配置静态路由CSDN 原创主页&#xff1a;不羁https://blog.csdn.net/2303_76492156?typeblog 一、概念 1、路由器的作用&#xff1a;通过路由表进行数据的转发。 2、交换机的作用&#xff1a;通过学习和识别 MAC 地址&#xff0c;依据 M…

如何用更少的内存训练你的PyTorch模型?深度学习GPU内存优化策略总结

在训练大规模深度学习模型时&#xff0c;GPU 内存往往成为关键瓶颈&#xff0c;尤其是面对大型语言模型&#xff08;LLM&#xff09;和视觉 Transformer 等现代架构时。由于大多数研究者和开发者难以获得配备海量 GPU 内存的高端计算集群&#xff0c;掌握高效的内存优化技术至关…

Dify+DeepSeek | Excel数据一键可视化(创建步骤案例)(echarts助手.yml)(文档表格转图表、根据表格绘制图表、Excel绘制图表)

Dify部署参考&#xff1a;Dify Rag部署并集成在线Deepseek教程&#xff08;Windows、部署Rag、安装Ragan安装、安装Dify安装、安装ollama安装&#xff09; DifyDeepSeek - Excel数据一键可视化&#xff08;创建步骤案例&#xff09;-DSL工程文件&#xff08;可直接导入&#x…