SeaTunnel扩展Source插件,自定义connector-webservice

news2025/1/10 17:03:22

代码结构

在seatunnel-connectors-v2中新建connector-webservice模块,可以直接赋值connector-http-base模块,webservice和http的方式比较类似,有些类直接复制了http中的代码。

核心类有WebserviceConfig,WebserviceParameter,WebserviceSource,WebserviceSourceReader

配置文件

env {
  # You can set engine configuration here STREAMING BATCH
  execution.parallelism = 1
  job.mode = "BATCH"

  #execution.checkpoint.data-uri = "hdfs://localhost:9000/checkpoint"
}

source {
  # This is a example source plugin **only for test and demonstrate the feature source plugin**
   Webservice {
            url = "http://www.xxx.com.cn/xxx/WeatherWebService.asmx?wsdl"
            method = "getSupportCity"
            namespaceUri = "http://xxx.com.cn/"
            params = {
                "byProvinceName"="xxx"
            }
            result_table_name="table_3"
        }
}
transform {

    Sql {
      source_table_name = "table_3"
      result_table_name = "table_4"
      query = "select content  as fname from table_3"
    }
}
sink {
    Jdbc {
            removeDatabase="true"
            code="target"
            _compsName="sss"
            description=""
            mapType="1"
            source_table_name="table_4"
            writeMode="0"
            type="5"
            database="xxx"
            password="xxx"
            driver="com.mysql.cj.jdbc.Driver"
            url="jdbc:mysql://192.168.xxx:3306/xxx_test"
            pluginName="Jdbc"
            datasource="197"
            emptyType="2"
            user="xxx"
            table="xxx"
        generate_sink_sql="true"
    }
}

代码说明

WebserviceConfig
package org.apache.seatunnel.connectors.seatunnel.webservice.config;

import lombok.Data;
import org.apache.seatunnel.api.configuration.Option;
import org.apache.seatunnel.api.configuration.Options;

import java.io.Serializable;
import java.util.Map;

@Data
public class WebserviceConfig  implements Serializable {

    public static final boolean DEFAULT_ENABLE_MULTI_LINES = false;
    public static final Option<String> FORMAT =
            Options.key("format").stringType()
                    .defaultValue("JSON")
                    .withDescription("Http response format");
    public static final Option<String> URL =
            Options.key("url").stringType().noDefaultValue().withDescription("Webservice request url");
    public static final Option<String> METHOD =
            Options.key("method")
                    .stringType().noDefaultValue().withDescription("Webservice request method");
    public static final Option<String> NAMESPACE_URI =
            Options.key("namespaceUri")
                    .stringType().noDefaultValue().withDescription("Webservice request namespaceUri");
    public static final Option<Map<String, String>> PARAMS =
            Options.key("params").mapType().noDefaultValue().withDescription("Webservice request params");

}

WebserviceParameter

package org.apache.seatunnel.connectors.seatunnel.webservice.config;

import lombok.Data;

import java.io.Serializable;
import java.util.Map;
import java.util.stream.Collectors;

import org.apache.seatunnel.shade.com.typesafe.config.Config;
@Data
public class WebserviceParameter implements Serializable {

    protected String url;
    protected String method;
    protected String namespaceUri;
    protected Map<String, String> params;
    protected String body;

    public void buildWithConfig(Config pluginConfig) {
        this.setUrl(pluginConfig.getString(WebserviceConfig.URL.key()));
        this.setMethod(pluginConfig.getString(WebserviceConfig.METHOD.key()));
        this.setNamespaceUri(pluginConfig.getString(WebserviceConfig.NAMESPACE_URI.key()));
        if (pluginConfig.hasPath(WebserviceConfig.PARAMS.key())) {
            this.setParams(
                    pluginConfig.getConfig(WebserviceConfig.PARAMS.key()).entrySet().stream()
                            .collect(
                                    Collectors.toMap(
                                            Map.Entry::getKey,
                                            entry -> String.valueOf(entry.getValue().unwrapped()),
                                            (v1, v2) -> v2)));
        }
    }

}

