引入七牛云 js 上传

本贴最后更新于 2557 天前,其中的信息可能已经沧海桑田

云存储有很多种方式,这里介绍前端页面直接通过 js 上传的方式,应为这种方式页面友好,对浏览器压力也小

云存储也有很多好处:

1、释放服务器磁盘空间

2、减轻服务器磁盘 IO 压力

3、减轻服务器带宽压力

4、服务器故障无影响

遇到的坑:

1、bad uptoken

2、error:incorrect zone, please use up-z2.qiniu.com

3、怎样获取文件名

4、怎样设置上传路径

5、怎样获取外部链接

6、怎样获取上传进度

bad uptoken:

在官方文档里面,七牛要求服务器返回 uptoken 格式为

|

1

2

3

|

{

"uptoken"``: ``"0MLvWPnyya1WtPnXFy9KLyGHyFPNdZceomL..."

}

|

但是这很模糊,试了几次都提示 bad token,最终在 uploader 的 uptoken 里应该直接写入字符串格式,如果是服务器返回的的 uptoken 请去掉两端的双引号,否则报错

|

1

2

3

4

5

6

7

8

9

10

11

12

13

14

|

function getTokenMessage() {

var token;

$.ajax({

url:``"http://localhost:8080/LRVideo/appservice/basic/getJSUpToken"``,

async:``false``,

success:``function (data) {

token = data;

}

})

return token;

}

var token = getTokenMessage();

uptoken = token.substring(token.indexOf(``"\""``)+1,token.lastIndexOf(``"\""``));

|

error:incorrect zone, please use up-z2.qiniu.com:

七牛官方 js 默认上传地区为华东地区,如果不是华东的则需要修改官方 js

怎样获取文件名

|

1

2

3

4

5

6

7

8

|

'Key'``: ``function``(up, file) {

// 若想在前端对每个文件的key进行个性化处理,可以配置该函数

// 该配置必须要在unique_names: false,save_key: false时才生效

var Date = getNowFormatDate();

var fileName = file.name;

console.log(``"filename" + file.name);

return key

}

|

怎样设置上传路径:

|

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

|

function getNowFormatDate() {

var myDate = ``new Date();

var year = myDate.getFullYear();

var month = myDate.getMonth() + 1;

var day = myDate.getDate();

var hour = myDate.getHours();

var min = myDate.getMinutes();

var second = myDate.getSeconds();

if (month >= 0 && month <= 9) {

month = ``"0" + month;

}

if (day >= 0 && day <= 9) {

day = ``"0" + day;

}

if (hour >= 0 && hour <= 9) {

hour = ``"0" + hour;

}

if (min >= 0 && min <= 9) {

min = ``"0" + min;

}

if (second >= 0 && second <= 9) {

second = ``"0" + second;

}

var currentdate = year + ``"/" + month + ``"/" + day + ``"/" + hour + ``"/" + min + ``"/" + second;

return currentdate;

}

'Key'``: ``function``(up, file) {

// 若想在前端对每个文件的key进行个性化处理,可以配置该函数

// 该配置必须要在unique_names: false,save_key: false时才生效

var Date = getNowFormatDate();

var fileName = file.name;

var key = getNowFormatDate() + ``"/" + file.name;

// do something with key here

return key

}

|

怎样获取外部链接:

这里首先需要将 uploader 的 domain 设置一下:

|

1

|

domain: ``'http://onsoxm2o9.bkt.clouddn.com'``, // bucket域名,下载资源时用到,必需

|

请参照该存储空间的外链默认域名,可自行修改

|

1

2

3

4

5

6

7

8

9

10

11

12

13

|

'FileUploaded'``: ``function``(up, file, info) {

// 每个文件上传成功后,处理相关的事情

// 其中info是文件上传成功后,服务端返回的json,形式如:

// {

// "hash": "Fh8xVqod2MQ1mocfI4S4KpRL6D98",

// "key": "gogopher.jpg"

// }

// 查看简单反馈

var domain = up.getOption(``'domain'``);

var res = JSON.parse(info);

sourceLink = domain +``"/"``+ res.key; ``//获取上传成功后的文件的Url

console.log(``"sourceLink:" + sourceLink);

},

|

怎样获取上传进度:

|

1

2

3

4

5

6

|

'UploadProgress'``: ``function``(up, file) {

var progress = ``new FileProgress(file, ``'fsUploadProgress'``);

var chunk_size = plupload.parseSize(``this``.getOption(``'chunk_size'``));

progress.setProgress(file.percent + ``"%"``, file.speed, chunk_size);

console.log(``"Progress:" + file.percent + ``"%"``);

},

