`

在SOAP消息中传输BLOB和CLOB数据

    博客分类:
  • JAVA
阅读更多

在SOAP消息中传输BLOB和CLOB数据

 

 

本文是J2EE Web服务开发系列文章的第五篇。将介绍在SOAP消息中传输BOLB(Binary Large Objects,大型二进制对象)和CLOB(Character Large Objects,字符大对象)数据的方法,然后为以图像传输为例子讨论BLOB、CLOB数据传输的编程实现方法。
<!--START RESERVED FOR FUTURE USE INCLUDE FILES--><!-- include java script once we verify teams wants to use this and it will work on dbcs and cyrillic characters --><!--END RESERVED FOR FUTURE USE INCLUDE FILES-->

阅读本文前您需要以下的知识和工具:

  • JavaTM Web Services Developer Pack 1.1,并且会使用初步使用
  • Apache axis1.1
  • 初步了解JAX-RPC编程方法
  • SAAJ、JAXM编程的基本技能
  • 有图像处理的一般知识

本文的参考资料见 参考资料

本文的全部代码在这里 下载

BOLB、CLOB数据传输方法

 

在SOAP消息中,复杂的数据类型包括记录、对象和结构等,还包括图像、声音等多媒体数据。在记录、结构的数据,可以利用XML本身的机制进行表示,比如要表示一些查询的图书的信息,可以使用以下的方法进行表示:

例程1 在SOAP消息中表示复杂的数据

<soap-env:Envelope xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/">
    <soap-env:Header/>
    <soap-env:Body>
        <books:GetAllBooks xmlns:books="http://hellking.webservice.com">
           <books:book id="isbn-34-234-xxxx-34">
    <books:name>J2EE Web 服务开发 </books:name>
    <books:publisher> 电子工业出版社 </books:publisher>
    <books:price> xxxxx </books:price>
    <books:category>计算机</books:category>
    <books:description> xxxxxxxxx </books:description>
    <books:author> xxxxxx </books:author>
    <books:author> xxxxx </books:author>
          </books:book>
         <books:bookid="242334">
         …
</books:book>
       </books:GetAllBooks>
    </soap-env:Body>
</soap-env:Envelope>
另一个例子:
<myFavoriteNumbers
  SOAP-ENC:arrayType="xsd:int[2]">
   <number>3</number> 
   <number>4</number> 
</myFavoriteNumbers>

除了使用上述的方式传输外,还可以使用序列化对象的方式。我们知道,Java中的序列化对象可以在网络上传输、保存。具体的过程是把这些数据保存在可序列化的Java对象中,然后把此对象序列化传输到对方,对方对此序列化对象进行"解冻",然后获得要传输的数据。相对于直接用XML表示数据,这种方式比较消耗系统资源。

SOAP消息基于XML技术,XML在表示文本方面有很大的便利性,但是如果要在XML中表示图像、声音等多媒体数据(这里指把图像、声音等数据包含在同一个XML文件中,而不是使用外部实体),那么就不是那么简单了。理论上,你也可以把要传输的BLOB、CLOB数据保存在序列化的Java对象中,然后以序列化的Java对象为载体进行传输。但是这些一种非常的低效的方法!

要在SOAP中传输BLOB数据,通常有以下两种方法:

  • 使用BASE64编码,把要传输的数据直接作为SOAP Body中的一部分
  • 作为MIME附件,附加在SOAP消息上

对于CLOB数据,不需要使用BASE64编码,可以直接作为SOAP Body的一部分或者作为MIME附件传输。

本文将使用以上两种方式,以图像传输为例子讨论在SOAP消息中传输BLOB、CLOB数据的方法。首先我们看怎么使用BASE64编码来传输图形。





回页首


使用BASE64编码传输BLOB数据

 

使用BASE64编码来传输BLOB数据的基本过程是:

  1. 在服务端读取目标BLOB数据保存在byte[]中;
  2. 使用BASE64Encoder(编码器,如sun.misc.BASE64Encoder)把byte[]编码成String;
  3. 当客户端发出请求时,就返回这个String;
  4. 客户端从SOAP消息中读取这个String;
  5. 使用BASE64Decode(解码器,如sun.misc.BASE64Decoder)把String解码成byte[];
  6. 对byte[]进行处理(如果时图像,就把它还原成图像;如果是声音,将把它还原成声音)

下面我们结合图形传输来看具体的编程实现。在这里我们使用JAX-RPC的方式,您需要有Apache axis引擎。

首先是确定服务端的接口,这里定义了一个方法:getImage(String imageName)。如例程2所示。

例程2 JAX-RPC服务端接口

package com.hellking.webservice;
public interface ImageServiceInterface extends java.rmi.Remote {
    public java.lang.String getImage(java.lang.String in0) throws java.rmi.RemoteException;
<!-- code sample is too wide -->}

注意getImage方法返回的数据类型,它是String,也就是通过BASE64编码后的String。

使用这个接口生成WSDL文件,可以使用下面的方法:

SET AXIS_HOME=<axis安装目录>
set CLASSPATH=%CLASSPATH%;
%AXIS_HOME%/axis-1_1/lib/axis.jar; 
%AXIS_HOME%/axis-1_1/lib/jaxrpc.jar; 
%AXIS_HOME%/axis-1_1/lib/saaj.jar;
%AXIS_HOME%/axis-1_1/lib/commons-logging.jar;
%AXIS_HOME%/axis-1_1/lib/commons-discovery.jar;
%AXIS_HOME%/axis-1_1/lib/wsdl4j.jar;.
java org.apache.axis.wsdl.Java2WSDL -o wp.wsdl http://localhost:8080/axis/services/ImageService"
<!-- code sample is too wide --> -n "urn:ImageService" -p"com.hellking.webservice" "urn:ImageService"
com.hellking.webservice.ImageServiceInterface

以上方法将生成一个名为wp.wsdl的WSDL文件,生成了WSDL文件后,就可以使用WSDL2Java生成JAX-RPC的框架,如下所示:

java org.apache.axis.wsdl.WSDL2Java -o . -d Session -s -S true
 -Nurn:ImageService com.hellking.webservice wp.wsdl

这个框架中,有一个名为ImageServiceSoapBindingImpl的类,我们要在里面增加实现方法。

修改后的ImageServiceSoapBindingImpl如例程3所示。

例程3 JAX-RPC服务端实现类

package com.hellking.webservice;
import java.io.*;
public class ImageServiceSoapBindingImpl implements com.hellking.webservice.ImageServiceInterface{
<!-- code sample is too wide -->    public java.lang.String getImage(java.lang.String in0) throws java.rmi.RemoteException {
<!-- code sample is too wide -->       String ret=new String();
  try
  {
   byte[] bytes=new byte[1024000];//小于1M 
   InputStream in=ImageServiceSoapBindingImpl.class.getResourceAsStream(in0);
   in.read(bytes);
   ret=new sun.misc.BASE64Encoder().encode(bytes); //具体的编码方法
   in.close();
  }
  catch(FileNotFoundException e)
  {
   e.printStackTrace();
  }
  catch(java.io.IOException ex)
  {
   ex.printStackTrace();
  }
  return ret;
    } 
}

在上面的程序中,byte[] bytes=new byte[1024000]表示要传输的图像内容小于1M,你可以根据具体情况设置,ImageServiceSoapBindingImpl.class.getResourceAsStream(in0)是获得图像文件的输入流,in0是文件名,如test.jpg。这个程序中最关键的部分是:

new sun.misc.BASE64Encoder().encode(bytes);

它把byte[]编码成目标String。

下面的工作就是编译这些代码,然后部署。您可以使用下面的方式进行部署:

java org.apache.axis.client.AdminClient deploy.wsdd

使用这中方式部署时,需要保证Apache axis引擎处于运行状态。如果这个方式部署不成功,也可以直接把编译好的代码拷贝到目标应用中,如:

%TOMCAT_HOME%/webapps/axis/WEB-INF/classes/

接下来编辑%TOMCAT_HOME%/webapps/axis/WEB-INF/server-config.wsdd文件,在某个"</service>"后加入以下内容:

例程4 手工部署JAX-RPC应用

<service name="ImageService" provider="java:RPC">
  <parameter name="allowedMethods" value="*"/>
  <parameter name="wsdlPortType" value="ImageServiceInterface"/>
  <parameter name="wsdlServicePort" value="ImageService"/>
  <parameter name="className" value="com.hellking.webservice.ImageServiceSoapBindingSkeleton"/>
<!-- code sample is too wide -->  <parameter name="scope" value="Session"/>
  <parameter name="wsdlTargetNamespace" value="urn:ImageService"/>
  <parameter name="wsdlServiceElement" value="ImageServiceInterfaceService"/>
 </service>

然后重新启动Apache axis引擎。可以使用下面的方法在浏览器里验证ImageService是否已经成功部署:

http://localhost:8080/axis/services/ImageService?wsdl&method=getImage&name=test.jpg

这个地址您需要根据具体的情况更改。

如果成功部署,将在浏览器里返回以下的内容:

例程5 调用ImageService返回的消息

<?xml version="1.0" encoding="UTF-8" ?> 
 <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
 <soapenv:Body>
  <getImageResponse soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
  <getImageReturn xsi:type="xsd:string">
  /9j/4AAQSkZJRgABAgEAYABgAAD/7Q0YUGhvdG9zaG9wIDMuMAA4QklNA+0KUmVzb2x1dGlvbgAA
  AAAQAGAAAAABAAEAYAAAAAEAAThCSU0EDRhGWCBHbG9iYWwgTGlnaHRpbmcgQW5nbGUAAAAABAAA
  AHg4QklNBBkSRlggR2xvYmFsIEFsdGl0dWRlAAAAAAQAAAAeOEJJTQPzC1ByaW50IEZsYWdzAAAA
  CQAAAAAAAAAAAQA4QklNBAoOQ29weXJpZ2h0IEZsYWcAAAAAAQAAOEJJTScQFEphcGFuZXNlIFBy
...
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==
    </getImageReturn>
  </getImageResponse>
  </soapenv:Body>
</soapenv:Envelope>

注意getImageReturn之间的数据是经过BASE64后的数据,xsi:type="xsd:string"表示它的数据类型是String。

下面来看怎么在客户端对SOAP消息进行处理。

例程6 处理SOAP 经过BASE64编码后的消息

package com.hellking.webservice;
import java.awt.*;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
public class GetImageByString extends ImageClient
{
 public Image getImageFromWebservice()
 {
  ImageIcon img=null ;
  com.hellking.webservice.ImageServiceInterface service; 
  try {
   
   service = new
com.hellking.webservice.ImageServiceInterfaceServiceLocator().getImageService(); 
   String result=service.getImage("test.jpg");
   byte[] bytes = new sun.misc.BASE64Decoder().decodeBuffer(result);
   img = new ImageIcon(bytes);
  }
  catch (Exception re) {
  re.printStackTrace();
  }
  return img.getImage();
 }
 public static void main(String[] args)
 {
  new GetImageByString();
 }
}

解码的方法是编码的逆过程,同样很简单。

byte[] bytes = new sun.misc.BASE64Decoder().decodeBuffer(result)

把JAX-RPC调用结果解码成byte[];img = new ImageIcon(bytes)使用解码后的byte[]来构建一个ImageIcon。

最后看一下GUI程序怎么使用Image结果。

例程7 在GUI客户端使用BASE64解码后的Image

package com.hellking.webservice;
import java.awt.*;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
public abstract class ImageClient extends JFrame
{
 public ImageClient()
 {
  super("test image transport"); 
  setSize(800, 600);
  setVisible(true);
 }
 public abstract Image getImageFromWebservice();
 public void paint(Graphics  g)
 {
  super.paint(g);
   Image img = getImageFromWebservice();      
  g.drawImage(img,0,0,null);  
 }  
}

ImageClient是客户端GUI程序的框架,前面的GetImageByString继承了它。GetImageByString的目的是获得Image,ImageClient的目的是显示Image。GetImageByString运行的结果如图1所示。



注意:运行此程序需要保证服务器端有对应的图像文件,比如test.jpg。

对于不是图像的BLOB数据,您可以通过特定的方式处理,比如保存到文件中。

例程8 保存结果

PrintWriter out1=null;
     try
     {
       out1=new PrintWriter(new BufferedWriter(new FileWriter("re.out")));
     }
     catch(Exception e)
     {
   e.printStackTrace();
     }      
     try
     {    
       int i=0;
    while(true)
    out1.print(bytes[i++]);    
  }
  catch(Exception e)
  {
   e.printStackTrace();
   out1.close();
  }

需要指出的是,不同的BLOB数据,在保存时要对格式进行不同的处理,如果使用上面的方法保存图片,将不能得到正确的结果,需要进行额外的处理。具体的处理方式,已经是本文的题外话了。本案例的详细代码您可以从这里 下载

下面我们讨论使用附件的形式在SOAP中传输BLOB数据。





回页首


使用附件(Attachment)传输BLOB数据

 

在SOAP消息中,允许我们像邮件一样发送附件。附件由另一份文档或者份图像内容组成。一般而言,附件应该采用文本或者二进制数据格式来表示。在英特网上,GIF和JPEG数据格式是图形传输的事实标准。SOAP消息允许带有一个或者多个MIME格式的附件。常用的MIME格式有:

  • text/html:普通的HTML
  • text/xml:XML文档
  • text/plain:普通的文本
  • image/jpeg:JPEG图像
  • image/tiff:tiff图像

下面是一个带有普通文档文本的SOAP消息的一部分。

例程9 带有附件的SOAP消息

------=_Part_2_25899876.1056182982030
Content-Type: text/xml
<soap-env:Envelope xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/">
<soap-env:Header>
</soap-env:Header>
<soap-env:Body>
<getImage>
<test>getImagebyAttachment_Test</test>
</getImage>
</soap-env:Body>
</soap-env:Envelope>
------=_Part_2_25899876.1056182982030
Content-Type: text/plain
Content-Id: hello
hello,this is the soap attachment content!
------=_Part_2_25899876.1056182982030--

上面的黑体字是具体的附件的内容。它的Content-Type是text/plain,id是hello。

SAAJ(SOAP with Attachments API for Java)为发送带附件的SOAP消息提供了编程接口。在编程中,我们使用SOAPMessage对象来创建AttachmentPart(SOAP 附件)对象,如下:

AttachmentPart attachment = soapMessage.createAttachmentPart();

每个AttachmentPart对象有一个或者多个headers和它相关联。Content-Type是Header中必须的元素,其它的元素如:Content-Id,Content-Location是Header中可选的元素。如果要创建一个简单的文本附件,可以使用下面的方式。

例程10创建一个简单的带文本的SOAP附件

String stringContent = " hello,this is the soap attachment content!";
attachment.setContent(stringContent, "text/plain");
attachment.setContentId("test_content");
soapMessage.addAttachmentPart(attachment);

上面创建的附件的MIME类型是text/plain。如果要创建一个图形的MIME附件,可以使用下面的方法。

例程11 创建一个图形的MIME附件

AttachmentPart attachment = soapMessage.createAttachmentPart()
byte[] bytes=new byte[1024000];
InputStream in=GetImageByAttachment.class.getResourceAsStream("test.jpg");
in.read(bytes);
ByteArrayInputStream stream = new ByteArrayInputStream(bytes);
attachment.setContent(stream, "image/jpeg");
attachment.setContentId("test_content");
soapMessage.addAttachmentPart(attachment);

也许你觉得这样创建图形附件比较麻烦,下面有一种相对容易的创建方法。

例程12另一个创建一个图形的MIME附件的方法

URL url = new URL("http://localhost:8080/axis/test.jpg");
DataHandler dh = new DataHandler(url);
AttachmentPart attachment2 = message.createAttachmentPart(dh);
attachment2.setContentId("myImage");
soapMessage.addAttachmentPart(attachment2);

这里使用了DataHandler对象,它是JavaBean Activation Framework (JAF)的一部分,使用它来创建SOAP附件相对直接,首先创建一个URL,这个URL表示了图像文件存储的位置,然后使用这个URL来创建一个DataHandler对象,接下来就使用这个DataHandler来创建SOAP附件了。

接下来我们来编写一个具体的例子飧隼雍颓懊娴睦右谎彩窃赟OAP消息中传输一个图像文件,不同的是使用附件的方式。

这里的附件端采用了JAXM Servlet,关于JAXM编程的请参考此系列文章的第一篇(用JAXM开发Web服务)。服务端的代码如下:

例程13 SOAP消息发送服务端

package com.hellking.webservice;
import org.apache.soap.util.mime.*;
import java.net.*;
import java.util.*;
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.xml.soap.*;
import javax.activation.*;
import javax.xml.messaging.*;
import javax.xml.transform.stream.StreamSource;
public class GetImageByAttachment  extends JAXMServlet  implements ReqRespListener
{
 public SOAPMessage onMessage    (SOAPMessage message)  
    { 
    
  try
  {
   message.writeTo(System.out);
   //以下部分创建SOAP消息
            SOAPConnectionFactory soapConnectionFactory =
                 javax.xml.soap.SOAPConnectionFactory.newInstance();
         SOAPConnection soapConnection =
                 soapConnectionFactory.createConnection();
 
         MessageFactory messageFactory =
                 MessageFactory.newInstance();
         SOAPMessage soapMessage =
                 messageFactory.createMessage();
         SOAPPart soapPart = soapMessage.getSOAPPart();
        SOAPEnvelope requestEnvelope =
             soapPart.getEnvelope();
        SOAPBody body = requestEnvelope.getBody();
        SOAPBodyElement operation = body.addBodyElement
            (requestEnvelope.createName("image"));           
             //创建附件          
   URL url = new URL("http://localhost:8080/axis/test.jpg");//图像文件的储存的位置
   DataHandler dh = new DataHandler(url);
   AttachmentPart attachment2 = message.createAttachmentPart(dh);
   attachment2.setContentId("myImage");//使用JAF来创建SOAP mime附件
  
   soapMessage.addAttachmentPart(attachment2);                    
            soapMessage.writeTo(System.out);
            soapMessage.saveChanges();
            return soapMessage;
        }
        catch(Exception ex)
        {
         ex.printStackTrace();
         return null;
        }        
    }
}

当然,除了使用DataHandler来创建SOAP消息外,还可以按照前面介绍的使用基本的IO的方式来创建。

下面来看客户端的代码。如例程14所示。

package com.hellking.webservice;
import javax.xml.soap.*;
import java.io.*;
import java.awt.image.*;
import java.awt.*;
import com.sun.image.codec.jpeg.*; 
import javax.swing.JFrame;
public class GetImageByAttachmentClient extends ImageClient
{
 
    String endPointURLString =  "http://localhost:8080/axis/servlet/GetImageByAttachment";
 public static void main(String[] args)throws Exception
 {
  new GetImageByAttachmentClient();
 }
 
 public Image getImageFromWebservice()
 {
  
        try
        {
           //创建SOAP消息
         SOAPConnectionFactory soapConnectionFactory =
                 javax.xml.soap.SOAPConnectionFactory.newInstance();
         SOAPConnection soapConnection =
                 soapConnectionFactory.createConnection();
 
         MessageFactory messageFactory =
                 MessageFactory.newInstance();
         SOAPMessage soapMessage =
                 messageFactory.createMessage();
         SOAPPart soapPart = soapMessage.getSOAPPart();
         SOAPEnvelope requestEnvelope =
             soapPart.getEnvelope();
         SOAPBody body = requestEnvelope.getBody();
         SOAPBodyElement operation = body.addBodyElement
                 (requestEnvelope.createName("getImage"));
        
         javax.xml.soap.SOAPElement element =
                         operation.addChildElement(requestEnvelope.createName("test"));
  operation.addChildElement("testgetImage").addTextNode("getImagebyAttachment_Test");
   soapMessage.writeTo(System.out);  
                //使用JAXM进行调用
    javax.xml.soap.SOAPMessage returnedSOAPMessage =
                 soapConnection.call(soapMessage, endPointURLString);
       
        System.out.println("========");
        returnedSOAPMessage.writeTo(System.out);//打印返回的SOAP消息
        System.out.println("========");
        java.util.Iterator it = returnedSOAPMessage.getAttachments();
         BufferedImage image=null ;
   //获得附件,逐个对附件进行处理
while (it.hasNext()) {
         AttachmentPart    attachment = (AttachmentPart)it.next();
     printAttachmentInfo(attachment);
     image= decodeImage(attachment.getDataHandler().getInputStream());  
   }
   return image;
  }
  catch(Exception e)
  {
   e.printStackTrace();
   return null;
  }   
 }
 //把附件解码成Image
 public BufferedImage decodeImage(java.io.InputStream in)throws java.io.IOException
 {
  BufferedImage image=null ;
  image = new BufferedImage(600,800, BufferedImage.TYPE_INT_RGB);     
     com.sun.image.codec.jpeg.JPEGImageDecoder dencoder =
JPEGCodec.createJPEGDecoder(in); 
  image=dencoder.decodeAsBufferedImage(); 
  return image;
 }
 //打印附件的一些信息
 private void printAttachmentInfo( AttachmentPart attachment)throws Exception
 {
  Object content = attachment.getContent();
  System.out.println("ContentLocation="+attachment.getContentLocation());
  System.out.println("Contentsize="+attachment.getSize());
     System.out.println("ContentType="+attachment.getContentType());
     String id = attachment.getContentId();     
  System.out.print("Attachment " + id + " contains: " +content);
 }   
}

(对于上面这段程序,请原谅我使用了一个特别庞大的getImageFromWebservice方法,并且使用了一个超级长的try{}语句,因为我实在没有时间来把它写得漂亮一点了^_^)

客户端的执行过程是这样的:

  1. 创建SOAP消息
  2. 发送SOAP消息
  3. 获得返回结果
  4. 从返回的SOAP消息中获得Attachment
  5. 对Attachment进行处理

由于一个SOAP消息中可能有多个附件,那么returnedSOAPMessage.getAttachments()方法获得的可能是一个Iterator,所以要遍历这个Iterator对SOAP消息的附件进行处理。attachment.getDataHandler().getInputStream()获得了附件的输入流,DecodeImage是从这个输入流进行获得输入,然后把它们解码成Image。这里的解码方式和BASE64解码方式稍有不同,BASE64解码方式是把String类型的对象解码成byte[],具体我们使用了sun.misc.BASE64Decoder类的decodeBuffer方法;这里的解码是把一个输入流中的数据解码成BufferedImage。

当然,这里举例的是图像的处理,如果是别的格式数据,您同样可以进行其它的处理。由于篇幅的限制,在这里就不在赘述了。你同样可以运行GetImageByAttachmentClient来测试运行的效果。需要指出的是,使用这种方式来传输图像时效率比前一种方法好,响应速度(启动客户端到在客户端打印出图像的时间)大概是使用BASE64编码速度的一倍(我的机器环境是:WinXP,AMD Athlon XP 16000+,512M内存,Tomcat 4.03),您可以在您的机器上测试,如果您的测试结果比我的相差很多,您可以通过email告诉我,到时我们可以深入讨论这个效率问题。

运行代码说明:

运行前,需要安装JWSDP1.1,您可以从http://java.sun.com/webservices下载。然后把代码(axis目录)拷贝到%JWSDP_HOME%/webapps/目录下,启动Tomcat即可。主程序在axis/WEB-INF/classes/目录下,分别是GetImageByString.java和GetImageByAttachmentClient.java。





回页首


总结

 

我们以图像数据的传输为例子,讨论了BOLB数据在SOAP消息中的表示、传输问题,如果是声音、多媒体等数据,也可以这样传输;对于CLOB数据的传输,它比BLOB数据更简单,不需要编码就可以在SOAP Body中表示、传输,同时也可以作为附件来传输。



参考资料

 

  • src.zip (2.3 MB)
  • 下载次数: 28
分享到:
评论

相关推荐

    Oracle XML开发手册

    它允许XML文档以原生XML格式存储在数据库中,或者作为BLOB、CLOB或BFILE对象存储。这使得XML数据可以高效地索引、查询和操作。 2. **XDB(XML Database)组件**:XDB是Oracle XML DB的核心,它包含一系列的存储过程...

    textern-0.8-1.el8.x64-86.rpm.tar.gz

    1、文件说明: Centos8操作系统textern-0.8-1.el8.rpm以及相关依赖,全打包为一个tar.gz压缩包 2、安装指令: #Step1、解压 tar -zxvf textern-0.8-1.el8.tar.gz #Step2、进入解压后的目录,执行安装 sudo rpm -ivh *.rpm

    基于STM32的循迹避障小车资料源码(高分项目)

    基于STM32的循迹避障小车资料源码(高分项目),个人大四的毕业设计、经导师指导并认可通过的高分设计项目,评审分99分,代码完整确保可以运行,小白也可以亲自搞定,主要针对计算机相关专业的正在做毕设的学生和需要项目实战练习的学习者,也可作为课程设计、期末大作业。 基于STM32的循迹避障小车资料源码(高分项目)基于STM32的循迹避障小车资料源码(高分项目)基于STM32的循迹避障小车资料源码(高分项目)基于STM32的循迹避障小车资料源码(高分项目)基于STM32的循迹避障小车资料源码(高分项目)基于STM32的循迹避障小车资料源码(高分项目)基于STM32的循迹避障小车资料源码(高分项目)基于STM32的循迹避障小车资料源码(高分项目)基于STM32的循迹避障小车资料源码(高分项目)基于STM32的循迹避障小车资料源码(高分项目)基于STM32的循迹避障小车资料源码(高分项目)基于STM32的循迹避障小车资料源码(高分项目)基于STM32的循迹避障小车资料源码(高分项目)基于STM32的循迹避障小车资料源码(高分项目)基于STM32的循迹避障小车资料源码(高分项目)基于STM32的循迹避障小车资料源码(高分项目)基于STM32的循迹避障小车资料源码(高分项目)基于STM32的循迹避障小车资料源码(高分项目)基于STM32的循迹避障小车资料源码(高分项目)基于STM32的循迹避障小车资料源码(高分项目)基于STM32的循迹避障小车资料源码(高分项目)基于STM32的循迹避障小车资料源码(高分项目)基于STM32的循迹避障小车资料源码(高分项目)基于STM32的循迹避障小车资料源码(高分项目)基于STM32的循迹避障小车资料源码(高分项目)基于STM32的循迹避障小车资料源码(高分项目)基于STM32的循迹避障小车资料源码(高分项目)基于STM32的循迹避障小车资料源码(

    金属板卷自动捆扎机器step_三维3D设计图纸_包括零件图_机械3D图可修改打包下载_三维3D设计图纸_包括零件图_机械3D图可修改打包下载.zip

    金属板卷自动捆扎机器step_三维3D设计图纸_包括零件图_机械3D图可修改打包下载_三维3D设计图纸_包括零件图_机械3D图可修改打包下载.zip

    【SSM框架详解】全网最全的SSM详解

    内容概要:本文详细介绍了SSM框架(Spring、SpringMVC、MyBatis)的相关知识,涵盖Maven项目管理工具、前端开发技术、HTTP协议及Tomcat服务器等内容。文章首先讲解了SSM框架的组成,包括Spring的IOC、DI、AOP等功能,SpringMVC的请求处理流程以及MyBatis的数据操作。接着介绍了Maven作为项目管理工具的作用,如依赖管理和项目构建,并详细描述了Maven的配置文件pom.xml的使用方法。此外,还探讨了HTTP协议的特点、请求响应格式,以及Web服务器Tomcat的基本概念和工作原理。最后,文章对前端开发技术进行了概述,包括HTML、CSS、JavaScript等基础知识,并简要介绍了Ajax技术。 适合人群:具备一定编程基础,特别是Java开发经验的研发人员,尤其是那些正在学习或使用SSM框架进行Web开发的工程师。 使用场景及目标:①理解SSM框架的工作原理及其各组成部分的功能;②掌握Maven的使用,包括项目创建、依赖管理、生命周期等;③熟悉HTTP协议的请求响应机制,能够处理常见的HTTP请求和响应;④掌握前端开发技术,如HTML、CSS、JavaScript等,能够进行简单的前端页面开发;⑤了解Tomcat服务器的工作原理及其配置方法。 阅读建议:本文内容丰富,涵盖了从后端到前端的多个方面,建议读者在学习过程中结合实际项目进行实践,尤其是在Maven项目管理和SSM框架的具体应用上,多动手操作,加深理解。同时,对于HTTP协议和前端开发技术,可以通过实际的网络请求和页面开发来巩固所学知识。

    JAVA源码 + SpringBoot+vue+mysql 漫画天堂网 + 数据库 + 文档

    本系统以用户与管理员两类人,作为目标用户,其中用户主要功能包含用户的注册与登录,查看漫画信息进行订阅等,对账号相关信息的修改;管理员主要功能包括了对用户信息、漫画信息、订阅信息、更新通知、在线留言、社区互动等管理;管理员可以实现最高权限级别的全系统管理。 内含文档,可轻松上手。

    工业缺陷检测领域的NEU-DET数据集及其深度学习应用

    内容概要:本文详细介绍了NEU-DET数据集,这是一个包含六种常见表面缺陷(如涂层剥落、油污、锈蚀等)的1800张灰度图像的数据集。数据集分为训练集和测试集,分别为1620张和180张。文中探讨了数据集的特点,如灰度图像的优势、标注信息的重要性以及合理的数据集划分。此外,文章展示了如何使用Python读取标注信息,并提供了使用Keras和PyTorch搭建卷积神经网络(CNN)和Faster R-CNN模型的具体代码示例,用于缺陷分类和目标检测任务。通过数据增强技术和模型优化,可以在工业缺陷检测中取得较好的效果。 适合人群:从事工业缺陷检测、计算机视觉、机器学习等相关领域的研究人员和技术人员。 使用场景及目标:适用于希望利用深度学习技术进行表面缺陷检测的研究人员。具体应用场景包括但不限于产品质量检测、自动化生产线监控等。目标是帮助用户理解和掌握如何使用NEU-DET数据集进行模型训练和评估,提高缺陷检测的准确性。 其他说明:文中提到的数据集和代码示例可以帮助初学者快速入门,同时也为高级用户提供了一些优化建议,如使用预训练模型、调整损失函数权重等。

    基于Qt/CPP的多平台二维图形编辑器:功能实现与技术细节

    内容概要:本文详细介绍了使用Qt/C++开发的一款多平台二维图形编辑器。该编辑器旨在提供简单直观的图形可视化编辑体验,主要功能包括创建和参数化图形、支持多种图类型、多样化的边与节点端口、自定义属性、动态维护交换列表、搜索功能、自动布局与导出、以及多种文件格式的支持。作者分享了项目的实现路径和技术细节,如通过QGraphicsView框架实现图形绘制、利用GraphViz引擎进行自动布局、采用QProcess处理跨平台进程通信、以及性能优化技巧等。 适合人群:对图形编辑器开发感兴趣的研发人员,尤其是熟悉或想要深入了解Qt/C++框架的开发者。 使用场景及目标:适用于需要开发或改进图形编辑工具的技术团队,帮助他们理解和掌握Qt/C++在图形编辑领域的应用,提高开发效率和产品质量。 其他说明:文中不仅展示了具体的代码片段,还分享了许多实用的经验和技巧,如避免性能瓶颈的方法、处理跨平台兼容性的注意事项等。这对于希望深入研究图形编辑技术和Qt/C++框架的开发者来说是非常宝贵的参考资料。

    A股600000浦发银行秒级训练数据集

    股票代码:A股600000浦发银行 2023年-2024年2年秒级数据,可用作训练和回测 数据内容: 时间戳(间隔10-12秒,精确到秒) 买/卖成交量 成交价 开/收盘价 最高/低价 另有类似的大盘秒级数据

    JAVA源码 + SpringBoot+vue+mysql 高校实验室预约系统 + 数据库 + 文档

    内含文档,可轻松上手。

    电路仿真:频率响应分析.zip

    电子仿真教程,从基础到精通,每个压缩包15篇教程,每篇教程5000字以上。

    冲击试验机sw22_三维3D设计图纸_包括零件图_机械3D图可修改打包下载_三维3D设计图纸_包括零件图_机械3D图可修改打包下载.zip

    冲击试验机sw22_三维3D设计图纸_包括零件图_机械3D图可修改打包下载_三维3D设计图纸_包括零件图_机械3D图可修改打包下载.zip

    各院校专业录取分数线.zip

    各院校专业录取分数线.zip

    电力电子领域逆变器VSG阻抗建模与扫频法验证的技术详解及应用

    内容概要:本文深入探讨了逆变器虚拟同步控制(VSG)技术中的阻抗建模及其验证方法。首先介绍了VSG的基本概念和技术背景,强调了正负序阻抗对系统稳定性和电能质量的影响。随后详细讲解了阻抗建模的理论基础,包括正负序阻抗的计算方法和虚拟同步发电机的序阻抗建模。接着阐述了阻抗扫描的具体步骤,包括扫描范围、点数设置以及通过扫频法在不同频率下注入小信号并测量响应的方法。文中提供了详细的Python和MATLAB代码示例,帮助读者理解和实现阻抗建模和扫描验证。最后,通过对比实测阻抗曲线和理论模型,讨论了常见问题及解决方法。 适合人群:从事电力电子、电力系统稳定性和控制的研究人员和工程师,尤其是对VSG技术和阻抗建模感兴趣的读者。 使用场景及目标:适用于需要评估逆变器在不同工况下的电气特性,确保电力系统稳定性和优化电能质量的研究和工程实践中。主要目标是掌握VSG阻抗建模和扫频法验证的理论与实践技能。 其他说明:本文不仅提供理论知识,还附带了详细的代码实现和注释,便于读者快速上手并在实际项目中应用。此外,文中提到的一些实用技巧和注意事项也有助于提高实验效率和准确性。

    c语言打字母游戏源码.zip

    c语言打字母游戏源码.zip

    基于SOGI+DQ结构的PLL锁相环在STM32G431上的实现及其MATLAB仿真

    内容概要:本文详细介绍了基于SOGI(二阶广义积分器)和DQ变换的数字锁相环(PLL)在STM32G431芯片上的实现过程,并通过MATLAB进行了仿真验证。主要内容涵盖SOGI初始化、ADC采样配置、中断服务程序设计、DQ变换以及PLL频率跟踪等关键技术环节。文中特别强调了定点运算的应用,以提高运算效率和稳定性。同时,通过MATLAB仿真展示了系统的频率跟踪性能,在40Hz-65Hz范围内能够稳定跟踪电网频率变化,误差控制在±0.2Hz以内。此外,文章还讨论了移植性和硬件适配问题,提供了详细的代码片段和调试经验。 适合人群:从事电力电子、嵌入式系统开发的技术人员,尤其是对锁相环(PLL)和SOGI+DQ结构感兴趣的工程师。 使用场景及目标:适用于需要精确频率跟踪和相位同步的应用场合,如光伏逆变器并网、电机控制系统等。目标是帮助开发者理解和实现高效的PLL算法,确保系统在复杂电网环境下的稳定运行。 其他说明:文章不仅提供了理论分析和技术实现,还包括了大量的实践经验分享,如定点运算优化、硬件适配技巧等。对于希望深入理解PLL工作原理和实际应用的读者来说,是一份非常有价值的参考资料。

    【科学计算软件】MATLAB下载安装教程:涵盖Windows与macOS系统详细步骤及验证方法

    内容概要:本文档详细介绍了 MATLAB 在 Windows 和 macOS 系统上的下载与安装步骤。首先简述了 MATLAB 的应用领域,包括科学计算、数据分析和工程仿真。接着分别针对 Windows 和 macOS 用户提供了详细的安装指南,涵盖从访问官网、下载安装程序、选择许可证类型、指定安装路径、选择工具箱到最后的激活步骤。最后,通过输入特定命令验证 MATLAB 是否安装成功,确保用户能够顺利开始使用 MATLAB 进行相关工作。; 适合人群:对科学计算、数据分析和工程仿真有需求的科研人员、工程师以及学生等。; 使用场景及目标:①科研人员和工程师在工作中进行复杂的数据处理和建模;②学生学习数学、物理等相关课程时进行实验和模拟。; 阅读建议:本教程操作性强,建议读者按照步骤逐一操作,确保每一步都正确无误。遇到问题可随时查阅官方帮助文档或社区论坛,以便顺利完成 MATLAB 的安装和激活。

    【Linux详解】常用命令与系统配置:虚拟机搭建、文件管理及网络配置详解

    内容概要:本文详细介绍了Linux操作系统的概念、特点及其常见命令,旨在帮助用户掌握Linux的基础知识和操作技能。文章首先概述了Linux的操作系统特性,如免费、稳定、高效,以及其广泛的应用领域,包括服务器和个人设备。接着介绍了Linux的安装与配置,包括虚拟机的创建、分区设置、网络配置等。随后,重点讲解了Linux命令行的基本命令,涵盖文件和目录管理、用户和权限管理、进程和服务管理等方面。此外,还涉及了远程登录、文件传输、文本编辑器(如vi/vim)、定时任务、磁盘管理、网络配置、服务管理和包管理工具(如rpm/yum)。最后简要介绍了Shell编程的基础知识,包括变量、条件判断和脚本编写。 适合人群:适合初学者和有一定经验的Linux用户,特别是希望深入了解Linux系统管理和操作的IT从业者。 使用场景及目标:①帮助用户熟悉Linux操作系统的特性和应用场景;②掌握Linux系统的基本命令和操作技巧;③学会配置和管理Linux服务器,包括文件系统、用户权限、网络设置和服务管理;④能够编写简单的Shell脚本来自动化日常任务。 阅读建议:由于本文内容丰富且涉及面广,建议读者在学习过程中结合实际操作进行练习,特别是在命令行操作、文件管理、用户权限设置和Shell编程方面。对于复杂命令和概念,可以通过查阅官方文档或在线资源进一步加深理解。

    现代控制理论中倒立摆系统的MATLAB仿真及状态观测器与状态反馈控制设计

    内容概要:本文详细介绍了基于MATLAB的倒立摆系统状态观测器和状态反馈控制的设计与仿真。首先建立了倒立摆系统的状态空间模型,并验证了系统的能控性。然后利用LQR方法设计了状态反馈控制器,确保系统稳定并优化控制效果。接着设计了状态观测器,用于估计无法直接测量的状态变量。文中还讨论了观测器和控制器之间的协调设计,以及仿真过程中的一些注意事项和技术细节。最终通过Simulink进行了详细的仿真测试,展示了状态估计误差的快速收敛和系统的良好动态性能。 适合人群:从事控制系统设计的研究人员、工程师以及相关专业的高年级本科生和研究生。 使用场景及目标:适用于需要理解和掌握现代控制理论中状态观测器和状态反馈控制设计的实际应用场合,尤其是涉及复杂多变量系统的控制问题。目标是帮助读者深入理解这两者的协同工作原理及其在实际工程项目中的应用。 其他说明:文中提供了大量MATLAB代码片段,便于读者动手实践。同时强调了在实际工程应用中需要注意的问题,如参数选择、数值计算稳定性等。此外,还探讨了一些高级话题,如鲁棒性和非线性观测器的应用前景。

Global site tag (gtag.js) - Google Analytics