DeserializationCollector

/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.apache.seatunnel.connectors.seatunnel.webservice.source;

import lombok.AllArgsConstructor;
import org.apache.seatunnel.api.serialization.DeserializationSchema;
import org.apache.seatunnel.api.source.Collector;
import org.apache.seatunnel.api.table.type.SeaTunnelRow;
import org.apache.seatunnel.format.json.JsonDeserializationSchema;

import java.io.IOException;

@AllArgsConstructor
public class DeserializationCollector {

    private DeserializationSchema<SeaTunnelRow> deserializationSchema;

    public void collect(byte[] message, Collector<SeaTunnelRow> out) throws IOException {
        if (deserializationSchema instanceof JsonDeserializationSchema) {
            ((JsonDeserializationSchema) deserializationSchema).collect(message, out);
        } else {
            SeaTunnelRow deserialize = deserializationSchema.deserialize(message);
            out.collect(deserialize);
        }
    }
}

SimpleTextDeserializationSchema

/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.apache.seatunnel.connectors.seatunnel.webservice.source;

import lombok.AllArgsConstructor;
import org.apache.seatunnel.api.serialization.DeserializationSchema;
import org.apache.seatunnel.api.table.type.SeaTunnelDataType;
import org.apache.seatunnel.api.table.type.SeaTunnelRow;
import org.apache.seatunnel.api.table.type.SeaTunnelRowType;

@AllArgsConstructor
public class SimpleTextDeserializationSchema implements DeserializationSchema<SeaTunnelRow> {

    private SeaTunnelRowType rowType;

    @Override
    public SeaTunnelRow deserialize(byte[] message) {
        return new SeaTunnelRow(new Object[] {new String(message)});
    }

    @Override
    public SeaTunnelDataType<SeaTunnelRow> getProducedType() {
        return rowType;
    }
}

WebserviceSource

package org.apache.seatunnel.connectors.seatunnel.webservice.source;

import com.google.auto.service.AutoService;
import org.apache.seatunnel.api.common.JobContext;
import org.apache.seatunnel.api.common.PrepareFailException;
import org.apache.seatunnel.api.serialization.DeserializationSchema;
import org.apache.seatunnel.api.source.Boundedness;
import org.apache.seatunnel.api.source.SeaTunnelSource;
import org.apache.seatunnel.api.table.catalog.CatalogTableUtil;
import org.apache.seatunnel.api.table.type.SeaTunnelDataType;
import org.apache.seatunnel.api.table.type.SeaTunnelRow;
import org.apache.seatunnel.api.table.type.SeaTunnelRowType;
import org.apache.seatunnel.common.config.CheckConfigUtil;
import org.apache.seatunnel.common.config.CheckResult;
import org.apache.seatunnel.common.constants.PluginType;
import org.apache.seatunnel.connectors.seatunnel.common.source.AbstractSingleSplitReader;
import org.apache.seatunnel.connectors.seatunnel.common.source.AbstractSingleSplitSource;
import org.apache.seatunnel.connectors.seatunnel.common.source.SingleSplitReaderContext;
import org.apache.seatunnel.connectors.seatunnel.webservice.config.WebserviceConfig;
import org.apache.seatunnel.connectors.seatunnel.webservice.config.WebserviceParameter;
import org.apache.seatunnel.format.json.JsonDeserializationSchema;
import org.apache.seatunnel.shade.com.typesafe.config.Config;


@AutoService(SeaTunnelSource.class)
public class WebserviceSource extends AbstractSingleSplitSource<SeaTunnelRow> {
    protected final WebserviceParameter webserviceParameter = new WebserviceParameter();
    protected SeaTunnelRowType rowType;
    protected JobContext jobContext;
    protected String contentField;

