项目接触到新的框架技术:springboot+angularjs+bootstrap 其中稍微有点难度的就属于上传下载了
1,上传文件
前端样式如上所示,点击"导入模板文件",浏览选择文件,点击“导入”则上传文件信息到服务器,当上传成功后,在右侧显示文件名,并且提供下载功能。
上传样式
<span style="font-size:18px;"> <div class="row">
<div class="col-md-12">
<form name="newDeviceType" class="form-inline" role="form">
<div style="width: 100%; height: 20px; background-color: #E0ECFB">厂商模板文件</div>
<table class="table table-hover table-bordered">
<tr>
<td>
<div style="margin-left: 15px;" flow-init="addFlowInitObjModel" class="col-md-8" flow-file-success="uploadSuccess( $file, $message, $flow )">
<span class="btn btn-small btn-info" flow-btn flow-attrs="{accept:'application/xml'}">导入模板文件</span>
<span class="btn btn-small btn-info" ng-click="$flow.upload()">
导入</span>
<div ng-repeat="file in $flow.files" class="transfer-box">
<span ng-if="file.progress() !== 1">{{file.relativePath}} ({{file.size}}bytes)</span>
<div class="progress progress-striped" ng-class="{active: file.isUploading()}" ng-if="file.progress() !== 1">
<div class="progress-bar" role="progressbar"
aria-valuenow="{{file.progress() * 100}}"
aria-valuemin="0"
aria-valuemax="100"
ng-style="{width: (file.progress() * 100) + '%'}">
<span class="sr-only">{{file.progress()}}% Complete</span>
</div>
</div>
</div>
</div>
</td>
<td>
<div >
点击下载文件<a style="hidden" href="" ng-click = "downloadFile()" id="filename"></a>
</div>
</td>
</tr>
</table>
</form>
</div>
</div></span>
这个控件在初始化的时候flow-init=“addFlowInitObjModel”,去加载请求路径
<span style="font-size:18px;"> // 上传模板文件
$scope.addFlowInitObjModel = {
target: '/deviceType/importFile',
//target: '/deviceType/importFile',
chunkSize: 1 * 1024 * 1024,
simultaneousUploads: 1,
throttleProgressCallbacks: 1,
testChunks: false,
singleFile: true
};</span>
之后点击上传的时候会发送到后台请求:ng-click="$flow.upload()"
angularjs提供了上传之后成功之后的操作函数:flow-file-success="uploadSuccess( $file, $message, $flow )"
$file :上传的文件,可以获得该文件的大小($file.size),文件名($file.name)等文件相关的参数
$message :后台返回的数据信息(在这里需要用到后台返回的上传文件的路径信息,只要后台return 路径,前端就可以使用$message,至于flow没用到)
后台处理的方法就是,读取文件流,然后将流写入到文件中就行,最后保存文件到指定的地方。
<span style="font-size:18px;">/**
* 上传模板文件并解析保存到本地
* @throws IOException
* @throws NoSuchPaddingException
* @throws NoSuchAlgorithmException
*/
@RequestMapping(value="/importFile",method=RequestMethod.POST)
public String importLicense(MultipartHttpServletRequest req) throws Exception{
try{
//long modelId = Long.parseLong(req.getParameter("id"));
// 读取流
StringBuffer strBuff = new StringBuffer();
InputStream in = req.getFile("file").getInputStream();
Reader in2 = new InputStreamReader(in);
BufferedReader reader = new BufferedReader(in2);
String line = null;
while ((line = reader.readLine()) != null) {
strBuff.append(line);
}
String ldbstr = strBuff.toString();
in.close();
System.out.println(ldbstr);
// 创建文件保存路径
File file =new File(FILE_PATH);
//如果文件夹不存在则创建
if (!file .exists() && !file .isDirectory())
{
System.out.println("//不存在");
file .mkdir();
} else
{
System.out.println("//目录存在");
}
String filePath = FILE_PATH+"\\2.xml";
File fileName=new File(filePath);
if(!file.exists()) {
fileName.createNewFile();
}
// 写入到文件中
OutputStream os = new FileOutputStream(fileName);
os.write(ldbstr.getBytes());
os.flush();
os.close();
// 修改数据库中版本类型对应的模板文件地址
// DeviceType type = deviceTypeService.findOne(id);
// type.setTemplateFilePath(filePath);
// deviceTypeService.update(type);
return filePath;
}catch(Exception e){
e.printStackTrace();
return "";
}
}</span>
由于需要路径参数,就需要返回到前端进行数据绑定(如果你只需要上传,则不需要)
<span style="font-size:18px;"> // 模板文件上传成功之后,返回文件路径,将路径保存到数据库中,同时显示上传文件名称,提供下载链接
$scope.uploadSuccess = function ($file, $message, $flow){
var deviceType = $scope.deviceTypeManager.currentDeviceType;
deviceType.templateFilePath = $message;
deviceType.put();
document.getElementById("filename").innerHTML = $file.name;//制定位置显示文件名称
}</span>
2,文件下载
下载比较简单,只要有路径就行。同样需要读流,然后write到前端就行,在这里使用了iframe来处理下载
<span style="font-size:18px;">// 上传模板文件下载
$scope.downloadFile = function (){
var typeId = $scope.deviceTypeManager.currentDeviceType.id;
//$scope.deviceTypeManager.currentDeviceType.get("/deviceType/downloadmcode?id="+typeId);
//target: '/versionFile/downloadmcode?id = '+ typeId;
// $http.get('/deviceType/downloadmcode', {
// params: { id: typeId }
// });
var frame = $("<iframe style='display: none;'/>");
frame.appendTo($("body")).attr({ "src": "/deviceType/downloadmcode?id="+typeId, "display": "block" });
setTimeout(function () {
frame.remove();
}, 3000);
}</span>
其中src就是后台请求路径:
<span style="font-size:18px;">/**
* 下载
*/
@RequestMapping(value="/downloadmcode",method=RequestMethod.GET)
public void downloadMcode(HttpServletResponse response,@RequestParam Long id){
try {
System.out.println("-------------------------------下载版本文件对应设备类型id="+id+"------------------------------------");
DeviceType dt = deviceTypeService.findByid(id);
String filePath = dt.getTemplateFilePath();// 文件路径
String [] fp = filePath.split("\\\\");
String fileName = fp[fp.length-1];// 文件名称
System.out.println("-------------------------------上传文件名为="+fileName);
//下载机器码文件
response.setHeader("conent-type", "application/octet-stream");
response.setContentType("application/octet-stream");
response.setHeader("Content-Disposition", "attachment; filename=" + new String(fileName.getBytes("ISO-8859-1"), "UTF-8"));
OutputStream os = response.getOutputStream();
BufferedOutputStream bos = new BufferedOutputStream(os);
InputStream is = null;
is = new FileInputStream(filePath);
BufferedInputStream bis = new BufferedInputStream(is);
int length = 0;
byte[] temp = new byte[1 * 1024 * 10];
while ((length = bis.read(temp)) != -1) {
bos.write(temp, 0, length);
}
bos.flush();
bis.close();
bos.close();
is.close();
} catch (Exception e) {
e.printStackTrace();
}
}</span>
这样在chrome里面就可以看到下方的下载情况了
<pre name="code" class="html">