|

这里用到了 new FileProgress 函数,需要引入官方文档 demo 里的 ui.js 文件

QiniuUtils

|

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

|

package com.utils.qiniu;

import java.io.IOException;

import com.qiniu.common.QiniuException;

import com.qiniu.common.Zone;

import com.qiniu.http.Response;

import com.qiniu.storage.Configuration;

import com.qiniu.storage.UploadManager;

import com.qiniu.util.Auth;

import com.qiniu.util.StringMap;

/**

* 七牛上传工具

*

*/

public class QiniuUtils {

//设置好账号的ACCESS_KEY和SECRET_KEY

String ACCESS_KEY = ``"EybSUWG7TpxDnHze3FeYG5Dk9YzceUnITeAUIkQH"``;

String SECRET_KEY = ``"IcyUqBR2Jm5oAoeAkeMNN_hG4IRclDkRL0TMYGdv"``;

//要上传的空间

String bucketname = ``"cczb"``;

String bucketname2 = ``"cczb-video"``;

//密钥配置

Auth auth = Auth.create(ACCESS_KEY, SECRET_KEY);

///////////////////////指定上传的Zone的信息//////////////////

//第一种方式: 指定具体的要上传的zone

//注:该具体指定的方式和以下自动识别的方式选择其一即可

//要上传的空间(bucket)的存储区域为华东时

// Zone z = Zone.zone0();

//要上传的空间(bucket)的存储区域为华北时

// Zone z = Zone.zone1();

//要上传的空间(bucket)的存储区域为华南时

//Zone z = Zone.zone2();

//第二种方式: 自动识别要上传的空间(bucket)的存储区域是华东、华北、华南。

Zone z = Zone.autoZone();

Configuration c = ``new Configuration(z);

//创建上传对象

UploadManager uploadManager = ``new UploadManager(c);

//简单上传,使用默认策略,只需要设置上传的空间名就可以了

public String getUpToken() {

return auth.uploadToken(bucketname);

}

//js上传

//scope通过 bucket、key间接设置,deadline 通过 expires 间接设置

public String getJSUpToken() {

return auth.uploadToken(bucketname2);

}

public static void main(String[] args) {

StringMap policy = ``new StringMap().put(``"deadline"``, ``1491159381``).put(``"saveKey"``, ``"qiangge.jpg"``);

Auth auth = Auth.create(``"EybSUWG7TpxDnHze3FeYG5Dk9YzceUnITeAUIkQH"``, ``"IcyUqBR2Jm5oAoeAkeMNN_hG4IRclDkRL0TMYGdv"``);

System.err.println(auth.uploadToken(``"cczb-video:aaaaaaaa.jpg"``, ``"qiange2.jpg"``, ``3600``, policy));

}

/**

* 上传文件

* @author WangQiang 2017年2月10日 下午1:09:00

* @version 出彩V直播2.0

* @param FilePath 上传文件的真实路径

* @param key 上传到七牛后保存的文件名(可以包含路径),如 /test/test.png

* @return

*/

public boolean uploadFIle(String FilePath ,String key){

boolean flag = ``false``;

try {

//调用put方法上传

Response res = uploadManager.put(FilePath, key, getUpToken());

//上传成功

if``(res.statusCode == ``200``){

flag = ``true``;

System.out.println(``"七牛上传文件成功:" + res.bodyString());

}``else``{

flag = ``false``;

System.out.println(``"七牛上传文件失败(七牛原因或者七牛的配置原因):" + res.bodyString());

}

} ``catch (QiniuException e) {

Response r = e.response;

// 请求失败时打印的异常的信息

System.out.println(``"七牛上传文件失败(自己原因):" + r.toString());

try {

//响应的文本信息

System.out.println(r.bodyString());

} ``catch (QiniuException e1) {

//ignore

}

}

return flag;

}

//上传测试

public void uploadTest(String FilePath , String key) ``throws IOException {

try {

//调用put方法上传

Response res = uploadManager.put(FilePath, key, getUpToken());

//打印返回的信息

System.out.println(res.bodyString());

System.out.println(res.statusCode);

// System.out.println(res.toString());

if``(res.statusCode == ``200``){

System.out.println(``"上传成功"``);

}``else {

System.out.println(``"上传失败:" + res.bodyString());

}

} ``catch (QiniuException e) {

Response r = e.response;

// 请求失败时打印的异常的信息

System.out.println(r.toString());

try {

//响应的文本信息

System.out.println(r.bodyString());

} ``catch (QiniuException e1) {

//ignore

}

}

}

}