    protected DeserializationSchema<SeaTunnelRow> deserializationSchema;
    @Override
    public String getPluginName() {
        return "Webservice";
    }

    @Override
    public void prepare(Config pluginConfig) throws PrepareFailException {
        CheckResult result = CheckConfigUtil.checkAllExists(pluginConfig, WebserviceConfig.URL.key());
        if (!result.isSuccess()) {
            throw new RuntimeException(
                    String.format(
                            "PluginName: %s, PluginType: %s, Message: %s",
                            getPluginName(), PluginType.SOURCE, result.getMsg()));
        }
        this.webserviceParameter.buildWithConfig(pluginConfig);
        buildSchemaWithConfig(pluginConfig);
    }

    protected void buildSchemaWithConfig(Config pluginConfig) {
        if (pluginConfig.hasPath(CatalogTableUtil.SCHEMA.key())) {
            this.rowType = CatalogTableUtil.buildWithConfig(pluginConfig).getSeaTunnelRowType();
            // default use json format
            String format = WebserviceConfig.FORMAT.defaultValue();
            if (pluginConfig.hasPath(WebserviceConfig.FORMAT.key())) {
                format = pluginConfig
                        .getString(WebserviceConfig.FORMAT.key());
            }
            switch (format.toLowerCase()) {
                case "json":
                    this.deserializationSchema =
                            new JsonDeserializationSchema(false, false, rowType);
                    break;
                default:
                    // TODO: use format SPI
                    throw new RuntimeException(
                            String.format(
                                    "Unsupported data format [%s], http connector only support json format now",
                                    format));
            }
        } else {
            this.rowType = CatalogTableUtil.buildSimpleTextSchema();
            this.deserializationSchema = new SimpleTextDeserializationSchema(this.rowType);
        }
    }

    @Override
    public void setJobContext(JobContext jobContext) {
        this.jobContext = jobContext;
    }

    @Override
    public Boundedness getBoundedness() {
        return Boundedness.BOUNDED;
    }

    @Override
    public SeaTunnelDataType<SeaTunnelRow> getProducedType() {
        return this.rowType;
    }

    @Override
    public AbstractSingleSplitReader<SeaTunnelRow> createReader(SingleSplitReaderContext readerContext) throws Exception {
        return new WebserviceSourceReader(webserviceParameter, readerContext,
                deserializationSchema,
                contentField);
    }
}

WebserviceSourceReader

package org.apache.seatunnel.connectors.seatunnel.webservice.source;


import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.template.Template;
import cn.hutool.http.webservice.SoapClient;
import cn.hutool.http.webservice.SoapProtocol;
import lombok.extern.slf4j.Slf4j;
import org.apache.seatunnel.api.serialization.DeserializationSchema;
import org.apache.seatunnel.api.source.Collector;
import org.apache.seatunnel.api.table.type.SeaTunnelRow;
import org.apache.seatunnel.connectors.seatunnel.common.source.AbstractSingleSplitReader;
import org.apache.seatunnel.connectors.seatunnel.common.source.SingleSplitReaderContext;
import org.apache.seatunnel.api.serialization.DeserializationSchema;
import org.apache.seatunnel.api.source.Boundedness;
import org.apache.seatunnel.api.source.Collector;
import org.apache.seatunnel.api.table.type.SeaTunnelRow;
import org.apache.seatunnel.common.utils.JsonUtils;
import org.apache.seatunnel.connectors.seatunnel.common.source.AbstractSingleSplitReader;
import org.apache.seatunnel.connectors.seatunnel.common.source.SingleSplitReaderContext;
import com.jayway.jsonpath.Configuration;
import com.jayway.jsonpath.JsonPath;
import com.jayway.jsonpath.Option;
import com.jayway.jsonpath.ReadContext;
import org.apache.seatunnel.connectors.seatunnel.webservice.config.WebserviceParameter;

import java.io.IOException;
import java.util.HashMap;

@Slf4j
public class WebserviceSourceReader extends AbstractSingleSplitReader<SeaTunnelRow> {

