Java客户端调用SOAP方式的WebService服务实现方式分析

简介

在多系统交互中,有时候需要以Java作为客户端来调用SOAP方式的WebService服务,本文通过分析不同的调用方式,以Demo的形式,帮助读者在生产实践中选择合适的调用方式。

本文JDK环境为JDK17。

结论

推荐使用Axis2或者Jaxws,以无客户端的形式来调用WebService。

有客户端,推荐Maven插件。

有客户端调用

主要时利用wsdl文档,自动生成对应的Java代码来实现

建议在pom文件中,配置对应的Maven插件来实现WebService客户端代码的自动生成。

JDK wsimport命令生成(不推荐)

简介

主要是利用jdk的自带工具wsimport工具实现,执行命令如下:

wsimport -s C:\tmp\com -p com.example.demo5.wsdl -encoding utf-8 http://www.webxml.com.cn/WebServices/IpAddressSearchWebService.asmx?wsdl

优点

通常装有JDK的电脑或者服务器都可以直接运行,方便生成。

缺点

在实际的运用中wsimport命令会有很多问题,首先只有JDK1.8才支持这个命令,即使能使用,仍然存在一些问题。其次,在JDK17以上没有自带这个工具,可能要安装插件才能使用,但是笔者安装了一些插件仍然无法使用。

ApacheCXF自动生成(不推荐)

简介

ApacheCXF通过安装也可以自动生成对应的WebService客户端代码。具体操作可见链接。

缺点

需要额外安装ApacheCXF插件。

Maven插件自动生成(推荐)

简介

通过spring.io网址的Demo示例,可以配置pom的maven插件,自动生成代码。

demo获取链接如下:

Getting Started | Consuming a SOAP web service (spring.io)

pom配置示例如下:

<build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin><!-- tag::wsdl[] --><plugin><groupId>com.sun.xml.ws</groupId><artifactId>jaxws-maven-plugin</artifactId><version>3.0.0</version><executions><execution><goals><goal>wsimport</goal></goals></execution></executions><configuration><packageName>com.example.consumingwebservice.wsdl</packageName><wsdlUrls>
<!--						<wsdlUrl>http://localhost:8080/ws/countries.wsdl</wsdlUrl>--><wsdlUrl>http://www.webxml.com.cn/WebServices/IpAddressSearchWebService.asmx?wsdl</wsdlUrl></wsdlUrls><sourceDestDir>${sourcesDir}</sourceDestDir><destDir>${classesDir}</destDir><extension>true</extension></configuration></plugin><!-- end::wsdl[] --></plugins></build>

生成代码如下:

调用方式:

@RequestMapping(value = "/{ip}", method = RequestMethod.GET)public ArrayOfString searchIp(@PathVariable("ip") String ip) {IpAddressSearchWebServiceSoap ipAddressSearchWebServiceSoap = new IpAddressSearchWebService().getIpAddressSearchWebServiceSoap();ArrayOfString response = ipAddressSearchWebServiceSoap.getCountryCityByIp(ip);return response;}

优点

操作简单,改动小。

缺点

唯一的缺点,也是有客户端调用普遍存在的,自动生成代码后,需要重新部署一次。

Springboot集成Git插件实现

通过Springboot集成git插件,可以通过接口的形式来修改maven的wsdlUrls配置,然后推送到git服务,最后触发Jenkins自动部署。

以Git推送代码的形式来实现代码的自动生成,其缺点是,每次根据一份wsdl文件生成完代码,需要重启一次服务,但是笔者通过自动配置的形式可以做到一键部署。

其中触发Jenkins自动部署,可以通过git的配置实现,通过访问特定的url实现。配置好的git部署链接如下:

http://192.168.22.22:8080/job/demo_test/build?token=1987654567890hjkoijghfvgjjnmkjkmk

其中token的值可以自动定义,这样在借助代码的形式就可以做到一键部署。

其实现代码如下:

package com.example.consumingwebservice;import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.util.Date;import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.transport.CredentialsProvider;
import org.eclipse.jgit.transport.HttpConfig;
import org.eclipse.jgit.transport.UsernamePasswordCredentialsProvider;public class GitUtil {//private static Log log = LogFactory.getLog(GitUtil.class);private GitUtil() {}public static Git getGit(String uri, CredentialsProvider credentialsProvider, String localDir) throws Exception {Git git = null;if (new File(localDir).exists() ) {git = Git.open(new File(localDir));} else {git = Git.cloneRepository().setCredentialsProvider(credentialsProvider).setURI(uri).setDirectory(new File(localDir)).call();}//设置一下post内存,否则可能会报错Error writing request body to servergit.getRepository().getConfig().setInt(HttpConfig.HTTP, null, HttpConfig.POST_BUFFER_KEY, 512*1024*1024);return git;}public static CredentialsProvider getCredentialsProvider(String username, String password) {return new UsernamePasswordCredentialsProvider(username, password);}public static Repository getRepository(Git git) {return git.getRepository();}public static void pull(Git git, CredentialsProvider credentialsProvider) throws Exception {git.pull().setRemote("origin").setCredentialsProvider(credentialsProvider).call();}public static void push(Git git, CredentialsProvider credentialsProvider, String filepattern, String message)throws Exception {git.add().addFilepattern(filepattern).call();git.add().setUpdate(true);git.commit().setMessage(message).call();git.push().setCredentialsProvider(credentialsProvider).call();}public static void main(String[] args) throws Exception {String uri = "http://192.168.9.11/test/webservice.git";String username = "343535@qq.com";String password = "xdfetrfrr";CredentialsProvider credentialsProvider = getCredentialsProvider(username, password);String localDir = "C:/tmp/git_test";Git git = getGit(uri, credentialsProvider, localDir);pull(git, credentialsProvider);changeFile(localDir + "/pom.xml");//        push(git, credentialsProvider, ".", "提交文件");push(git, credentialsProvider, "pom.xml", "修改pom文件" + new Date());}private static final String newText = "    <wsdlUrl>http://www.webxml.com.cn/WebServices/IpAddressSearchWebService.asmx?wsdl</wsdlUrl>\r\n                    </wsdlUrls>";protected static void changeFile(String filePath) {try {// 读取文本文件的内容Path path = Paths.get(filePath);String content = Files.readString(path);System.out.println(content);// 替换内容String modifiedContent = content.replace("</wsdlUrls>", newText);// 将修改后的内容写回文本文件Files.write(path, modifiedContent.getBytes(), StandardOpenOption.WRITE);System.out.println("文本文件内容已成功修改!");} catch (IOException e) {System.out.println("修改文本文件内容时出现错误:" + e.getMessage());}}}

 如要实现流程图的规划,可以后台通过http的get请求上文的git部署链接,实现接口的自动部署。

无客户端调用

也就是不需要按wsdl的格式来生成对应的Java代码,原理时通过构建xml的形式来访问WebService。

这里推荐使用Axis2或者Jaxws的方式来调用,二者各有优劣。

Axis调用(不推荐)

简介

通过pom引入axis依赖,实现无客户端访问,所需依赖如下:

<dependency>
<groupId>axis</groupId>
<artifactId>axis</artifactId>
<version>1.4</version>
</dependency>

代码实现如下:

public static void main(String[] args){try {String nameSpac = "http://WebXml.com.cn/";URL url = new URL("http://ws.webxml.com.cn/WebServices/MobileCodeWS.asmx?wsdl");QName sname = new QName(nameSpac, "MobileCodeWS");QName pname = new QName(nameSpac, "MobileCodeWSSoap");Service service = new Service( url, sname);Call call = (Call)service.createCall(pname);call.setSOAPActionURI(nameSpac + "getMobileCodeInfo");call.setOperationName(new QName(nameSpac, "getMobileCodeInfo")); // 需要请求的方法call.addParameter(new QName(nameSpac, "mobileCode"), XMLType.XSD_STRING, ParameterMode.IN);  // 入参call.addParameter(new QName(nameSpac, "userID"), XMLType.XSD_STRING, ParameterMode.IN);  // 入参
//            call.addParameter("param3", XMLType.SOAP_STRING, ParameterMode.IN);  // 入参String param1 = "15932582632";  // 参数String param2 = null;  // 参数call.setReturnClass(String.class);  // 设置返回值call.setUseSOAPAction(true);Object invoke = call.invoke(new Object[]{param1, param2});// 调用获取返回值
//            Object invoke =  call.invoke(new Object[]{});// 调用获取返回值System.out.println(invoke);}catch (Exception e){e.printStackTrace();}}

优点

较少的代码量,依赖需要少,实现简单

缺点

通过笔者的实验,发现Axis的调用并不稳定,对于不同的接口,有的接口无参数调用可以调通,有参数调用会报错,有的接口有参数调用可以调通(如例),无参数调用会报错。

实际上,这个依赖在2006年便没有维护了,它的功能转移到了Axis2。

Axis2调用(推荐)

简介

通过pom引入axis2依赖,实现无客户端访问,所需依赖如下:

<dependency>
<groupId>org.apache.axis2</groupId>
<artifactId>axis2-jaxws</artifactId>
<version>1.7.0</version>
</dependency><dependency>
<groupId>org.apache.axis2</groupId>
<artifactId>axis2-adb-codegen</artifactId>
<version>1.7.0</version>
</dependency><dependency>
<groupId>org.apache.axis2</groupId>
<artifactId>axis2-transport-local</artifactId>
<version>1.7.0</version>
</dependency><dependency>
<groupId>org.apache.axiom</groupId>
<artifactId>com.springsource.org.apache.axiom</artifactId>
<version>1.2.5</version>
</dependency>

代码实现如下:

import org.apache.axiom.om.OMAbstractFactory;
import org.apache.axiom.om.OMElement;
import org.apache.axiom.om.OMFactory;
import org.apache.axiom.om.OMNamespace;
import org.apache.axis2.AxisFault;
import org.apache.axis2.addressing.EndpointReference;
import org.apache.axis2.client.Options;
import org.apache.axis2.client.ServiceClient;
import org.apache.axis2.transport.http.impl.httpclient3.HttpTransportPropertiesImpl;/**** @ClassName: MobileClientDoc* @Description: TODO* 方法二: 应用document方式调用 用ducument方式应用现对繁琐而灵活。现在用的比较多。因为真正摆脱了我们不想要的耦合* 即使用org.apache.axis2.client.ServiceClient类进行远程调用web服务,不生成客户端** @date 2017年11月9日 下午1:27:17**/
public class SoapAxis2Client {private static String requestName = "getCountryCityByIp";public static void ipWS() {try {ServiceClient serviceClient = new ServiceClient();//创建服务地址WebService的URL,注意不是WSDL的URLString url = "http://www.webxml.com.cn/WebServices/IpAddressSearchWebService.asmx";EndpointReference targetEPR = new EndpointReference(url);Options options = serviceClient.getOptions();options.setTo(targetEPR);//确定调用方法(wsdl 命名空间地址 (wsdl文档中的targetNamespace) 和 方法名称 的组合)options.setAction("http://WebXml.com.cn/" + requestName);//设置密码HttpTransportPropertiesImpl.Authenticator auth = new HttpTransportPropertiesImpl.Authenticator();
//            auth.setUsername(username);  //服务器访问用户名
//            auth.setPassword(password); //服务器访问密码
//            options.setProperty(HTTPConstants.AUTHENTICATE, auth);OMFactory fac = OMAbstractFactory.getOMFactory();/** 指定命名空间,参数:* uri--即为wsdl文档的targetNamespace,命名空间* perfix--可不填*/OMNamespace omNs = fac.createOMNamespace("http://WebXml.com.cn/", "");// 指定方法OMElement method = fac.createOMElement(requestName, omNs);// 指定方法的参数OMElement theIpAddress = fac.createOMElement("theIpAddress", omNs);theIpAddress.setText("111.249.198.56");
//            OMElement userID = fac.createOMElement("userID", omNs);
//            userID.setText("");method.addChild(theIpAddress);
//            method.addChild(userID);method.build();//远程调用web服务OMElement result = serviceClient.sendReceive(method);//值得注意的是,返回结果就是一段由OMElement对象封装的xml字符串。String xml = result.cloneOMElement().toString();System.out.println(xml);} catch (AxisFault axisFault) {axisFault.printStackTrace();}}public static void main(String[] args) throws AxisFault {ipWS();}}

优点

代码量较少,通过配置xml节点实现系统调用,可以设置灵活的调用方式。经过实验,对各种WebService接口的有参无参调用,都能取得正确的返回结果。

测试结果如下:

<getCountryCityByIpResponse xmlns="http://WebXml.com.cn/"><getCountryCityByIpResult><string>111.249.198.56</string><string>台湾省  </string></getCountryCityByIpResult></getCountryCityByIpResponse>

缺点

所需的pom配置文件较多,且引用不正确较难排查问题,且各个pom之间的版本冲突也需要解决。

Jaxws调用(推荐)

简介

引入对于的pom配置文件

<dependency><groupId>org.apache.axis2</groupId><artifactId>axis2-jaxws</artifactId><version>1.7.0</version>
</dependency>

这里提前说下,下面代码大部分来自于csdn作者——LengYouNuan的文章,但是实在找不到对于作者了,提前声明。

还有它的原始代码并不能正常运行,会有服务器未能识别 HTTP 头 SOAPAction 的值的报错,笔者通过实验和研究,添加了如下配置,才能正常运行:

//这句话很重要,否则报错服务器未能识别 HTTP 头 SOAPAction 的值
dispatch.getRequestContext().put(SOAPACTION_URI_PROPERTY, nameSpace + elementName);
dispatch.getRequestContext().put(SOAPACTION_USE_PROPERTY, true);

由于使用的JDK17,对应的配置和以前不一样了:

public interface BindingProvider {String USERNAME_PROPERTY = "jakarta.xml.ws.security.auth.username";String PASSWORD_PROPERTY = "jakarta.xml.ws.security.auth.password";String ENDPOINT_ADDRESS_PROPERTY = "jakarta.xml.ws.service.endpoint.address";String SESSION_MAINTAIN_PROPERTY = "jakarta.xml.ws.session.maintain";String SOAPACTION_USE_PROPERTY = "jakarta.xml.ws.soap.http.soapaction.use";String SOAPACTION_URI_PROPERTY = "jakarta.xml.ws.soap.http.soapaction.uri";
......

应该主要是javax和jakarta的区别。

完整可运行代码如下:

package com.example.consumingwebservice;import com.sun.xml.ws.client.BindingProviderProperties;
import com.sun.xml.ws.developer.JAXWSProperties;
import jakarta.xml.soap.*;
import jakarta.xml.ws.Dispatch;
import jakarta.xml.ws.Service;
import org.w3c.dom.Document;import javax.xml.namespace.QName;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;import static jakarta.xml.ws.BindingProvider.SOAPACTION_URI_PROPERTY;
import static jakarta.xml.ws.BindingProvider.SOAPACTION_USE_PROPERTY;/*** soap方式调用webservice方式客户端** @author LengYouNuan* @create 2021-05-31 下午2:35*/
public class SoapJaxwsClient {String nameSpace = ""; //wsdl的命名空间String wsdlUrl = ""; //wsdl文档地址String serviceName = ""; //服务的名字String portName = "";String responseName = ""; //@WebResult:注解上的name值String elementName = ""; //默认是要访问的方法名 如果@WebMethod属性name有值 则是该值,实际还是以wsdl文档为主int timeout = 20000;/*** @param nameSpace* @param wsdlUrl* @param serviceName* @param portName* @param element* @param responseName*/public SoapJaxwsClient(String nameSpace, String wsdlUrl,String serviceName, String portName, String element,String responseName) {this.nameSpace = nameSpace;this.wsdlUrl = wsdlUrl;this.serviceName = serviceName;this.portName = portName;this.elementName = element;this.responseName = responseName;}/*** @param nameSpace* @param wsdlUrl* @param serviceName* @param portName* @param element* @param responseName* @param timeOut      毫秒*/public SoapJaxwsClient(String nameSpace, String wsdlUrl,String serviceName, String portName, String element,String responseName, int timeOut) {this.nameSpace = nameSpace;this.wsdlUrl = wsdlUrl;this.serviceName = serviceName;this.portName = portName;this.elementName = element;this.responseName = responseName;this.timeout = timeOut;}public String sendMessage(HashMap<String, String> inMsg) throws Exception {// 创建URL对象URL url = null;try {url = new URL(wsdlUrl);} catch (Exception e) {e.printStackTrace();return "创建URL对象异常";}// 创建服务(Service)QName sname = new QName(nameSpace, serviceName);Service service = Service.create(url, sname);// 创建Dispatch对象Dispatch<SOAPMessage> dispatch = null;try {dispatch = service.createDispatch(new QName(nameSpace, portName), SOAPMessage.class, Service.Mode.MESSAGE);} catch (Exception e) {e.printStackTrace();return "创建Dispatch对象异常";}// 创建SOAPMessagetry {//这句话很重要,否则报错服务器未能识别 HTTP 头 SOAPAction 的值dispatch.getRequestContext().put(SOAPACTION_URI_PROPERTY, nameSpace + elementName);dispatch.getRequestContext().put(SOAPACTION_USE_PROPERTY, true);SOAPMessage msg = MessageFactory.newInstance(SOAPConstants.SOAP_1_1_PROTOCOL).createMessage();msg.setProperty(SOAPMessage.CHARACTER_SET_ENCODING, "UTF-8");SOAPEnvelope envelope = msg.getSOAPPart().getEnvelope();// 创建SOAPHeader(不是必需)// SOAPHeader header = envelope.getHeader();// if (header == null)// header = envelope.addHeader();// QName hname = new QName(nameSpace, "username", "nn");// header.addHeaderElement(hname).setValue("huoyangege");// 创建SOAPBodySOAPBody body = envelope.getBody();QName ename = new QName(nameSpace, elementName, "");SOAPBodyElement ele = body.addBodyElement(ename);// 增加Body元素和值for (Map.Entry<String, String> entry : inMsg.entrySet()) {ele.addChildElement(new QName(nameSpace, entry.getKey())).setValue(entry.getValue());}// 超时设置dispatch.getRequestContext().put(BindingProviderProperties.CONNECT_TIMEOUT, timeout);dispatch.getRequestContext().put(JAXWSProperties.REQUEST_TIMEOUT, timeout);// 通过Dispatch传递消息,会返回响应消息SOAPMessage response = dispatch.invoke(msg);// 响应消息处理,将响应的消息转换为doc对象Document doc = response.getSOAPPart().getEnvelope().getBody().extractContentAsDocument();String ret = doc.getElementsByTagName(responseName).item(0).getTextContent();return ret;} catch (Exception e) {e.printStackTrace();throw e;}}public static void main(String[] args) throws Exception {
//        SoapClient soapClient=new SoapClient("http://spring.io/guides/gs-producing-web-service","http://localhost:8080/ws/countries.wsdl",
//                "CountriesPortService","CountriesPortSoap11","getCountry",
//                "getCountryResponse",
//                2000);SoapJaxwsClient soapClient = new SoapJaxwsClient("http://WebXml.com.cn/", "http://ws.webxml.com.cn/WebServices/MobileCodeWS.asmx?wsdl","MobileCodeWS", "MobileCodeWSSoap", "getDatabaseInfo","getDatabaseInfoResponse",2000);
//        SoapClient soapClient=new SoapClient("http://WebXml.com.cn/","http://www.webxml.com.cn/WebServices/IpAddressSearchWebService.wsdl",
//                "IpAddressSearchWebService","IpAddressSearchWebServiceSoap","getCountryCityByIp",
//                "getCountryCityByIpResult",
//                2000);//封装请求参数HashMap<String, String> msg = new HashMap<>();
//        msg.put("theIpAddress","111.249.198.56");
//        msg.put("mobileCode","18702750020");
//        msg.put("userID","");String s = soapClient.sendMessage(msg);System.out.println(s);}
}

测试结果:

优点

pom配置简单,无须解决各种版本依赖的问题。

缺点

可以看到Jaxws的调用和Axis2一样,都具有较高的灵活性,都可以自定义xml的节点数据。

所不同的是,它的调用代码稍显繁琐,但如果在生产中,有良好的封装,这应该不是问题。

小结

对于SOAP方式WebService的调用,有客户端的调用,推荐maven插件自动生成代码的形式,唯一的缺点是需要重新部署一次。

对于无客户端的调用,推荐Axis2或者Jaxws的形式,考虑到二者实现其实各有优劣,有需要的读者可以自行甄别选用。

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

3款自己电脑就可以运行AI LLM的项目

AnythingLLM、LocalGPT和PrivateGPT都是与大语言模型&#xff08;LLM&#xff09;相关的项目&#xff0c;它们允许用户在本地环境中与文档进行交互&#xff0c;但它们在实现方式和特点上存在一些差异。AnythingLLM使用Pinecone和ChromaDB来处理矢量嵌入&#xff0c;并使用OpenA…

Flask项目搭建及部署 —— Python

flask搭建及部署 pip 19.2.3 python 3.7.5 Flask 1.1.1 Flask-SQLAlchemy 2.4.1 Pika 1.1.0 Redis 3.3.11 flask-wtf 0.14.2 1、创建flask项目&#xff1a; 创建完成后整个项目结构树&#xff1a; app.py: 项⽬管理⽂件&#xff0c;通过它管理项⽬。 static: 存放静态…

Visio 2019 中文版安装下载教程【32/64位】,图文步骤详解,超简单,无套路!!!

文章目录 前言软件介绍软件下载安装步骤激活步骤 前言 本文针对visio 2019 的下载安装进行详细讲解&#xff0c;没有任何套路&#xff0c;大家可以放心使用&#xff0c;由于该类文章容易被和谐&#xff0c;大家可以收藏关注&#xff0c;以免迷路&#xff0c;若安装出现问题&am…

ubuntu重装系统后,安装cuda,cudnn

一、 先安装驱动&#xff0c;如果驱动安装不成功&#xff0c;会影响桌面&#xff0c;再重装系统还来得及&#xff0c;尝试了很多方法&#xff0c;还是用系统安装最靠谱&#xff1a; 首先进入Ubuntu搜索栏目&#xff0c;找到软件更新器的一个图标&#xff0c;点开之后是这样的。…

电力需求预测挑战赛笔记 Taks1 跑通baseline

#AI夏令营 #Datawhale #夏令营 赛题 一句话介绍赛题任务可以这样理解赛题&#xff1a; 【训练时序预测模型助力电力需求预测】 电力需求的准确预测对于电网的稳定运行、能源的有效管理以及可再生能源的整合至关重要。 赛题任务 给定多个房屋对应电力消耗历史 N 天的相关序列数…

网信大数据信用报告查询怎么查?网信大数据有什么作用?

随着互联网的快速发展&#xff0c;大数据技术已经广泛应用于各行各业。其中&#xff0c;网信大数据信用报告查询成为了许多人关注的焦点。那么&#xff0c;如何查询网信大数据信用报告呢?网信大数据又有哪些作用呢?本文将为您一一解答。 一、如何查询网信大数据信用报告? 要…

keepalive和haproxy

1、keepalive 1.1概念 调度器的高可用 vip地址主备之间的切换&#xff0c;主在工作时&#xff0c;vip地址只在主上&#xff0c;主停止工作&#xff0c;vip漂移到备服务器 在主备的优先级不变的情况下&#xff0c;主恢复工作&#xff0c;vip会飘回到主服务器 1、配优先级 …

java通过poi-tl导出word实战详细步骤

文章目录 与其他模版引擎对比1.引入maven依赖包2.新建Word文档exportWprd.docx模版3.编写导出word接口代码4.导出成果 poi-tl是一个基于Apache POI的Word模板引擎&#xff0c;也是一个免费开源的Java类库&#xff0c;你可以非常方便的加入到你的项目中&#xff0c;并且拥有着让…

图论·Day01

P3371 P4779 P3371 【模板】单源最短路径&#xff08;弱化版&#xff09; 注意的点&#xff1a; 边有重复&#xff0c;选择最小边&#xff01;对于SPFA算法容易出现重大BUG&#xff0c;没有负权值的边时不要使用&#xff01;&#xff01;&#xff01; 70分代码 朴素板dijsk…

100 个网络基础知识普及,看完成半个网络高手!

1&#xff09;什么是链接&#xff1f; 链接是指两个设备之间的连接。它包括用于一个设备能够与另一个设备通信的电缆类型和协议。 2&#xff09;OSI 参考模型的层次是什么&#xff1f; 有 7 个 OSI 层&#xff1a;物理层&#xff0c;数据链路层&#xff0c;网络层&#xff0…

医疗器械网络安全 | 漏洞扫描、渗透测试没有发现问题,是否说明我的设备是安全的?

尽管漏洞扫描、模糊测试和渗透测试在评估系统安全性方面是非常重要和有效的工具&#xff0c;但即使这些测试没有发现任何问题&#xff0c;也不能完全保证您的医疗器械是绝对安全的。这是因为安全性的评估是一个多维度、复杂且持续的过程&#xff0c;涉及多个方面和因素。以下是…

uniapp实现table排序

根据后端接口传来的数字大小对列表进行升序/降序展示 效果图&#xff0c;价格由高到低降序 价格由低到高 升序 js 降序升序代码如下 export default {data() {return {MtList:[]}},onLoad() {this.MtypeName();//加载列表方法},methods: {MtypeName(){//列表方法this.$api.…

办公技巧:如何编辑带有工作表保护的Excel文件?

在日常工作中&#xff0c;我们经常会遇到带有工作表保护的Excel文件&#xff0c;这些文件虽然可以被打开查看&#xff0c;但无法直接编辑或修改其中的数据。然而&#xff0c;在某些情况下&#xff0c;我们可能需要编辑这些受保护的工作表以满足工作需求。本文将介绍几种方法来编…

【Linux】Linux操作系统

Linux基本指令 os概念与定位 本节内容&#xff1a; Linux操作系统讲解 os概念与定位 操作系统&#xff08;Operating System&#xff0c;简称OS&#xff09;是管理和控制计算机硬件与软件资源的计算机程序。总的来讲&#xff0c;操作系统是一款做软硬件管理的软件。 了解操作…

FastGPT+OneAI接入网络模型

文章目录 FastGPT连接OneAI接入网络模型1.准备工作2.开始部署2.1下载 docker-compose.yml2.2修改docker-compose.yml里的参数 3.打开FastGPT添加模型3.1打开OneAPI3.2接入网络模型3.3重启服务 FastGPT连接OneAI接入网络模型 1.准备工作 本文档参考FastGPT的官方文档 主机ip接…

配置光源——笔记

一、灯光的类型 (一&#xff09;Directional Light&#xff08;定向光&#xff09; 1、只改变方向变化&#xff0c;不记录位置变化 2、相当于太阳光 3、室外一般使用 (二&#xff09;Spot 聚光灯&#xff1a;昏暗&#xff08;凌晨或傍晚&#xff09;&#xff0c;有一个光斑…

科普文:spring boot中常用的接口、工具栏、注解整理

1.springboot 常用接口 1.1 Aware接口 Spring IOC容器中 Bean是感知不到容器的存在&#xff0c;Aware(意识到的)接口就是帮助Bean感知到IOC容器的存在&#xff0c;即获取当前Bean对应的Spring的一些组件&#xff0c;如当前Bean对应的ApplicationContext等。 1.1.1 Applicati…

SSM学习6:Spring事务

简介 事务作用&#xff1a;在数据层保障一系列的数据库操作同成功同失败Spring事务作用&#xff1a;在数据层或业务层保障一系列的数据库操作同成功同失败 public interface PlatformTransactionManager{void commit(TransactionStatus status) throws TransactionStatus ;vo…

数据分析:小红书户外风潮起,内容种草新密码

导语 随着巴黎奥运会临近&#xff0c;小红书顺应热点推出《大家运动会》等S级IP&#xff0c;让户外运动与社区更好地有机融合&#xff0c;为品牌带来更广泛的市场曝光和用户参与度。品牌如何借势热点&#xff0c;完成新一轮的增长呢&#xff1f; S级IP《大家运动会》 千瓜数…

python如何查看类的函数

Python非常方便&#xff0c;它不需要用户查询文档&#xff0c;只需掌握如下两个帮助函数&#xff0c;即可查看Python中的所有函数&#xff08;方法&#xff09;以及它们的用法和功能&#xff1a; dir()&#xff1a;列出指定类或模块包含的全部内容&#xff08;包括函数、方法、…