最近做了一个下载文档的功能,于是联想到了上传功能,于是自己研究了一下后台语言是java的情况下怎样实现将文件上传到指定的目录,以下是项目的语言:

1、后台用jfinal框架

2、前台用jquery提交

3、样式用了bootstrap和jquery

中间还因为需求发现了一个不错的jquery库,后面会有讲解,不多啰嗦了,下面直接开始吧:

一、前端

1、先添加一个上传文件的按钮:

<button id="upload_blog" type="button" class="btn btn-info btn-lg" >
<span class="glyphicon glyphicon-upload">上传</span>
</button>

注意:button和span中的class都是bootstrap中的样式,直接拿过来用,不过用之前是要引入bootstrap相关样式的!!!

2、点击上传文件的按钮弹出一个选择上传文件的modal(模态框):

<div class="modal fade" id="myModal" role="dialog">
<div class="modal-dialog"> <!-- Modal content-->
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" id="close">&times;</button>
<h4 class="modal-title">上传文件</h4>
</div>
<div class="modal-body">
<div id="sizecheck" class="alert alert-danger">
提示:上传文件大小不能超过50M!
</div>
<form action="" enctype="multipart/form-data" id="upload_file_form" accept="application/msword">
<span style="display: inline;margin-left: 50px;">请选择上传文件:</span><input id="file1" type="file" name="up_blog" style="display: inline;">
<div id="filecheck" class="alert alert-danger"><strong>Warning!</strong>只能上传pdf和word两种类型的文件</div>
</form>
</div>
<div class="modal-footer">
<button id="yes_blog" type="button" class="btn btn-info">确定</button>
<button id="no_blog" type="button" class="btn btn-info" data-dismiss="modal">取消</button>
</div>
</div>
</div>
</div>

上面是弹出的选择文件的模态框,点击确定按钮会向后台发送上传文件的请求:

3、提交表单,将上传请求发送到服务器:

$("#upload_blog").click(function(){
$("#myModal").modal();
$("#filecheck").attr("hidden","hidden");
$("#sizecheck").attr("hidden","hidden"); $("#yes_blog").click(function(){
$("#upload_file_form").ajaxSubmit({
url:"/blog/uploadFile",
type:"POST",
dataType:"json",
async:false,
data:{},
beforeSubmit:function(){
//先判断文件类型--只能上传word、pdf或txt等文本类型的文件
var fileName = $("#file1").val();
var extension = fileName.substr(fileName.lastIndexOf("."));
if(extension==".pdf" || extension==".doc" || extension==".docx"){
$("#filecheck").attr("hidden","hidden");
}else{
$("#filecheck").removeAttr("hidden");
return false;
} //判断上传文件的大小
var fileSize = $("#file1")[0].files[0].size;
//获取的文件大小单位是比特byte
if((fileSize/(1024*1024))>50){
$("#sizecheck").removeAttr("hidden");
return false;
}else{
$("#sizecheck").attr("hidden","hidden");
}
},
success:function(m){
if(m.error=="1"){
alert(m.message);
clearFile();
return false;
}else{
$("#close").trigger("click");
toastr.success("文件上传成功!");
clearFile();
return true;
}
}
});
});
});

上面的JS代码就会将上传文件的表单提交到后台,在提交表单之前进行了一系列的验证:
第一:判断文件类型,只能上传word、pdf和txt等文本类型,否则会有提示并阻止表单的提交;

第二:判断文件的大小是否超过50M,否则会有提示并阻止表单的提交;

二、后台:

1、jfinal的controller中完成uploadFile方法:

/**
* 上传文件
* @throws IOException
* @throws FileNotFoundException
*/
public void uploadFile(){
/*String fileDate = new SimpleDateFormat("yyyy-MM-dd").format(new Date());*/
UploadFile uploadFile = this.getFile();
JSONObject jsonObj = new JSONObject();
String fileName = uploadFile.getFileName();
File file = uploadFile.getFile();
String extension = fileName.substring(fileName.lastIndexOf("."));
String prefix;
if(extension.equals(".jpg")||extension.equals(".png")||extension.equals(".gif")){
prefix = "images";
}else{
prefix = "docs";
}
String filePath = file.getAbsolutePath();
File targetDir = new File(filePath.substring(0,filePath.indexOf(fileName))+prefix);
File targetFile = new File(targetDir.getPath()+"/"+fileName);
if(!targetDir.exists()){
targetDir.mkdir();
}
//字节数组方式上传文件
//jsonObj = BlogService.sevice.uploadByByte(filePath, fileName, file, targetFile);
//通道方式上传文件
jsonObj = BlogService.sevice.uploadByChanel(filePath, fileName, file, targetFile);
renderJson(jsonObj.toJSONString());
}