    protected final SingleSplitReaderContext context;
    private static final Option[] DEFAULT_OPTIONS = {
            Option.SUPPRESS_EXCEPTIONS, Option.ALWAYS_RETURN_LIST, Option.DEFAULT_PATH_LEAF_TO_NULL
    };
    private final String contentJson;
    private final Configuration jsonConfiguration =
            Configuration.defaultConfiguration().addOptions(DEFAULT_OPTIONS);

    protected final WebserviceParameter webserviceParameter;

    private final DeserializationCollector deserializationCollector;

    public WebserviceSourceReader(
            WebserviceParameter webserviceParameter,
            SingleSplitReaderContext context,
            DeserializationSchema<SeaTunnelRow> deserializationSchema,
            String contentJson) {
        this.webserviceParameter = webserviceParameter;
        this.context = context;
        this.contentJson = contentJson;
        this.deserializationCollector = new DeserializationCollector(deserializationSchema);
    }
    @Override
    public void open() throws Exception {
        log.info("WebserviceSourceReader open");
    }

    @Override
    public void close() throws IOException {
        log.info("WebserviceSourceReader close");
    }

    @Override
    public void pollNext(Collector<SeaTunnelRow> output) throws Exception {
        try {
            SoapClient client = SoapClient.create(webserviceParameter.getUrl())
                    .setMethod(webserviceParameter.getMethod(), webserviceParameter.getNamespaceUri());
            for (String key : webserviceParameter.getParams().keySet()) {
                String param = webserviceParameter.getParams().get(key);
                client = client.setParam(key, param);
            }
            String result = client.send(false);
//        deserializationCollector.collect(result.getBytes(), output);
            SeaTunnelRow seaTunnelRow = new SeaTunnelRow(new Object[]{getSoapBody(result)});
            output.collect(seaTunnelRow);
            log.info("WebserviceSourceReader pollNext");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (Boundedness.BOUNDED.equals(context.getBoundedness())) {
                // signal to the source that we have reached the end of the data.
                log.info("Closed the bounded http source");
                context.signalNoMoreElement();
            }
        }
    }

    public String getSoapBody(String xml) {
        if (xml.indexOf("<soap:Body>") != -1) {
            return StrUtil.subBetween(xml, "<soap:Body>", "</soap:Body>");
        } else {
            return StrUtil.subBetween(xml, "<soap12:Body>", "</soap12:Body>");
        }
    }
}

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<!--

    Licensed to the Apache Software Foundation (ASF) under one or more
    contributor license agreements.  See the NOTICE file distributed with
    this work for additional information regarding copyright ownership.
    The ASF licenses this file to You under the Apache License, Version 2.0
    (the "License"); you may not use this file except in compliance with
    the License.  You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing, software
    distributed under the License is distributed on an "AS IS" BASIS,
    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    See the License for the specific language governing permissions and
    limitations under the License.

-->
<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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.apache.seatunnel</groupId>
        <artifactId>seatunnel-connectors-v2</artifactId>
        <version>2.3.3-SNAPSHOT</version>
    </parent>

    <artifactId>connector-webservice</artifactId>
    <name>SeaTunnel : Connectors V2 : Webservice</name>

    <properties>
        <rabbitmq.version>5.9.0</rabbitmq.version>
        <json-path.version>2.7.0</json-path.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.apache.seatunnel</groupId>
            <artifactId>connector-common</artifactId>
            <version>${project.version}</version>
        </dependency>

        <dependency>
            <groupId>org.apache.seatunnel</groupId>
            <artifactId>seatunnel-format-json</artifactId>
            <version>${project.version}</version>
        </dependency>
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>5.8.22</version>
        </dependency>

        <dependency>
            <groupId>com.jayway.jsonpath</groupId>
            <artifactId>json-path</artifactId>
            <version>${json-path.version}</version>
        </dependency>
    </dependencies>

  <scm>
    <tag>2.3.2</tag>
  </scm>
