引入七牛云 js 上传

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

云存储有很多种方式,这里介绍前端页面直接通过 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 网页增加动态功能。

    730 引用 • 1284 回帖

相关帖子

欢迎来到这里!

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

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

推荐标签 标签

  • CSDN

    CSDN (Chinese Software Developer Network) 创立于 1999 年,是中国的 IT 社区和服务平台,为中国的软件开发者和 IT 从业者提供知识传播、职业发展、软件开发等全生命周期服务,满足他们在职业发展中学习及共享知识和信息、建立职业发展社交圈、通过软件开发实现技术商业化等刚性需求。

    14 引用 • 155 回帖 • 1 关注
  • Typecho

    Typecho 是一款博客程序,它在 GPLv2 许可证下发行,基于 PHP 构建,可以运行在各种平台上,支持多种数据库(MySQL、PostgreSQL、SQLite)。

    12 引用 • 67 回帖 • 447 关注
  • MySQL

    MySQL 是一个关系型数据库管理系统,由瑞典 MySQL AB 公司开发,目前属于 Oracle 公司。MySQL 是最流行的关系型数据库管理系统之一。

    694 引用 • 537 回帖
  • 智能合约

    智能合约(Smart contract)是一种旨在以信息化方式传播、验证或执行合同的计算机协议。智能合约允许在没有第三方的情况下进行可信交易,这些交易可追踪且不可逆转。智能合约概念于 1994 年由 Nick Szabo 首次提出。

    1 引用 • 11 回帖
  • 机器学习

    机器学习(Machine Learning)是一门多领域交叉学科,涉及概率论、统计学、逼近论、凸分析、算法复杂度理论等多门学科。专门研究计算机怎样模拟或实现人类的学习行为,以获取新的知识或技能,重新组织已有的知识结构使之不断改善自身的性能。

    77 引用 • 37 回帖
  • 快应用

    快应用 是基于手机硬件平台的新型应用形态;标准是由主流手机厂商组成的快应用联盟联合制定;快应用标准的诞生将在研发接口、能力接入、开发者服务等层面建设标准平台;以平台化的生态模式对个人开发者和企业开发者全品类开放。

    15 引用 • 127 回帖
  • 叶归
    14 引用 • 62 回帖 • 26 关注
  • Shell

    Shell 脚本与 Windows/Dos 下的批处理相似,也就是用各类命令预先放入到一个文件中,方便一次性执行的一个程序文件,主要是方便管理员进行设置或者管理用的。但是它比 Windows 下的批处理更强大,比用其他编程程序编辑的程序效率更高,因为它使用了 Linux/Unix 下的命令。

    125 引用 • 74 回帖
  • SendCloud

    SendCloud 由搜狐武汉研发中心孵化的项目,是致力于为开发者提供高质量的触发邮件服务的云端邮件发送平台,为开发者提供便利的 API 接口来调用服务,让邮件准确迅速到达用户收件箱并获得强大的追踪数据。

    2 引用 • 8 回帖 • 512 关注
  • GitBook

    GitBook 使您的团队可以轻松编写和维护高质量的文档。 分享知识,提高团队的工作效率,让用户满意。

    3 引用 • 8 回帖 • 2 关注
  • V2EX

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

    16 引用 • 236 回帖 • 237 关注
  • JSON

    JSON (JavaScript Object Notation)是一种轻量级的数据交换格式。易于人类阅读和编写。同时也易于机器解析和生成。

    53 引用 • 190 回帖 • 3 关注
  • 小说

    小说是以刻画人物形象为中心,通过完整的故事情节和环境描写来反映社会生活的文学体裁。

    32 引用 • 108 回帖
  • 脑图

    脑图又叫思维导图,是表达发散性思维的有效图形思维工具 ,它简单却又很有效,是一种实用性的思维工具。

    32 引用 • 100 回帖
  • WordPress

    WordPress 是一个使用 PHP 语言开发的博客平台,用户可以在支持 PHP 和 MySQL 数据库的服务器上架设自己的博客。也可以把 WordPress 当作一个内容管理系统(CMS)来使用。WordPress 是一个免费的开源项目,在 GNU 通用公共许可证(GPLv2)下授权发布。

    46 引用 • 114 回帖 • 160 关注
  • Word
    13 引用 • 41 回帖
  • Netty

    Netty 是一个基于 NIO 的客户端-服务器编程框架,使用 Netty 可以让你快速、简单地开发出一个可维护、高性能的网络应用,例如实现了某种协议的客户、服务端应用。

    49 引用 • 33 回帖 • 44 关注
  • 持续集成

    持续集成(Continuous Integration)是一种软件开发实践,即团队开发成员经常集成他们的工作,通过每个成员每天至少集成一次,也就意味着每天可能会发生多次集成。每次集成都通过自动化的构建(包括编译,发布,自动化测试)来验证,从而尽早地发现集成错误。

    15 引用 • 7 回帖 • 3 关注
  • Eclipse

    Eclipse 是一个开放源代码的、基于 Java 的可扩展开发平台。就其本身而言,它只是一个框架和一组服务,用于通过插件组件构建开发环境。

    76 引用 • 258 回帖 • 632 关注
  • 房星科技

    房星网,我们不和没有钱的程序员谈理想,我们要让程序员又有理想又有钱。我们有雄厚的房地产行业线下资源,遍布昆明全城的 100 家门店、四千地产经纪人是我们坚实的后盾。

    6 引用 • 141 回帖 • 616 关注
  • SpaceVim

    SpaceVim 是一个社区驱动的模块化 vim/neovim 配置集合,以模块的方式组织管理插件以
    及相关配置,为不同的语言开发量身定制了相关的开发模块,该模块提供代码自动补全,
    语法检查、格式化、调试、REPL 等特性。用户仅需载入相关语言的模块即可得到一个开箱
    即用的 Vim-IDE。

    3 引用 • 31 回帖 • 112 关注
  • Oracle

    Oracle(甲骨文)公司,全称甲骨文股份有限公司(甲骨文软件系统有限公司),是全球最大的企业级软件公司,总部位于美国加利福尼亚州的红木滩。1989 年正式进入中国市场。2013 年,甲骨文已超越 IBM,成为继 Microsoft 后全球第二大软件公司。

    107 引用 • 127 回帖 • 341 关注
  • Elasticsearch

    Elasticsearch 是一个基于 Lucene 的搜索服务器。它提供了一个分布式多用户能力的全文搜索引擎,基于 RESTful 接口。Elasticsearch 是用 Java 开发的,并作为 Apache 许可条款下的开放源码发布,是当前流行的企业级搜索引擎。设计用于云计算中,能够达到实时搜索,稳定,可靠,快速,安装使用方便。

    117 引用 • 99 回帖 • 201 关注
  • JRebel

    JRebel 是一款 Java 虚拟机插件,它使得 Java 程序员能在不进行重部署的情况下,即时看到代码的改变对一个应用程序带来的影响。

    26 引用 • 78 回帖 • 688 关注
  • Notion

    Notion - The all-in-one workspace for your notes, tasks, wikis, and databases.

    10 引用 • 77 回帖
  • 浅吟主题

    Jeffrey Chen 制作的思源笔记主题,项目仓库:https://github.com/TCOTC/Whisper

    2 引用 • 32 回帖
  • LeetCode

    LeetCode(力扣)是一个全球极客挚爱的高质量技术成长平台,想要学习和提升专业能力从这里开始,充足技术干货等你来啃,轻松拿下 Dream Offer!

    209 引用 • 72 回帖