注意:在上面的代码中可以看到有【字节数组方式上传文件】和【通道方式上传文件】,这是我在实现过程中发现的,并对这两种方法都做了实现:

2、在service中编写业务逻辑,有两种方式:

第一种方式:字节数组方式

/**
* 使用字节的方式上传文件
* @param filePath
* @param fileName
* @param sourceFile
* @param targetFile
* @return
*/
public JSONObject uploadByByte(String filePath,String fileName,File sourceFile,File targetFile){
FileInputStream fis = null;
FileOutputStream fos = null;
JSONObject jsonObj = new JSONObject();
try { fis = new FileInputStream(sourceFile);
int fileSize = fis.available();
fos = new FileOutputStream(targetFile);
byte[] file_byte = new byte[fileSize];
if(fis.read(file_byte,0, fileSize)!=-1){
fos.write(file_byte, 0, fileSize);
}
jsonObj.put("error", 0);
sourceFile.delete();
} catch (FileNotFoundException e) {
jsonObj.put("error", 1);
jsonObj.put("message", "上传出现错误,请稍后再上传");
}catch (Exception e) {
jsonObj.put("error", 1);
jsonObj.put("message", "文件写入服务器出现错误,请稍后再上传");
}finally{
try {
fis.close();
fos.close();
deleteAllFile(new File(filePath.substring(0,filePath.indexOf(fileName))));
} catch (IOException e) {
e.printStackTrace();
}
}
return jsonObj;
}

第二种方式:通道方式

/**
* 使用通道的方式上传文件
* @param filePath
* @param fileName
* @param sourceFile
* @param targetFile
* @return
*/
public JSONObject uploadByChanel(String filePath,String fileName,File sourceFile,File targetFile){
JSONObject jsonObj = new JSONObject();
FileInputStream fis = null;
FileOutputStream fos = null;
FileChannel in = null;
FileChannel out = null;
try {
targetFile.createNewFile();
fis = new FileInputStream(sourceFile);
fos = new FileOutputStream(targetFile);
in = fis.getChannel();//得到对应的文件通道
out = fos.getChannel();
in.transferTo(0,in.size(),out);//连接两个通道,并且从in通道读取后写入out通道
jsonObj.put("error", "0");
} catch (IOException e) {
jsonObj.put("error", "1");
jsonObj.put("message", "文件写入服务器出错,请稍后再传!");
}finally{
try {
fis.close();
fos.close();
in.close();
out.close();
deleteAllFile(new File(filePath.substring(0,filePath.indexOf(fileName))));
} catch (IOException e) {
e.printStackTrace();
}
}
return jsonObj;
}

其实两种方式的差别不是特别大,大家可以自己研究一下!!
注意:在controller中对文件上传的位置进行了自定义:

首先Jfinal默认保存路径是webroot下的upload文件夹,要想保存在自己定义的文件夹中,先要在jfinal中进行配置,如果我要保存在webroot下的/static/upload中就要进行下面的配置:

me.setBaseUploadPath(PathKit.getWebRootPath()+"/static/upload");

然后要根据文件的类型,在自定义路径下分类创建不同的文件夹保存文件。controller中调用service之前的代码就是做了这个功能:

UploadFile uploadFile = this.getFile();
JSONObject jsonObj = new JSONObject();
String fileName = uploadFile.getFileName();
File file = uploadFile.getFile();
String extension = fileName.substring(fileName.lastIndexOf("."));
String prefix;
if(extension.equals(".jpg")||extension.equals(".png")||extension.equals(".gif")){
prefix = "images";
}else{
prefix = "docs";
}
String filePath = file.getAbsolutePath();
File targetDir = new File(filePath.substring(0,filePath.indexOf(fileName))+prefix);
File targetFile = new File(targetDir.getPath()+"/"+fileName);
if(!targetDir.exists()){
targetDir.mkdir();
}