</project>

执行结果

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

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

相关文章

Maven的配置亲测有效

文章目录 前言一、maven网址二、操作步骤三.配置环境变量四.配置本地仓库五.找到mirror 和配置JDK六.胜利七.提醒⏰;总结 前言 &#xff08;我讲一下什么是maven&#xff0c;不想看跳到下一步就行了&#xff0c;也没必要看&#xff09; Maven&#xff08;Apache Maven&#x…

2023认证杯小美赛数学建模国际赛ABCD题思路及python代码分享

大家好呀&#xff0c;认证杯小美赛数学建模开始了&#xff0c;来说一下初步的选题建议吧&#xff1a; 首先定下主基调&#xff0c; 本次小美赛难度&#xff1a;D&#xff1c;A≈C&#xff1c;B。推荐选择D题。预计12.2中午更新D完整论文。预定论文请往后滑看完本文档链接。 A…

Python+Requests模拟发送GET请求

模拟发送GET请求 前置条件&#xff1a;导入requests库 一、发送不带参数的get请求 代码如下&#xff1a; 以百度首页为例 import requests# 发送get请求 response requests.get(url"http://www.baidu.com") print(response.content.decode("utf-8"))…

geoserver 发布图层(tif、shp等)

我们用得最多的是这个板块的内容 下面我们来尝试发布地图。点击【数据】——【工作区】——【添加新的工作区】&#xff0c;工作区可以理解为是用来存放发布地图的一个集合。 在【新建工作区】中输入名称&#xff0c;还有一个命名空间URI&#xff0c;这个只要保持和之前的工作区…

大气多功能工作室个人引导页源码

源码简介 大气多功能工作室个人引导页源码&#xff0c;支持三端自适应&#xff0c;带赞助功能&#xff0c;采用设计配色网站点赞量最高的一个配色方案&#xff0c;一个二次元风格的引导页就此诞生&#xff0c;经过长传美国服务器测试&#xff0c;结果也是很理想&#xff0c;测速…

AI时代架构师之路:技术、洞察和创新的完美融合

随着人工智能技术的飞速发展&#xff0c;我们正置身于一个由数据驱动的时代。在这个充满无限可能性的AI时代&#xff0c;架构师成为设计和构建先进系统的关键角色。然而&#xff0c;在追逐技术的同时&#xff0c;架构师需要修炼一系列综合素养&#xff0c;使其在技术、业务和伦…

OSI七层模型与TCP/IP四层模型的区别(计算机网络)

一、OSI七层网络模型 OSI 网络模型共有 7 层&#xff0c;分别是应用层、表示层、会话层、传输层、网络层、数据链路层和物理层。 应用层&#xff0c;负责给应用程序提供统一的接口&#xff1b;表示层&#xff0c;负责把数据转换成兼容另一个系统能识别的格式&#xff1b;会话…

java数据结构(哈希表—HashMap)含LeetCode例题讲解

目录 1、HashMap的基本方法 1.1、基础方法&#xff08;增删改查&#xff09; 1.2、其他方法 2、HashMap的相关例题 2.1、题目介绍 2.2、解题 2.2.1、解题思路 2.2.2、解题图解 2.3、解题代码 1、HashMap的基本方法 HashMap 是一个散列表&#xff0c;它存储的内容是键…

全志XR806基于FreeRTOS下部署竞技机器人先进模糊控制器

前言 很荣幸参与到由“极术社区和全志在线联合组织”举办的XR806开发板试用活动。本人热衷于各种的开发板的开发&#xff0c;同时更愿意将其实现到具体项目中。秉承以上原则&#xff0c;发现大家的重心都放在开发中的环境构建过程&#xff0c;缺少了不少实际应用场景的运用&am…

postman参数为D:\\audio\\test.mp3请求报错

