当前位置: 首页 > 编程日记 > 正文

ueditor与七牛云存储结合

2019独角兽企业重金招聘Python工程师标准>>> hot3.png

摘要:  ueditor与七牛云存储结合,主要是表单api.

ueditor上传图片到七牛云存储

ueditor结合七牛传图片

传统上,图片是存在自己的服务器上(图片->自己服务器),如果使用了云存储之后,有两种方式存到云端:

  • (图片->自己服务器->云存储)
  • (图片->云存储) 
    明显第二种节省自己服务器的压力,结合七牛来说就是使用七牛的form api。

很多开发网络应用的用户需要从他们自己的客户端访问七牛云存储。传统上,用户会将数据上传至他们的业务服务器,然后由业务服务器转发至云存储。这种做法增加了客户业务服务器的压力,并且增加了用户的流量成本。七牛云存储允许用户从客户端直接上传数据,而无需到业务服务器中转。这种模式具有更广泛的用途和灵活性。

在客户端直接上传数据的基础上,为方便用户业务服务器和客户端的信息交互,七牛云存储还提供了回调业务服务器的功能。用户可以在一次数据上传请求中,完成客户端和业务服务器的数据交换。在此基础上,七牛云存储还允许用户利用魔法变量和自定义变量设定回调中所传递的数据。

七牛的试炼

这次使用七牛SDK中的一些东西,结合jsp完成ueditor和七牛的结合。 
项目放在osc@git上,可以下载源码对照查看。

1http://git.oschina.net/duoduo3_69/QiNiuWithUeditor.git

开发前的准备与注意事项说明

1.请将tomcat中server.xml里面context的path改为”“,这样访问时你的站点访问地址为http://你的域名/,(注意没有工程名字),例如:

1<Context docBase="QiNiu" path="" reloadable="true" source="org.eclipse.jst.jee.server:QiNiu"/></Host>

2.因为ueditor上传文件使用的是swfuplod,使用云存储回调是flash需要查找你的网站有没有crossdomain.xml,所以请在WebContent放一个crossdomain.xml,这里提供一个简单的配置,如果有别的需求可以自行定制。

1<?xml version="1.0"?>
2<!DOCTYPE cross-domain-policy SYSTEM "http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd">
3<cross-domain-policy>
4<allow-access-from domain="*" />
5<allow-http-request-headers-from
6domain="*" headers="*" />
7</cross-domain-policy>

Let's rock

与ueditor结合前的准备工作

首先从表单开始

1<form method="post" action="http://up.qiniu.com/" enctype="multipart/form-data">
2<input name="key" type="hidden" value="<resource key>">
3<input name="x:<custom_field_name>" type="hidden" value="<custom value>">
4<input name="token" type="hidden" value="<token>">
5<input name="file" type="file" />
6...
7</form>

这段代码是七牛api里面给的,结合七牛的文档可以看出,表单api必须有两个字段,一个是token,一个是file,file也就是文件,token简单的说就是七牛验证你身份的一个加密编码的串,七牛上传的图片的action就是http://up.qiniu.com/。

在此输入图片描述

生成token

token的生成有一套规则,官网api有介绍,结合七牛java的sdk非常简单就可以搞定。 
首先把sdk中需要的东西搞出来,因为不会用到里面所有的类,而且七牛sdk里面分了好多包,自己的项目七牛所有的东西我都扔在com.qiniu下,看着比较顺眼。

七牛的sdk 
在此输入图片描述

需要用到的类和依赖的jar包(sdk是maven搞的,会自动下载,拖过来就行) 
在此输入图片描述 
在此输入图片描述

ok,找到里面的Config.java

01public class Config {
02
03public static String USER_AGENT;
04
05/**
06* You can get your accesskey from <a href="https://dev.qiniutek.com"
07* target="blank"> https://dev.qiniutek.com </a>
08*/
09public static String ACCESS_KEY = "<Please apply your access key>";
10
11/**
12* You can get your accesskey from <a href="https://dev.qiniutek.com"
13* target="blank"> https://dev.qiniutek.com </a>
14*/
15public static String SECRET_KEY = "<Apply your secret key here, and keep it secret!>";
16
17public static String RS_HOST = "http://rs.qbox.me";
18
19public static String UP_HOST = "http://up.qbox.me";
20
21public static String RSF_HOST = "http://rsf.qbox.me";
22
23}

