当前位置: 首页 > news >正文

SpringBoot整合WebService

SpringBoot整合WebService

WebService是一个比较旧的远程调用通信框架,现在企业项目中用的比较少,因为它逐步被SpringCloud所取代,它的优势就是能够跨语言平台通信,所以还有点价值,下面来看看如何在SpringBoot项目中使用WebService

我们模拟从WebService客户端发送请求给WebService服务端暴露的下载文件服务,并获取服务端返回的文件保存到本地

环境

SpringBoot2.7.3

Jdk17

服务端

在SpringBoot中整合WebService的服务端,需要通过一个配置文件将服务接口暴露出去给客户端调用

项目结构

image-20230727183518916

配置

服务端POM

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.7.3</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>com.example</groupId><artifactId>webservice</artifactId><version>0.0.1-SNAPSHOT</version><name>webservice</name><description>webservice</description><properties><java.version>17</java.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId><scope>runtime</scope><optional>true</optional></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><!--cxf--><dependency><groupId>org.apache.cxf</groupId><artifactId>cxf-rt-transports-http</artifactId><version>3.5.1</version></dependency><dependency><groupId>org.apache.cxf</groupId><artifactId>cxf-rt-frontend-jaxws</artifactId><version>3.5.1</version></dependency><!--hutool--><dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.8.12</version></dependency><!--fastjson--><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>2.0.16</version></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><configuration><excludes><exclude><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></exclude></excludes></configuration></plugin></plugins></build></project>

服务端YML

server: # 必须配置端口,客户端需要port: 7001

FileCxfConfig

该文件为WebService服务暴露配置文件

package com.example.webservice.config;import com.example.webservice.service.FileCxfService;
import com.example.webservice.service.impl.FileCxfServiceImpl;
import org.apache.cxf.Bus;
import org.apache.cxf.bus.spring.SpringBus;
import org.apache.cxf.jaxws.EndpointImpl;
import org.apache.cxf.transport.servlet.CXFServlet;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;import javax.xml.ws.Endpoint;@Configuration
public class FileCxfConfig {@Bean(name = Bus.DEFAULT_BUS_ID)public SpringBus springBus() {return new SpringBus();}@Bean(name = "downloadFileBean")public ServletRegistrationBean dispatcherServlet() {ServletRegistrationBean wbsServlet = new ServletRegistrationBean(new CXFServlet(), "/file/*");return wbsServlet;}@Beanpublic FileCxfService fileCxfService() {return new FileCxfServiceImpl();}@Beanpublic Endpoint endpointPurchase(SpringBus springBus, FileCxfService fileCxfService) {EndpointImpl endpoint = new EndpointImpl(springBus(), fileCxfService());endpoint.publish("/download");System.err.println("服务发布成功!地址为:http://localhost:7001/file/download?wsdl");return endpoint;}}

FileCxfService

该类指定了暴露的服务接口,注意类中的注解都很重要,不能丢,具体可以看说明

package com.example.webservice.service;import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebResult;
import javax.jws.WebService;
import javax.xml.ws.BindingType;@BindingType(value = "http://www.w3.org/2003/05/soap/bindings/HTTP/")
@WebService(serviceName = "FileCxfService", // 与接口中指定的name一致targetNamespace = "http://webservice.example.com" // 与接口中的命名空间一致,一般是接口的包名倒
)
public interface FileCxfService {@WebMethod(operationName = "downloadFile")@WebResult(name = "String")String downloadFile(@WebParam(name = "params", targetNamespace = "http://webservice.example.com") String params,@WebParam(name = "token", targetNamespace = "http://webservice.example.com") String token);}

FileCxfServiceImpl

该类指定了暴露的服务接口的具体实现,注意类中的注解都很重要,不能丢,具体可以看说明

