钉钉H5微应用Springboot+Vue开发分享
文章目录
- 说明
- 技术路线
- 注意
- 操作步骤
- 思路图
- 一、创建钉钉应用
- 二、创建java项目
- 三、创建vue项目(或uniapp项目),npm引入sdk的依赖
- 四、拥有公网域名端口。开发环境可以使用(贝锐花生壳等工具)
- 五、打开钉钉开发者平台,配置钉钉应用的h5公网地址
- 六、打开手机钉钉,即可看到开发的页面
说明
由于钉钉开发文档的内容特别多,虽然介绍已经非常仔细了,当对于那些第一次看这个文档的时候,会有些疑惑。为了避免少走很多弯路,故写下该文章进行技术分享
- 本文主要功能:1、钉钉免登录获取用户信息 2、钉钉获取当前的定位
简单来说,就是在钉钉里面,展示我们编写的手机格式大小的网页页面
技术路线
VUE作为前端开发框架,后端为Springboot项目
可以直接通过npm运行项目或者nginx运行项目
为了方便(只需要部署一个项目),我把vue打包成为静态文件,放置到Springboot的 static 文件中。
注意
1、钉钉开发文档,有时候叫 开发H5微应用,有时候叫 开发网页应用,注意分辨
2、开发过程中,有时候会用到小程序开发者工具,注意看说明书。jsapi接口有时候这个工具用不了,得实际放到钉钉dingtalk才有用
3、目前该分享,只是涉及到网页应用,不涉及小程序应用。要注意分辨
操作步骤
1、获取钉钉的应用(corpId/agentId/appKey/appSecret)。开发环境可以自己注册企业,自己创建钉钉应用(注意配置免密的权限)
2、创建java项目,pom引入钉钉的sdk
3、创建vue项目(或uniapp项目),npm引入sdk的依赖
4、拥有公网域名端口。开发环境可以使用(贝锐花生壳等工具)
5、打开钉钉开发者平台,配置钉钉应用的h5公网地址
6、打开手机钉钉,即可看到开发的页面
思路图
获取免登录
jsapi鉴权获取定位坐标(只有安卓端 或 苹果端有用)
一、创建钉钉应用
注册钉钉企业,打开钉钉开发者平台
https://open-dev.dingtalk.com/
记录下 corpId
创建应用
记录下 agentId、appKey、appSecret
二、创建java项目
POM引入依赖,因为钉钉的接口分为新的接口和旧的接口,目前最新的版本,新接口和旧接口都是可以使用的。所以两个接口的依赖同时引入
参考我上传到 gitee的后端代码
https://gitee.com/chencanzhan/cancan-java-share/tree/master/dingtalk-demo
核心pom文件
<!-- 新的接口 --><dependency><groupId>com.aliyun</groupId><artifactId>dingtalk</artifactId><version>2.1.21</version></dependency><!-- 旧的接口 --><dependency><groupId>com.aliyun</groupId><artifactId>alibaba-dingtalk-service-sdk</artifactId><version>2.0.0</version></dependency>
核心代码
@Service
public class DingH5Service {@Value("${dingtalk.appKey}")private String appKey;@Value("${dingtalk.appSecret}")private String accessKeySecret;public DingUserInfo getUserByCode(String code) {DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/v2/user/getuserinfo");OapiV2UserGetuserinfoRequest req = new OapiV2UserGetuserinfoRequest();req.setCode(code);OapiV2UserGetuserinfoResponse rsp = null;try {rsp = client.execute(req, getAccessToken());} catch (Exception e) {throw new RuntimeException(e);}cn.hutool.json.JSONObject entries = JSONUtil.parseObj(rsp.getBody());Integer errcode = entries.getInt("errcode");if(errcode == 0){cn.hutool.json.JSONObject result = entries.getJSONObject("result");DingUserInfo dingUserInfo = new DingUserInfo();dingUserInfo.setAssociatedUnionid(result.getStr("associated_unionid"));String unionid = result.getStr("unionid");dingUserInfo.setUnionid(unionid);String deviceId = result.getStr("device_id");dingUserInfo.setDeviceId(deviceId);dingUserInfo.setSysLevel(result.getInt("sys_level"));String name = result.getStr("name");dingUserInfo.setName(name);dingUserInfo.setSys(result.getBool("sys"));String userid = result.getStr("userid");dingUserInfo.setUserid(userid);return dingUserInfo;}return null;}public String getJsapiTicket() {com.aliyun.dingtalkoauth2_1_0.Client client = null;try {client = createClient();} catch (Exception e) {throw new RuntimeException(e);}try {com.aliyun.dingtalkoauth2_1_0.models.CreateJsapiTicketHeaders createJsapiTicketHeaders = new com.aliyun.dingtalkoauth2_1_0.models.CreateJsapiTicketHeaders();createJsapiTicketHeaders.xAcsDingtalkAccessToken = getAccessToken();CreateJsapiTicketResponse jsapiTicketWithOptions = client.createJsapiTicketWithOptions(createJsapiTicketHeaders, new RuntimeOptions());CreateJsapiTicketResponseBody body = jsapiTicketWithOptions.getBody();return body.getJsapiTicket();} catch (TeaException err) {if (!com.aliyun.teautil.Common.empty(err.code) && !com.aliyun.teautil.Common.empty(err.message)) {// err 中含有 code 和 message 属性,可帮助开发定位问题}} catch (Exception _err) {TeaException err = new TeaException(_err.getMessage(), _err);if (!com.aliyun.teautil.Common.empty(err.code) && !com.aliyun.teautil.Common.empty(err.message)) {// err 中含有 code 和 message 属性,可帮助开发定位问题}}return null;}/*** 创建钉钉客户端* @return* @throws Exception*/public static com.aliyun.dingtalkoauth2_1_0.Client createClient() throws Exception {com.aliyun.teaopenapi.models.Config config = new com.aliyun.teaopenapi.models.Config();config.protocol = "https";config.regionId = "central";return new com.aliyun.dingtalkoauth2_1_0.Client(config);}public String getAccessToken() throws Exception {com.aliyun.teaopenapi.models.Config config = new com.aliyun.teaopenapi.models.Config();config.protocol = "https";config.regionId = "central";com.aliyun.dingtalkoauth2_1_0.Client client = new com.aliyun.dingtalkoauth2_1_0.Client(config);com.aliyun.dingtalkoauth2_1_0.models.GetAccessTokenRequest getAccessTokenRequest = new com.aliyun.dingtalkoauth2_1_0.models.GetAccessTokenRequest().setAppKey(appKey).setAppSecret(accessKeySecret);try {return client.getAccessToken(getAccessTokenRequest).getBody().getAccessToken();} catch (TeaException err) {if (!com.aliyun.teautil.Common.empty(err.code) && !com.aliyun.teautil.Common.empty(err.message)) {// err 中含有 code 和 message 属性,可帮助开发定位问题}} catch (Exception _err) {TeaException err = new TeaException(_err.getMessage(), _err);if (!com.aliyun.teautil.Common.empty(err.code) && !com.aliyun.teautil.Common.empty(err.message)) {// err 中含有 code 和 message 属性,可帮助开发定位问题}}return null;}}
@RestController
@RequestMapping("/ding-h5")
public class DingH5Controller {@Value("${dingtalk.agentId}")private String agentId;@Value("${dingtalk.corpId}")private String corpId;@Value("${dingtalk.appKey}")private String appKey;@Value("${dingtalk.urlPath}")private String urlPath;@Autowiredprivate DingH5Service dingH5Service;/*** 获取签名* @param dingConfigSignVo* @param request* @return*/@PostMapping("/signAll")public ResponseEntity<Object> signAll(@RequestBody DingConfigSignVo dingConfigSignVo, HttpServletRequest request){String sign = null;String signedUrl = urlPath;String jticket = dingH5Service.getJsapiTicket();dingConfigSignVo.setJsticket(jticket);Map<String, Object> jMap = new HashMap<>();try {sign = DdConfigSign.sign(dingConfigSignVo.getJsticket(),dingConfigSignVo.getNonceStr(),dingConfigSignVo.getTimeStamp(),signedUrl);} catch (Exception e) {throw new RuntimeException(e);}jMap.put("agentId",agentId);jMap.put("corpId",corpId);jMap.put("appKey",appKey);jMap.put("sign",sign);return new ResponseEntity<>(jMap, HttpStatus.OK);}/*** 根据code获取用户信息* @param code* @return*/@GetMapping("/getUserByCode")public ResponseEntity<Object> getUserByCode(String code){DingUserInfo userByCode = dingH5Service.getUserByCode(code);return new ResponseEntity<>(userByCode, HttpStatus.OK);}}
/*** 计算dd.config的签名参数**/
public class DdConfigSign {/*** 计算dd.config的签名参数** @param jsticket 通过微应用appKey获取的jsticket* @param nonceStr 自定义固定字符串* @param timeStamp 当前时间戳* @param url 调用dd.config的当前页面URL* @return* @throws Exception*/public static String sign(String jsticket, String nonceStr, long timeStamp, String url) throws Exception {String plain = "jsapi_ticket=" + jsticket + "&noncestr=" + nonceStr + "×tamp=" + String.valueOf(timeStamp)+ "&url=" + decodeUrl(url);try {MessageDigest sha1 = MessageDigest.getInstance("SHA-256");sha1.reset();sha1.update(plain.getBytes("UTF-8"));return byteToHex(sha1.digest());} catch (Exception e) {throw new Exception(e.getMessage());}}// 字节数组转化成十六进制字符串private static String byteToHex(final byte[] hash) {Formatter formatter = new Formatter();for (byte b : hash) {formatter.format("%02x", b);}String result = formatter.toString();formatter.close();return result;}/*** 因为ios端上传递的url是encode过的,android是原始的url。开发者使用的也是原始url,* 所以需要把参数进行一般urlDecode** @param url* @return* @throws Exception*/private static String decodeUrl(String url) throws Exception {URL urler = new URL(url);StringBuilder urlBuffer = new StringBuilder();urlBuffer.append(urler.getProtocol());urlBuffer.append(":");if (urler.getAuthority() != null && urler.getAuthority().length() > 0) {urlBuffer.append("//");urlBuffer.append(urler.getAuthority());}if (urler.getPath() != null) {urlBuffer.append(urler.getPath());}if (urler.getQuery() != null) {urlBuffer.append('?');urlBuffer.append(URLDecoder.decode(urler.getQuery(), "utf-8"));}return urlBuffer.toString();}public static String getRandomStr(int count) {String base = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";Random random = new Random();StringBuffer sb = new StringBuffer();for (int i = 0; i < count; i++) {int number = random.nextInt(base.length());sb.append(base.charAt(number));}return sb.toString();}
}
三、创建vue项目(或uniapp项目),npm引入sdk的依赖
1、使用npm安装。
npm install dingtalk-jsapi --save2、加载 dingtalk-jsapi
import * as dd from 'dingtalk-jsapi'; // 此方式为整体加载,也可按需进行加载
完整的代码
<template><el-main><div>用户名:{{name}}</div><div>当前位置:{{rrsss.address}}</div><button @click="handlegetSignAll">测试</button></el-main>
</template><script>import api from '@/api';
import * as dd from 'dingtalk-jsapi'; // 此方式为整体加载,也可按需进行加载export default {data() {return {t1: 0,name: '',agentId: '',appKey: '',corpId: '',sign: '',rrsss: {},}},mounted() {this.handlegetSignAll();},methods: {handlegetSignAll() {this.t1 = Date.now()let params = {nonceStr: 'a',timeStamp: this.t1}api.getSignAll(params).then(res => {if (res && res.status === 200) {this.agentId = res.data.agentIdthis.appKey = res.data.appKeythis.corpId = res.data.corpIdthis.sign = res.data.signthis.setDDConfig();this.getAuthCode();}})},setDDConfig() {/**钉钉鉴权 */dd.config({agentId: this.agentId, // 必填,微应用IDcorpId: this.corpId,//必填,企业IDtimeStamp: this.t1, // 必填,生成签名的时间戳nonceStr: 'a', // 必填,自定义固定字符串。signature: this.sign, // 必填,签名type: 0, //选填。0表示微应用的jsapi,1表示服务窗的jsapi;不填默认为0。该参数从dingtalk.js的0.8.3版本开始支持jsApiList: ['device.geolocation.get'] // 必填,需要使用的jsapi列表,注意:不要带dd。})this.getGeolocation();//该方法必须带上,用来捕获鉴权出现的异常信息,否则不方便排查出现的问题dd.error(function () {console.log("钉钉鉴权失败,无法定位等,请联系管理员,或重新尝试!");})},getGeolocation() {dd.ready(() => {dd.device.geolocation.get({targetAccuracy: 200,coordinate: 1,withReGeocode: true,useCache: false,onSuccess: function (res) {// 调用成功时回调console.log(res)this.rrsss = res},onFail: function (err) {// 调用失败时回调console.log(err)}});})},getAuthCode() {dd.requestAuthCode({corpId: this.corpId,clientId: this.appKey,onSuccess: (result) => {api.getUserInfo({code:result.code}).then(res => {if (res && res.status === 200) {this.name = res.data.name}})},onFail: function () { },});} }
}
</script>
<style scoped>
</style>
四、拥有公网域名端口。开发环境可以使用(贝锐花生壳等工具)
这自己百度,映射到本地端口可以直接通过npm运行项目或者nginx运行项目
为了方便(只需要部署一个项目),我把vue打包成为静态文件,放置到Springboot的 static 文件中。
五、打开钉钉开发者平台,配置钉钉应用的h5公网地址
选择添加应用能力
填写公网域名
同时记得开放权限
六、打开手机钉钉,即可看到开发的页面
相关文章:
钉钉H5微应用Springboot+Vue开发分享
文章目录 说明技术路线注意操作步骤思路图 一、创建钉钉应用二、创建java项目三、创建vue项目(或uniapp项目),npm引入sdk的依赖四、拥有公网域名端口。开发环境可以使用(贝锐花生壳等工具)五、打开钉钉开发者平台&…...
项目:微服务即时通讯系统客户端(基于C++QT)]四,中间界面搭建和逻辑准备
四,中间界面搭建 前言:当项目越来越复杂的时候,或许画草图是非常好的选择 一,初始化中间窗口initMidWindow void mainWidget::initMidWindow() {//使用网格布局进行管理QGridLayout* layout new QGridLayout();//距离上方 20px 的距离&…...
【C语言】指针详解(一)
个人主页 : zxctscl 如有转载请先通知 文章目录 1.内存与地址2.指针变量与地址2.1 取地址操作符&2.2 指针变量2.3 指针类型2.4 解引用操作符2.5 指针变量的大小 3. 指针变量类型的意义3.1 指针的解引用 4. const修饰指针4.1 const修饰变量4.2 const修饰指针变量…...
unity3D雨雪等粒子特效不穿透房屋效果实现(粒子不穿透模型)
做项目有时候会做天气模拟,模拟雨雪天气等等。但是容易忽略一个问题,就是房屋内不应该下雨或者下雪,这样不就穿帮了嘛。 下面就粒子穿透物体问题做一个demo。 正常下雨下雪在室内的话,你可以看到,粒子是穿透建筑的。 那要怎么模拟真实的雨雪天气,不让粒子穿透房屋建筑呢…...
ROS2安装cartographer
2. 安装Cartographer和Cartographer ROS 使用apt安装(推荐): bash sudo apt install ros-humble-cartographer-ros或者,从源代码安装: bash sudo apt-get update sudo apt-get install -y python3-wstool python3…...
kafka测试
1】确认 ZooKeeper 服务状态 为了进一步确认 ZooKeeper 服务的状态,你可以执行以下操作: 检查 ZooKeeper 服务状态: docker ps 确保 ZooKeeper 容器正在运行。 检查 ZooKeeper 日志: docker logs zookeeper 查看最新的日志条目&…...
总结C/C++中内存区域划分
目录 1.C/C程序内存分配主要的几个区域: 2.内存分布图 1.C/C程序内存分配主要的几个区域: 1、栈区 2、堆区 3、数据段(静态区) 4.代码段 2.内存分布图 如图: static修饰静态变量成员——放在静态区 int globalVar 是…...
第168天:应急响应-ELK 日志分析系统Yara规则样本识别特征提取规则编写
目录 案例一:ELK 搭建使用-导入文件&监控日志&语法筛选 案例二:Yara 规则使用-规则检测&分析特征&自写规则 案例一:ELK 搭建使用-导入文件&监控日志&语法筛选 该软件是专业分析日志的工具,但是不支持安…...
MySQL 面试题及答案
MySQL 面试题及答案: 一、基础问题 什么是数据库索引?有哪些类型? 答:数据库索引是一种数据结构,用于提高数据库查询的效率。它就像一本书的目录,可以快速定位到特定的数据行。 类型主要有: …...
vue仿chatGpt的AI聊天功能--大模型通义千问(阿里云)
vue仿chatGpt的AI聊天功能–大模型通义千问(阿里云) 通义千问是由阿里云自主研发的大语言模型,用于理解和分析用户输入的自然语言。 1. 创建API-KEY并配置环境变量 打开通义千问网站进行登录,登陆之后创建api-key,右…...
养老院管理系统(含源码+sql+视频导入教程+文档)
👉文末查看项目功能视频演示获取源码sql脚本视频导入教程视频 1 、功能描述 养老院管理系统拥有两种角色:管理员和护工 管理员:用户管理、老人信息管理、事故记录管理、入住费用管理、护工薪资管理、护工请假管理、床位管理、请假管理等 护…...
大数据的挑战是小文件
小文件可能会给存储平台及其支持的应用程序带来大问题。在 Google 上搜索 “small files performance” 会产生 2M 的结果。这篇博文将更深入地研究小文件问题,深入研究其根源并总结解决方案。 问题陈述 出于本讨论的目的,小文件通常被视为小于 64 KB …...
迁移学习案例-python代码
大白话 迁移学习就是用不太相同但又有一些联系的A和B数据,训练同一个网络。比如,先用A数据训练一下网络,然后再用B数据训练一下网络,那么就说最后的模型是从A迁移到B的。 迁移学习的具体形式是多种多样的,比如先用A训练…...
MCUboot 和 U-Boot区别
MCUboot 和 U-Boot 都是用于嵌入式系统的引导加载程序,但它们在一些方面存在区别: 功能特性 安全特性侧重不同 MCUboot :更专注于安全引导方面,强调安全启动、固件完整性验证和加密等安全功能。它提供了强大的安全机制来防止恶意…...
Apache OFBiz SSRF漏洞CVE-2024-45507分析
Apache OFBiz介绍 Apache OFBiz 是一个功能丰富的开源电子商务平台,包含完整的商业解决方案,适用于多种行业。它提供了一套全面的服务,包括客户关系管理(CRM)、企业资源规划(ERP)、订单管理、产…...
计算机毕业设计 饮食营养管理信息系统的设计与实现 Java实战项目 附源码+文档+视频讲解
博主介绍:✌从事软件开发10年之余,专注于Java技术领域、Python人工智能及数据挖掘、小程序项目开发和Android项目开发等。CSDN、掘金、华为云、InfoQ、阿里云等平台优质作者✌ 🍅文末获取源码联系🍅 👇🏻 精…...
828华为云征文|华为云Flexus云服务器X实例部署——盲盒抽奖商城系统以及编译发布小程序
盲盒抽奖商城系统使用 thinkphp6.0 uniapp 开发,做到了全移动端兼容。一个系统不仅可以打包 小程序 还可以 打包APP ,H5 华为云Flexus云服务器X实例在安装搭建盲盒商城小程序方面具有显著优势,这些优势主要体现在以下几个方面: …...
优化理论及应用精解【12】
文章目录 最优化基础基本概念一、目标函数二、约束条件三、约束函数 可行域与可行点可行点可行域可行点与可行域的关系示例 最优值与可行域的关系1. 最优值一定在可行域内取得2. 可行域定义了最优解的搜索空间3. 最优值的存在性与可行域的性质有关4. 最优值与可行域的边界关系示…...
excel 填充内容的公式
多行填充快捷方式: 使用“CtrlEnter”键,这样所有选中的空单元格前就会自动添加上相同的字符。 对于多行填充,Excel提供了几个快捷键来提高工作效率: “CtrlR”用于向右填充数据。如果你在表格的某一列输入了数据,选…...
这款工具在手,前端开发轻松搞定!
这款工具在手,前端开发轻松搞定! 引言 在之前的一篇文章中,已经给大家分享了一款AI助手。尽管该助手能够生成前端代码,但遗憾的是缺少了实时预览的功能。而现在,这一缺憾已经被弥补——你只需要描述你的设计想法&…...
Hadoop三大组件之HDFS(一)
HDFS 简介 HDFS (Hadoop Distributed File System) 是一个分布式文件系统,用于存储文件,采用目录树结构来定位文件。它由多个服务器组成,每个服务器在集群中扮演不同的角色。 适合一次写入,多次读取的场景。文件创建、写入和关闭…...
基于Hadoop的NBA球员大数据分析及可视化系统
作者:计算机学姐 开发技术:SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等,“文末源码”。 专栏推荐:前后端分离项目源码、SpringBoot项目源码、Vue项目源码、SSM项目源码 精品专栏:Java精选实战项目…...
docker容器安装nginx
docker安装nginx部署前端项目 拉取镜像 docker pull nginx:1.24.0运行容器 docker run --name nginx -p 80:80 -d nginx:1.24.0创建本地挂载的目录 mkdir -p /docker/nginx/conf mkdir -p /docker/nginx/log mkdir -p /docker/nginx/html复制运行的nginx配置到宿主机上 将…...
LC记录一:寻找旋转数组最小值、判断旋转数组是否存在给定元素
文章目录 33.搜索旋转排序数组81.搜索旋转排序数组||153.寻找旋转排序数组中的最小值154.寻找旋转排序数组中的最小值||参考链接 33.搜索旋转排序数组 https://leetcode.cn/problems/search-in-rotated-sorted-array/description/ 下面这张图片是LC154题官方题解提供的一个图…...
关于 JVM 个人 NOTE
目录 1、JVM 的体系结构 2、双亲委派机制 3、堆内存调优 4、关于GC垃圾回收机制 4.1 GC中的复制算法 4.2 GC中的标记清除算法 1、JVM 的体系结构 "堆"中存在垃圾而"栈"中不存在垃圾的原因: 堆(Heap) 用途ÿ…...
网络工程和信息安全专业应该考哪些证书?
网络工程和信息安全专业在校大学生可以考的网络信息安全方向证书有NISP一级、NISP二级、CISP-DSG、CISP-PTE! 一、NISP一级 NISP一级是网络安全行业入门证书! NISP一级报名条件:年满16周岁即可 NISP一级报名时间:随时可报 NI…...
ASP.NET Core 创建使用异步队列
示例图 在 ASP.NET Core 应用程序中,执行耗时任务而不阻塞线程的一种有效方法是使用异步队列。在本文中,我们将探讨如何使用 .NET Core 和 C# 创建队列结构以及如何使用此队列异步执行操作。 步骤 1:创建 EmailMessage 类 首先,…...
从Linux系统的角度看待文件-基础IO
目录 从Linux系统的角度看待文件 系统文件I/O open write read 文件操作的本质 vim中批量注释的方法 从Linux系统的角度看待文件 关于文件的共识: 1.空文件也要占用磁盘空间 2.文件内容属性 3.文件操作包括文件内容/文件属性/文件内容属性 4.文件路径文…...
总结之Coze 是一站式 AI Bot 开发平台——工作流使用及coze总结(三)
工作流介绍 工作流支持通过可视化的方式,对插件、大语言模型、代码块等功能进行组合,从而实现复杂、稳定的业务流程编排,例如旅行规划、报告分析等。 当目标任务场景包含较多的步骤,且对输出结果的准确性、格式有严格要求时&…...
汽车线束之故障诊断方案-TDR测试
当前,在汽车布局中的线束的性能要求越来越高。无法通过简单的通断测试就能满足性能传输要求。早起对智能化要求不高,比如没有激动雷达、高清摄像、中央CPU等。 近几年的智能驾驶对网络传输要求越来越高,不但是高速率,还需要高稳定…...
wordpress缩略图模糊/工具大全
在VMware里克隆出来的CentOS Linux,ifconfig...没有看到eth0,然后重启网卡又报下面错误。 故障现象: service network restartShutting down loopback insterface: …...
威海做网站多少钱/制作网站代码
什么是Mybatis?众所周知,MyBatis 是一款非常优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。不仅避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。还可以使用简单的 XML 或注解来配置和映射原生信息,将接口…...
为什么很多公司没自己的网站/百度seo哪家公司好
创建容器时指定网络模式 docker run -d -p 外部访问端口:容器内端口 --net"网络模式" -v 本机目录:容器内目录 --name"容器名称" 镜像名 要执行的角本 docker ps 查看启动的容器列表 docker ps -a 查看所有的容器列表 docker start 容器名称 …...
如何做电子书网站/爱站小工具圣经
如果一个网站的页面有一个部位经常用到时,可以写一个单独的jsp页面 <jsp:include page"xx.jsp"/>这条代码,单独写个文件来联合起来,类似于一个通用的页面 例如网站顶部的登陆注册栏...
菏泽网站建设价格/石家庄网站建设就找
2019独角兽企业重金招聘Python工程师标准>>> project ----> Bulid Automatically 勾选 创建或保存java类时,eclipse会自动编译该类并生成相应的.class文件 转载于:https://my.oschina.net/u/3285916/blog/873130...
外贸建站网站建设/爱战网关键词
文章内容由「Crossin的编程教室」撰写并授权使用近来知乎上冒出了大把的爬虫案例。这当然好事,具有一定 Python 基础的同学们可以更轻松地找到练手的小案例。不过我不是针对谁,我是说网上绝大多数的爬虫案例,都缺乏可操作性。案例是死的&…...