Springmvc之文件上传和下载

Springmvc之文件上传和下载

前提

  • 在上传和下载之前需要在对应的根目录下创建对应的文件夹,比如我们在webApp下创建upload文件夹下

添加依赖

  • commons-io
  • commons-fileupload
    
        
            commons-io
            commons-io
            2.4
        

        
            commons-fileupload
            commons-fileupload
            1.3.1
        

在配置文件中配置(spring-mvc.xml)

  • id的名称一定是multipartResolver,不能任意指定
    
    
        
        
         
        
    

制作上传表单

  • 表单的提交方式一定为POST
  • 必须追加enctype="multipart/form-data"
file:

完成controller

  • 上传的参数一定为MultipartFile file
@RequestMapping("/upload.do")
    public String uplaod(MultipartFile file) throws IllegalStateException, IOException{
        String fileName=file.getOriginalFilename();  //获取文件名
        Long fileSize=file.getSize();   //获取文件大小
        //上传  参数是文件上传后储存的路径,最终的文件上传后的文件路径为/home/chenjiabing/Documents/Blog/fileName
        file.transferTo(new File("/home/chenjiabing/Documents/Blog",fileName));
        //重定向到首页
        return "redirect:../main/showIndex.do";
    }

异步上传文件

定义表单

  • 设置onchange事件,只要input的改变了,那么就上传文件

定义Controller

  • 其中的参数最好定义映射关系@RequestParam("file"),否则有时候会出现不对应的情况
  • 数据库中保存的文件的路径不需要保存项目路径,只需要保存项目的文件路径即可,比如/upload/文件名,那么我们使用http://localhost:8080/TeduStore/upload/文件名就能访问到
    @RequestMapping("/getImage.do")
    @ResponseBody
    public ResponseResult getImage(@RequestParam("file")MultipartFile file,HttpSession session) throws IllegalStateException, IOException{
        ResponseResult result = new ResponseResult();
        
        // 如果文件不为空
        if (!file.isEmpty()) {
            String originalFilename = file.getOriginalFilename(); // 获取初始的文件名称
            UUID uuid = UUID.randomUUID();
            // 使用随机算法生成文件名称,保证文件名称不冲突
            String fileName = uuid.toString()
                    + originalFilename.substring(originalFilename
                            .lastIndexOf("."));

            // 获取文件在项目中的上传路径
            String filePath = session.getServletContext().getRealPath(
                    "/upload/");

            // 创建文件的存储路径
            File f1 = new File(filePath, fileName);

            // 判断项目中这个upload文件夹是否存在
            if (!f1.getParentFile().exists()) {
                f1.getParentFile().mkdirs(); // 创建
            }
            // 保存文件
            try {
                file.transferTo(f1);
                // 存储到数据库中的路径
                String fileToDatabase = "/upload/" + fileName;
                Integer id=this.getId(session);
                bloggerService.modifyImage(id, fileToDatabase);
                result.setState(1);
                result.setMessage("头像上传成功");
            } catch (Exception e) {
                result.setState(0);
                result.setMessage("头像上传失败");
            }
        }
        return result;
    }

AJAx异步提交

  • 必须设置contentType:false,processData:false
  • 使用FormData对象保存数据,当然处理文件类型(File类型)的,我们也可以存储键值对,比如formdata.append("username","jack"),最后一起提交即可
//上传文件的方法
function getImageFun(){
    var file=document.getElementById("iconPic").files[0];  //获取当前的file
    // 创建FormData对象
    var formData=new FormData();
    formData.append("file",file);  //将文件放入formData中
    $.ajax({
        "url":"${pageContext.request.contextPath}/user/getImage.do",
        "data":formData,
        "type":"post",
        "dataType":"json",   //返回数据类型
        "contentType":false,  //不设置上传文件类型  ,因为上传的文件有多种类型的
        "processData":false,    //不处理数据
        "success":function(obj){
            alert(obj.message);
            var url=window.URL.createObjectURL(file);  //获取上传的的本地路径
            $("#icon").attr("src",url);  //将上面的头像显示为当前选择的图片
        }
    })
}

文件下载

