文件上传

1.配置MultipartResolver
在Spring的配置文件中添加:

<!--MultipartResolver -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
</bean>

 

2.通过控制器接受并处理请求
处理请求的方法中必须添加"MultipartFile file"参数,该参数名需要与前端页面的控件中使用的"name"值保持一致,另外,需要添加"RequestParam("file")"注解,使用注解后,需要保持一致的名称就是注解中使用的名称:

@RequestMapping(value="upload.do")
public String handleUpload(@RequestParam("file") MultipartFile file) throws IllegalStateException, IOException{

   return null;
}

 

3.关于上传后在服务器端的文件名

保存到服务器端后使用的文件名必须不能发生冲突,否则,后续上传的文件,会覆盖前序上传的文件!关于“File”类,使用1个“String”作为构造方法参数时,表示目标文件的完整路径,也可以使用2个“String”作为构造方法的参数,第1个表示文件夹,第2个表示文件名:

//确定上传到服务器,保存到的目标文件
File dest=new File("E:/","1.jpg");

接下来,应该将第2个参数设置为变量,可以自行决定,使用时间、随机数等元素作为文件名的一部分,就可以保证文件名不会发生冲突。

System.currentTimeMillis()+"";

例如:使用UUID作为文件名:
//确定文件名
String filename=UUID.randomUUID().toString();

 

另外,还需要保证文件有正确的扩展名,应该取决于上传时,该文件在客户端计算机中保存时使用的名称,通过参数对象的"String getOriginalFilename()"方法可以获取文件的原名,然后查询最后一个小数点的位置,并截取出
扩展名:

//获取文件原名
String originalFilename=file.getOriginalFilename();
//获取扩展名
String suffix="";
int beginIndex=originalFilename.lastIndexOf(".");
if(beginIndex!=-1){
suffix=originalFilename.substring(beginIndex);
}
//确定文件名
String filename=UUID.randomUUID().toString()+suffix;

4.文件必须上传到部署的Tomcat中,当上传后,才可以保证后续的使用或下载,可以通过"HttpServletRequest"对象的"rquest.getServletContext().getRealPath("upload");"获取指定文件夹的实际路径。

确定上传的文件夹:

//确定上传的文件夹
//获取上传到服务器文件夹的路径地址
String dirPath=rquest.getServletContext().getRealPath("upload");
File dir=new File(dirPath);
if(!dir.exists()){
   dir.mkdirs();
}


基于该文件确定最终上传的文件位置:
//确定上传到服务器,保存到的目标文件
File dest=new File(dir,filename);

 

5.MultipartFile相关API
boolean isEmpty
该方法用于判断上传的文件是否为空,当用户没有选择需要上传的文件或选中的文件时空文件(0字节)
时,该方法返回"true",可用于验证


long getSize();
该方法用于获取文件的大小,以字节为单位,通常,用于限制上传文件的大小。


String getContentType()
该方法用于获取文件的MIME类型,通常,用于限制上传的文件的类型。

关于各种文件扩展名对应的MIME类型,可以上网查询,也可以在Tomcat目录中的"conf/web.xml"文件中查找。
MIME的值,完全取决于文件的扩展名,如果文件的扩展名被修改,MIME也可能发生变化。

String getOriginalFilename()
获取文件的原名,即该文件在客户端的文件全名,典型的用途就是获取文件的扩展名。

void transferTo(File dest)
执行保存所上传的文件。


InputStream getInputStream()
获取输入字节流,用于自定义接收所上传的文件。
注意:该方法与以上"transferTo"不可以同时使用,对于每个请求,只能选取其中1个方法来获取数据并保存文件。

 

8.关于MultipartResolver的配置

1.setMaxUploadSize
用于配置上传的文件的最大大小,例如:当设置值为5M时,则上传的文件均不可以超过5M,
即使一次性上传10个文件,则10个文件的大小总和不允许超过5M;

