精华内容
下载资源
问答
  • 涂鸦方案门锁的云云对接文档。
  • 什么是视频监控平台的平台对接

    千次阅读 2020-04-23 09:18:48
    比如上级平台要看下级平台的视频,那我们需要将下级平台对接到上级平台,那究竟什么叫平台对接呢,下面我们来大概解释一下。 所谓上、下平台对接就是,通过协议(国标协议、私有协议)向下级平台拉取数据(包含设备信息...

    视频监控平台通常别分为多个级:上级、本级、同级(平级)、下级。
    而在这些不同级之间,我们需要产生一定的联系,也就是所谓的级联。比如上级平台要看下级平台的视频,那我们需要将下级平台对接到上级平台,那究竟什么叫平台对接呢,下面我们来大概解释一下。
    所谓上、下平台对接就是,通过协议(国标协议、私有协议)向下级平台拉取数据(包含设备信息、码流等),然后讲这些数据推送到上级平台。那么如何向下级拉取这些数据呢,首先下级平台如果是国标平台,那么直接通过国标协议拉取,但如果是私有协议呢,那下级平台就需要封装API,通过api拉取,拉取到数据后,中间层也封装API,上级平台调用api,然后进行数据推送。

    展开全文
  • 中的res是什么意思? res这个参数可以理解为一个Object。 res.data指服务器返回的内容。res参数还有其他的属性,比如statusCode(指开发者服务器返回的 HTTP 状态码),还有header(指开发者服务器返回的 ...

    对接后端接口时success: (res)=>中的res是什么意思?

    res这个参数可以理解为一个Object。 res.data指服务器返回的内容。res参数还有其他的属性,比如statusCode(指开发者服务器返回的 HTTP 状态码),还有header(指开发者服务器返回的 HTTP Response Header)。

    展开全文
  • 浅谈数据对接

    千次阅读 2020-03-16 15:47:19
    浅谈数据对接 一般来讲,数据对接就是将己方收集到的客户数据转化为平台方的规范要求的数据格式上传的一种方式。各个平台对于数据的要求格式各不相同。那怎么才能快速做好数据对接,而且重复劳动尽量少地完成,返工...

    浅谈数据对接

    	一般来讲,数据对接就是将己方收集到的客户数据转化为平台方的规范要求的数据格式上传的一种方式。各个平台对于数据的要求格式各不相同。那怎么才能快速做好数据对接,而且重复劳动尽量少地完成,返工也要尽量少。我觉得要分几个步骤去进行。切记不能一头热栽在文档上,死命地对,很可能你的接口后期要崩死,考虑平台方的修改和己方数据的缺失或者并不完全符合的情况。
    1.粗略看下对接文档和客户需求(这个必须看,不看后期等着改死吧)。特别对日期敏感,数据对接很可能为了验收  ,有一段日期里的数据特别重要。
    2.了解收集到的客户数据,并将字段和了解到的对接文档字段一一对应。对于编码一定要重视,一般数据上传失败会在这里栽跟头。
    3.等了解了己方数据库字段和文档的对应关系后,别急着下手。还有一步是一定要做的。查看数据库的垃圾数据,想必大家都知道,但凡数据大了之后,总有垃圾数据会在上传的时候影响上传的数据的准确性。当然会有人建立日志去记录,上传数据的成功率。但是去搜索日志需要耗费精力,还要去确定问题的根源,会浪费大量时间。与其去后期处理,不如预先做好预防,提前将垃圾数据给筛掉,保证数据上传的精确。
    4.前面工作做完才能安心码代码编写接口将数据上传。
    

    下面举个例子 (后台框架mybatis+mvc)
    对接方式 :导出txt (昨天的数据) 再上传平台
    后台sql

        <select id="getMeatTzInHz" resultType="net.***.**.platform.meat.entity.MeatTzInHz">
    		SELECT
    			instock.slaughterCode,
    			instock.instockDate,
    			SUM(instock.checkInstockNum),
    			AVG(instock.price) 				AS price,
    			SUM(instock.quantityAndWeight)  AS quantityAndWeight,
    			SUM(instock.transportDeathNum)  AS transportDeathNum,
    			produceCode
    		FROM (
                     SELECT
                        COALESCE(trace_mainbody_employee.mainbody_record_info :: JSON ->> 'meatCommerceCode', '')  AS slaughterCode,
                        --主体编码
                        COALESCE(trace_mainbody_employee.mainbody_name, '')                                    AS slaughterName,
                        --主体名称
                        TO_CHAR(trace_instock.instock_date,'yyyyMMdd')                  		    AS instockDate,
                        --进场日期
                        COALESCE(substr(trace_mainbody_provider.mainbody_record_info :: JSON ->> 'commerceCode',1,9), '') AS ownerCode,
                        --货主编码
                        COALESCE(trace_mainbody_provider.mainbody_name, '')                               		 AS ownerName,
                        --货主名称
                        COALESCE(trace_batch.inspection_info :: JSON ->> 'CitypfTzPigCertCode', '')       		 AS checkCertCode,
                        --生猪产地检疫证号,--json格式要得到CitypfTzPigCertCode
                        CAST(COALESCE(trace_batch.batch_other_info :: JSON ->> 'detectionQuantity', '0') AS int) AS checkInstockNum,
                        --检疫证进场数量,--json格式要得到CitypfTzQuarantineCount
                        COALESCE(trace_batch.batch_price, 0)                                              		 AS price,
                        --批次单价
                        COALESCE(trace_batch.batch_quantity, 0)                                           		 AS quantityAndWeight
    
                        FROM
                            t_trace_instock trace_instock --入库基础
                            INNER JOIN t_trace_instock_detail trace_instock_detail
                        ON (
                            trace_instock.ID = trace_instock_detail.instock_id
                            AND trace_instock_detail.del_flg = '0'
                            )
                            INNER JOIN t_trace_mainbody trace_mainbody_employee --企业表
                            ON (
                            trace_mainbody_employee.trace_mainbody_code = trace_instock.trace_mainbody_code
                            AND trace_mainbody_employee.mainbody_type in ('101')
                            AND trace_mainbody_employee.del_flg = '0'
                            AND trace_mainbody_employee.mainbody_record_info :: JSON ->> 'meatCommerceCode' != ''
    						<if test="division != null and division != ''">
    							  AND split_part(trace_mainbody_employee.mainbody_record_info :: JSON ->> 'divisionName',',',2) like ('%' || #{division,jdbcType = VARCHAR} || '%')
    						</if>
    						<if test="mainBodyCode != null and mainBodyCode != ''">
    							AND main.mainbody_code = #{mainBodyCode,jdbcType = VARCHAR}
    						</if>
                            )
                            LEFT JOIN t_trace_mainbody trace_mainbody_provider --供应商表
                            ON (
                            trace_mainbody_provider.mainbody_code = trace_instock.supplier_code
                            AND trace_mainbody_provider.mainbody_type = '102'
                            AND trace_mainbody_provider.del_flg = '0'
                            )
                            INNER JOIN t_trace_batch trace_batch --批次表
                            ON (
                            trace_batch.batch_code = trace_instock_detail.batch_code
                            AND trace_batch.del_flg = '0'
                            )
                        WHERE
                            trace_mainbody_employee.mainbody_record_info :: JSON ->> 'nodeType' = '101'
                            AND trace_instock.del_flg = '0'
                          <![CDATA[
                            AND CAST(trace_instock.sys_reg_tmsp AS DATE) >= CAST(#{startTagSysRegTmsp,jdbcType = VARCHAR} AS DATE)
                            AND CAST(trace_instock.sys_reg_tmsp AS DATE) <= CAST(#{endTagSysRegTmsp,jdbcType = VARCHAR} AS DATE)
                          ]]>
    		) instock
    		GROUP BY instock.slaughterCode, instock.instockDate, produceCode
    	</select>
    
    

    实体

    public class MeatTzInHz implements Serializable {
    
        /**
         * 屠宰厂编码
         */
        protected String slaughterCode;
    
        /**
         * 进厂日期
         */
        protected String instockDate;
    
        /**
         * 检疫证进场数量
         */
        protected int checkInstockNum;
    
        /**
         * 采购价
         */
        protected double price;
    
        /**
         * 实际数量和重量
         */
        protected double quantityAndWeight;
    
        /**
         * 途亡数
         */
        protected int transportDeathNum;
    
        /**
         * 产地编码
         */
        protected String produceCode;
    
        @Override
        public String toString() {
            return  FileEnum.DIVIDE_COMMA.getSymbol() + slaughterCode +
                    FileEnum.DIVIDE_COMMA.getSymbol() + instockDate +
                    FileEnum.DIVIDE_COMMA.getSymbol() + checkInstockNum +
                    FileEnum.DIVIDE_COMMA.getSymbol() + price +
                    FileEnum.DIVIDE_COMMA.getSymbol() + quantityAndWeight +
                    FileEnum.DIVIDE_COMMA.getSymbol() + transportDeathNum +
                    FileEnum.DIVIDE_COMMA.getSymbol() + produceCode + FileEnum.ENTER_LINE_BREAK.getSymbol();
        }
    

    mapper

    List<MeatTzOutHz> getMeatTzOutHz(DataCondition dataCondition);
    

    service

        public List<MeatTzInHz> getMeatTzInHz(DataCondition dataCondition) {
            List<MeatTzInHz> meatTzInHzList = meatMapper.getMeatTzInHz(dataCondition);
            //验证数据非空
            if(CollectionUtils.isEmpty(meatTzInHzList)) {
                return new ArrayList<>();
            }
            return meatTzInHzList;
        }
    

    导出service(方法名自写,只剖了方法体) ExportService

            List<MeatTzOutHz> meatTzOutHzList = meatService.getMeatTzOutHz(dataCondition);
            meatTzOutHzList.stream()
                    .filter(meatTzOutHz -> StringUtils.isNotBlank(meatTzOutHz.getSlaughterCode()))
                    .forEach(meatTzOutHz -> {
                        String fileName = txtFileUtil.getFileName(FileEnum.POSTFIX_MEAT_TZ_OUT_HZ_TXT.getSymbol(), meatTzOutHz.getSlaughterCode(), meatTzOutHz.getOutstockDate());
                        try {
                            txtFileUtil.writeFileToDateDirectory(meatTzOutHz.toString(), fileName);
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    });
    

    定时任务
    大同小异

        @Autowired
        private ExportService exportService;
    /**
    *  秒  分   时  日  月  年  
    */
        @Scheduled(cron = "0 30 4,11 * * ? ")
        private void grouppurchasing() {
            List<MainBody> mainBodyList = nodeService.getMainBodyByNodeType(2);
    
            if(CollectionUtils.isNotEmpty(mainBodyList)){
                logger.info("生成数据文件开始!");
                mainBodyList.forEach(mainBody -> {
                    logger.info("生成企业:{} 数据文件开始!", mainBody.getMainbodyName());
                    DataCondition dataCondition = new DataCondition();
                    dataCondition.setDivision("上海");
                    dataCondition.setStartTagSysRegTmsp(DateUtil.getYesterdayByDefultFormat());
                    dataCondition.setEndTagSysRegTmsp(DateUtil.getNowByDefultFormat());
                    //dataCondition.setNodeTypeList(Arrays.asList(PlatformConstant.NODE_TYPE_110));
                    dataCondition.setMainBodyCode(mainBody.getMainbodyCode());
    
                    baseNodeInfo(dataCondition ,true);
    
                    exportService.exportGpToTxt(dataCondition);
                    logger.info("生成企业:{} 数据文件结束!", mainBody.getMainbodyName());
                });
                logger.info("生成数据文件结束!");
            }
    
        }
    

    工具类 fileEnum txtFileUtil

    public enum FileEnum {
    POSTFIX_MEAT_TZ_OUT_TXT("{0}_{1}_T2.TXT"),;
        private String symbol;
    
        FileEnum(String symbol) {
            this.symbol = symbol;
        }
    
        public String getSymbol() {
            return symbol;
        }
    }
    
        public String getFileName(String pattern, Object... arguments) {
            if (arguments == null || arguments.length == 0) {
                return pattern;
            }
            return MessageFormat.format(pattern, arguments);
        }
        /**
         * 写文件
         *
         * @param line
         * @param fileName
         * @throws IOException
         */
        public void writeFileToDateDirectory(String line, String fileName) throws IOException {
            String dateDir = DateUtil.getYesterdayByDefultFormat() + "/";
            String dirFile = this.fileOutputDirectory + dateDir + fileName;
            byte[] buff = line.getBytes(Charset.forName("GBK"));
    
            FileOutputStream out = fileMap.get(dirFile);
            if (out == null) {
                File directoryFile = new File(this.fileOutputDirectory + dateDir);
                File file = new File(dirFile);
                if (!directoryFile.exists()) {
                    directoryFile.mkdirs();
                }
                // 文件不存在,创建
                if (!file.exists()) {
                    file.createNewFile();
                }
                // append 参数为false,覆盖原来的文件
                out = new FileOutputStream(file, false);
                fileMap.put(dirFile, out);
            }
            out.write(buff);
        }
    

    DateUtil

        private static Date add(Date date, int calendarField, int amount) {
            if (date == null) {
                throw new IllegalArgumentException("The date must not be null");
            } else {
                Calendar c = Calendar.getInstance();
                c.setTime(date);
                c.add(calendarField, amount);
                return c.getTime();
            }
        }
        /**
         * 增加天
         *
         * @param date
         * @param amount
         * @return
         */
        public static Date addDays(Date date, int amount) {
            return add(date, 5, amount);
        }
            /**
         * 获取昨天
         * @return
         */
        public static Date getYesterday() {
            return addDays(getNow(), -1);
        }
            /**
         * 把日期类型格式化成字符串
         *
         * @param date
         * @param format
         * @return
         */
        public static String convert2String(Date date, String format) {
            SimpleDateFormat formater = new SimpleDateFormat(format);
            try {
                return formater.format(date);
            } catch (Exception e) {
                return null;
            }
        }
            /**
         * 获取昨天的日期并转化为yyyyMMdd
         * @return
         */
        public static String getYesterdayByDefultFormat() {
            return convert2String(getYesterday(), DATE_FORMAT_YYYYMMDD);
        }
    

    到这里,应该能生成txt文件了。还有一步上传。
    平台方要求 生成zip 再用webservice的方式上传到平台
    先po功能代码 ,再给工具类

        /**
         * webservice  上传zip文件(一天一次)
         * 6:30 12:30
         */
        @Scheduled(cron = "0 30 6,12 * * ? ")
        private void uploadZipByWebservice() {
            //打包
            String zipPath = "/sh";
            String zipName = DateUtil.getYesterdayByDefultFormat();
            ZipUtils.createZipFile(zipPath,zipName);
            //地址
            String fileName = "sh" + zipName + ".zip";
            Identity identity  = new Identity();
            ReqEntity<Identity> reqEntity = new ReqEntity<>();
            identity.setFileName(fileName);
            identity.setFileCreateTime(new SimpleDateFormat("yyyy-MM-dd").format(new Date()));
            File file = new  File("/data/"+ fileName);
            identity.setFileSize(String.valueOf(file.length()));
            reqEntity.setIdentity(identity);
            reqUtil.sendXml(reqEntity);
        }
    

    看着很简洁 ,包含了三个工具类,和 两个实体类
    实体类

    @Data
    //只检测属性不检测方法了
    @JsonAutoDetect(fieldVisibility=JsonAutoDetect.Visibility.ANY, getterVisibility=JsonAutoDetect.Visibility.NONE)
    public class Identity implements Serializable {
    
        private String UserName;
        private String Password;
        private String FileName;
        private String FileSize;
        private String FileCreateTime;
    }
    
    

    父类

    @Data
    //只检测属性不检测方法了
    @JsonAutoDetect(fieldVisibility=JsonAutoDetect.Visibility.ANY, getterVisibility=JsonAutoDetect.Visibility.NONE)
    public class ReqEntity<Identity> implements Serializable {
    
        private String pfileType;
        private String pbuffer;
        private String usercode;
        private String userPass;
        private Identity identity;
        private  String pErrmasg;
    
    }
    

    其实就是定义一些字段,啥也没写。=。=
    工具类的话
    生成压缩文件 zipUtil

        /**
         * 创建压缩文件
         */
        public static void createZipFile(String saveFilePath ,String zipName) {
            FileOutputStream fileOutputStream = null;
            try {
                File zipFile = new File(saveFilePath + zipName.replaceAll("(.*?)(/*)$","$1") + ".zip");
                fileOutputStream = new FileOutputStream(zipFile);
                ZipUtils.toZip(saveFilePath + "/"+zipName+"/", fileOutputStream, false);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        /**
         * 压缩成ZIP 方法1
         *
         * @param srcDir           压缩文件夹路径
         * @param out              压缩文件输出流
         * @param KeepDirStructure 是否保留原来的目录结构,true:保留目录结构;
         *                         false:所有文件跑到压缩包根目录下(注意:不保留目录结构可能会出现同名文件,会压缩失败)
         * @throws RuntimeException 压缩失败会抛出运行时异常
         */
        public static void toZip(String srcDir, OutputStream out, boolean KeepDirStructure)
                throws RuntimeException {
    
            long start = System.currentTimeMillis();
            ZipOutputStream zos = null;
            try {
                zos = new ZipOutputStream(out);
                File sourceFile = new File(srcDir);
                compress(sourceFile, zos, sourceFile.getName(), KeepDirStructure);
                long end = System.currentTimeMillis();
                logger.info("压缩完成,耗时:" + (end - start) + " ms");
            } catch (Exception e) {
                throw new RuntimeException("zip error from ZipUtils", e);
            } finally {
                if (zos != null) {
                    try {
                        zos.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
        /**
         * 递归压缩方法
         *
         * @param sourceFile       源文件
         * @param zos              zip输出流
         * @param name             压缩后的名称
         * @param KeepDirStructure 是否保留原来的目录结构,true:保留目录结构;
         *                         false:所有文件跑到压缩包根目录下(注意:不保留目录结构可能会出现同名文件,会压缩失败)
         * @throws Exception
         */
        private static void compress(File sourceFile, ZipOutputStream zos, String name,
                                     boolean KeepDirStructure) throws Exception {
            byte[] buf = new byte[BUFFER_SIZE];
            if (sourceFile.isFile()) {
                // 向zip输出流中添加一个zip实体,构造器中name为zip实体的文件的名字
                zos.putNextEntry(new ZipEntry(name));
                // copy文件到zip输出流中
                int len;
                FileInputStream in = new FileInputStream(sourceFile);
                while ((len = in.read(buf)) != -1) {
                    zos.write(buf, 0, len);
                }
                // Complete the entry
                zos.closeEntry();
                in.close();
            } else {
                File[] listFiles = sourceFile.listFiles();
                if (listFiles == null || listFiles.length == 0) {
                    // 需要保留原来的文件结构时,需要对空文件夹进行处理
                    if (KeepDirStructure) {
                        // 空文件夹的处理
                        zos.putNextEntry(new ZipEntry(name + "/"));
                        // 没有文件,不需要文件的copy
                        zos.closeEntry();
                    }
                } else {
                    for (File file : listFiles) {
                        // 判断是否需要保留原来的文件结构
                        if (KeepDirStructure) {
                            // 注意:file.getName()前面需要带上父文件夹的名字加一斜杠,
                            // 不然最后压缩包中就不能保留原来的文件结构,即:所有文件都跑到压缩包根目录下了
                            compress(file, zos, name + "/" + file.getName(), KeepDirStructure);
                        } else {
                            compress(file, zos, file.getName(), KeepDirStructure);
                        }
                    }
                }
            }
        }
        /**
         * 根据文件路径读取文件转出 byte[]
         *
         * @param filePath 文件路径
         * @return 字节数组
         * @throws IOException
         */
        public static byte[] getFileToByteArray(String filePath) throws IOException {
            File file = new File(filePath);
            long fileSize = file.length();
            if (fileSize > Integer.MAX_VALUE) {
                return null;
            }
            FileInputStream fileInputStream = new FileInputStream(file);
            byte[] buffer = new byte[(int) fileSize];
            int offset = 0;
            int numRead = 0;
            while (offset < buffer.length && (numRead = fileInputStream.read(buffer, offset, buffer.length - offset)) >= 0) {
                offset += numRead;
            }
            // 确保所有数据均被读取
            if (offset != buffer.length) {
                logger.error("Could not completely read file : {}" , file.getName());
                throw new IOException("Could not completely read file " + file.getName());
            }
            fileInputStream.close();
            return buffer;
        }
        
    

    还有上传的一个工具类 reqUtil

        @Value("${webservice.url}")
        private String webUrl;
        /**
         * xml  上报方式
         * @param reqEntity
         * @return
         */
        public String sendXml( ReqEntity<Identity> reqEntity) {
            URL url = null;
            String fileName = reqEntity.getIdentity().getFileName();
            String fileSize = reqEntity.getIdentity().getFileSize();
            String createTime = reqEntity.getIdentity().getFileCreateTime();
            String fileStr = "";
            String responsMess  = "";
            try {
                url = new URL(webUrl);
                reqUtilLogger.info("requestUrl:" + url);
                HttpURLConnection con = (HttpURLConnection) url.openConnection();
                byte[] zipOutput = ZipUtils.getFileToByteArray("/data/"+ fileName);
                fileStr = new sun.misc.BASE64Encoder().encode(zipOutput);
    
                //拼接好xml
                StringBuffer sb = new StringBuffer();
                sb.append("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" +
                        "<soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">\n" +
                        "  <soap:Header>\n" +
                        "    <Identify xmlns=\"FjUpdate1\">\n" +
                        "      <UserName>"+userName+"</UserName>\n" +
                        "      <Password>"+password+"</Password>\n" +
                        "      <FileName>"+fileName+"</FileName>\n" +
                        "      <FileSize>"+fileSize+"</FileSize>\n" +
                        "      <FileCreateTime>"+createTime+"</FileCreateTime>\n" +
                        "    </Identify>\n" +
                        "  </soap:Header>\n" +
                        "  <soap:Body>\n" +
                        "    <UpFile xmlns=\"FjUpdate1\">\n" +
                        "      <pFileType>" + fileName.split("\\.")[0] + "</pFileType>\n" +
                        "      <pBuffer>"+fileStr+"</pBuffer>\n" +
                        "      <usercode>"+userName+"</usercode>\n" +
                        "      <userpass>"+password+"</userpass>\n" +
                        "    </UpFile>\n" +
                        "  </soap:Body>\n" +
                        "</soap:Envelope>\n");
    
                String xmlStr = sb.toString();
                System.out.println(xmlStr);
                //设置好header信息
                con.setRequestMethod("POST");
                con.setRequestProperty("content-type", "text/xml; charset=utf-8");
                con.setRequestProperty("Content-Length", String.valueOf(xmlStr.getBytes().length));
    //      con.setRequestProperty("soapActionString", soapActionString);
    
                //post请求需要设置
                con.setDoOutput(true);
                con.setDoInput(true);
    
                //对请求body 往里写xml 设置请求参数
                OutputStream ops = con.getOutputStream();
                ops.write(xmlStr.getBytes());
                ops.flush();
                ops.close();
    
                //设置响应回来的信息
                InputStream ips = con.getInputStream();
                ByteArrayOutputStream baos = new ByteArrayOutputStream();
                byte[] buf = new byte[1024];
                int length = 0;
                while( (length = ips.read(buf)) != -1){
                    baos.write(buf, 0, length);
                    baos.flush();
                }
                byte[] responsData = baos.toByteArray();
                baos.close();
    
                //处理写响应信息
                responsMess = new String(responsData,"utf-8");
                reqUtilLogger.info("响应报文:"+ responsMess);
                reqUtilLogger.info(String.valueOf(con.getResponseCode()));
            } catch (MalformedURLException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return responsMess;
        }
    

    这里@value的参数就不po了,大家懂的自然懂,怎么配置。
    userName和password自行定义即可。

    这样,就大功告成了。(^-^)V。
    很多人会问,用这么多类,你的 maven需要导入很多依赖包
    基础的mybatis,springframework等的我就不po了,大家都知道的。然后就是正常的io依赖也没啥特别的。自行解决就好。

    展开全文
  • 什么是API接口,具体是什么意思

    万次阅读 多人点赞 2019-02-19 22:36:34
    什么叫API,看一下餐厅里怎么点餐的就行了。 到了饭店,喊一场服务员,点餐。服务员拿出来菜单给你看,你点什么,她在小本本上记什么。点好了之后,再把菜单送到后厨去。这里服务员就是提供服务的(不然也不叫服务员...
    说到API,往往是和SDK放在一起的。什么叫API,看一下餐厅里怎么点餐的就行了。
    

    到了饭店,喊一场服务员,点餐。服务员拿出来菜单给你看,你点什么,她在小本本上记什么。点好了之后,再把菜单送到后厨去。这里服务员就是提供服务的(不然也不叫服务员),提供什么服务呢?点餐服务。
    点餐服务需要什么呢?谈一个服务,通常就是要谈输入是什么,输出又是什么。从眼下这个例子来看,输入就是一道道菜品的名字(或者是ID,不知道你们见过菜品上面有编号,服务员只记编号的?),输出的结果就是端过来的一道道菜。有了输入和输出,服务员就可以提供了点餐的功能,这就是API顾客就是调用者,服务员就是服务的提供者。
    你可以在这里把服务员替换成猫猫,假设女王大人猫猫来给你提供服务,只要输出是菜品的名字,输出是菜品,这个API就是能够正常使用的。而且,所有的顾客都可以用这种方式来点菜 的再想想 ,是不是有的服务员手里拿的是点餐机? 想想一个漂亮的小姑娘,拿着一个和手机大小差不多的点餐机,这个点餐机,就是需要和后厨删除线格式 系统有交互,这种交互,就需要一种约束,来声明点菜功能的输入是什么,输出是什么。比如说,如果用户点了一道已经估清的菜,是不是服务员要告诉顾客一下?
    API通常是以Http的形式提供,它隐藏的含义就是,只要你符合我定义的标准,你就

    可以来使用我。比如说,服务员是中国姑娘,顾客是美国人,没关系,只要美国人能说中国话,这套API就可以使用。如果美国人只会说英语,怎么办?让和美国人一起来吃饭的中国朋友翻译成中文,就可以了~~~~
    那么什么是SDK呢?当美国人不会说中文的时候,饭店里的大堂经理来了,他来给美国佬当翻译。这就是SDK,SDK一般都是和语言相关,是官方提供的各种不同语言的实现版本。同样的,我们再把思维模式扩大一点。除了Http这种API,内部系统集成的组件,是否也是有API?你会发现,确实是这样的,比如说,JDK本身提供的各种API,在这里,API和SDK的概念没有那么清楚了,但是API本身的含义就是,当服务的提供方对外提供服务的时候,应该声明输入和输出和功能的明确含义。而一组组明确声明了的输入,输出和功能描述,就是服务方提供的各种API。比如说数组对外暴露的方法,链表对外暴露的方法等等。那么,API和方法之间有没有明显的区别呢?暴露出去的,可被公开使用的方法,统称为API~~~以上解释不够严谨,但是对于初学者来说,理解起来应该够了。如果你在理解API的时候有困难,大概问题并不是在API上,而是你有没有理解清楚什么叫做封装,什么叫做服务?

    展开全文
  • 银联对接参考

    千次阅读 2019-10-31 14:11:18
    业务需要,前段时间做了一下银联对接,包括了银行信息实名认证以及预授权交易方面。 银联对接也是相当耗时的一件事,这里留存一下自己的成果。 首先需要去银联申请对接资格,然后拿到对应的对接的资料(包括测试...
  • GB/T-28181平台对接接口详解,在进行国标平台对接的时候参考文档
  • 根据客户提供的有赞账号密码登录有赞云 (https://www.youzanyun.com/) ,并完成有赞云的 实名认证功能以及个人资料中的 邮箱绑定,... (该操作需要地区大客户人员与客户操作完成,我们提供协助,审核时间大概1-3天) ...
  • SAP EWM 与 AGV 机器人对接的三种模式

    千次阅读 2018-11-21 13:17:59
    SAP EWM 与 AGV 机器人对接的三种模式   https://mp.weixin.qq.com/s/xGfUMSBTEMYKce5oXcWDqA   导读 本文转载自:弘毅供应链,跟随供应链专家卓弘毅的脚步,了解 SAP EWM 与 AGV 物流机器人究竟是如何连接...
  • 分子对接理论基础分子对接就是两个或多个分子之间通过几何匹配和能量匹配而相互识别的过程。分子对接在药物设计中已经体现出十分重要的应用价值。在酶激活剂、酶抑制剂与酶相互作用以及药物分子产生药理反应的过程中...
  • 小白如何进行支付对接

    千次阅读 2019-07-24 11:09:24
    后端和第三方支付平台对接好了,尽量不要和前端联调测试,可以借助ios的scheme或者自己写一些简单的demo,然后给前端程序提供他说需要的接口,比如下单接口,支付成功查询接口(基本上都需要的),以文档形式给出并...
  • java中API什么意思

    千次阅读 2019-10-06 13:48:04
    api,application programming interface,应用程序编程接口。 在不同场合,这个编程接口的含义不同 java api是指java标准类库提供的函数,android开发的api是指android sdk函数库。 网站api一般是指一个网站提供的...
  • 视频监控对接GB/T28181国标平台

    千次阅读 2021-02-23 22:54:02
    一、NVR对接GB/T28181国标平台 1、判断监控设备(NVR)是否支持接入国标平台 2、监控设备通过国标协议接入视频融合平台流程 3、通过视频专网接入平台的网络拓扑 4、通过公网接入平台的网络拓扑 5、监控设备接入...
  • 工商银行对接注意点

    2019-03-14 11:52:07
    公司业务需要,应上级要求对接工商在线支付。工程辗转多人(公司技术为php,所以一直拖着未实现),到博主手上的只有一份工行demo,是java实现的,博主做过java,遂实现之,后来好奇工行不至于不针对php开发一套扩展...
  • 网络协议对接——HTTP

    2020-08-03 20:24:09
    在嵌入式设备中,软件... 总而言之: HTTP协议是一种都是由客户端发起的,非常简单的,无状态,无连接的协议,它是基于TCP/IP的应用层协议,开发中我们常用libcurl库来实现一个HTTP协议对接,具体如何实现,请看后续!
  • LTE概述

    千次阅读 2019-10-09 17:05:00
    :实现对SeGW、HeNB GW、AAA, HSS等设备管理,与BOSS对接 控制面 : Femto Internet SeGW X HeNB GW MME User plane: femto Internet SeGW x HeNB GW S-GW eNode B基本功能 具有Node B的全部和RNC 1...
  • 和 Android | IOS 对接问题 用js和 Android 和 IOS 对接交互,Android和Ios监听我每次点击的内容 (每次点击图片,向Android发送用户点击的信息,比如图片的地址,图片的id) 在js中写一个点击事件,和 Android 要取...
  • 关于API技术对接

    万次阅读 2017-10-26 16:06:12
    API的技术是见证当前网络时代的发展,什么是api,我们要如何运用这项技术,都能在文章中体现
  • 系统接口对接:(1)

    2020-09-28 16:32:39
    今天贴上系统之间调取接口的工具类代码吧,参数可以是json格式,也可以是string,具体的双方设定好即可,选择合适的: package com.jeeplus.common.utils.baidu; ... ... import org.apache.commons.httpcl
  • 蚁群算法求解有时间窗约束的车辆路径问题matlab程序 1 简介 带时间窗的车辆路径问题(VRPTW)一般描述为从某一物流配送中心出发,用多台车辆向多个顾客送货,车辆完成配送任务后返回配送中心。 已知每个顾客的位置...
  • 2)接口对接的定义:服务端通过暴露地址/参数名称/编码,指引客户端发送一个Rest风格的URL请求,服务端读取Rest风格的URL,并返回一个响应; 接口有四部分组成:方法、uri、请求参数、返回参数;默认接口格式是JSON...
  • 为了支持这一输入架构,工程师必须设计与ADC进行差分对接的信号链。  为了获得最佳性能,用户必须在信号链上选择一个balun(平衡不平衡变换器),虽然这可能会导致某些应用中的耦合问题。然而,耦合问题并不是总是...
  • 对接SAP问题

    2019-09-17 23:24:03
    这个是从和银行对接放款中找到的灵感,他们那边的操作是,我们这边执行放款操作,如果操作正常的话,会再请求一下银行查询交易的接口,如果银行那边返回结果较晚,可能我们这边就会报超时的异常,得再查询一下交易,...
  • 两分钟读懂什么是TPS和QPS

    千次阅读 热门讨论 2021-06-15 03:38:40
    1、TPS:Transactions Per ...2、QPS:Queries Per Second,意思是每秒查询率。指一台服务器每秒能够响应的查询次数,用于衡量特定的查询服务器在规定时间内所处理流量多少,主要针对专门用于查询的服务器的性能指标。
  • 银联支付对接指南

    千次阅读 2019-06-02 14:05:51
    如果你正在对接银联支付,参照官网的样例代码,猜测注释的意思,吭哧吭哧的写着代码,怀着日狗的心情,一遍遍的运行调试demo,着那么这篇文章有必要看一下。 不要再做了,官网的那个现在已经不能用了。 现在要...
  • 平台api对接

    千次阅读 2019-02-14 20:11:05
    在工作日常中,跨平台api对接是再正常不过的事情了,例如,需要调用api,这个api:免费api ,这是个免费的获取天气信息Get Api。 为了调用这个api,我们需要使用Apache的网络通信java包:org.apache....
  • 关于系统之间的单点登陆对接

    千次阅读 2020-04-08 22:44:51
    但是在工作需求有时候会遇到,尤其是做定制化产品.一个客户买了我们公司一个产品,同时买了另外一个公司的产品.现在想让这两个产品进行单点登陆,一般是这A系统需要打开到B系统做一些操作,或者调用B系统的一些接口等...
  • 前端如何对接接口

    万次阅读 多人点赞 2019-11-07 12:04:52
    作为一名前端工程师,不能只会写静态页面,还要会对接后端的接口。 1.把地址改为后端工程师的电脑地址 在webpack.base.config.js中把测试地址改成后端地址 proxy: { '/aaa': { //识别url的第一个路径来判断 //...
  • 今天我们来聊聊,如何做好第三方系统对接

    千次阅读 多人点赞 2020-12-18 18:40:43
    文章目录前言What 是什么Why 为什么How 怎么做对接对接对接对接风险总结与思考 前言 无论你是做面向ToB、ToC还是ToG的业务,开发业务系统,永远也逃脱不了与第三方系统对接的命运,例如:常见的支付宝、微信...
  • vos对接移动、电信、联通各种线路

    千次阅读 2021-03-31 20:20:02
    现在外呼行业管的很严,线路商都通过三大运营申请各种接入方式的线路,接入方式复杂,这里大概归类了一下: 1、传统的数字中继线路,就是常用是2M线路,一个2M管30路并发。也有开155M的中继线,可以1900并发左右。...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 19,382
精华内容 7,752
关键字:

对接一下是什么意思