jCO--http://www.cnblogs.com/zfswff/p/5671148.html

2024-06-23 11:38

本文主要是介绍jCO--http://www.cnblogs.com/zfswff/p/5671148.html,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

SAP接口编程 之 JCo3.0系列(01):JCoDestination

字数2101 阅读103 评论0 

JCo3.0是Java语言与ABAP语言双向通讯的中间件。与之前1.0/2.0相比,是重新设计的产品。API和架构设计与NCo3.0比较类似,前面也说过,NCo3.0的设计参考了JCo3.0。从本篇开始,系统介绍JCo3.0编程的技术要点。

JCo3.0安装

从https://service.sap.com/connectors 可以下载JCo3.0,注意下载的时候根据操作系统JVM版本(32位还是64)选择不同的版本。安装就是解压,将文件解压到目标文件夹。以Windows系统为例,主要的文件包括:

sapjco3.dll
sapjco3.jar

SAP强烈推荐将这两个文件放在同一文件夹下。测试安装是否成功,可以在命令窗口下,进入安装文件夹,运行下面的命令:

java -jar sapjco3.jar

如果安装成功,应该显示如下界面:

id="iframe_0.16730619855632956" src="data:text/html;charset=utf8,%3Cimg%20id=%22img%22%20src=%22http://upload-images.jianshu.io/upload_images/1765749-7e0730f1f0f37a62.png?imageMogr2/auto-orient/strip%257CimageView2/2/w/1240&_=5670223%22%20style=%22border:none;max-width:999px%22%3E%3Cscript%3Ewindow.onload%20=%20function%20()%20%7Bvar%20img%20=%20document.getElementById('img');%20window.parent.postMessage(%7BiframeId:'iframe_0.16730619855632956',width:img.width,height:img.height%7D,%20'http://www.cnblogs.com');%7D%3C/script%3E" frameborder="0" scrolling="no" style="margin: 0px; padding: 0px; border: none; width: 392px; height: 450px;">
jco3安装成功的显示界面

JCoDestination

JCoDestination代表后台SAP系统,程序员不用关心与SAP的连接,jco3.0运行时环境负责管理连接和释放连接。我们先以一个简单的例子看看jco3.0 JCoDestination类的一些要点。

我使用的编程环境是Eclipse,环境准备如下:

  • 新建一个Java项目,项目名为JCo3Demo。
  • 将sapjco3.jar加入到项目的build path中。注意前面所说的sapjco3.jar和sapjco3.dll要放在同一个文件夹下。
  • 在Eclipse Java项目文件夹下,新建一个文本文件,文件名命名为ECC.jocdestination, 文件的内容如下(SAP系统的连接参数的设置):

    #SAP Logon parameters!
    #Tue Dec 08 16:41:30 CST 2015
    jco.client.lang=EN
    jco.client.client=001
    jco.client.passwd=xxxxxx
    jco.client.user=STONE
    jco.client.sysnr=00
    jco.client.ashost=192.168.65.100

对照SAP GUI,不难理解:

id="iframe_0.6278244840647245" src="data:text/html;charset=utf8,%3Cimg%20id=%22img%22%20src=%22http://upload-images.jianshu.io/upload_images/1765749-97643b097b86c2a3.jpg?imageMogr2/auto-orient/strip%257CimageView2/2/w/1240&_=5670223%22%20style=%22border:none;max-width:999px%22%3E%3Cscript%3Ewindow.onload%20=%20function%20()%20%7Bvar%20img%20=%20document.getElementById('img');%20window.parent.postMessage(%7BiframeId:'iframe_0.6278244840647245',width:img.width,height:img.height%7D,%20'http://www.cnblogs.com');%7D%3C/script%3E" frameborder="0" scrolling="no" style="margin: 0px; padding: 0px; border: none; width: 540px; height: 556px;">
SAP GUI

环境准备好了,先来一段最简单的代码:

package jco3.demo1;import java.util.Properties;
import org.junit.Test;
import com.sap.conn.jco.JCoDestination; import com.sap.conn.jco.JCoDestinationManager; import com.sap.conn.jco.JCoException; public class JCoDestinationDemo { public JCoDestination getDestination() throws JCoException { /** * Get instance of JCoDestination from file: ECC.jcodestination * which should be located in the installation folder of project */ JCoDestination dest = JCoDestinationManager.getDestination("ECC"); return dest; } @Test public void pingDestination() throws JCoException { JCoDestination dest = this.getDestination(); dest.ping(); } }