把ACCESS_KEY,和SECRET_KEY这两个东西给填上,登录七牛,不要选择空间,然后点击账号设置就会看到密钥,粘到这个里面。 
在此输入图片描述

建立图片空间

下一步在七牛空间里建一个空间,专门来存图片,请将空间设置为公开空间,根据七牛的规则,公开空间里面的文件都是外链直接可以访问的,而私用空间想要下载需要费一番功夫。因为我们需要把图片存在云里面供别人访问,所以将这个空间设置为公开即可。例如我的空间为duoduo。 
在此输入图片描述

生成token

在sdk里面会发先有test这一组测试用的包,其中有一个Uptoken,这个就是用来生成token的,将里面的bucketName设置为你的图片空间,例如我的是duoduo。PutPolicy里面的参数请参照官网api。

01package com.qiniu;
02
03import java.util.UUID;
04
05import org.json.JSONException;
06
07import com.qiniu.Mac;
08import com.qiniu.Config;
09import com.qiniu.PutPolicy;
10
11public class Uptoken {
12public final static String makeUptoken() throws AuthException,
13JSONException {
14
15Mac mac = new Mac(Config.ACCESS_KEY, Config.SECRET_KEY);
16String bucketName = "duoduo";
17PutPolicy putPolicy = new PutPolicy(bucketName);
18// 可以根据自己需要设置过期时间,sdk默认有设置,具体看源码
19// putPolicy.expires = getDeadLine();
20putPolicy.returnUrl = "http://127.0.0.1/QiNiuCallback.jsp";
21putPolicy.returnBody = "{\"name\": $(fname),\"size\": \"$(fsize)\",\"w\": \"$(imageInfo.width)\",\"h\": \"$(imageInfo.height)\",\"key\":$(etag)}";
22String uptoken = putPolicy.token(mac);
23return uptoken;
24}
25
26/**
27* 生成32位UUID 并去掉"-"
28*/
29public static String getUUID() {
30return UUID.randomUUID().toString().replaceAll("-", "");
31}
32}

上传流程

七牛的上传流程如下图

在此输入图片描述

用户上传后,七牛怎样将上传结果返回给用户呢?有两种方式,简单的说一个是get方法传值,一个是post传值。returnUrl用的就是get(301跳转),而callbackUrl 则是post(异步回调)。

在此输入图片描述 
在此输入图片描述

可以看到我在Uptoken使用的是returnUrl,注意这里要写绝对路径,而returnBody里面可以参照api来设置,我在这里取了文件上传前的名字(name),现在的名字(key),并把他们拼成了json的格式,实际上仅仅需要key就可以和ueditor集成。另外,policy里面的deadline不需要操心,sdk里面有默认的设置,当然你也可以自行设置,不过注意,时间一定要大于当前时间*。

1putPolicy.returnUrl = "http://127.0.0.1/QiNiuCallback.jsp";
2putPolicy.returnBody = "{\"name\": $(fname),\"size\": \"$(fsize)\",\"w\": \"$(imageInfo.width)\",\"h\": \"$(imageInfo.height)\",\"key\":$(etag)}";

集成ueditor

ok,准备工作完毕,开始集成ueditor,上官网下载最新的jsp版本,当前为1.2.6.1 Jsp ,utf8版。解压,扔在项目里面WebContent。

找到ueditor.config.js这个配置文件,更改一些配置,使ueditor与七牛结合。

首先是URL,这是为了让项目能找到ueditor里面的一些文件,还记得注意事项里面说的将server.xml更改的问题吗,就是为了/ueditor/准备的,当然你也可以自行配置,不过可能会遇到一些路径的问题,比如returnUrl。

1var URL = window.UEDITOR_HOME_URL || "/ueditor/";

然后是图片上传的部分,imageUrl就是七牛传图片的地址是http://up.qiniu.com/,imagePath则是用户访问图片的一个修正路径,从哪里找呢?在设置的图片空间(duoduo)里面的空间设置->域名设置那里查看,如图。七牛需要两个字段,一个是file,一个是token,file在ueditor中需要设置两次,第一次是在这里设置,第二次和token都在image.html里面设置,后面会说。

