这里我们来总结整理一下常用的两种文件上传方式以及要注意的东西:
1、springmvc .MultipartFile 的上传方式。
2、org.apache.commons.fileupload 使用apache的fileuoload 来实现
当我们使用springmvc 的MultipartFile 时我们要在spring的配置文件中添加如下的配置文件:
(1)、bean的引入以及编码和上传文件大小两个属性的设置
- <bean id="multipartResolver"
- class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
- <property name="defaultEncoding" value="UTF-8" />
- <property name="maxUploadSize" value="2000000000" />
- </bean>
(2)、控制层的代码:
- public void upload2(HttpServletRequest request) {
- // 转型为MultipartHttpRequest
- try {
- MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
- List<MultipartFile> fileList = multipartRequest.getFiles("file");
- for (MultipartFile mf : fileList) {
- if(!mf.isEmpty()){
- }
- }
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
这样就简单的获取了上传文件,其实我们上传的文件就是一个MultipartFile 对象,获取了对象后我们就可以获取文件名以及输入流。
(3)、控制层的第二种方式:
- public String upload(HttpServletRequest request,
- @RequestParam(value = "file") MultipartFile[] files) {
- try {
- for (MultipartFile mf : files) {
- if(!mf.isEmpty()){
- }
- }
- } catch (Exception e) {
- e.printStackTrace();
- }
- return "upload";
- }
(2)、(3)、不管哪种,其实都是一样的原理,都是将上传文件转化为了对象。
这里springMVC 都为我们封装好成自己的文件对象了,转换的过程就在我们所配置的CommonsMultipartResolver这个转换器里面下面再来看看它的源码
看到这个你应该明白了,如果你配置了multipartResolver 这个bean 则程序会自动调用fileUpload 来解析request ,在控制层获取的request已经是被解析过的,所以不用在手动去调用fileUpload 的相关方法来解析这个request。但注意,如果在spring的配置文件中没有配置这个bean的话,则我们自己要在controller层调用fileUpload 的相关方法来解析request 。ok这里说了第一种使用springmvc 的MultipartFile ,但是第二种和第一种其实是一样的,第一种解析的过程由spring替我们干了,我们只需要获取数据就ok而第二种方式就是在spring 的配置文件中不配置bean 这样在控制层中我们只能自己去解析请求。
所以简单的来说其实就是一种技术的两种使用方式,第一种是配置在了spring 容器中而第二种就是不配置在spring容器中而是自己去解析请求信息。
注意:刚开始学习的时候,你肯能不了解而出现了获取不到数据的这种情况,那就是在你不知不觉中解析了两次request所以你获取不到你想要的数据,那怎么处理那其实很简单,具体看下面:
1、不在spring的配置文件中配置,则需要你在控制层调用fileupload 的方法进行解析:
- @RequestMapping(value="/upload.do")
- @SuppressWarnings("unchecked")
- public void upload(HttpServletRequest request,HttpServletResponse response) throws IOException, FileUploadException{
- System.out.println("文件存放目录、临时文件目录准备完毕 ...");
- System.out.println("filePath-->:"+filePath);
- System.out.println("tempPath-->:"+tempPath);
- response.setContentType("text/plain;charset=utf-8");
- PrintWriter pw = response.getWriter();
- // 磁盘文件工厂,创建缓存文件
- DiskFileItemFactory diskFactory = new DiskFileItemFactory();
- // threshold 极限、临界值,即磁盘缓存大小设置
- diskFactory.setSizeThreshold(10*4 * 1024);
- // repository 贮藏室,即临时文件目录 ,设置文件的缓存路径
- diskFactory.setRepository(new File(tempPath));
- ServletFileUpload upload = new ServletFileUpload(diskFactory);
- // 设置允许上传的最大文件大小 ,如果是-1表示没有限制
- upload.setSizeMax(10 * 1024 * 1024);
- //解决上传的文件名乱码
- upload.setHeaderEncoding("UTF-8");
- // 3、判断用户的表单提交方式是不是multipart/form-data,这也是我们在form中设置的那个属性的值 是不是……
- boolean bb = upload.isMultipartContent(request);
- if (!bb) {
- return ;
- }
- // 解析HTTP请求消息头 ,也就是调用方法解析提交的内容并将其组装成一个个的FileItem对象
- // 而其中上传的一个文件就是一个FileItem对象
- List<FileItem> fileItems = upload.parseRequest(request);
- try {
- Iterator<FileItem> iter = fileItems.iterator();
- while(iter.hasNext())
- {
- FileItem item = (FileItem)iter.next();
- //按照给定的编码格式获取上传文件内容
- String fieldValue = item.getString("UTF-8");
- //获取标签名称
- String tagName = item.getFieldName();
- //获取文件名称
- String fileName= item.getName();
- //上传文件输入流,也就是整个上传文件的流
- InputStream input = item.getInputStream();
- System.out.println("tagName--->:"+tagName +"fileName--->"+fileName );
- //判断这个FileItem是不是表单属性(他能判断是上传的文件还是表单属性)
- if(item.isFormField())
- {
- System.out.println("处理表单内容 ...");
- processFormField(item, pw);
- }else{
- System.out.println("处理上传的文件 ...");
- processUploadFile(item, pw);
- }
- }
- } catch (Exception e) {
- e.printStackTrace();
- }finally{
- pw.close();
- }
- }
- /**
- * 处理表单内容
- * @param item
- * @param pw
- * @throws Exception
- */
- private void processFormField(FileItem item, PrintWriter pw)
- throws Exception
- {
- String tagName = item.getFieldName();
- String fileName = item.getString("utf-8");
- pw.println(tagName + " : " + fileName + "\r\n");
- }
- /**
- * 处理上传的文件
- * @param item
- * @param pw
- * @throws Exception
- */
- private void processUploadFile(FileItem item, PrintWriter pw)
- throws Exception
- {
- //文件名称
- String filename = item.getName();
- System.out.println("完整的文件名:" + filename);
- //上传文件大小(byte)
- long fileSize = item.getSize();
- if("".equals(filename) && fileSize == 0)
- {
- System.out.println("文件名为空 ...");
- return;
- }
- System.out.println("filePath:-->"+filePath);
- System.out.println("filename:--->"+filename);
- //创建保存文件路径
- File uploadFile = new File(filePath +File.separator + filename);
- if(!uploadFile.getParentFile().exists()){
- uploadFile.getParentFile().mkdirs();
- }
- uploadFile.createNewFile();
- //将上传上来的文件内容写到指定的文件
- item.write(uploadFile);
- //向浏览器打印
- pw.println(filename + " 文件保存完毕 ...");
- pw.println("文件大小为 :" + fileSize + "\r\n");
- }
2、在spring的配置文件中配置了这个bean 则不在需要我们自己调用一个fileupload 的方法再去解析一次,而是直接使用:
- /**
- * spring mvc MultipartFile 多文件上传
- * @param request
- * @param response
- * @throws IOException
- */
- @RequestMapping(value="/upload1.do")
- public void upload1(HttpServletRequest request,HttpServletResponse response) throws IOException{
- //创建一个通用的多部分解析器
- CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver(request.getSession().getServletContext());
- //判断用户的表单提交方式是不是multipart/form-data,这也是我们在form中设置的那个属性的值 是不是……
- if(multipartResolver.isMultipart(request)){
- //判断 request 是否有文件上传,即多部分请求
- MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
- //获取所有上传文件的名称是input标签中的名称
- Iterator<String> iter = multipartRequest.getFileNames();
- while(iter.hasNext()){
- String name = iter.next();
- //按照文件名称获取这个上传文件,上传文件被转化为MultipartFile 对象
- MultipartFile file= multipartRequest.getFile(name);
- //获取文件名,这里的fname也是input标签中的name而不是文件名
- String fname= file.getName();
- //这里获取到的才是真真的文件名称 比如test.txt等这样的名称。
- String myfname= file.getOriginalFilename();
- //获取输入流
- InputStream input = file.getInputStream();
- System.out.println("fname: "+fname +" name: "+name +" myfname:"+myfname);
- }
- //这的getFiles("file")就是获取多个input标签名称为file的文件。
- List<MultipartFile> fileList = multipartRequest.getFiles("file");
- for(MultipartFile file:fileList){
- System.out.println("----fileList size:"+fileList.size());
- //获取input标签中的名称
- String name= file.getName();
- //这里获取到的才是真真的文件名称 比如test.txt等这样的名称。
- String myfname= file.getOriginalFilename();
- //获取这个文件的输入流
- InputStream input = file.getInputStream();
- System.out.println("name"+name +"myfname:"+myfname);
- }
- }
- PrintWriter p= response.getWriter();
- p.write("ok!!!");
- }
ok到这里两种使用方法也说完了,也明白了SpringMVC中servletFileUpload.parseRequest(request)解析为空获取不到数据的问题,获取不到是因为我们解析了两次,所以我们要知道,如果你在spring的配置文件中配置了,值按照2 这种方式直接使用,而如果没有配置则需要我们按照1 中的方式先去解析request 在使用!