|

获取 uptoken

|

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

|

@RequestMapping``(value = ``"/uploadFile"``)

@ResponseBody

public Object uploadFile(HttpServletRequest request, HttpServletResponse response,

@RequestParam``(value = ``"file"``, required = ``false``) MultipartFile file) ``throws IOException {

// TODO 文件上传接口

String fileName = file.getOriginalFilename();

Map m = ``new HashMap();

BufferedOutputStream outputStream = ``null``;

try {

InputStream fileInputStream = file.getInputStream();

String datefolder = ``"/" + DateUtil.dateToString(``new Date(), ``"yyyy"``) + ``"/"

+ DateUtil.dateToString(``new Date(), ``"MM"``) + ``"/"

+ DateUtil.dateToString(``new Date(), ``"dd" + ``"/" + (Integer.parseInt(DateUtil.dateToString(``new Date(), ``"hh"``))+``0``) )

+ DateUtil.dateToString(``new Date(), ``"mm" + DateUtil.dateToString(``new Date(), ``"ss"``));``// 日期命名的文件夹

String webParentPath = ``new File(request.getSession().getServletContext().getRealPath(``"/"``)).getParent()

.replace(``"\\"``, ``"/"``);``// 当前WEB环境的上层目录

String realPath = webParentPath + ``"/gcrcsUploadFile" + datefolder;``// 文件上传到服务器的真实路径

File up = ``new File(realPath);

if (!up.exists()) {

up.mkdirs();

}

String newFileName = fileName;

String filePath = ``"/gcrcsUploadFile" + datefolder + ``"/" + newFileName;

outputStream = ``new BufferedOutputStream(``new FileOutputStream(``new File(realPath, newFileName)));

IOUtils.copy(fileInputStream, outputStream);

//这两个流一定要关闭,不然接下来上传到七牛上文件会缺失

fileInputStream.close();

outputStream.close();

logger.error(``"文件在服务器的绝对路径:"``+ ``new File(realPath, newFileName).toString());

logger.error(``"文件在服务器的相对路径:" + filePath);

// ++++++++上传文件到七牛 +++++++++

boolean flag = ``new QiniuUtils().uploadFIle( ``new File(realPath, newFileName).toString().replace(``"\\"``, ``"/"``) , filePath);

Map data = ``new HashMap();

// 保存附件

data.put(``"picUrl"``, filePath);

data.put(``"videoUrl"``, filePath);

m.put(``"status"``, ``0``);

m.put(``"msg"``, ``"上传成功"``);

m.put(``"data"``, data);

if``(flag){

logger.error(``"++++++++++ 上传文件" + filePath + ``"到七牛【成功】 ++++++++++"``);

//后期上传到云 成功 后把上传到本地的删除

}``else``{

m.put(``"status"``, ``1``);

m.put(``"msg"``, ``"上传失败"``);

m.put(``"data"``, data);

logger.error(``"++++++++++ 上传文件到七牛【失败】 ++++++++++"``);

}

} ``catch (Exception e) {

logger.error(``"error on deploy process, because of file input stream"``, e);

} ``finally {

outputStream.flush();

outputStream.close();

}

return m;

}

/**

* 七牛云上传获得uptoken

* @author wanningxi

* @return

*/

@ResponseBody

@RequestMapping``(``"/getJSUpToken"``)

public Object getJSUpToken() {

logger.error(``"获取七牛UpToken"``);

Map map = ``new HashMap();

try {

return new QiniuUtils().getJSUpToken();

} ``catch (Exception e) {

e.printStackTrace();

logger.error(``"Exception : " + e);

return ResultMapUtils.systemError(e);

}

}

|

qiniuTest.jsp

|

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

|

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>

html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">`

<``html``>

<``head``>

<``meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

<``title``>七牛云测试

<%-- 引入qiniu扩展 --%>

<``script src="${pageContext.request.contextPath}/resources/js/qiniu/jquery.min.js" type="text/javascript" charset="utf-8">

<%-- <``script src="${pageContext.request.contextPath}/resources/js/qiniu/moxie.js" type="text/javascript" charset="utf-8"> --%>

<%-- <``script src="${pageContext.request.contextPath}/resources/js/qiniu/plupload.full.min.js" type="text/javascript" charset="utf-8"> --%>