第一种方式

  • 直接在输入地址即可,比如:http://localhost:8080/TeduStore/upload.do/download.do?fileName=1.jpg
    /**
     * 文件下载
     * @param fileName  文件名
     * @param request  
     * @throws IOException
     */ 
    @RequestMapping("/download.do")
    public ResponseEntity download(@RequestParam("fileName")String fileName,HttpServletRequest request) throws IOException{
        //获取下载文件的路径,在文件中的真实路径
        String path=request.getServletContext().getRealPath("/upload/");
        //下载文件的全路径
        File file=new File(path+File.separator+fileName);
        HttpHeaders headers = new HttpHeaders();  
        //下载显示的文件名,解决中文名称乱码问题  
        String downloadFielName = new String(fileName.getBytes("UTF-8"),"iso-8859-1");
        //通知浏览器以attachment(下载方式)打开图片
        headers.setContentDispositionFormData("attachment", downloadFielName); 
        //application/octet-stream : 二进制流数据(最常见的文件下载)。
        headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
         
        return new ResponseEntity(FileUtils.readFileToByteArray(file),    
                headers, HttpStatus.CREATED); 
    }

第二种方式

  • controller方法返回byte[]
  • 使用@ResponseBody注解
  • 设置请求头的ContentType类型为下载文件的类型
  • 设置请求头的ContentDisposition

下载图片

  • 只需要在浏览器中输入 :http://localhost:8080/Project/download/download.do?filename=1.png.就会下载项目路径下的文件夹upload中文件
@RequestMapping("/download.do")
    @ResponseBody
    public byte[] download(HttpServletResponse response,HttpServletRequest request,String filename)
            throws IOException {
        // 转换编码格式为iso-8859-1
        filename = URLEncoder.encode(filename, "utf-8");
        // 设置响应头 contentType,这里是下载图片 因此写的是 image/png
        response.setContentType("image/png");
        // 设置响应头Content-Disposition,使用转义双引号
        response.setHeader("Content-Disposition", "attachment;filename=\""
                + filename + "\"");
        
        return getImage(filename, request);
    }

    
    /**
     * 返回需要下载图片的byte数组
     * @param filename 图片的名称
     * @param request  HttpServletRequest对象,需要获取下载图片的项目路径
     * @return  byte数组
     * @throws IOException
     */
    public byte[] getImage(String filename,HttpServletRequest request) throws IOException{
        
        //获取图片文件存放的位置,在项目的upload文件夹下
        String projectPath=request.getServletContext().getRealPath("/upload/");
        //获取需要下载的图片的路径
        File file=new File(projectPath+File.separator+filename);
        
        //创建输入流,读取图片
        InputStream inputStream=new FileInputStream(file);
        //创建内存操作流
        ByteArrayOutputStream out=new ByteArrayOutputStream();
        
        byte[] b=new byte[1000];  //创建一个缓冲数组
        int len=0;
        //读取字节流,读入到byte数组中
        while((len=inputStream.read(b))!=-1){
            out.write(b,0,len);  //写入byte数组输入流
        }
        inputStream.close();
        out.close();
        return out.toByteArray(); 
    }

导出Excel文件

  • 改变请求头中的contentType类型为excel类型的即可
@RequestMapping("/export.do")
    @ResponseBody
    public byte[] export(HttpServletResponse response) throws IOException {
        String filename="excel表格.xlsx";
        // 转换编码格式为iso-8859-1
        filename = URLEncoder.encode(filename, "utf-8");
        // 设置响应头 contentType,这里是下载excel
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        // 设置响应头Content-Disposition
        response.setHeader("Content-Disposition", "attachment;filename=\""
                + filename + "\"");
        return createExcel();
    }
    
    //创建excel表格,变成byte数组
    private byte[] createExcel() throws IOException{
        //使用POI生成Excel
        XSSFWorkbook workbook=new XSSFWorkbook(); //生成工作簿
        
        XSSFSheet sheet = workbook.createSheet("第一张表");  //在工作簿中创建一个工作表
        
        XSSFRow row = sheet.createRow(0);  //创建行 行号从0开始
        
        XSSFCell cell = row.createCell(0);  //在行中创建单元格,从0开始,一行中包括多个单元格
        
        cell.setCellValue("第一行第一个单元格");  //在单元格中添加数据 

        ByteArrayOutputStream outputStream=new ByteArrayOutputStream();
        
        workbook.write(outputStream);   //写入ByteOutputStream流中
        
        workbook.close();
        
        outputStream.close();
        
        return outputStream.toByteArray();
    }

导出数据库中的信息

  • 我们可以使用上面的方式,将数据库中的信息写入到excel文件中,然后用户点击链接直接下载即可

你可能感兴趣的:(Springmvc之文件上传和下载)