代码说明:

  • getDestination()方法中,JCoDestinationManager.getDestination("ECC")从ECC.jcodestination文件中获取连接参数,创建JCoDestination对象的实例。
    这里有一个重要的约定,JCoDestinationManager.getDestination("ECC")方法,会从Eclipse Java项目的根目录,查找ECC.jcodestination文件(文件路径和扩展名不能改变)是否存在,如果存在,从文件的内容中获取连接参数。这是DestinationDataProvider接口的一个默认实现,在开发和测试的时候还是很方便的,但如果在真实项目中使用,安全性和灵活性就不够。后面会介绍解决方法。

  • pingDestination()方法调用JcoDestination对象的ping()方法测试SAP系统的连接。

  • @Test: 使用junit进行测试

配置文件的生成

刚才我们手工编辑了ECC.jcodestination文件,对于这个配置文件,因为很多连接参数来自于DestinationDataProvider接口,如果想通过代码来创建配置文件,可以使用如下代码:

package jco3.demo2;import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream; import java.io.IOException; import java.util.Properties; import org.junit.Test; import com.sap.conn.jco.ext.DestinationDataProvider; public class DestinationFile { private Properties setProperties() { // logon parameters and other properties Properties connProps = new Properties(); connProps.setProperty(DestinationDataProvider.JCO_ASHOST, "192.168.65.100"); connProps.setProperty(DestinationDataProvider.JCO_SYSNR, "00"); connProps.setProperty(DestinationDataProvider.JCO_USER, "STONE"); connProps.setProperty(DestinationDataProvider.JCO_PASSWD, "xxxxxx"); connProps.setProperty(DestinationDataProvider.JCO_CLIENT, "001"); connProps.setProperty(DestinationDataProvider.JCO_LANG, "EN"); return connProps; } private void doCreateFile(String fName, String suffix, Properties props) throws IOException { /** * Write contents of properties into a text file * which was named [fName+suffix.jcodestination] */ File cfg = new File(fName+"."+suffix); if (!cfg.exists()){ // file not exists // Create file output stream, not using append mode FileOutputStream fOutputStream = new FileOutputStream(cfg, false); // store the properties in file output stream // and also add comments props.store(fOutputStream, "SAP logon parameters:"); fOutputStream.close(); }else{ throw new RuntimeException("File alreay exists."); } } @Test public void createConfigFile() throws IOException { Properties props = this.setProperties(); String fileName = "SAP_AS"; // sap application server // jcodestination suffix is required by JCoDestinationManager this.doCreateFile(fileName, "jcodestination", props); } }

代码说明:

  • setProperties()方法属性参照DestinationDataProvider类的常量设置Properties的实例。
  • doCreateFile()方法根据需求的文件名,扩展名在Eclipse项目的根文件夹下,创建一个文本文件,文件的内容就是Properties实例的内容。
  • createConfigFile()方法,调用上面的两个方法,创建配置文件。

更改配置文件名的路径和扩展名

我们看到,默认情况下,SAP对配置文件的路径和扩展名都不能改变,如果我们想把文件放在任意位置,扩展名也使用其他的扩展名,有没有办法?答案是有,方法是实现DestinationDataProvider接口,并改写(override)getDestinationProperties()方法,然后通过Environment.registerDestinationDataProvider()方法进行注册。

OK, 一起来看看代码,代码分为三个部分:

  • 第一部分: 创建FileDestinationDataProviderImp类,实现DestinationDataProvider接口
  • 第二部分: 创建FileDestinationDataProvider类,注册FileDestinationDataProviderImp的实例,并提供getDestination()方法供调用
  • 第三部分:调用FileDestinationDataProvider类的getDestination()方法

第一部分:DestinationDataProvider接口的实现:

package jco3.demo2;import java.io.File;
import java.io.FileInputStream;
import java.io.IOException; import java.util.Properties; import com.sap.conn.jco.ext.DestinationDataEventListener; import com.sap.conn.jco.ext.DestinationDataProvider; public class FileDestinationDataProviderImp implements DestinationDataProvider { private File dir; private String destName; // destination name private String suffix; public void setDestinationFile(File dir, String destName, String suffix) { this.dir = dir; this.destName = destName; this.suffix = suffix; } private Properties loadProperties(File dir, String destName, String suffix) throws IOException { Properties props = null; // create a file with name: fullName in destDirectory File destFile = new File(dir, destName+"."+suffix); if (destFile.exists()){ FileInputStream fInputStream = new FileInputStream(destFile); props = new Properties(); props.load(fInputStream); fInputStream.close(); }else{ throw new RuntimeException("Destination file does not exist."); } return props; } @Override public Properties getDestinationProperties(String destName) { Properties props = null; try { props = this.loadProperties(this.dir, this.destName, this.suffix); } catch (IOException e) { e.printStackTrace(); } return props; } @Override public void setDestinationDataEventListener(DestinationDataEventListener listener) { throw new UnsupportedOperationException(); } @Override public boolean supportsEvents() { return false; } }

第二部分: 创建FileDestinationDataProvider类,注册FileDestinationDataProviderImp的实例,并且提供getDestination()方法。

package jco3.demo2;import java.io.File;
import com.sap.conn.jco.JCoDestination;
import com.sap.conn.jco.JCoDestinationManager;
import com.sap.conn.jco.JCoException; import com.sap.conn.jco.ext.Environment; public class FileDestinationDataProvider { public static JCoDestination getDestination() throws JCoException { File directory = new File("."); // current directory; String fileName = "SAP_AS"; String suffix = "txt"; FileDestinationDataProviderImp destDataProvider = new FileDestinationDataProviderImp(); destDataProvider.setDestinationFile(directory, fileName, suffix); Environment.registerDestinationDataProvider(destDataProvider); JCoDestination dest = JCoDestinationManager.getDestination(fileName); return dest; } }

我们看到,getDestination方法中,文件的路径,文件的扩展名,都是我们自己定义的。文件名作为JCoDestinationManager.getDestination方法的destination name。从这里也可可以看到,JCoDestinationManager.getDestination方法从哪里查找连接参数,是依赖于Environment注册的DestinationDataProvider实现

第三部分:测试代码FileDestinationDataProvidergetDestination方法:

package jco3.demo2;import org.junit.Test;
import com.sap.conn.jco.JCoDestination;
import com.sap.conn.jco.JCoException; public class TestFileDestinationProvider { @Test public void pingSAPDestination() throws JCoException { JCoDestination dest = FileDestinationDataProvider.getDestination(); dest.ping(); } }

DestinationDataProvider另一种实现

记得nco3.0可以将登陆参数写在代码中吗,如果我们也想将连接参数直接写在代码中,怎么做呢?刚才说过了,关键就是实现DestinationDataProvider接口,并改写getDestinationProperties()方法。不多说,上代码。

第一部分:DestinationDataProvider接口实现

package jco3.demo3;import java.util.HashMap;
import java.util.Map;
import java.util.Properties; import com.sap.conn.jco.ext.DestinationDataEventListener; import com.sap.conn.jco.ext.DestinationDataProvider; public class DestinationDataProviderImp implements DestinationDataProvider { /** * DestinationDataProvider is an interface * We define DestinationDataProviderImp class to implements this interface * so that we can define the logon parameters more flexibly * not just in xxx.jcodestionation file. * * The key point is that we override getDestinationProperties() method * Afterwards, instance of DestinationDataProvider should be registered * using Environment.registerDestinationDataProvider() method to take effect */ @SuppressWarnings("rawtypes") private Map provider = new HashMap(); @SuppressWarnings("unchecked") public void addDestinationProperties(String destName, Properties props) { provider.put(destName, props); } @Override public Properties getDestinationProperties(String destName) { if (destName == null){ throw new NullPointerException("Destinantion name is empty."); } if (provider.size() == 0){ throw new IllegalStateException("Data provider is empty."); } return (Properties) provider.get(destName); } @Override public void setDestinationDataEventListener(DestinationDataEventListener listener) { throw new UnsupportedOperationException(); } @Override public boolean supportsEvents() { return false; } }

第二部分:创建DestinationProivder类,提供getDestination()方法,注册DestinationDataProviderImp类的实例:

package jco3.demo3;import java.util.Properties;
import com.sap.conn.jco.JCoDestination;
import com.sap.conn.jco.JCoDestinationManager; import com.sap.conn.jco.JCoException; import com.sap.conn.jco.ext.DestinationDataProvider; import com.sap.conn.jco.ext.Environment; public class DestinationProvider { private static Properties setProperties() { // logon parameters and other properties Properties connProps = new Properties(); connProps.setProperty(DestinationDataProvider.JCO_ASHOST, "192.168.65.100"); connProps.setProperty(DestinationDataProvider.JCO_SYSNR, "00"); connProps.setProperty(DestinationDataProvider.JCO_USER, "STONE"); connProps.setProperty(DestinationDataProvider.JCO_PASSWD, "xxxxxx"); connProps.setProperty(DestinationDataProvider.JCO_CLIENT, "001"); connProps.setProperty(DestinationDataProvider.JCO_LANG, "EN"); return connProps; } public static JCoDestination getDestination() throws JCoException { String destName = "SAP_AS"; Properties props = setProperties(); DestinationDataProviderImp destDataProvider = new DestinationDataProviderImp(); destDataProvider.addDestinationProperties(destName, props); Environment.registerDestinationDataProvider(destDataProvider); JCoDestination dest = JCoDestinationManager.getDestination(destName); return dest; } }

第三部分:测试DestinationProvidergetDestination()方法:

package jco3.demo3;import org.junit.Test;
import com.sap.conn.jco.JCoDestination;
import com.sap.conn.jco.JCoException; public class TestDestionProvider { @Test public void pingSAPDestination() throws JCoException { JCoDestination dest = DestinationProvider.getDestination(); dest.ping(); } }
 

JCo3.0调用SAP函数的过程

大致可以总结为以下步骤:

  • 连接至SAP系统
  • 创建JcoFunction接口的实例(这个实例代表SAP系统中相关函数)
  • 设置importing参数
  • 调用函数
  • 从exporting参数或者table参数获取数据

代码:

package jco3.demo4;import org.junit.Test;
import com.sap.conn.jco.JCoDestination;
import com.sap.conn.jco.JCoDestinationManager; import com.sap.conn.jco.JCoException; import com.sap.conn.jco.JCoField; import com.sap.conn.jco.JCoFunction; import com.sap.conn.jco.JCoRepository; import com.sap.conn.jco.JCoStructure; public class RFC { public void getCompanyCodeDetail(String cocd) throws JCoException { // JCoDestination instance represents the backend SAP system JCoDestination dest = JCoDestinationManager.getDestination("ECC"); // JCoFunction instance is the FM in SAP we will use JCoRepository repository = dest.getRepository(); JCoFunction fm = repository.getFunction("BAPI_COMPANYCODE_GETDETAIL"); if (fm == null){ throw new RuntimeException("Function does not exists in SAP system."); } // set import parameter(s) fm.getImportParameterList().setValue("COMPANYCODEID", cocd); // call function fm.execute(dest); // get company code detail from exporting parameter 'COMPANYCODE_DETAIL' JCoStructure cocdDetail = fm.getExportParameterList() .getStructure("COMPANYCODE_DETAIL"); this.printStructure(cocdDetail); } private void printStructure(JCoStructure jcoStru) { for(JCoField field : jcoStru){ System.out.println(String.format("%s\\t%s", field.getName(), field.getString())); } } @Test public void test() throws JCoException { this.getCompanyCodeDetail("Z900"); } }

JCoFunction接口说明

  • JCoFunction是一个接口,代表SAP系统的函数

  • JCoFunction包含importing参数,exporting参数,changing参数,table参数。分别使用getImportParameterList方法,getExportParameterList方法,getChangingParameterList方法和getTableParameterList获得。这些方法的返回值都是JCoParameter类型

  • JCoFunction.execute方法实际执行函数

如何创建JCoFunction对象

上面的代码是第一种创建JCoFunction实例的方法:

JCoRepository repository = dest.getRepository();    
JCoFunction fm = dest.getRepository().getFunction("BAPI_COMPANYCODE_GETDETAIL");

如果我们不关心JCoRepository,也可以这样写:

JCoFunction fm = dest.getRepository().getFunction("BAPI_COMPANYCODE_GETDETAIL");

第三种方法是使用JCoFunctionTemplate.getFunction方法,JCoFunctionTemplate也是一个接口,代表SAP函数的meta-data。

JCoFunctionTemplate fmTemplate = dest.getRepository().getFunctionTemplate("BAPI_COMPANYCODE_GETDETAIL");
JCoFunction fm = fmTemplate.getFunction();

JCoStructure接口

BAPI_COMPANY_CODE_GETDETAIL函数的COMPANYCODE_DETAIL参数是一个结构,刚才我们看到遍历结构所有字段的方式:

private void printStructure(JCoStructure jcoStru) { for(JCoField field : jcoStru){ System.out.println(String.format("%s\\t%s", field.getName(), field.getString())); } }

因为JCoStructure实现了Iterable接口,所以可以采取上面的办法进行迭代。另外一种方法进行遍历:

private void printStructure2(JCoStructure jcoStructure) { for (int i = 0; i < jcoStructure.getMetaData().getFieldCount(); i++){ System.out.println(String.format("%s\\t%s", jcoStructure.getMetaData().getName(i), jcoStructure.getString(i))); } }

BAPI_COMPANYCODE_GETDETAIL是一个适合演示的函数,没有import paramter参数,调用后COMPANYCODE_GETDETAIL 表参数返回SAP系统中所有公司代码的清单。只包括公司代码ID和公司代码名称两个字段。

JCo中,与表参数相关的两个接口是JCoTableJCoRecordMetaDtaJCoTable就是RFM中tabl参数,而JCoRecordMetaDtaJCoTableJCoStructure的元数据。

在.net环境中,我喜欢将IRfcTable转换成DataTable,但Java没有类似的数据结构,所以决定直接在方法中传递JCoTable算了。但为了方便显示,可以考虑使用一个通用代码进行输出:

package jco3.utils;import com.sap.conn.jco.JCoField;
import com.sap.conn.jco.JCoRecordMetaData;
import com.sap.conn.jco.JCoTable;public class JCoUtils
{public static void printJCoTable(JCoTable jcoTable) { // header // JCoRecordMeataData is the meta data of either a structure or a table. // Each element describes a field of the structure or table. JCoRecordMetaData tableMeta = jcoTable.getRecordMetaData(); for(int i = 0; i < tableMeta.getFieldCount(); i++){ System.out.print(String.format("%s\t", tableMeta.getName(i))); } System.out.println(); // new line // line items for(int i = 0; i < jcoTable.getNumRows(); i++){ // Sets the row pointer to the specified position(beginning from zero) jcoTable.setRow(i); // Each line is of type JCoStructure for(JCoField fld : jcoTable){ System.out.print(String.format("%s\t", fld.getValue())); } System.out.println(); } } }

要点说明

对JCoTable,输出表头和行项目。表头通过获取JCoTable的meta-data,然后使用meta-data的getName()方法。

JCoRecordMetaData tableMeta = jcoTable.getRecordMetaData();        
for(int i = 0; i < tableMeta.getFieldCount(); i++){System.out.print(String.format("%s\t", tableMeta.getName(i))); }

JCoTable每一行都是一个JCoStructure,可以通过setRow()设置指针的位置,然后再遍历各个field:

        for(int i = 0; i < jcoTable.getNumRows(); i++){// Sets the row pointer to the specified position(beginning from zero) jcoTable.setRow(i); // Each line is of type JCoStructure for(JCoField fld : jcoTable){ System.out.print(String.format("%s\t", fld.getValue())); } System.out.println(); }

完成输出之后,接下来就是RFM调用:

package jco3.demo5;import org.junit.Test;
import com.sap.conn.jco.*;
import jco3.utils.JCoUtils; public class JCoTableDemo { public JCoTable getCocdList() throws JCoException { /** * Get company code list in SAP * using BAPI BAPI_COMPANYCODE_GETLIST. * * Since JCoTable is rather flexible, we simply use * this interface as return value */ JCoDestination dest = JCoDestinationManager.getDestination("ECC"); JCoFunction fm = dest.getRepository().getFunction("BAPI_COMPANYCODE_GETLIST"); fm.execute(dest); JCoTable companies = fm.getTableParameterList().getTable("COMPANYCODE_LIST"); return companies; } @Test public void printCompanies() throws JCoException { JCoTable companies = this.getCocdList(); JCoUtils.printJCoTable(companies); } }

Table参数作为import parameter

table作为输入参数,主要解决填充table的问题,基本模式如下:

someTable.appendRow();
someTable.setValue("FLDNAME", someValue);

以RFC_READ_TABLE为例,读取SAP USR04表。

package jco3.demo5;import org.junit.Test;
import com.sap.conn.jco.*;
import jco3.utils.JCoUtils; public class JCoTableAsImport { public JCoTable readTable() throws JCoException { /** * Shows how to process JCoTable (as importing) */ JCoDestination dest = JCoDestinationManager.getDestination("ECC"); JCoFunction fm = dest.getRepository().getFunction("RFC_READ_TABLE"); // table we want to query is USR04 // which is user authorization table in SAP fm.getImportParameterList().setValue("QUERY_TABLE", "USR04"); // output data will be delimited by comma fm.getImportParameterList().setValue("DELIMITER", ","); // processing table parameters JCoTable options = fm.getTableParameterList().getTable("OPTIONS"); // modification date >= 2012.01.01 and <= 2015.12.31 options.appendRow(); options.setValue("TEXT", "MODDA GE '20120101' "); options.appendRow(); options.setValue("TEXT", "AND MODDA LE '20151231' "); // We only care about fields of [user id] and [modification date] String[] outputFields = new String[] {"BNAME", "MODDA"}; JCoTable fields = fm.getTableParameterList().getTable("FIELDS"); int count = outputFields.length; fields.appendRows(count); for (int i = 0; i < count; i++){ fields.setRow(i); fields.setValue("FIELDNAME", outputFields[i]); } fm.execute(dest); JCoTable data = fm.getTableParameterList().getTable("DATA"); return data; } @Test public void printUsers() throws JCoException { JCoTable users = this.readTable(); JCoUtils.printJCoTable(users); } }

在代码中我们使用了两种方法来插入table的行项目,第一种方法:

JCoTable options = fm.getTableParameterList().getTable("OPTIONS");
// modification date >= 2012.01.01 and <= 2015.12.31 options.appendRow(); options.setValue("TEXT", "MODDA GE '20120101' "); options.appendRow(); options.setValue("TEXT", "AND MODDA LE '20151231' ");

第二种方法:

String[] outputFields = new String[] {"BNAME", "MODDA"};
JCoTable fields = fm.getTableParameterList().getTable("FIELDS"); int count = outputFields.length; fields.appendRows(count); for (int i = 0; i < count; i++){ fields.setRow(i); fields.setValue("FIELDNAME", outputFields[i]); }

JCoTable重要方法总结

id="iframe_0.6286778007291249" src="data:text/html;charset=utf8,%3Cimg%20id=%22img%22%20src=%22http://upload-images.jianshu.io/upload_images/1765749-980063a33463da2f.gif?imageMogr2/auto-orient/strip&_=5671148%22%20style=%22border:none;max-width:999px%22%3E%3Cscript%3Ewindow.onload%20=%20function%20()%20%7Bvar%20img%20=%20document.getElementById('img');%20window.parent.postMessage(%7BiframeId:'iframe_0.6286778007291249',width:img.width,height:img.height%7D,%20'http://www.cnblogs.com');%7D%3C/script%3E" frameborder="0" scrolling="no" style="margin: 0px; padding: 0px; border: none; width: 629px; height: 472px;">
jcoTable_methods.gif


这篇关于jCO--http://www.cnblogs.com/zfswff/p/5671148.html的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1087049

相关文章

Vue3 的 shallowRef 和 shallowReactive:优化性能

大家对 Vue3 的 ref 和 reactive 都很熟悉,那么对 shallowRef 和 shallowReactive 是否了解呢? 在编程和数据结构中,“shallow”(浅层)通常指对数据结构的最外层进行操作,而不递归地处理其内部或嵌套的数据。这种处理方式关注的是数据结构的第一层属性或元素,而忽略更深层次的嵌套内容。 1. 浅层与深层的对比 1.1 浅层(Shallow) 定义

这15个Vue指令,让你的项目开发爽到爆

1. V-Hotkey 仓库地址: github.com/Dafrok/v-ho… Demo: 戳这里 https://dafrok.github.io/v-hotkey 安装: npm install --save v-hotkey 这个指令可以给组件绑定一个或多个快捷键。你想要通过按下 Escape 键后隐藏某个组件,按住 Control 和回车键再显示它吗?小菜一碟: <template

【 html+css 绚丽Loading 】000046 三才归元阵

前言:哈喽,大家好,今天给大家分享html+css 绚丽Loading!并提供具体代码帮助大家深入理解,彻底掌握!创作不易,如果能帮助到大家或者给大家一些灵感和启发,欢迎收藏+关注哦 💕 目录 📚一、效果📚二、信息💡1.简介:💡2.外观描述:💡3.使用方式:💡4.战斗方式:💡5.提升:💡6.传说: 📚三、源代码,上代码,可以直接复制使用🎥效果🗂️目录✍️

【前端学习】AntV G6-08 深入图形与图形分组、自定义节点、节点动画(下)

【课程链接】 AntV G6:深入图形与图形分组、自定义节点、节点动画(下)_哔哩哔哩_bilibili 本章十吾老师讲解了一个复杂的自定义节点中,应该怎样去计算和绘制图形,如何给一个图形制作不间断的动画,以及在鼠标事件之后产生动画。(有点难,需要好好理解) <!DOCTYPE html><html><head><meta charset="UTF-8"><title>06

BUUCTF靶场[web][极客大挑战 2019]Http、[HCTF 2018]admin

目录   [web][极客大挑战 2019]Http 考点:Referer协议、UA协议、X-Forwarded-For协议 [web][HCTF 2018]admin 考点:弱密码字典爆破 四种方法:   [web][极客大挑战 2019]Http 考点:Referer协议、UA协议、X-Forwarded-For协议 访问环境 老规矩,我们先查看源代码

计算机毕业设计 大学志愿填报系统 Java+SpringBoot+Vue 前后端分离 文档报告 代码讲解 安装调试

🍊作者:计算机编程-吉哥 🍊简介:专业从事JavaWeb程序开发,微信小程序开发,定制化项目、 源码、代码讲解、文档撰写、ppt制作。做自己喜欢的事,生活就是快乐的。 🍊心愿:点赞 👍 收藏 ⭐评论 📝 🍅 文末获取源码联系 👇🏻 精彩专栏推荐订阅 👇🏻 不然下次找不到哟~Java毕业设计项目~热门选题推荐《1000套》 目录 1.技术选型 2.开发工具 3.功能

Vue3项目开发——新闻发布管理系统(六)

文章目录 八、首页设计开发1、页面设计2、登录访问拦截实现3、用户基本信息显示①封装用户基本信息获取接口②用户基本信息存储③用户基本信息调用④用户基本信息动态渲染 4、退出功能实现①注册点击事件②添加退出功能③数据清理 5、代码下载 八、首页设计开发 登录成功后,系统就进入了首页。接下来,也就进行首页的开发了。 1、页面设计 系统页面主要分为三部分,左侧为系统的菜单栏,右侧

【Linux】应用层http协议

一、HTTP协议 1.1 简要介绍一下HTTP        我们在网络的应用层中可以自己定义协议,但是,已经有大佬定义了一些现成的,非常好用的应用层协议,供我们直接使用,HTTP(超文本传输协议)就是其中之一。        在互联网世界中,HTTP(超文本传输协议)是一个至关重要的协议,他定义了客户端(如浏览器)与服务器之间如何进行通信,以交换或者传输超文本(比如HTML文档)。

【VUE】跨域问题的概念,以及解决方法。

目录 1.跨域概念 2.解决方法 2.1 配置网络请求代理 2.2 使用@CrossOrigin 注解 2.3 通过配置文件实现跨域 2.4 添加 CorsWebFilter 来解决跨域问题 1.跨域概念 跨域问题是由于浏览器实施了同源策略,该策略要求请求的域名、协议和端口必须与提供资源的服务相同。如果不相同,则需要服务器显式地允许这种跨域请求。一般在springbo

HTML提交表单给python

python 代码 from flask import Flask, request, render_template, redirect, url_forapp = Flask(__name__)@app.route('/')def form():# 渲染表单页面return render_template('./index.html')@app.route('/submit_form',