<%-- <``script src="${pageContext.request.contextPath}/resources/js/qiniu/qiniu.js" type="text/javascript" charset="utf-8"> --%>

<``script type="text/javascript" src="https://cdn.staticfile.org/plupload/2.1.8/plupload.full.min.js">

<``script type="text/javascript" src="https://cdn.staticfile.org/plupload/2.1.9/moxie.min.js">

<``script type="text/javascript" src="https://cdn.staticfile.org/qiniu-js-sdk/1.0.14-beta/qiniu.min.js">

<``script src="${pageContext.request.contextPath}/resources/js/qiniu/ui.js" type="text/javascript" charset="utf-8">

``

<``body``>

<``p class="tip1">本demo实现的图片预览功能需要浏览器支持data URL,IE8+以及其他标准浏览器都是支持的

<``div id="container">

<``a class="btn btn-default btn-lg " id="pickfiles" style="width:160px" href="#" >

<``i class="glyphicon glyphicon-plus">

<``span``>选择文件

``

``

``

``

<``script type="text/javascript">

var time = getNowFormatDate();

var token = getTokenMessage();

uptoken = token.substring(token.indexOf("\"")+1,token.lastIndexOf("\""));

var uploader = Qiniu.uploader({

runtimes: 'html5,flash,html4', // 上传模式,依次退化

browse_button: 'pickfiles', // 上传选择的点选按钮,必需

// 在初始化时,uptoken,uptoken_url,uptoken_func三个参数中必须有一个被设置

// 切如果提供了多个,其优先级为uptoken > uptoken_url > uptoken_func

// 其中uptoken是直接提供上传凭证,uptoken_url是提供了获取上传凭证的地址,如果需要定制获取uptoken的过程则可以设置uptoken_func

uptoken : uptoken, // uptoken是上传凭证,由其他程序生成

// uptoken_url: 'http://localhost:8080/LRVideo/appservice/basic/getJSUpToken', // Ajax请求uptoken的Url,强烈建议设置(服务端提供)

// uptoken_func: function(file){ // 在需要获取uptoken时,该方法会被调用

// // do something

// return uptoken;

// },

get_new_uptoken: false, // 设置上传文件的时候是否每次都重新获取新的uptoken

// downtoken_url: '/downtoken',

// Ajax请求downToken的Url,私有空间时使用,JS-SDK将向该地址POST文件的key和domain,服务端返回的JSON必须包含url字段,url值为该文件的下载地址

// unique_names: true, // 默认false,key为文件名。若开启该选项,JS-SDK会为每个文件自动生成key(文件名)

// save_key: true, // 默认false。若在服务端生成uptoken的上传策略中指定了sava_key,则开启,SDK在前端将不对key进行任何处理

domain: 'http://onsoxm2o9.bkt.clouddn.com', // bucket域名,下载资源时用到,必需

container: 'container', // 上传区域DOM ID,默认是browser_button的父元素

max_file_size: '100000mb', // 最大文件体积限制

flash_swf_url: 'path/of/plupload/Moxie.swf', //引入flash,相对路径

max_retries: 3, // 上传失败最大重试次数

dragdrop: true, // 开启可拖曳上传

drop_element: 'container', // 拖曳上传区域元素的ID,拖曳文件或文件夹后可触发上传

chunk_size: '0mb', // 分块上传时,每块的体积

auto_start: true, // 选择文件后自动上传,若关闭需要自己绑定事件触发上传

//x_vars : {

// 查看自定义变量

// 'time' : function(up,file) {

// var time = (new Date()).getTime();

// do something with 'time'

// return time;

// },

// 'size' : function(up,file) {

// var size = file.size;

// do something with 'size'

// return size;

// }

//},

init: {

'FilesAdded': function(up, files) {

plupload.each(files, function(file) {

// 文件添加进队列后,处理相关的事情

});

},

'BeforeUpload': function(up, file) {

// 每个文件上传前,处理相关的事情

},

'UploadProgress': function(up, file) {

var progress = new FileProgress(file, 'fsUploadProgress');

var chunk_size = plupload.parseSize(this.getOption('chunk_size'));

progress.setProgress(file.percent + "%", file.speed, chunk_size);

console.log("Progress:" + file.percent + "%");

},

'FileUploaded': function(up, file, info) {

// 每个文件上传成功后,处理相关的事情

// 其中info是文件上传成功后,服务端返回的json,形式如:

// {

// "hash": "Fh8xVqod2MQ1mocfI4S4KpRL6D98",

// "key": "gogopher.jpg"

// }

// 查看简单反馈

var domain = up.getOption('domain');

var res = JSON.parse(info);

sourceLink = domain +"/"+ res.key; //获取上传成功后的文件的Url

console.log("sourceLink:" + sourceLink);

},

'Error': function(up, err, errTip) {

//上传出错时,处理相关的事情

},

'UploadComplete': function() {

//队列文件处理完毕后,处理相关的事情

},

'Key': function(up, file) {

// 若想在前端对每个文件的key进行个性化处理,可以配置该函数

// 该配置必须要在unique_names: false,save_key: false时才生效

var Date = getNowFormatDate();

var fileName = file.name;

var key = getNowFormatDate() + "/" + file.name;

// do something with key here

return key

}

}

});