1//图片上传配置区
2,imageUrl:"http://up.qiniu.com/"            //图片上传提交地址
3,imagePath:"http://duoduo.u.qiniudn.com/"                     //图片修正地址,引用了fixedImagePath,如有特殊需求,可自行配置
4//七牛结合需要改成file
5,imageFieldName:"file"

在此输入图片描述

下一步,在index.html里面显示ueditor,没什么说的,代码如下。

01<!DOCTYPE html>
02<html>
03<head>
04<meta charset="UTF-8">
05<title>ueditor 七牛</title>
06<link rel="stylesheet" type="text/css" href="/QiNiu/ueditor/themes/default/css/ueditor.css"/>
07<script type="text/javascript" src="/QiNiu/ueditor/ueditor.config.js"></script>
08<script type="text/javascript" src="/QiNiu/ueditor/ueditor.all.js"></script>
09</head>
10<body>
11<div style="width:800px;margin:20px auto 40px;">
12<script type="text/plain" id="editor" name="content" style="width:100%;height:200px;"></script>
13</div>
14<script type="text/javascript">
15UE.getEditor('editor')
16</script>
17</body>
18</html>

接下来,在ueditor/dialogs/image下找到image.html,这是图片上传的配置文件,image文件夹底下的东西都是和图片上传有关的,如果需要更高级的配置,请参照源码(image.js),结合ueditor.config.js里面的参数,进行操作。

image.html在这个文件加载的时候,我们需要从后台Uptoken那里拿到这次上传的token(token每次上传都是不一样的,因为他会自动加上deadline进行Base64编码),使用ajax,我用的是jquery。在image.html里面加了一个hidden的input框,暂时存一个变量,也就是需要传给七牛的token。

1<input id="qiniu_token" type="hidden" name="token" />

然后找到下面的标签,ajax取值,这里用的是一个Uptoken.jsp,后面介绍。注意我贴上的代码editor.setOpt部分有一个变量imageFieldName:“file”,这就是file的第二次修改地方。

01<script type="text/javascript">
02$(function(){
03$.get("/QiNiu/Uptoken.jsp", function(data) {
04$("#qiniu_token").val(data["token"]);
05});
06});
07//全局变量
08var imageUrls = [],          //用于保存从服务器返回的图片信息数组
09selectedImageCount = 0;  //当前已选择的但未上传的图片数量
10
11editor.setOpt({
12imageFieldName:"file",
13compressSide:0,
14maxImageSideLength:900
15});
16......