最后,会发现即便是自己根据文件类型在默认路径下定义了新的文件夹,而且文件也会分类保存在相应的文件夹下,但是jfinal还是会在默认路径下保存一份文件,这样同一份文件,在默认路径下和默认路径下的自定义路径中都
保存了一份,如下图所示:

所以为了上文件只保存在指定的目录中,就要做一个删除upload目录下的冗余文件的操作,就是service中调用的deleteAllFile(new File(filePath.substring(0,filePath.indexOf(fileName))));这部分,实现如下:

    /**
* 删除默认路径下的文件
* @param file
*/
public void deleteAllFile(File file){
File[] files = file.listFiles();
for(int i=0;i<files.length;i++){
File filei = files[i];
if(filei.isFile()){
filei.delete();
}
}
}

以上所有步骤就完成了一次上传文件到指定目录的功能,下面说一下刚开始说的发现的有趣的jquery库,可以在提交表单的代码中看到这么一句:

toastr.success("文件上传成功!");

其实这是一个提示框,而且可以设置自动消失,避免用户知道自己操作成功之后还要手动关闭提示框的操作,下面说一下这个技术的实现:
第一步:下载相关的包,并引入相关文件:

只要搜索toastr.js下载就会找到github资源路径,下载压缩包,解压后找到这几个文件:

不一定都能用到,但是都放在lib里,以备不时之需,我在这里只用到了这几个:

<link rel="stylesheet" type="stylesheet" href="../../static/js/lib/bootstrap/css/message/toastr.min.css">
<link rel="stylesheet" type="stylesheet" href="../../static/js/lib/bootstrap/css/message/messenger.css">
<script type="text/javascript" src="../../static/js/lib/bootstrap/js/message/messenger.min.js?v=${version}"></script>
<script type="text/javascript" src="../../static/js/lib/bootstrap/js/message/messenger-theme-future.js?v=${version}"></script>

第二步:使用前进行配置:

/*提示框配置  */
toastr.options = {
/* closeButton:false,//是否配置关闭按钮
debug:false,//是否开启debug模式
neweastOnTop:false,//新消息是否排在最上面
progressBar:false,//是否显示进度条
preventDuplicates:false,//是否阻止弹出多个消息框
onclick:null,//点击回调函数
showDuration:"300",//显示动作时间
hideDuration:"300",//隐藏动作时间 */
positionClass: "toast-center",//消息框的显示的位置
timeOut:"1000",//自动关闭的超时时间,即1秒后关闭
/* extentedTimeOut:"1000",
showEasing:"swing",
hideEasing:"liner",
showMethod:"fadeIn",//显示的方式
hideMethod: "fadeOut",//关闭的方式 */
}

上面是所有配置信息以及作用的解释,值得注意的是,positionClasss属性,默认的值有:

可以看到,这些属性值中,提示框的位置都是在边缘,没有在中间的,所以我就自定义了一个处于中间位置的class:toaster-center

大家也可以根据自己的页面属性自定义 !!

配置完之后就是使用了,其实使用起来很简单,就一句代码的事:

toastr.success("文件上传成功!");

success方式只是定义了弹出框的背景颜色,总共有四种方式:
1、success成功:绿色

2、info信息:蓝色

3、warning警告:橙色

4、error错误:深红色

这个颜色的标准跟bootstrap中是一样的!

以上就是本次文件上传的所有代码,以及延伸jquery库的介绍,下次会介绍后台语言选择PHP的情况下的文件上传,今天就到此为止吧,抬头发现,人都走了,我也该下班去锻炼身体了!