// domain为七牛空间对应的域名,选择某个空间后,可通过 空间设置->基本设置->域名设置 查看获取

// uploader为一个plupload对象,继承了所有plupload的方法

function getTokenMessage() {

var token;

$.ajax({

url:"http://localhost:8080/LRVideo/appservice/basic/getJSUpToken",

async:false,

success:function (data) {

token = data;

}

})

return token;

}

function getNowFormatDate() {

var myDate = new Date();

var year = myDate.getFullYear();

var month = myDate.getMonth() + 1;

var day = myDate.getDate();

var hour = myDate.getHours();

var min = myDate.getMinutes();

var second = myDate.getSeconds();

if (month >= 0 && month <= 9) {

month = "0" + month;

}

if (day >= 0 && day <= 9) {

day = "0" + day;

}

if (hour >= 0 && hour <= 9) {

hour = "0" + hour;

}

if (min >= 0 && min <= 9) {

min = "0" + min;

}

if (second >= 0 && second <= 9) {

second = "0" + second;

}

var currentdate = year + "/" + month + "/" + day + "/" + hour + "/" + min + "/" + second;

return currentdate;

}

``

|

  • JavaScript

    JavaScript 一种动态类型、弱类型、基于原型的直译式脚本语言,内置支持类型。它的解释器被称为 JavaScript 引擎,为浏览器的一部分,广泛用于客户端的脚本语言,最早是在 HTML 网页上使用,用来给 HTML 网页增加动态功能。

    710 引用 • 1173 回帖 • 176 关注

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...