ueditor怎么在图片上传的时候传附加的参数呢?首先找到utils.domReady(function()这个部分地下的ext:'{"param1":"value1", "param2":"value2"}',,把这行注释掉,以为以前用的时候如果这行没注释自己的附加值传不过去。往下找在 $G("upload").onclick = function () {里面找到postParams,加上你想传的参数。

1var postParams = {
2"dir":baidu.g("savePath").value,
3"token":$("#qiniu_token").val()
4};

下面介绍上传和回调有关的两个jsp

1* Uptoken.jsp,这是为了获得uptoken,并且把token包成json的。
2* QiNiuCallback.jsp,七牛returnUrl的回调地址,需要将七牛的状态码转换为ueditor的状态码,这样才能正确显示。

Uptoken.jsp,使用org.json-chargebee-1.0.jar这个包,这是sdk里面自动下的。然后调用 Uptoken.makeUptoken()取到token放到json里面,ok。

01<%@ page language="java" contentType="text/html; charset=utf-8"
02pageEncoding="utf-8"%>
03<%@ page import="com.qiniu.*,org.json.JSONObject"%>
04<%
05request.setCharacterEncoding("utf-8");
06response.setCharacterEncoding("utf-8");
07response.setContentType("application/json");
08JSONObject json = new JSONObject();
09json.append("token", Uptoken.makeUptoken());
10response.getWriter().print(json.toString());
11%>

现在你就可以上传了。传图之前,打开狐火firebug,查看网络面板里面查看网络的信息,当你点击开始上传按钮之后,就会看到网络面板里面七牛以301get方式回调你当时returnUrl里面设定的地址,打开七牛的空间可以看到你上传成功的图片。

QiNiuCallback.jsp,图片上传之后七牛主要有两种状态,一种是成功,一种是失败,成功就会按照你在policy里面设置的returnBody的格式回调,如果失败,则会返回一个json格式类似{“error”:“错误信息”},而ueditor里面需要一个json格式的state来告诉他图片上传的状态,如果state是"SUCCESS”,则ueditor认为此次上传成功,其余状态均为失败。所以我的回调jsp如下。

01<%@ page language="java" contentType="text/html; charset=utf-8"
02pageEncoding="utf-8"%>
03<%@ page import="com.qiniu.*,org.json.JSONObject"%>
04<%
05request.setCharacterEncoding("utf-8");
06response.setCharacterEncoding("utf-8");
07String upload_ret = request.getParameter("upload_ret");
08JSONObject callback = new JSONObject(Base64Coder.decode(upload_ret));
09JSONObject json = new JSONObject();
10if (callback.has("error")) {
11json.put("state", callback.get("error"));
12} else {
13json.put("original", callback.get("name"));
14json.put("url", callback.get("key")+"-v001");
15json.put("state", "SUCCESS");
16}
17response.getWriter().print(json.toString());
18%>

在这里加了一个"v001”,json.put("url", callback.get("key")+"-v001");这是什么呢?七牛会存你上传的原图,如果原图过大,显示效果可能不会很好,因此,可以使用七牛的缩略图功能。首先新建一个v001的缩略图模板(名字随便起)。在空间的数据处理,图片处理那个位置。 
设置了缩略图之后怎么访问呢?就是原图的外链地址加上样式分隔符加上缩略图模板名字,例如图片的key为XXXAAA,样式分隔符为-,模板名为v001,则缩略图url为XXXAAA-v001。

在此输入图片描述

另外Base64Coder.decode这个是解码的类,因为七牛在回调的时候回调的字符串也经过了Base64编码。sdk里面没找到解码的方法,需要加上这个解码的类,代码如下。

01package com.qiniu;
02
03import org.apache.commons.codec.binary.Base64;
04import org.apache.commons.codec.binary.StringUtils;
05
06public class Base64Coder {
07
08public static String decode(String s) {
09return StringUtils.newStringUtf8(Base64.decodeBase64(s));
10}
11
12public static String encode(String s) {
13return Base64.encodeBase64String(StringUtils.getBytesUtf8(s));
14}
15}

至此,图片本地上传功能结束。

将ueditor中的图片模块的在线管理功能和七牛结合

第一步,更改ueditor.config.js,找到imageManagerUrl,虽然和ueditor里面的里面在线管理jsp的名字一样,不过请注意他的路径。imageManagerPath则是一个图片修正路径,和之前图片上传的修正路径对应。

1//图片在线管理配置区
2,imageManagerUrl: "imageManager.jsp"       //图片在线管理的处理地址
3,imageManagerPath:"http://duoduo.u.qiniudn.com/"

然后是imageManager.jsp,经过ueditor里面imageManager.jsp和Uploader.java两个文件的研究发现,imageManager.jsp实际上是会返回一个/图片aue_separate_ue/图片bue_separate_ue/图片cue_separate_ue的字符串,然后image.js会将这个串根据ue_separate_ue切割,并且在前面加上imageManagerPath组成最终的一个图片列表。搞明白机制之后不难根据七牛的sdk写出如下的代码。

01<%@ page language="java" pageEncoding="utf-8"%>
02<%@ page import="java.util.*,com.qiniu.*"%>
03<%@ page import="java.io.*"%>
04<%@ page import="javax.servlet.ServletContext"%>
05<%@ page import="javax.servlet.http.HttpServletRequest"%>
06<%
07Mac mac = new Mac(Config.ACCESS_KEY, Config.SECRET_KEY);
08RSFClient client = new RSFClient(mac);
09ListPrefixRet list = client.listPrifix("duoduo", "", "", 10);
10StringBuffer sb = new StringBuffer();
11for (ListItem item : list.results) {
12sb.append("/");
13sb.append(item.key);
14sb.append("ue_separate_ue");
15}
16String imgStr = sb.toString();
17if (imgStr != "") {
18imgStr = imgStr
19.substring(0, imgStr.lastIndexOf("ue_separate_ue"))
20.replace(File.separator, "/").trim();
21}
22out.print(imgStr);
23%>

至此,ueditor和七牛云存储图片功能的全部整合就结束了。图片上传的配置主要在image.html里面。

转载于:https://my.oschina.net/juzhang/blog/177014

相关文章:

微服务网关从零搭建——(七)更改存储方式为oracle

资源准备&#xff1a; 下载开源项目 新建oracle表&#xff1a; -- ---------------------------- -- Table structure for OcelotGlobalConfiguration -- ----------------------------CREATE TABLE OcelotGlobalConfiguration (Id NUMBER(11) NOT NULL ,GatewayName NVARCHAR2…

Rocksdb 的优秀代码(一) -- 工业级分桶算法实现分位数p50,p99,p9999

文章目录基本概念普通的分位数计算Rocksdb中的应用rocksdb中的分桶算法结果展示rocksdb 分桶算法实现一些总结 和 相关论文我们知道一个完整的监控系统必须存在p99/p999等分位数指标&#xff0c;作为系统可用性的评判标准之一。而像开源监控系统中做的很不错的grafana和prometh…

Java项目:前后端分离疫情防疫平台设计和实现(java+springmvc+VUE+node.js+mybatis+mysql+springboot+redis+jsp)

源码获取&#xff1a;博客首页 "资源" 里下载&#xff01; 主要技术&#xff1a;Java、springmvc、VUE、node.js、mybatis、mysql、tomcat、jquery、layui、bootstarp、JavaScript、html、css、jsp、log4j等一些常见的基本技术。 主要模块功能有&#xff1a; 管理员…

js里的匿名函数 数组排序

// 匿名函数&#xff1a;其实就是函数的简写形式 var method function(){ alert("123"); } method(); // 匿名函数可以用于事件的处理 function func(){ alert("456"); } window.οnlοadfunc; window.οnlοadfunction(){ alert("加载完成&#xff0…

oracle监听器动态注册于静态注册的区别

2019独角兽企业重金招聘Python工程师标准>>> 1, oracle 10g 用netca方式建立的都默认为动态注册方式 2&#xff0c;如果想改为静态注册的方式则在listener.ora 中加入如下内容即可 SID_LIST_LISTENER (SID_LIST (SID_DESC (SID_NAME PLSExtProc) (ORACLE_HOME …

什么是Singleton?

Singleton&#xff1a;在Java中即指单例设计模式&#xff0c;它是软件开发中最常用的设计模式之一。 单&#xff1a;指唯一 例&#xff1a;指实例 单例设计模式&#xff0c;即某个类在整个系统中只能有一个实例对象可被获取和使用的代码模式。 要点&#xff1a; 一、单例类只能…

磁盘I:O 性能指标 以及 如何通过 fio 对nvme ssd,optane ssd, pmem 性能摸底

文章目录1. 磁盘I/O性能指标1.1 性能指标1.2 I/O 观测1.2.1 磁盘I/O 观测1.2.2 进程I/O观测2. Fio 性能测试2.1 环境准备2.2 测试维度选择2.3 测试2.3.1 optane ssd和nvme ssd性能测试2.3.2 aep性能测试(intel persistent memory)真正测试之前 我们需要清楚 评判磁盘I/O性能 是…

Java项目:旅游网站管理系统设计和实现(java+springboot+jsp+mysql+spring)

源码获取&#xff1a;博客首页 "资源" 里下载&#xff01; 运行环境: java jdk 1.8 IDE环境&#xff1a; IDEA tomcat环境&#xff1a; Tomcat 7.x,8.x,9.x版本均可 主要功能说明&#xff1a; 管理员角色包含以下功能&#xff1a;管理员登录,用户管理,旅游路线管理,…

稀疏矩阵十字链表表示

类型定义 #include<stdio.h> #include<malloc.h> #include<stdlib.h> #define MAX 100 /*稀疏矩阵的十字链表表示&#xff1a;非零元素节点与表头节点公用一种类型 */ typedef struct matrixnode {int row,col;struct matrixnode *right,*down;union{int val…

thrift框架使用C++

2019独角兽企业重金招聘Python工程师标准>>> 1. 编写thrift接口文件student.thrift struct Student{1: i32 sno,2: string sname,3: bool ssex,4: i16 sage, } service Serv{i32 put(1: Student s), } 2. 用“thrift -r --gen cpp student.thrift”在gen-cpp文件夹中…

shell编程:实现shell字符串连接功能

功能&#xff1a;实现shell字符串连接功能 a0 s1test. s2.wav s3.mp3 s40 s500str"sox ./${s1}${a}${s2} ./${a}${s3}"./tts -c bcgirl.0.0.4.bin -b 1 -i input.txt -s 1.0 -speed 1.0 $str rm ./*.wav转载于:https://www.cnblogs.com/kay2018/p/10673110.html

一文运维zookeeper

文章目录1. zookeeper生产环境的安装配置1.1 软件配置1.2 硬件配置1.3 日志配置文件1.4 配置三节点的zookeeper集群2. zookeeper的监控方法2.1 four letters命令2.2 JMX 监控方式3. 通过zookeeper observer实现跨地域部署3.1 什么是observer3.2 observer 提升 写性能3.3 observ…

Java项目:电商书城平台系统设计和实现(java+springboot+mysql+spring+jsp)

源码获取&#xff1a;博客首页 "资源" 里下载&#xff01; JAVA springboot 电商书城平台系统(已调试) 主要实现了书城网站的浏览、加入购物车操作、订单操作、支付操作、分类查看、搜索、以及后台上传图书信息以及订单管理和一些基本操作功能 主要功能截图如下&…

(周三赛)FATE

//题意 打怪的经验值 &#xff0c;消耗忍耐度 看升级后还能保留的最大忍耐度 用 背包去做&#xff0c;不是很会啊 T T Description 最近xhd正在玩一款叫做FATE的游戏&#xff0c;为了得到极品装备&#xff0c;xhd在不停的杀怪做任务。久而久之xhd开始对杀怪产生的厌恶感&#…

ASP.NET MVC 3中ViewBag, ViewData和 TempData

ViewBag, ViewData十分类似&#xff0c;都可用于把数据从controller传递到view。 ViewBag是WebViewPage中的一个属性&#xff0c;它的类型是dynamic。dynamic类型可以理解为&#xff0c;编译器在编译到这种类型时&#xff0c;会跳过类型检查&#xff0c;而在运行时做这些事情。…

如何在指定文件夹下进入jupyter notebook

第一步&#xff1a; 打开 Anaconda Prompt 第二步&#xff1a; 查看文件夹所在路径 例如&#xff1a;你有个jupyterwork文件夹在 D:\ 路径下 第三步&#xff1a; 在Anaconda Prompt依次输入一下命令&#xff1a; d:cd jupyterworkjupyter notebook完成。转载于:https://www.cnb…

Go 分布式学习利器(16) -- go中可复用的package构建

通过本文&#xff0c;你将了解go 语言中如何将自己的package构建到项目中 以及如何将远程&#xff08;github&#xff09;的package构建到项目中。 1. 构建本地的package package 是可复用模块的基本单元&#xff0c;以首字母大写的函数实现来表明可被包外代码访问代码的pack…

JQuery UI

//拖拽插件 draggable <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns"http://www.w3.org/1999/xhtml"><head><title>拖曳…

Java项目:房屋租赁系统设计和实现(java+ssm+mysql+spring+jsp)

源码获取&#xff1a;博客首页 "资源" 里下载&#xff01; 主要功能描述&#xff1a; 1.登录管理&#xff1a;主要有管理员登录和租客登录 2.房源列表以及添加房源功能&#xff1a; 3.租赁合同管理以及在租房源和已退租房源信息管理: 4.看房申请和退租申请管理&a…

学习网页制作中如何在正确选取和使用 CSS 单位

在 CSS 测量系统中&#xff0c;有好几种单位&#xff0c;如像素、百分比、英寸、厘米等等&#xff0c;Web 开发人员很难了解哪些单位在何处使用&#xff0c;如何使用。很多人习惯了总是使用同一种单位&#xff0c;但这一决定可能会严重限制你的设计的执行。 这里推荐的《Which …

SPOJ GSS3-Can you answer these queries III-分治+线段树区间合并

Can you answer these queries III SPOJ - GSS3 这道题和洛谷的小白逛公园一样的题目。 传送门&#xff1a; 洛谷 P4513 小白逛公园-区间最大子段和-分治线段树区间合并(单点更新、区间查询) 代码: 1 #include<bits/stdc.h>2 using namespace std;3 typedef long long l…

Zookeeper ZAB协议原理浅析

文章目录前言1. 基本角色和概念2. Leader Election3. Discovery4. Synchronization5. BroadCast后记前言 DTCC 要在下周一到周三要在北京举办&#xff0c;身边有不少人都去参加了&#xff0c;领略中国最为领先的一些公司的自研存储技术。 阿里自研polardb&#xff0c;polardb-…

Java项目:仓库管理系统设计和实现(java+ssm+springboot+layui)

源码获取&#xff1a;博客首页 "资源" 里下载&#xff01; 主要功能模块 1.用户模块管理&#xff1a;用户登录、用户注册、用户的查询、添加、删除操作、 2.客户信息管理&#xff1a;.客户列表的展示、添加、修改、删除操作、 3.供应商管理&#xff1a;供应商详情…

Java Web 中的一些问题

http://localhost:8080/struts2demo/online/userLogin.jsp 请求模式 :// 主机名名称&#xff08;或者服务器名称&#xff09; : 端口 / Servlet容器的名称&#xff08;通常为项目名称&#xff09; / 自定义的网页文件夹名或者映射中的文件包名 / 网页名称及其后缀或者响应动作…

《零成本实现Web自动化测试--基于Selenium》第一章 自动化测试基础

第一篇 Selenium 和WebDriver工具篇 第一章 自动化测试基础 1.1 初识自动化测试 自动化测试有两种常见方式 1.1.1 代码驱动测试&#xff0c;又叫测试驱动开发&#xff08;TDD&#xff09; 1.1.2 图形用户接口测试: 测试框架产生用户接口事件&#xff08;例如键盘敲击&#x…

第11章 AOF持久化

AOF持久化在硬盘上保存的是对Redis进行的逻辑操作&#xff0c;类似InnoDB中的bin log。说白了就是你对一个Redis输入了哪些语句&#xff0c;AOF文件都会原封不动的保存起来&#xff0c;等到需要回复Redis的时候再把这些语句执行一遍。 11.1 AOF持久化的实现 AOF简单的理解是把执…

Go 语言实现字符串匹配算法 -- BF(Brute Force) 和 RK(Rabin Karp)

今天介绍两种基础的字符串匹配算法&#xff0c;当然核心还是熟悉一下Go的语法&#xff0c;巩固一下基础知识 BF(Brute Force)RK(Rabin Karp) 源字符串&#xff1a;src, 目标字符串:dest&#xff1b; 确认dest是否是src 的一部分。 BF算法很简单暴力&#xff0c;维护两个下标…

Java项目:前后端分离网上手机商城平台系统设计和实现(java+vue+redis+springboot+mysql+ssm)

源码获取&#xff1a;博客首页 "资源" 里下载&#xff01; 主要模块设计如下&#xff1a; 前后端主要技术&#xff1a;Java springboot springMVC mybatis mysql vue jquery node.js redis 1) 用户注册和登录功能&#xff1a;。 2) 用户信息的管理以及角色的…

利用AutoSPSourceBuilder和Autospinstaller自动安装SharePoint Server 2013图解教程——Part 1...

这是一篇对之前 《利用AutoSPSourceBuilder和Autospinstaller自动安装SharePoint Server 2013图解教程——Part 2》的补充。本篇博客将对AutoSPSourceBuilder的使用进行说明。 AutoSPSourceBuilder介绍 下载AutoSPSourceBuilder点击进入AutoSPSourceBuilder的官网&#xff0c;找…

Git 版本还原命令

转载&#xff1a;https://blog.csdn.net/yxlshk/article/details/79944535 1.需求场景&#xff1a; 在利用github实现多人协作开发项目的过程中&#xff0c;有时会出现错误提交的情况&#xff0c;此时我们希望能撤销提交操作&#xff0c;让当前版本回到提交前的样子或者某一个版…