文件上传之Java篇的更多相关文章

  1. 【转】JSch - Java实现的SFTP(文件上传详解篇)

    JSch是Java Secure Channel的缩写.JSch是一个SSH2的纯Java实现.它允许你连接到一个SSH服务器,并且可以使用端口转发,X11转发,文件传输等,当然你也可以集成它的功能到 ...

  2. JSch - Java实现的SFTP(文件上传详解篇)

    JSch是Java Secure Channel的缩写.JSch是一个SSH2的纯Java实现.它允许你连接到一个SSH服务器,并且可以使用端口转发,X11转发,文件传输等,当然你也可以集成它的功能到 ...

  3. JSch - Java实现的SFTP(文件上传详解篇) [转载]

    文章来源:http://www.cnblogs.com/longyg/archive/2012/06/25/2556576.html JSch是Java Secure Channel的缩写.JSch是 ...

  4. JSch - Java实现的SFTP(文件上传详解篇)(转)

    JSch是Java Secure Channel的缩写.JSch是一个SSH2的纯Java实现.它允许你连接到一个SSH服务器,并且可以使用端口转发,X11转发,文件传输等,当然你也可以集成它的功能到 ...

  5. 求超大文件上传方案( Java )

    最近遇见一个需要上传百兆大文件的需求,调研了七牛和腾讯云的切片分段上传功能,因此在此整理前端大文件上传相关功能的实现. 在某些业务中,大文件上传是一个比较重要的交互场景,如上传入库比较大的Excel表 ...

  6. 完整的多文件上传实例(java版)

    昨天刚刚做了一个文件列表上传,后端很简单,用 MultipartFile[] files 获取文件流数组,后端就当IO流操作就可以,似乎好像没啥好写的,但是!!!!!前端是真的糙单.要是自己写一个前端 ...

  7. HttpApplication实战大文件上传 (第四篇)

    一.Asp.net中的文件上传 在Asp.net 1.1中,文件在上传过程中将被全部保存在内存中,对于大文件来说,会造成内存空间的过度使用,可能会招致恶意攻击.为了解决这个问题,Asp.net在配置文 ...

  8. 文件上传之Ajax篇

    AJAX上传文件 1.为什么要写这篇文章  楼主前几天去北京面试,聊起ajax上传文件, 面试官告之不能,遂讨论之,不得果,于是写下这篇文章,希望能和大家一起学习 2.正文 首先,要使用ajax上传文 ...

  9. 超大文件上传方案( Java )

    1.介绍enctype enctype 属性规定发送到服务器之前应该如何对表单数据进行编码. enctype作用是告知服务器请求正文的MIME类型(请求消息头content-type的作用一样) 1. ...

随机推荐

  1. RMQ问题——ST算法

    比赛当中,常会出现RMQ问题,即求区间最大(小)值.我们该怎样解决呢? 主要方法有线段树.ST.树状数组.splay. 例题 题目描述 2008年9月25日21点10分,酒泉卫星发射中心指控大厅里,随 ...

  2. ActiveMQ 知识点

    消息队列高可用 持久化,事务,签收,zookeeper+replicated-leveldb-store的主从集群 异步发送 同步发送: 明确指定同步发送 未使用事务的前提下,发送持久化消息(会使用同 ...

  3. Less适配移动端rem

    @ue-width: 750; /* 设计图的宽度 */ .px2rem(@px) { @remValue: @px/@ue-width*10; @pxToRem: ~"@{remValue ...

  4. js摇一摇事件

    今早同事过来说.要做个小游戏.里面有个摇一摇动作. 平时都是做的手机营销h5比较少.  发现很有意思.  一时间没有反应过来. 怎么实现的摇一摇. 现在吧代码叠出来给2货的我. //运动事件监听if ...

  5. Joomla - 优化(时区、google字体、压缩图片、压缩自定义代码)

    Joomla - 优化(时区.google字体.压缩图片.压缩自定义代码) 一.时区 发布文章是往往会发现发布时间和当前时间对不上,原因是 Joomla 用的是国际标准时间,和中国时区大约相差8小时, ...

  6. 前端面试题之一JAVASCRIPT(理论类)

    一.请描述一下 cookies.sessionstorage .localstorage 和session的区别?(1)cookie是网站为了标示用户身份而储存在用户本地终端(client side) ...

  7. 数据库备份还原——mysqlbackup与mysqldump对比测试

    1      环境描述 1.1      硬件环境 服务器类型:华为RH5885 IP: 10.148.128.100 内存: 64G 物理CPU个数:4 CPU核数:8 逻辑CPU个数:64 Int ...

  8. Leetcode965. Univalued Binary Tree单值二叉树

    如果二叉树每个节点都具有相同的值,那么该二叉树就是单值二叉树. 只有给定的树是单值二叉树时,才返回 true:否则返回 false. 示例 1: 输入:[1,1,1,1,1,null,1] 输出:tr ...

  9. hdu6277

    hdu6277结论题 #include<iostream> #include<cstdio> #include<queue> #include<algorit ...

  10. js节点

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...