推荐标签 标签

  • React

    React 是 Facebook 开源的一个用于构建 UI 的 JavaScript 库。

    192 引用 • 291 回帖 • 439 关注
  • Bug

    Bug 本意是指臭虫、缺陷、损坏、犯贫、窃听器、小虫等。现在人们把在程序中一些缺陷或问题统称为 bug(漏洞)。

    77 引用 • 1741 回帖
  • 开源

    Open Source, Open Mind, Open Sight, Open Future!

    395 引用 • 3408 回帖
  • sts
    2 引用 • 2 回帖 • 146 关注
  • 工具

    子曰:“工欲善其事,必先利其器。”

    273 引用 • 679 回帖 • 1 关注
  • IBM

    IBM(国际商业机器公司)或万国商业机器公司,简称 IBM(International Business Machines Corporation),总公司在纽约州阿蒙克市。1911 年托马斯·沃森创立于美国,是全球最大的信息技术和业务解决方案公司,拥有全球雇员 30 多万人,业务遍及 160 多个国家和地区。

    16 引用 • 53 回帖 • 118 关注
  • 创造

    你创造的作品可能会帮助到很多人,如果是开源项目的话就更赞了!

    172 引用 • 990 回帖
  • GitHub

    GitHub 于 2008 年上线,目前,除了 Git 代码仓库托管及基本的 Web 管理界面以外,还提供了订阅、讨论组、文本渲染、在线文件编辑器、协作图谱(报表)、代码片段分享(Gist)等功能。正因为这些功能所提供的便利,又经过长期的积累,GitHub 的用户活跃度很高,在开源世界里享有深远的声望,并形成了社交化编程文化(Social Coding)。

    207 引用 • 2031 回帖
  • 星云链

    星云链是一个开源公链,业内简单的将其称为区块链上的谷歌。其实它不仅仅是区块链搜索引擎,一个公链的所有功能,它基本都有,比如你可以用它来开发部署你的去中心化的 APP,你可以在上面编写智能合约,发送交易等等。3 分钟快速接入星云链 (NAS) 测试网

    3 引用 • 16 回帖 • 5 关注
  • 深度学习

    深度学习(Deep Learning)是机器学习的分支,是一种试图使用包含复杂结构或由多重非线性变换构成的多个处理层对数据进行高层抽象的算法。

    40 引用 • 40 回帖 • 1 关注
  • Android

    Android 是一种以 Linux 为基础的开放源码操作系统,主要使用于便携设备。2005 年由 Google 收购注资,并拉拢多家制造商组成开放手机联盟开发改良,逐渐扩展到到平板电脑及其他领域上。

    333 引用 • 323 回帖 • 71 关注
  • 分享

    有什么新发现就分享给大家吧!

    242 引用 • 1746 回帖 • 1 关注
  • Swagger

    Swagger 是一款非常流行的 API 开发工具,它遵循 OpenAPI Specification(这是一种通用的、和编程语言无关的 API 描述规范)。Swagger 贯穿整个 API 生命周期,如 API 的设计、编写文档、测试和部署。

    26 引用 • 35 回帖 • 12 关注
  • Spark

    Spark 是 UC Berkeley AMP lab 所开源的类 Hadoop MapReduce 的通用并行框架。Spark 拥有 Hadoop MapReduce 所具有的优点;但不同于 MapReduce 的是 Job 中间输出结果可以保存在内存中,从而不再需要读写 HDFS,因此 Spark 能更好地适用于数据挖掘与机器学习等需要迭代的 MapReduce 的算法。

    74 引用 • 46 回帖 • 550 关注
  • 创业

    你比 99% 的人都优秀么?

    82 引用 • 1398 回帖 • 1 关注
  • V2Ray
    1 引用 • 15 回帖
  • Node.js

    Node.js 是一个基于 Chrome JavaScript 运行时建立的平台, 用于方便地搭建响应速度快、易于扩展的网络应用。Node.js 使用事件驱动, 非阻塞 I/O 模型而得以轻量和高效。

    138 引用 • 268 回帖 • 201 关注
  • WiFiDog

    WiFiDog 是一套开源的无线热点认证管理工具,主要功能包括:位置相关的内容递送;用户认证和授权;集中式网络监控。

    1 引用 • 7 回帖 • 547 关注
  • RESTful

    一种软件架构设计风格而不是标准,提供了一组设计原则和约束条件,主要用于客户端和服务器交互类的软件。基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存等机制。

    30 引用 • 114 回帖 • 3 关注
  • 周末

    星期六到星期天晚,实行五天工作制后,指每周的最后两天。再过几年可能就是三天了。

    14 引用 • 297 回帖 • 1 关注
  • Mobi.css

    Mobi.css is a lightweight, flexible CSS framework that focus on mobile.

    1 引用 • 6 回帖 • 696 关注
  • ActiveMQ

    ActiveMQ 是 Apache 旗下的一款开源消息总线系统,它完整实现了 JMS 规范,是一个企业级的消息中间件。

    19 引用 • 13 回帖 • 628 关注
  • Ruby

    Ruby 是一种开源的面向对象程序设计的服务器端脚本语言,在 20 世纪 90 年代中期由日本的松本行弘(まつもとゆきひろ/Yukihiro Matsumoto)设计并开发。在 Ruby 社区,松本也被称为马茨(Matz)。

    7 引用 • 31 回帖 • 176 关注
  • OpenStack

    OpenStack 是一个云操作系统,通过数据中心可控制大型的计算、存储、网络等资源池。所有的管理通过前端界面管理员就可以完成,同样也可以通过 Web 接口让最终用户部署资源。

    10 引用 • 9 关注
  • V2EX

    V2EX 是创意工作者们的社区。这里目前汇聚了超过 400,000 名主要来自互联网行业、游戏行业和媒体行业的创意工作者。V2EX 希望能够成为创意工作者们的生活和事业的一部分。

    17 引用 • 236 回帖 • 420 关注
  • 京东

    京东是中国最大的自营式电商企业,2015 年第一季度在中国自营式 B2C 电商市场的占有率为 56.3%。2014 年 5 月,京东在美国纳斯达克证券交易所正式挂牌上市(股票代码:JD),是中国第一个成功赴美上市的大型综合型电商平台,与腾讯、百度等中国互联网巨头共同跻身全球前十大互联网公司排行榜。

    14 引用 • 102 回帖 • 401 关注
  • Log4j

    Log4j 是 Apache 开源的一款使用广泛的 Java 日志组件。

    20 引用 • 18 回帖 • 43 关注