2.setMaxUploadSizePerFile
用于配置上传的每个文件的最大大,例如:当设置值为5M时,如果一次性上传10个文件,则每个文件都不允许
超过5M,但是总大小可以接近50M;


3.setDefaultEncoding
用于配置默认编码,上传的文件本身是不考虑编码问题的,只要文件的内容(表示文件内容信息含义的二进制序列
)是正确的就可以了!由于上传过程中,会通过‘CommonsMultipartResolver’去组织上传时表单中的数据,
表单中可能包括例如输入框等控件,则同一个表单中还可能提交例如用户名等文本信息,这些信息都需要
使用正确的编码来进行传递!

<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
    <property name="maxUploadSize" value="5242880"/>
</bean>

 4.设置虚拟目录

      <Context path="/upload" docBase="D:/upload"  reloadable="true"/>
      contex指上下文,实际上就是一个web项目;
      path是虚拟目录,访问的时候用127.0.0.1:8080/upload/*.jpg访问网页
      docBase是网页实际存放位置的根目录,映射为path虚拟目录;
       reloadable="true"表示你修改了jsp文件后不需要重启就可以实现显示的同步。

 

 

 

 完整代码:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>基于SpringMVC的文件上传</title>
</head>

<body>

<form action="upload.do" method="post" enctype="multipart/form-data">
<p>请选择您要上传的文件</p>
<p><input type="file" name="file" onchange="preview(this);"/></p>
<!-- 这个是在上传之前回显图片图片展示 -->
<div id="preview">
   <!--这个是为了将页面返回的图片展示出来的.默认隐藏-->
   <img style="width: 100px; height: 100px;display:none" id="imgHidden" />
</div>
<p><input type="submit" value="上传"/></p>
</form>


</body>


<script>
function preview(file){
var prevDiv = document.getElementById('preview');

if(file.files && file.files[0]){
var reader=new FileReader();
reader.onload=function(evt){
prevDiv.innerHTML='<img style="width: 100px;height: 100px;" src="' + evt.target.result + '" />';
}
reader.readAsDataURL(file.files[0]);
}else{
prevDiv.innerHTML = '<div class="img" style="width: 100px;height:100px;filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(sizingMethod=scale,src=\'' + file.value + '\'"></div>';
}
}
</script>


</html>

 

@Controller
public class UploadController {
    
    /**
     * 
     * @param file
     * @return
     * @throws IOException 
     * @throws IllegalStateException 
     */
    @RequestMapping(value="upload.do")
    public String handleUpload(HttpServletRequest rquest,@RequestParam("file") MultipartFile file) throws IllegalStateException, IOException{
    
        //判断上传的文件是否为空文件
        boolean isEmpty=file.isEmpty();
        if(isEmpty){
            return "error"; 
        }
        //限制上传文件大小
        long size=file.getSize();
        if(size>2*1024*1024){
            return "error";
        }
        //限制上传文件类型
        String contentType=file.getContentType();
        List<String> types=new ArrayList<String>();
        types.add("image/jpeg");
        types.add("image/png");
        types.add("image/gif");
        if(!types.contains(contentType)){
            return "error";
        }
        
        //确定上传的文件夹
        //获取上传到服务器文件夹的路径地址
        String dirPath=rquest.getServletContext().getRealPath("upload");
        File dir=new File(dirPath);
        if(!dir.exists()){
            dir.mkdirs();
        }
        
        //获取文件原名
        String originalFilename=file.getOriginalFilename();
        //获取扩展名
        String suffix="";
        int beginIndex=originalFilename.lastIndexOf(".");
        if(beginIndex!=-1){
            suffix=originalFilename.substring(beginIndex);
        }
        //确定文件名
        String filename=UUID.randomUUID().toString()+suffix;
        //确定上传到服务器,保存到的目标文件
        File dest=new File(dir,filename);
        //执行保存
        file.transferTo(dest);
        return null;
    }

}

 

posted @ 2020-01-30 22:45  一场屠夫的战争  阅读(296)  评论(0编辑  收藏  举报