报错信息 报错 java.lang.IllegalArgumentException: Invalid character found in the request target [/v1/audio/transcriptions?audioPathD:\\audio\\test.mp3 ]. The valid characters are defined in RFC 7230 and RFC 3986 解决方式 yml文件上放行指定字符 relaxed-pa…

外包搞了6年,技术退步明显......

先说情况&#xff0c;大专毕业&#xff0c;18年通过校招进入湖南某软件公司&#xff0c;干了接近6年的功能测试&#xff0c;今年年初&#xff0c;感觉自己不能够在这样下去了&#xff0c;长时间呆在一个舒适的环境会让一个人堕落!而我已经在一个企业干了四年的功能测试&#xf…

Python+Requests模块session处理和SSL证书处理关闭警告

session处理 部分接口需要先登录网址&#xff0c;才能有权限进行调用&#xff0c;这时可以使用到session&#xff0c;具体操作是&#xff1a;先使用网站 的登录api进行登录&#xff0c;得到session后&#xff0c;然后用该session来请求其它的接口。 示例代码&#xff1a; se…

[1] AR Tag 在ros中的使用

1.定义 AR Tag 是一种用于增强现实&#xff08;AR&#xff09;应用中的视觉标记&#xff0c;用于跟踪和定位虚拟物体在现实世界中的位置。 AR Tag由黑白正方形图像表示&#xff0c;图像内部有黑色边框中的某些图案。它与我们经常用到的二维码长得类似&#xff0c;原理其实也一…

百元挂耳式蓝牙耳机推荐,几款性价比高的开放式蓝牙耳机

在百元价位段&#xff0c;挂耳式蓝牙耳机是备受消费者追捧&#xff0c;提供了出色的音质、便携性和无拘束的使用体验&#xff0c;无论您是追求音乐品质&#xff0c;还是需要在办公或运动中保持通讯畅通&#xff0c;基本上都是离不开耳机的身影&#xff0c;今天小编为大家推荐几…

Leetcode-二叉树oj题

1.二叉树的前序遍历 144. 二叉树的前序遍历https://leetcode.cn/problems/binary-tree-preorder-traversal/这个题目在遍历的基础上还要求返回数组&#xff0c;数组里面按前序存放二叉树节点的值。 既然要返回数组&#xff0c;就必然要malloc一块空间&#xff0c;那么我们需…

temu货不对板哪里修改图片

在Temu这个跨境电商平台上&#xff0c;如果您需要修改商品图片&#xff0c;通常需要在卖家中心进行操作。下面是一般的步骤&#xff0c;但请注意&#xff0c;不同平台的操作可能略有不同&#xff0c;具体请参考Temu官方的帮助文档或联系客服。 先给大家推荐一款拼多多/temu运营…

数据结构 / 队列 / 循环队列

1. 定义 为充分利用向量空间&#xff0c;克服假溢出现象的方法是&#xff1a;将向量空间想象为一个首尾相接的圆环&#xff0c;并称这种向量为循环向量。存储在其中的队列称为循环队列&#xff08;Circular Queue&#xff09;。循环队列是把顺序队列首尾相连&#xff0c;把存储…

【Java8系列07】Java8日期处理

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

【电路笔记】-并联电阻

并联电阻 文章目录 并联电阻1、概述2、并联电阻示例13、并联电阻示例24、并联电阻电路中的电流5、并联电阻器示例36、总结 当电阻器的两个端子分别连接到另一个或多个电阻器的每个端子时&#xff0c;电阻器被称为并联连接在一起。 1、概述 与之前的串联电阻电路不同&#xff0…

「Qt Widget中文示例指南」如何创建一个计算器?(二)

Qt 是目前最先进、最完整的跨平台C开发工具。它不仅完全实现了一次编写&#xff0c;所有平台无差别运行&#xff0c;更提供了几乎所有开发过程中需要用到的工具。如今&#xff0c;Qt已被运用于超过70个行业、数千家企业&#xff0c;支持数百万设备及应用。 本文将展示如何使用…