Flow.js and Java Servlet上传文件0字节
Flow.js and Java Servlet upload file 0 bytes
我按照说明和对 java servlet 的调用在我的项目中添加了 flow.js:
localhost:8080/WebExample/UploadImgServlet?flowChunkNumber=1&flowChunkSize=1048576&flowCurrentChunkSize=693916&flowTotalSize=693916&flowIdentifier=693916-image2png&flowFilename=image2.png&flowRelativePath=image2.png&flowTotalChunks=1`
在我的 servlet 中,我获得了 url 的所有参数(flowChuckNumber、flowChuckSize 等),但是当我尝试获取文件 (request.getInputStream()) 时,它是空的并且上传了 0 个字节.
问题出在哪里?任何的想法?
我发现了一个类似的问题,但它与 PHP...
我的代码:
HTML(图片显示):
...
...
<div flow-init="{singleFile:true}"
flow-file-added="!!{png:1,gif:1,jpg:1,jpeg:1}[$file.getExtension()]"
flow-files-submitted="$flow.upload()"
flow-file-success="$file.msg = $message">
<div class="drop" flow-drop ng-class="dropClass">
<md-button class="md-raised md-primary" type="file" flow-btn>Upload Image</md-button>
<b>OR</b>
Drag And Drop your image here
</div>
<div class="thumbnail" ng-show="!$flow.files.length">
<img src="http://www.placehold.it/200x150/EFEFEF/AAAAAA&text=no+image" alt="Image"/>
</div>
<div class="thumbnail" ng-show="$flow.files.length">
<img flow-img="$flow.files[0]" />
</div>
<table>
<tr ng-repeat="file in $flow.files">
<td>{{$index+1}}</td>
<td>{{file.name}}</td>
<td>{{file.msg}}</td>
</tr>
</table>
</div>
...
...
应用AngularJs:
var app = angular.module("webexample", ['ngMaterial', 'ngNotify','uiGmapgoogle-maps','flow'])
.config(['flowFactoryProvider', function (flowFactoryProvider) {
flowFactoryProvider.defaults = {
target: '/WebExample/UploadImgServlet',
permanentErrors: [404, 500, 501],
maxChunkRetries: 1,
chunkRetryInterval: 5000,
simultaneousUploads: 1
};
flowFactoryProvider.on('catchAll', function (event) {
console.log('catchAll', arguments);
});
// Can be used with different implementations of Flow.js
// flowFactoryProvider.factory = fustyFlowFactory;
}])
.directive('appDownloadUrl', [function () {
return {
restrict: 'A',
link: function(scope, element, attrs) {
element.bind('dragstart', function (event) {
var config = scope.$eval(attrs.appDownloadUrl);
if (!config.disabled) {
var data = config.mime + ':' + config.name + ':' + window.location.href + config.url;
console.log("data: "+data);
event.dataTransfer.setData('DownloadURL', data);
}
});
}
};
}])
.directive("appDragstart", [function () {
return function(scope, element, attrs) {
element.bind('dragstart', function (event) {
scope.$eval(attrs.appDragstart);
});
}
}]).directive("appDragend", [function () {
return function(scope, element, attrs) {
element.bind('dragend', function (event) {
scope.$eval(attrs.appDragend);
});
}
}]).run(function ($rootScope) {
$rootScope.dropEnabled = true;
});
我的 Servlet(我遵循了这个 example):
protected void doService(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException
{
LOGGER.debug("[UploadImgServlet - doService] - init");
int resumableChunkNumber = getResumableChunkNumber(request);
ResumableInfo info = getResumableInfo(request);
//info contains all flow parameters of the url.
RandomAccessFile raf = new RandomAccessFile(info.resumableFilePath, "rw");
//Seek to position
raf.seek((resumableChunkNumber - 1) * info.resumableChunkSize);
//Save to file
InputStream is = request.getInputStream();
long readed = 0;
long content_length = request.getContentLength();
//**PROBLEM: request.getContentLength return -1 so read 0 bytes**
byte[] bytes = new byte[1024 * 100];
while(readed < content_length) {
int r = is.read(bytes);
if (r < 0) {
break;
}
raf.write(bytes, 0, r);
readed += r;
}
raf.close();
...
...
您无需担心内容长度。 HttpServletRequest
将在正确的点终止输入流。一直读到流结束。
我想要一个库来上传比默认 html 输入具有更多选项和视觉吸引力(从文件夹中删除文件、缩略图等)的图像,但我无法使用 Flowjs 和 Java Servlet,所以我又找了一个库:
https://github.com/danialfarid/ng-file-upload
https://angular-file-upload.appspot.com/
有了这个库,我发现它很容易与 Java Servlet 一起使用。
如果有人找到使用 Flowjs 的方法,我不会将此 post 标记为已解决。
输入流将为空,因为 flowjs 默认使用 MultiPart 发布内容。
Java 代码的作者指定 "Octet" 应该用于上传,而不是多部分。
UploadServlet accepts Resumable.js Upload with 'octet'
您需要将 "method:octet" 添加到您的初始化中,
<div flow-init="{singleFile:true, method:octet}"
我正在使用 Spring,所以我只是使用 MultipartHttpServletRequest 来获取 MultiPart 的发布数据,因为 MultiPart 更常见。
这是我收到文件内容的方式:
Iterator<String> itr = request.getFileNames();
/* Iterate each file, there should only be one/one chunk */
while (itr.hasNext()) {
fileUploaded = request.getFile(itr.next());
raf.write(fileUploaded.getBytes());
}
raf.close();
我不得不对提供的 java 代码做更多的修复,因为它估计要接收的块数是错误的,所以我只使用了 "flowTotalChunks" 参数。
我按照说明和对 java servlet 的调用在我的项目中添加了 flow.js:
localhost:8080/WebExample/UploadImgServlet?flowChunkNumber=1&flowChunkSize=1048576&flowCurrentChunkSize=693916&flowTotalSize=693916&flowIdentifier=693916-image2png&flowFilename=image2.png&flowRelativePath=image2.png&flowTotalChunks=1`
在我的 servlet 中,我获得了 url 的所有参数(flowChuckNumber、flowChuckSize 等),但是当我尝试获取文件 (request.getInputStream()) 时,它是空的并且上传了 0 个字节.
问题出在哪里?任何的想法?
我发现了一个类似的问题,但它与 PHP...
我的代码:
HTML(图片显示):
...
...
<div flow-init="{singleFile:true}"
flow-file-added="!!{png:1,gif:1,jpg:1,jpeg:1}[$file.getExtension()]"
flow-files-submitted="$flow.upload()"
flow-file-success="$file.msg = $message">
<div class="drop" flow-drop ng-class="dropClass">
<md-button class="md-raised md-primary" type="file" flow-btn>Upload Image</md-button>
<b>OR</b>
Drag And Drop your image here
</div>
<div class="thumbnail" ng-show="!$flow.files.length">
<img src="http://www.placehold.it/200x150/EFEFEF/AAAAAA&text=no+image" alt="Image"/>
</div>
<div class="thumbnail" ng-show="$flow.files.length">
<img flow-img="$flow.files[0]" />
</div>
<table>
<tr ng-repeat="file in $flow.files">
<td>{{$index+1}}</td>
<td>{{file.name}}</td>
<td>{{file.msg}}</td>
</tr>
</table>
</div>
...
...
应用AngularJs:
var app = angular.module("webexample", ['ngMaterial', 'ngNotify','uiGmapgoogle-maps','flow'])
.config(['flowFactoryProvider', function (flowFactoryProvider) {
flowFactoryProvider.defaults = {
target: '/WebExample/UploadImgServlet',
permanentErrors: [404, 500, 501],
maxChunkRetries: 1,
chunkRetryInterval: 5000,
simultaneousUploads: 1
};
flowFactoryProvider.on('catchAll', function (event) {
console.log('catchAll', arguments);
});
// Can be used with different implementations of Flow.js
// flowFactoryProvider.factory = fustyFlowFactory;
}])
.directive('appDownloadUrl', [function () {
return {
restrict: 'A',
link: function(scope, element, attrs) {
element.bind('dragstart', function (event) {
var config = scope.$eval(attrs.appDownloadUrl);
if (!config.disabled) {
var data = config.mime + ':' + config.name + ':' + window.location.href + config.url;
console.log("data: "+data);
event.dataTransfer.setData('DownloadURL', data);
}
});
}
};
}])
.directive("appDragstart", [function () {
return function(scope, element, attrs) {
element.bind('dragstart', function (event) {
scope.$eval(attrs.appDragstart);
});
}
}]).directive("appDragend", [function () {
return function(scope, element, attrs) {
element.bind('dragend', function (event) {
scope.$eval(attrs.appDragend);
});
}
}]).run(function ($rootScope) {
$rootScope.dropEnabled = true;
});
我的 Servlet(我遵循了这个 example):
protected void doService(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException
{
LOGGER.debug("[UploadImgServlet - doService] - init");
int resumableChunkNumber = getResumableChunkNumber(request);
ResumableInfo info = getResumableInfo(request);
//info contains all flow parameters of the url.
RandomAccessFile raf = new RandomAccessFile(info.resumableFilePath, "rw");
//Seek to position
raf.seek((resumableChunkNumber - 1) * info.resumableChunkSize);
//Save to file
InputStream is = request.getInputStream();
long readed = 0;
long content_length = request.getContentLength();
//**PROBLEM: request.getContentLength return -1 so read 0 bytes**
byte[] bytes = new byte[1024 * 100];
while(readed < content_length) {
int r = is.read(bytes);
if (r < 0) {
break;
}
raf.write(bytes, 0, r);
readed += r;
}
raf.close();
...
...
您无需担心内容长度。 HttpServletRequest
将在正确的点终止输入流。一直读到流结束。
我想要一个库来上传比默认 html 输入具有更多选项和视觉吸引力(从文件夹中删除文件、缩略图等)的图像,但我无法使用 Flowjs 和 Java Servlet,所以我又找了一个库:
https://github.com/danialfarid/ng-file-upload
https://angular-file-upload.appspot.com/
有了这个库,我发现它很容易与 Java Servlet 一起使用。
如果有人找到使用 Flowjs 的方法,我不会将此 post 标记为已解决。
输入流将为空,因为 flowjs 默认使用 MultiPart 发布内容。 Java 代码的作者指定 "Octet" 应该用于上传,而不是多部分。
UploadServlet accepts Resumable.js Upload with 'octet'
您需要将 "method:octet" 添加到您的初始化中,
<div flow-init="{singleFile:true, method:octet}"
我正在使用 Spring,所以我只是使用 MultipartHttpServletRequest 来获取 MultiPart 的发布数据,因为 MultiPart 更常见。
这是我收到文件内容的方式:
Iterator<String> itr = request.getFileNames();
/* Iterate each file, there should only be one/one chunk */
while (itr.hasNext()) {
fileUploaded = request.getFile(itr.next());
raf.write(fileUploaded.getBytes());
}
raf.close();
我不得不对提供的 java 代码做更多的修复,因为它估计要接收的块数是错误的,所以我只使用了 "flowTotalChunks" 参数。