package com.example.webservice.service.impl;import cn.hutool.core.codec.Base64;
import com.alibaba.fastjson2.JSONObject;
import com.example.webservice.pojo.FileDto;
import com.example.webservice.service.FileCxfService;import javax.jws.WebService;@WebService(serviceName = "FileCxfService", // 与接口中指定的name一致targetNamespace = "http://webservice.example.com" // 与接口中的命名空间一致,一般是接口的包名倒
)
public class FileCxfServiceImpl implements FileCxfService {@Overridepublic String downloadFile(String params, String token) {//下载文件System.err.println("params : " + params);FileDto fileDto = JSONObject.parseObject(params, FileDto.class);System.err.println("fileDto : " + fileDto);String data = null;try {data = Base64.encode("C:\\Users\\YIQI\\Desktop\\ebook\\Java70.pdf");} catch (Exception e) {e.printStackTrace();}System.err.println(data);return data;}}

FileDto

该类为参数实体类,用于接受客户端传来的参数

package com.example.webservice.pojo;import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.ToString;@Data
@AllArgsConstructor
@ToString
public class FileDto {private String fileId;private String newFileId;private String bucketName;}

客户端

在SpringBoot中整合WebService的客户端,需要指定服务端暴露的服务接口

项目结构

image-20230727184202714

配置

客户端POM

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.7.3</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>com.example</groupId><artifactId>webclient</artifactId><version>0.0.1-SNAPSHOT</version><name>webclient</name><description>webclient</description><properties><java.version>17</java.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId><scope>runtime</scope><optional>true</optional></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><!--cxf--><dependency><groupId>org.apache.cxf</groupId><artifactId>cxf-rt-transports-http</artifactId><version>3.5.1</version></dependency><dependency><groupId>org.apache.cxf</groupId><artifactId>cxf-rt-frontend-jaxws</artifactId><version>3.5.1</version></dependency><!--hutool--><dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.8.12</version></dependency><!--fastjson--><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>2.0.16</version></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><configuration><excludes><exclude><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></exclude></excludes></configuration></plugin></plugins></build></project>

客户端YML

server: # 可以不配置port: 1000

FileCxfService

这个文件和服务端的FileCxfService保持一致,用于指定客户端请求的方式

package com.example.webclient.service;import javax.jws.WebParam;
import javax.jws.WebService;@WebService(name = "FileCxfService", // 暴露服务名称targetNamespace = "http://webservice.example.com"// 命名空间,一般是接口的包名倒序
)
public interface FileCxfService {String downloadFile(@WebParam(name = "data", targetNamespace = "http://webservice.example.com") String data,@WebParam(name = "token", targetNamespace = "http://webservice.example.com") String token);}

FileCxfClient

这个类是客户端的主类,里面有发送WebService请求的方法

package com.example.webclient.client;import cn.hutool.core.codec.Base64;
import com.alibaba.fastjson2.JSONObject;
import com.example.webclient.pojo.FileDto;
import com.example.webclient.service.FileCxfService;
import com.example.webclient.util.ConvertBASE64;import javax.xml.bind.DatatypeConverter;
import javax.xml.namespace.QName;
import javax.xml.ws.Service;
import java.net.URL;public class FileCxfClient {public static void main(String[] args) throws Exception {// 创建wsdl的urlURL url = new URL("http://localhost:7001/file/download?wsdl");// 指定命名空间和服务名称QName qName = new QName("http://webservice.example.com", "FileCxfService");Service service = Service.create(url, qName);// 通过getPort方法返回指定接口FileCxfService myServer = service.getPort(FileCxfService.class);// 调用方法返回数据FileDto fileDto = new FileDto();fileDto.setFileId("1");fileDto.setNewFileId("1");fileDto.setBucketName("book");String params = JSONObject.toJSONString(fileDto);Long st = System.currentTimeMillis();String file = myServer.downloadFile(params, "TOKEN:ABC");// 解析文件到本地// 可以解析成字节数组,如果服务端返回的也是字节数组的话byte[] decode= Base64.decode(file);// 也可以将Base64写入到本地文件中ConvertBASE64.decoderBase64File(file, "C:\\Users\\YIQI\\Desktop\\ebook\\demo70.pdf");System.err.println("decode : " + decode.toString());System.err.println("result get file success!");System.err.println("cost time : " + (System.currentTimeMillis() - st) / 1000 + " s.");}}

FileDto

这个类是封装请求参数的实体类,和服务端的FileDto保持一致

package com.example.webclient.pojo;import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;@Data
@AllArgsConstructor
@NoArgsConstructor
@ToString
public class FileDto {private String fileId;private String newFileId;private String bucketName;}

ConvertBASE64

该类是Base64工具类,可以完成Base64字符串和文件的互换

package com.example.webclient.util;import cn.hutool.core.codec.Base64Decoder;
import cn.hutool.core.codec.Base64Encoder;
import cn.hutool.core.io.FileUtil;
import com.alibaba.fastjson2.JSONObject;import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;public class ConvertBASE64 {/*** 将文件转成base64编码字符串** @param path* @return* @throws Exception*/public static String encodeBase64File(String path) throws Exception {File file = new File(path);FileInputStream inputFile = new FileInputStream(file);byte[] buffer = new byte[(int) file.length()];inputFile.read(buffer);inputFile.close();return new Base64Encoder().encode(buffer);}/*** 将base64编码字符串转成文件** @param base64Code* @param targetPath* @throws Exception*/public static void decoderBase64File(String base64Code, String targetPath)throws Exception {byte[] buffer = Base64Decoder.decode(base64Code);FileOutputStream out = new FileOutputStream(targetPath);out.write(buffer);out.close();}/*** 将base64字节装成文件** @param base64Code* @param targetPath* @throws Exception*/public static void toFile(String base64Code, String targetPath)throws Exception {byte[] buffer = base64Code.getBytes();FileOutputStream out = new FileOutputStream(targetPath);out.write(buffer);out.close();}public static String toJson(Object obj) {return JSONObject.toJSONString(obj);}public static Object toObject(String JSONString, Class cls) {return JSONObject.parseObject(JSONString, cls);}public static void writeByteArrayToFile(File desFile, byte[] data)throws IOException {FileUtil.writeBytes(data, desFile);}public static byte[] readFileToByteArray(File srcFile)throws IOException {return FileUtil.readBytes(srcFile);}public static String encode(String string) {return new String(Base64Encoder.encode(string.getBytes()));}public static void main(String[] args) {try {String a = encodeBase64File("C:\\Users\\YIQI\\Desktop\\工作文件\\bg2.jpg");// String base64Code = encodeBase64File("D:/0101-2011-qqqq.tif");System.out.println(a);decoderBase64File(a, "C:\\Users\\YIQI\\Desktop\\工作文件\\bg3.jpg");// toFile(base64Code, "D:\\three.txt");} catch (Exception e) {e.printStackTrace();}}}

测试

先启动服务端,可以看到对外发布的服务

image-20230727190423700

在启动客户端给服务端发送请求的方法,可以看到服务端返回的数据

image-20230727190539581

因为我把从服务端获取的文件写入到了本地,所以可以在文件目录中看到该文件

image-20230727190638111

相关文章:

SpringBoot整合WebService

SpringBoot整合WebService WebService是一个比较旧的远程调用通信框架&#xff0c;现在企业项目中用的比较少&#xff0c;因为它逐步被SpringCloud所取代&#xff0c;它的优势就是能够跨语言平台通信&#xff0c;所以还有点价值&#xff0c;下面来看看如何在SpringBoot项目中使…...

【LangChain】向量存储之FAISS

LangChain学习文档 【LangChain】向量存储(Vector stores)【LangChain】向量存储之FAISS 概要 Facebook AI 相似性搜索&#xff08;Faiss&#xff09;是一个用于高效相似性搜索和密集向量聚类的库。它包含的算法可以搜索任意大小的向量集&#xff0c;甚至可能无法容纳在 RAM 中…...

小研究 - 主动式微服务细粒度弹性缩放算法研究(三)

微服务架构已成为云数据中心的基本服务架构。但目前关于微服务系统弹性缩放的研究大多是基于服务或实例级别的水平缩放&#xff0c;忽略了能够充分利用单台服务器资源的细粒度垂直缩放&#xff0c;从而导致资源浪费。为此&#xff0c;本文设计了主动式微服务细粒度弹性缩放算法…...

驱动开发相关内容复盘

并发与竞争 并发 ​ 多个“用户”同时访问同一个共享资源。 竞争 并发和竞争的处理方法 处理并发和竞争的机制&#xff1a;原子操作、自旋锁、信号量和互斥体。 1、原子操作 ​ 原子操作就是指不能再进一步分割的操作&#xff0c;一般原子操作用于变量或者位操作。 ​ …...

2.2 身份鉴别与访问控制

数据参考&#xff1a;CISP官方 目录 身份鉴别基础基于实体所知的鉴别基于实体所有的鉴别基于实体特征的鉴别访问控制基础访问控制模型 一、身份鉴别基础 1、身份鉴别的概念 标识 实体身份的一种计算机表达每个实体与计算机内部的一个身份表达绑定信息系统在执行操作时&a…...

C++ 注释

程序的注释是解释性语句&#xff0c;您可以在 C 代码中包含注释&#xff0c;这将提高源代码的可读性。所有的编程语言都允许某种形式的注释。 C 支持单行注释和多行注释。注释中的所有字符会被 C 编译器忽略。 C 注释一般有两种&#xff1a; // - 一般用于单行注释。 /* … …...

Spring事务(声明式事务)(Spring的事务,Spring隔离级别,事务传播机制)

目录 一、什么是事务&#xff0c;为什么要用事务 二、Spring声明式事务 &#x1f345; 1、Transactional的使用 &#x1f388; 事务回滚 &#x1f388;注意&#xff1a;异常被捕获&#xff0c;不会发生事务回滚 &#x1f345; 2、Transactional 作⽤范围 &#x1f345; …...

Linux运维面试题(四)之Linux服务管理

Linux运维面试题&#xff08;四&#xff09;之Linux服务管理 4.1 SSHSSH的登录验证方式SSH的登陆端口&#xff08;默认22&#xff09;和监听设置&#xff08;/etc/ssh/sshd_config&#xff09;SSH的登录用户限制(/etc/ssh/sshd_config PermitRootLogin)SSH的登录超时设置(/etc/…...

ChatGPT能否撰写科研论文?

ChatGPT&#xff0c;这款被许多人誉为语言处理领域的“黑马”&#xff0c;究竟能否应用于撰写科研论文&#xff1f;近期&#xff0c;以色列理工学院生物学家兼数据科学家Roy Kishony带领的团队&#xff0c;针对这一问题进行了系列研究&#xff0c;其结果已在《Nature》杂志上发…...

2023 电赛 E 题 K210方案

第一章&#xff1a;K210 介绍 K210芯片是一款基于RISC-V架构的嵌入式人工智能芯片&#xff0c;具备低功耗、高性能的特点。它拥有强大的图像处理和机器学习能力&#xff0c;适用于边缘计算设备和物联网应用。为了方便开发者&#xff0c;K210芯片提供了丰富的外设接口&#xff…...

网络知识介绍

一、TCP 传输控制协议&#xff0c;Transmission Control Protocol。 面向广域网的通信协议&#xff0c;跨域多个网络通信时&#xff0c;为两个通信端点之间提供一条具有如下特点的通信方式&#xff1a; 基于流、面向连接、可靠通信方式、网络状况不佳时尽量降低系统由于重传带…...

MapStruct设置全局的ComponentModel

在mapStruct上边&#xff0c;如果我们要切换成非默认的组件模式&#xff0c;常常要在Mapper注释中添加componentModel "spring"&#xff0c;如果类太多的了的话&#xff0c;非常麻烦&#xff0c;有没有更好的方式呢&#xff0c;有的&#xff0c;可以在pom中添加一个…...

LinearAlgebraMIT_6_ColumnSpaceAndNullSpace

这节课的两个重点是column space列空间和null space零空间。 x.1 pre-multiply/left multiply and post-multiply/right multiply 对于pre-multiply/left multiply左乘和post-multiply/right multiply右乘&#xff0c;如果用英文的pre-和post-是比较容易理解的&#xff0c; A…...

出版物经营许可办理 出版物许可地址变更 出版物零售延期

一、出版物零售单位设立所需材料 1、申请书 2、营业执照 3、租赁合同 4、主要负责人身 份证 5、出版物经营许可申请表 二、办理出版物经营许可证所要符合的条件 1、有确定的企业名称和经营范围; 2、有出版物业务的经营场地; 3、有出版物业务的组织机构和发行人员。 三、…...

【LeetCode每日一题】——807.保持城市天际线

文章目录 一【题目类别】二【题目难度】三【题目编号】四【题目描述】五【题目示例】六【题目提示】七【解题思路】八【时间频度】九【代码实现】十【提交结果】 一【题目类别】 矩阵 二【题目难度】 中等 三【题目编号】 1572.矩阵对角线元素的和 四【题目描述】 给你一…...

JavaScript--Date(日期)对象

介绍和说明 创建一个Date对象并获取当前日期和时间&#xff1a; 使用new Date()语句可以创建一个表示当前日期和时间的Date对象。它将使用客户端设备上的当前日期和时间。例如&#xff1a;const currentDate new Date(); 获取特定日期的年、月、日、小时、分钟、秒&#xff1…...

一文讲清多线程与多线程同步

1 多线程 1.1 线程的概念 十多年前&#xff0c;主流观点主张在可能的情况下优先选择多进程而非多线程&#xff0c;如今&#xff0c;多线程编程已经成为编程领域的事实标准。多线程技术在很大程度上改善了程序的性能和响应能力&#xff0c;使其能够更加高效地利用系统资源&…...

《Java-SE-第二十六章》之线程池

前言 在你立足处深挖下去,就会有泉水涌出!别管蒙昧者们叫嚷:“下边永远是地狱!” 博客主页&#xff1a;KC老衲爱尼姑的博客主页 博主的github&#xff0c;平常所写代码皆在于此 共勉&#xff1a;talk is cheap, show me the code 作者是爪哇岛的新手&#xff0c;水平很有限&…...

【数据库】将excel数据导入mysql数据库

环境&#xff1a;Windows10 mysql8以上 将你要导入的excel表另存为txt格式 打开txt格式文件&#xff0c;删除表头行并另存为并更改编码方式&#xff08;由于与数据库的编码不同&#xff0c;会导致导入报错&#xff09; 通过命令行登录数据库 winr cmd进入 进入装mysql的目录位…...

无涯教程-Lua - repeat...until 语句函数

与 for 和 while 循环(它们在循环顶部测试循环条件)不同&#xff0c;Lua编程中的 repeat ... until 循环语言在循环的底部检查其条件。 repeat ... until 循环与while循环相似&#xff0c;不同之处在于&#xff0c;保证do ... while循环至少执行一次。 repeat...until loop - …...

2025年能源电力系统与流体力学国际会议 (EPSFD 2025)

2025年能源电力系统与流体力学国际会议&#xff08;EPSFD 2025&#xff09;将于本年度在美丽的杭州盛大召开。作为全球能源、电力系统以及流体力学领域的顶级盛会&#xff0c;EPSFD 2025旨在为来自世界各地的科学家、工程师和研究人员提供一个展示最新研究成果、分享实践经验及…...

理解 MCP 工作流:使用 Ollama 和 LangChain 构建本地 MCP 客户端

&#x1f31f; 什么是 MCP&#xff1f; 模型控制协议 (MCP) 是一种创新的协议&#xff0c;旨在无缝连接 AI 模型与应用程序。 MCP 是一个开源协议&#xff0c;它标准化了我们的 LLM 应用程序连接所需工具和数据源并与之协作的方式。 可以把它想象成你的 AI 模型 和想要使用它…...

【网络安全产品大调研系列】2. 体验漏洞扫描

前言 2023 年漏洞扫描服务市场规模预计为 3.06&#xff08;十亿美元&#xff09;。漏洞扫描服务市场行业预计将从 2024 年的 3.48&#xff08;十亿美元&#xff09;增长到 2032 年的 9.54&#xff08;十亿美元&#xff09;。预测期内漏洞扫描服务市场 CAGR&#xff08;增长率&…...

解锁数据库简洁之道:FastAPI与SQLModel实战指南

在构建现代Web应用程序时&#xff0c;与数据库的交互无疑是核心环节。虽然传统的数据库操作方式&#xff08;如直接编写SQL语句与psycopg2交互&#xff09;赋予了我们精细的控制权&#xff0c;但在面对日益复杂的业务逻辑和快速迭代的需求时&#xff0c;这种方式的开发效率和可…...

多模态商品数据接口:融合图像、语音与文字的下一代商品详情体验

一、多模态商品数据接口的技术架构 &#xff08;一&#xff09;多模态数据融合引擎 跨模态语义对齐 通过Transformer架构实现图像、语音、文字的语义关联。例如&#xff0c;当用户上传一张“蓝色连衣裙”的图片时&#xff0c;接口可自动提取图像中的颜色&#xff08;RGB值&…...

BCS 2025|百度副总裁陈洋:智能体在安全领域的应用实践

6月5日&#xff0c;2025全球数字经济大会数字安全主论坛暨北京网络安全大会在国家会议中心隆重开幕。百度副总裁陈洋受邀出席&#xff0c;并作《智能体在安全领域的应用实践》主题演讲&#xff0c;分享了在智能体在安全领域的突破性实践。他指出&#xff0c;百度通过将安全能力…...

多模态大语言模型arxiv论文略读(108)

CROME: Cross-Modal Adapters for Efficient Multimodal LLM ➡️ 论文标题&#xff1a;CROME: Cross-Modal Adapters for Efficient Multimodal LLM ➡️ 论文作者&#xff1a;Sayna Ebrahimi, Sercan O. Arik, Tejas Nama, Tomas Pfister ➡️ 研究机构: Google Cloud AI Re…...

智能分布式爬虫的数据处理流水线优化:基于深度强化学习的数据质量控制

在数字化浪潮席卷全球的今天&#xff0c;数据已成为企业和研究机构的核心资产。智能分布式爬虫作为高效的数据采集工具&#xff0c;在大规模数据获取中发挥着关键作用。然而&#xff0c;传统的数据处理流水线在面对复杂多变的网络环境和海量异构数据时&#xff0c;常出现数据质…...

GruntJS-前端自动化任务运行器从入门到实战

Grunt 完全指南&#xff1a;从入门到实战 一、Grunt 是什么&#xff1f; Grunt是一个基于 Node.js 的前端自动化任务运行器&#xff0c;主要用于自动化执行项目开发中重复性高的任务&#xff0c;例如文件压缩、代码编译、语法检查、单元测试、文件合并等。通过配置简洁的任务…...

如何更改默认 Crontab 编辑器 ?

在 Linux 领域中&#xff0c;crontab 是您可能经常遇到的一个术语。这个实用程序在类 unix 操作系统上可用&#xff0c;用于调度在预定义时间和间隔自动执行的任务。这对管理员和高级用户非常有益&#xff0c;允许他们自动执行各种系统任务。 编辑 Crontab 文件通常使用文本编…...