WebService入门学习一
参考:https://blog.csdn.net/c99463904/article/details/76018436
1、WebService简介?
Web Service技术, 能使得运行在不同机器上的不同应用无须借助附加的、专门的第三方软件或硬件, 就可相互交换数据或集成。依据Web Service规范实施的应用之间, 无论它们所使用的语言、 平台或内部协议是什么, 都可以相互交换数据。
简单的说,WebService就是一种跨编程语言和跨操作系统平台的远程调用技术。所谓跨编程语言和跨操作平台,就是说服务端程序采用java编写,客户端程序则可以采用其他编程语言编写,反之亦然。跨操作系统平台则是指服务端程序和客户端程序可以在不同的操作系统上运行。 远程调用,就是一台计算机的应用可以调用其他计算机上的应用。例如:支付宝,支付宝并没有银行卡等数据,它只是去调用银行提供的接口来获得数据。还有天气预报等,也是气象局把自己的系统服务以webservice服务的形式暴露出来,让第三方网站和程序可以调用这些服务功能,再比如,各个门户网站显示的股票行情信息数据。
2、WebService原理?
1)、XML,SOAP和WSDL就是构成WebService平台的三大技术 。
2)、WebService采用Http协议来在客户端和服务端之间传输数据。WebService使用XML来封装数据,XML主要的优点在于它是跨平台的。
3)、WebService通过HTTP协议发送请求和接收结果时,发送的请求内容和结果内容都采用XML格式封装,并增加了一些特定的HTTP消息头,以说明HTTP消息的内容格式,这些特定的HTTP消息头和XML内容格式就是SOAP协议规定的。
4)、WebService服务器端首先要通过一个WSDL文件来说明自己有什么服务可以对外调用。简单的说,WSDL就像是一个说明书,用于描述WebService及其方法、参数和返回值。 WSDL文件保存在Web服务器上,通过一个url地址就可以访问到它。客户端要调用一个WebService服务之前,要知道该服务的WSDL文件的地址。WebService服务提供商可以通过两种方式来暴露它的WSDL文件地址:1.注册到UDDI服务器,以便被人查找;2.直接告诉给客户端调用者。
5)、WebService交互的过程就是,WebService遵循SOAP协议通过XML封装数据,然后由Http协议来传输数据。
3、Web Service是什么?
1)、基于Web的服务:服务器端整出一些资源让客户端应用访问(获取数据)。
2)、一个跨语言、跨平台的规范(抽象)。
3)、多个跨平台、跨语言的应用间通信整合的方案(实际)。
4)、以各个网站显示天气预报功能为例,气象中心的管理系统将收集的天气信息并将数据暴露出来(通过WebService Server),而各大站点的应用就去调用它们得到天气信息并以不同的样式去展示(WebService Client),网站提供了天气预报的服务,但其实它们什么也没有做,只是简单了调用了一下气象中心服务器上的一段代码而已。
4、为什么要用Web service?
答:web service能解决:跨平台调用、跨语言调用、远程调用。
5、什么时候使用web Service?
1)、同一家公司的新旧应用之间。
2)、不同公司的应用之间,分析业务需求:天猫网与中通物流系统如何交互。
3)、一些提供数据的内容聚合应用:天气预报、股票行情。
6、Web Service中的几个重要术语.
1)、 WSDL:web service definition language(WebService定义语言)。
1.1、对应一种类型的文件.wsdl。
1.2、定义了web service的服务器端与客户端应用交互传递请求和响应数据的格式和方式。
1.3、一个web service对应一个唯一的wsdl文档。
2)、SOAP:simple object access protocal(简单对象访问协议)。
2.1、是一种简单的、基于HTTP和XML的协议, 用于在WEB上交换结构化的数据,结构化数据实际上就是xml的数据。
2.2、soap消息:请求消息和响应消息。
2.3、http+xml片断。
3)、SEI:WebService EndPoint Interface(终端, web service的终端接口)。
3.1、就是WebService服务器端用来处理请求的接口。
4)、CXF:Celtix + XFire,一个apache的用于开发webservice服务器端和客户端的框架。
7、WebService入门案例,开发webservice的条件,使用JDK开发(JDK版本,1.6及以上版本),在实际的项目中可以使用CXF框架进行开发。webservice的组成是由客户端和服务器端组成的。
第一步,首先,编写SEI(Service Endpoint Interface),SEI在webservice中称为portType,在java中就是普通接口 。
1 package com.bie.webservice.sei; 2 3 import javax.jws.WebMethod; 4 import javax.jws.WebService; 5 6 /** 7 * 8 * @author 9 * 编写SEI(Service Endpoint Interface),SEI在webservice中称为portType,在java中就是普通接口 。 10 * 11 * 1、第一步,开发服务器端,Web Service编码。 12 * –@WebService(SEI和SEI的实现类),该注解用来定义SEI和SEI的实现类。 13 * –@WebMethod(SEI中的所有方法),该注解用来定义SEI里面的方法。 14 * 2、第二步,发布Web Service,–Endpoint(终端, 发布webservice)。 15 */ 16 @WebService 17 public interface HelloWebServiceSEI { 18 19 @WebMethod 20 public String sayHello(String name); 21 22 }
第二步,编写SEI实现类,此类作为webservice提供服务类,如下所示:
1 package com.bie.webservice.sei.impl; 2 3 import javax.jws.WebService; 4 5 import com.bie.webservice.sei.HelloWebServiceSEI; 6 7 /** 8 * 9 * @author 10 * 11 * 1、SEI实现类 12 * 13 * 14 */ 15 @WebService // SEI实现类也要使用此注解 16 public class HelloWebServiceSEIImpl implements HelloWebServiceSEI { 17 18 @Override 19 public String sayHello(String name) { 20 System.out.println("Service server sayHello() : " + name); 21 return "hello " + name; 22 } 23 24 }
第三步:发布服务,Endpoint类发布服务,publish方法,两个参数:参数1.服务地址,参数2.服务实现类。
1 package com.bie.webservice.endpoint; 2 3 import javax.xml.ws.Endpoint; 4 5 import com.bie.webservice.sei.HelloWebServiceSEI; 6 import com.bie.webservice.sei.impl.HelloWebServiceSEIImpl; 7 8 /** 9 * 10 * @author 1、发布WebService,Endpoint(终端, 发布webservice)。 11 * 12 */ 13 public class WebServiceEndpoint { 14 15 public static void main(String[] args) { 16 // 使用Endpoint发布webservice 17 // 参数一,url地址 18 String address = "http://localhost:8989/webservice/hello"; 19 // 参数二,是SEI实现类对象 20 HelloWebServiceSEI implementor = new HelloWebServiceSEIImpl(); 21 Endpoint.publish(address, implementor); 22 23 System.out.println("使用Endpoint发布webservice,发布成功Success......"); 24 } 25 26 }
第四步,测试服务是否发布成功,通过阅读wsdl,确定客户端调用的接口、方法、参数和返回值存在,证明服务发布成功。我们在浏览器输入 http://127.0.0.1:8989/webservice/hello?wsdl 来获取wsdl文件进行阅读。wsdl,是以XML文件形式来描述WebService的"说明书",有了说明书,我们才可以知道如何使用或是调用这个服务。现在我们还不知道怎么去阅读,后面我们会详解,只要能获取到,就能确定WebService服务发布成功。
现在,首先使用eclipse提供的web service浏览器访问,查看对应的wsdl文档(每一个WebService都有一个wsdl文档):http://localhost:8989/webservice/hello?wsdl (一般浏览器就可以进行访问),请求webService并查看请求和响应消息(webservice浏览器)。
也可以使用eclipse自带的web service浏览器进行访问的,输入参数,就可以进行调用服务器端的方法,如下所示:
8、客户端的实现,客户端调用服务有很多种方法,我们先用工具生成客户端代码,wsimport(借助jdk的wsimort.exe工具生成客户端代码)是jdk自带的webservice客户端工具,可以根据wsdl文档生成客户端调用代码(java代码)。当然,无论服务器端的WebService是用什么语言写的,都可以生成调用webservice的客户端代码。
首先,创建一个客户端空项目,cmd命令行模式下,进入此项目的src目录,使用以下命令生成客户端代码:wsimport -s . http://localhost:8989/webservice/hello?wsdl。
其中,-s参数是指编译出源代码文件,后面的.(点)指將代码放到当前目录下,最后面的http://localhost:8989/webservice/hello是指获取wsdl说明书的地址。
这里借助jdk的wsimort.exe工具生成客户端代码:wsimport -keep http://localhost:8989/webservice/hello?wsdl,wsimport -keep url,其中url为wsdl文件的路径。
然后刷新eclipse的项目,可以看到已经生成完毕了,如下所示:
开始编写客户端,如下所示:
1 package com.bie.webservice.client; 2 3 import com.bie.webservice.sei.impl.HelloWebServiceSEIImpl; 4 import com.bie.webservice.sei.impl.HelloWebServiceSEIImplService; 5 6 /** 7 * 调用WebService里面的方法,借助生成的代码编写请求代码 8 * 9 * @author 10 * 11 */ 12 public class HelloClient { 13 14 public static void main(String[] args) { 15 // 创建服务视图,视图是从wsdl文件的service标签的name属性获取 16 HelloWebServiceSEIImplService factory = new HelloWebServiceSEIImplService(); 17 // 获取到jdk动态对立对象 18 // 获取服务实现类,实现类从wsdl文件的portType的name属性获取 19 HelloWebServiceSEIImpl helloWebServiceSEIImplPort = factory.getHelloWebServiceSEIImplPort(); 20 // class com.sun.proxy.$Proxy32 21 System.out.println(helloWebServiceSEIImplPort.getClass()); 22 // 获取查询方法,从portType的operation标签获取 23 String sayHello = helloWebServiceSEIImplPort.sayHello("Tom"); 24 System.out.println("client : " + sayHello); 25 26 } 27 28 }
效果如下所示:
9、监听请求和相应的过程,可以使用工具TCP/IP Monitor。
监听请求: 使用Eclipse的TCP/IP工具(端口转发器),这需要一个工具TCP/IP Monitor ,Eclipse自带的Debug工具之一,用于捕获Http、TCP/IP协议包。原理是一个代理服务,客户端先把数据发送到代理服务,然后代理服务再把数据发送到服务器,这样就能获取请求数据和响应数据。
第一步:打开这个工具,选择Window -> Preferences -> Run/Debug (Tcp/Ip Monitor)。或者输入TCP/IP Monitor找到即可。
新增一个Tcp/Ip Monitor,然后点击启动start按钮启动,如下所示:
第二步,检测是否设置成功,我们访问代理服务器来获得wsdl文件,如下所示:
第三步,将服务器端的WSDL文档保存到客户端本地,然后修改文档,将端口号从8989改为8080,然后根据本地的wsdl文档生成客户端代码(可以将之前由网络生成的代码删除掉的), 并编写客户端的调用代码,最后配置eclipse的TCP/IP,启动监听。
根据本地文件生成客户端代码,如下所示:
第四步,由本地生成的代码,启动客户端来进行监听测试,获取请求数据和响应数据,如下所示:
10、免费webservice地址:http://www.webxml.com.cn/zh_cn/web_services.aspx。
现在以调用免费的web service(天气预报),Google”免费WebService”,找到提供天气预报Webservice的网络地址http://webservice.webxml.com.cn/WebServices/WeatherWS.asmx。
客户端编码方式访问,借助命令工具自动生成客户端代码(只要拿到Webservice服务器端的wsdl即可生成客户端的代码),借助生成的代码编写请求代码。
1 PS D:\eclipse\workspace_spring\weatherWebService\src> wsimport -keep http://ws.webxml.com.cn/WebServices/WeatherWS.asmx?wsdl 2 正在解析 WSDL... 3 4 5 [WARNING] src-resolve.4.2: 解析组件 's:schema' 时出错。在该组件中检测到 's:schema' 位于名称空间 'http://www.w3.org/2001/XMLSchema' 中, 但无法从方案文档 'http://ws.webxml.com.cn/WebServices/WeatherWS.asmx?wsdl#types?schema1' 引用此名称空间的组件。如果这是不正确的名称空间, 则很可能需要更改 's:schema' 的前缀。如果这是正确的名称空间, 则应将适当的 'import' 标记添加到 'http://ws.webxml.com.cn/WebServices/WeatherWS.asmx?wsdl#types?schema1'。 6 http://ws.webxml.com.cn/WebServices/WeatherWS.asmx?wsdl#types?schema1的第 15 行 7 8 [WARNING] src-resolve: 无法将名称 's:schema' 解析为 'element declaration' 组件。 9 http://ws.webxml.com.cn/WebServices/WeatherWS.asmx?wsdl#types?schema1的第 15 行 10 11 [ERROR] undefined element declaration 's:schema' 12 http://ws.webxml.com.cn/WebServices/WeatherWS.asmx?wsdl的第 15 行 13 14 [ERROR] undefined element declaration 's:schema' 15 http://ws.webxml.com.cn/WebServices/WeatherWS.asmx?wsdl的第 61 行 16 17 [ERROR] undefined element declaration 's:schema' 18 http://ws.webxml.com.cn/WebServices/WeatherWS.asmx?wsdl的第 101 行 19 20 Exception in thread "main" com.sun.tools.internal.ws.wscompile.AbortException 21 at com.sun.tools.internal.ws.processor.modeler.wsdl.JAXBModelBuilder.bind(JAXBModelBuilder.java:129) 22 at com.sun.tools.internal.ws.processor.modeler.wsdl.WSDLModeler.buildJAXBModel(WSDLModeler.java:2283) 23 at com.sun.tools.internal.ws.processor.modeler.wsdl.WSDLModeler.internalBuildModel(WSDLModeler.java:183) 24 at com.sun.tools.internal.ws.processor.modeler.wsdl.WSDLModeler.buildModel(WSDLModeler.java:126) 25 at com.sun.tools.internal.ws.wscompile.WsimportTool.buildWsdlModel(WsimportTool.java:429) 26 at com.sun.tools.internal.ws.wscompile.WsimportTool.run(WsimportTool.java:190) 27 at com.sun.tools.internal.ws.wscompile.WsimportTool.run(WsimportTool.java:168) 28 at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 29 at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 30 at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 31 at java.lang.reflect.Method.invoke(Method.java:498) 32 at com.sun.tools.internal.ws.Invoker.invoke(Invoker.java:159) 33 at com.sun.tools.internal.ws.WsImport.main(WsImport.java:42) 34 PS D:\eclipse\workspace_spring\weatherWebService\src>
说明: 直接生成客户端代码会抛异常, 无法生成客户端代码,,解决办法:
第一步,将对应的wsdl文档保存到本地。
第二步,修改wsdl文档的部分内容(有三处需要更换的):将 <s:element ref="s:schema" /><s:any /> 替换成 <s:any minOccurs="2" maxOccurs="2"/>。
备注: 这个是Java调用.net的webservice都有的问题。
将使用的网络地址url修改为本地地址的url,如下所示:
开始编写客户端测试代码,如下所示:
1 package cn.com.webxml.client; 2 3 import java.util.Iterator; 4 import java.util.List; 5 6 import cn.com.webxml.ArrayOfString; 7 import cn.com.webxml.WeatherWS; 8 import cn.com.webxml.WeatherWSSoap; 9 10 public class WeatherClient { 11 12 public static void main(String[] args) { 13 // 寻找起始类,可以根据WeatherWS.wsdl文档里面的<wsdl:service name="WeatherWS">此标签 14 // 此标签里面的类即为起始类,继承Service,此类相当于是一个工厂 15 WeatherWS weatherWS = new WeatherWS(); 16 // 返回一个代理对象,获取此对象就可以进行发送请求了 17 WeatherWSSoap weatherWSSoap = weatherWS.getWeatherWSSoap(); 18 // 调用获取天气的对象,系统维护 免费用户服务暂停。http://www.webxml.com.cn/ 19 String theCityCode = "原阳县";// 地方 20 String theUserID = "";// 可以为空 21 ArrayOfString weather = weatherWSSoap.getWeather(theCityCode, theUserID); 22 List<String> list = weather.getString(); 23 // 必须可以上网才可以进行调用 24 for (int i = 0; i < list.size(); i++) { 25 System.out.println(list.get(i)); 26 } 27 28 // 获得中国省份、直辖市、地区和与之对应的ID 29 ArrayOfString regionProvince = weatherWSSoap.getRegionProvince(); 30 Iterator<String> iterator = regionProvince.getString().iterator(); 31 while (iterator.hasNext()) { 32 String next = iterator.next(); 33 System.out.println(next); 34 } 35 } 36 37 }
可以再搞一下获取手机号归属地的操作,如下所示:
1 package cn.com.webxml.client; 2 3 import cn.com.webxml.MobileCodeWS; 4 import cn.com.webxml.MobileCodeWSSoap; 5 6 public class PhoneClient { 7 8 public static void main(String[] args) { 9 MobileCodeWS factory = new MobileCodeWS(); 10 MobileCodeWSSoap mobileCodeWSSoap = factory.getMobileCodeWSSoap(); 11 String mobileCode = "1851375xxxx"; 12 String userID = ""; 13 String mobileCodeInfo = mobileCodeWSSoap.getMobileCodeInfo(mobileCode, userID); 14 System.out.println(mobileCodeInfo); 15 } 16 17 }
11、使用CXF开发web service,加入cxf的jar包即可(apache-cxf-2.5.9\lib下面的jar包),其它不需要改动,启动的时候就变成了以cxf的方式进行启动了。引入cxf的包之后,启动服务端,可以进行访问查看,如下所示:
配置一下D:\biehl\apache-cxf-2.5.9\bin的路径到环境变量中,开始使用此框架的生成代码脚本,如下所示:
然后将;%APACHE-CXF_PATH%\bin;加到path最后即可。然后根据D:\biehl\apache-cxf-2.5.9\bin\wsdl2java.bat脚本生成客户端代码,如下所示:
然后刷新项目即可就可以看到生成的代码了。
12、WebService请求深入分析,分析WebService的WSDL文档结构。
WSDL(Web Services Description Language), web服务描述语言,他是webservice服务端使用说明书,说明服务端接口、方法、参数和返回值,WSDL是随服务发布成功,自动生成,无需编写。
文档结构,如下所示:
1)、Service:相关端口的集合,包括其关联的接口、操作、消息等。
说明:service服务器端的一个webservice的容器,其name属性用来指定客户端容器类。其port属性用来指定一个服务器端处理请求的入口(就是SEI的实现),binding属性用来引用上面定义的<binding>标签。address标签是当前webservice的请求地址。
2)、Binding:特定端口类型的具体协议和数据格式规范的绑定。
说明:binding用于定义SEI的实现类,binding的type属性引用上面定义的prottype标签,<soap:binding style="document"> 绑定的数据是一个document。子标签operation用来定义实现类的方法,<soap:operation style="document"/> 传输的是document即xml,其子标签input指定客户端应用传过来的数据,input的子标签<soap:body use="literal"/>传输的是xml格式的文本数据,子标签output指定服务器端返回给客户端的数据,output的子标签<soap:body use="literal"/>传输的是xml格式的文本数据。
3)、portType: 服务端点,描述 web service可被执行的操作方法,以及相关的消息,通过binding指向portType,用来指定服务器端的SEI,operation用来指定SEI中的处理请求的方法。
说明:protype用来定义服务器端的SEI,子标签operator用来指定SEI的处理请求的方法,子标签input指定客户端应用传过来的数据,会引用上面定义的message标签,子标签output指定服务器端返回给客户端的数据同时引用上面的message标签。
4)、message: 定义一个操作(方法)的数据参数。通信消息的数据结构的抽象类型化定义。引用types中定义的标签。
说明:message用来定义消息的结构,part指定引用types中定义的标签片段。
5)、types: 定义 web service 使用的全部数据类型,数据类型(标签)定义的容器,里面使用schema定义了一些标签结构供message引用。
6)、port - 定义为协议/数据格式绑定与具体Web访问地址组合的单个服务访问点。
阅读方式WSDL文档应该从下往上阅读。
第一步、先看service标签,看相应port的binding属性,然后通过值查找上面的binding标签。
第二步、通过binding标签可以获得具体协议等信息,然后查看binding的type属性
第三步、通过binding的type属性,查找对应的portType,可以获得可操作的方法和参数、返回值等。
第四步、通过portType下的operation标签的message属性,可以向上查找message获取具体的数据参数信息。
13、SOAP,SOAP即简单对象访问协议,他是使用http发送的XML格式的数据,它可以跨平台,跨防火墙,SOAP不是webservice的专有协议。
1)、SOAP=http+xml。
2)、SOAP结构,如下所示:
a、必需的 Envelope 元素,可把此XML文档标识为一条 SOAP 消息。
b、可选的 Header 元素,包含头部信息。
c、必需的 Body 元素,包含所有的调用和响应信息。
d、可选的 Fault 元素,提供有关在处理此消息所发生错误的信息。
14、CXF支持的数据类型,参数调用的时候可以使用这些参数类型进行调用。
1)、基本类型,int,float,boolean等
2)、引用类型,String、集合包含数组,List, Set,Map。自定义类型,比如实体类类型。
15、一次Web service请求的流程,其本质,如下所示:
1)、客户端向服务器端发送了一个soap消息(http请求+xml片断),调用服务器端方法的时候发送请求,发送的是soap消息(http请求+xml片断,此xml片段是参考wsdl文件生成的),遵循的还是http协议,调用服务器端的某个方法,可以将参数传递给该方法进行调用。
2)、服务器端处理完请求后, 向客户端返回一个soap消息(xml片段)。
16、使用注解修改WSDL内容,作用是通过注解,可以更加形像的描述Web服务。对自动生成的wsdl文档进行修改,为使用者提供一个更加清晰的wsdl文档。
1 WebService的注解都位于javax.jws包下: 2 3 @WebService-定义服务,在类上边,作用在具体类上。而不是接口。一个类只有添加了此注解才可以通过Endpoint发布为一个web服务。一个添加了此注解的类,必须要至少包含一个实例方法。静态方法和final方法不能被发布为服务方法: 4 targetNamespace:指定命名空间。 5 name:Web Service的portType的名称。 6 portName:Web Service的端口port的名称。 7 serviceName:Web Service的服务名称。 8 endpointInterface:SEI接口地址,如果一个服务类实现了多个接口,只需要发布一个接口的方法,可通过此注解指定要发布服务的接口。 定义服务抽象Web Service协定的服务端点接口的完整名称。
wsdlLocation:描述服务的预定义WSDL的位置。
9 10 @WebMethod-定义方法,在公开方法上边,此注解用在方法上,用于修改对外暴漏的方法,定制返回值到wsdl部分和xml元素的映射关系: 11 operationName:方法名。 12 exclude:设置为true表示此方法不是webservice方法,反之则表示webservice方法,默认是false,将某一方法标记为不作为一个web方法公开 。 13 14 @WebResult-定义返回值,在方法返回值前边,用于定制返回值到wsdl的映射: 15 name:返回结果值的名称 。
header:如果为true,则结果是从消息头而不是消息正文获取的。
partName:表示此返回值的wsdl:part的名称。
targetNamespace返回值的xml名称空间。 16 17 @WebParam-定义参数,在方法参数前边,用于定义wsdl中的参数映射,定制单个参数到web service消息部分和xml元素的映射关系: 18 name:指定参数的名称。
header:如果为true,则参数是从消息头而不是消息正文获取的。
node:参数的流向(in、out、inout之一)。
partName:表示此参数的wsdl:part的名称。
targetNamespace:参数的xml名称空间。
案例,如下所示:
1 package com.bie.webservice.sei.impl; 2 3 import javax.jws.WebMethod; 4 import javax.jws.WebParam; 5 import javax.jws.WebResult; 6 import javax.jws.WebService; 7 8 import com.bie.webservice.sei.HelloWebServiceSEI; 9 10 /** 11 * 12 * @author 13 * 14 * 1、SEI实现类 15 * 16 * 17 */ 18 @WebService( 19 targetNamespace = "http://www.biexiansheng.com", 20 portName = "HelloSOAPPort", 21 serviceName = "HelloWSS", 22 name = "HelloSOAP") // SEI实现类也要使用此注解 23 public class HelloWebServiceSEIImpl implements HelloWebServiceSEI { 24 25 @Override 26 @WebMethod( 27 operationName="getHello", 28 exclude=false 29 ) 30 public @WebResult(name="hellResult")String sayHello(@WebParam(name="helloName")String name) { 31 System.out.println("Service server sayHello() : " + name); 32 return "hello " + name; 33 } 34 35 }
演示效果,如下所示:
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?