springMVC上传头像且下载

在之前springMVC上传功能详解(一)中新增加controller进行处理,配置文件照旧

项目架构如下:

controller处理器:

package controller;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.io.FileUtils;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.multipart.MaxUploadSizeExceededException;
import org.springframework.web.multipart.MultipartFile;

import entity.User;

/**
 * 上传用户头像 
 */
@Controller
public class UploadImageController {
	//上传头像的表单页面
	@RequestMapping("/toUploadHead.do")
	public String toUploadHead(){
		return "userHead/uploadHead";
	}
	
	@RequestMapping("/uploadHead.do")
	//将上传文件自动绑定到该属性headimage
	public String uploadHead(User user, HttpServletRequest request){
		MultipartFile headimage = user.getHeadimage();//文件对象
		String fileName = headimage.getOriginalFilename();//文件名  例如:wq.png
		String path = getImagePath(request);
		File targetFile = new File(path ,fileName);
		if(!targetFile.exists()){//若文件夹不存在则重新创建
			targetFile.mkdirs();
		}
		//保存
		try {
			headimage.transferTo(targetFile);
			request.setAttribute("fileUrl", getURLEncoderString(path + File.separator + fileName));//编码(传入前端路径可能乱码)
		} catch (Exception e) {
			e.printStackTrace();
			throw new RuntimeException(e);
		}
		return "userHead/userInfo";
	}
	
	//获取上传头像的路径
	public String getImagePath(HttpServletRequest request){
		String path = request.getSession().getServletContext().getRealPath("");
		path = path.substring(0,path.lastIndexOf(File.separator));
		path = path.substring(0,path.lastIndexOf(File.separator) + 1);//  D:\liferay\tomcat\tomcat-7.0.81
		return path + "uploadImg";
	}
	
	@RequestMapping("/getImage.do")
	//显示头像图片
	public void getImage(HttpServletRequest request, HttpServletResponse response){
		String fileUrl = request.getParameter("fileUrl");//文件路径 
		System.out.println("显示路径:"+fileUrl);
		FileInputStream fis = null;
		OutputStream os = null;
		try {
			fis = new FileInputStream(fileUrl);
			os = response.getOutputStream();
			int count = 0;
			byte[] buffer = new byte[1024 * 8];
			while ((count = fis.read(buffer)) != -1) {
				os.write(buffer, 0, count);
			}
			os.flush();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
			throw new RuntimeException(e);
		} catch (IOException e) {
			e.printStackTrace();
			throw new RuntimeException(e);
		} finally {
			if(fis != null){
				try {
					fis.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if(os != null){
				try {
					os.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}
	
	@RequestMapping("/downImage.do")
	//下载头像图片
	public void downImage(HttpServletRequest request, HttpServletResponse response) throws IOException{
		String fileUrl = request.getParameter("fileUrl");//文件路径(不解码,否则+号变成了空格)   
		System.out.println("下载路径:"+fileUrl);
		File file = new File(fileUrl);
		//以下载方式打开
		FileInputStream fis = null;
		OutputStream os = null;
		String downName = new String(file.getName().getBytes("UTF-8"),"iso-8859-1");
		response.setHeader("Content-Disposition", "attachment;filename=" + downName);
		try {
			fis = new FileInputStream(file);//创建流对象
			os = response.getOutputStream();//写出
			int count = 0;
			byte[] buffer = new byte[1024 * 8];
			while ((count = fis.read(buffer)) != -1) {
				os.write(buffer, 0, count);
			}
			os.flush();
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
			throw new RuntimeException(e);
		} catch (FileNotFoundException e) {
			e.printStackTrace();
			throw new RuntimeException(e);
		} catch (IOException e) {
			e.printStackTrace();
			throw new RuntimeException(e);
		} finally {//释放资源
			if(fis != null){
				try {
					fis.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if(os != null){
				os.close();
			}
		}
		
		/*
		//* 方式二
		String fileUrl = request.getParameter("fileUrl");//文件路径(不解码,否则+号变成了空格)
		File file = new File(fileUrl);
		System.out.println(file.getName());
		HttpHeaders headers = new HttpHeaders();//http头信息
		String downloadFileName = new String(file.getName().getBytes("UTF-8"),"iso-8859-1");//设置编码
		headers.setContentDispositionFormData("attachment", downloadFileName);
        headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
        //MediaType:互联网媒介类型  contentType:具体请求中的媒体类型信息
        return new ResponseEntity<byte[]>(FileUtils.readFileToByteArray(file),headers,HttpStatus.CREATED);
        */
	}
	
	//编码和解码
	public static String getURLEncoderString(String str) {
        String result = "";
        if (null == str) {
            return "";
        }
        try {
            result = java.net.URLEncoder.encode(str, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return result;
    }

    public static String URLDecoderString(String str) {
        String result = "";
        if (null == str) {
            return "";
        }
        try {
            result = java.net.URLDecoder.decode(str, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return result;
    }

    //异常处理
  	@ExceptionHandler
  	public String exHandle(Exception ex, HttpServletRequest request){
  		if(ex instanceof MaxUploadSizeExceededException){
  			//long maxSize = ((MaxUploadSizeExceededException) ex).getMaxUploadSize();//允许上传文件的最大值  
  			request.setAttribute("errorMsg", "文件总内容超过了3 M");
  			return "error/error";
  		}else{
  			return "error/system_error";
  		}
  	}
	
}

spring配置文件与之前一致,拦截器也不变,两个错误页面不变

User实体类如下:

这个实体类中的headimage属性的主要作用就是用来映射我们上传的文件,可以看到它是MultipartFile类型的,其主要作用是用来映射把上面的form表单的headimage属性自动注入到对象里面(在controller中获取参数时候将参数注入到实体类中)

package entity;

import java.io.Serializable;

import org.springframework.web.multipart.MultipartFile;

public class User implements Serializable{
	private static final long serialVersionUID = 1L;
	private String userName;
	private MultipartFile headimage;//上传文件会自动绑定到该属性
	public String getUserName() {
		return userName;
	}
	public void setUserName(String userName) {
		this.userName = userName;
	}
	public MultipartFile getHeadimage() {
		return headimage;
	}
	public void setHeadimage(MultipartFile headimage) {
		this.headimage = headimage;
	}
	
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result
				+ ((headimage == null) ? 0 : headimage.hashCode());
		result = prime * result
				+ ((userName == null) ? 0 : userName.hashCode());
		return result;
	}
	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		User other = (User) obj;
		if (headimage == null) {
			if (other.headimage != null)
				return false;
		} else if (!headimage.equals(other.headimage))
			return false;
		if (userName == null) {
			if (other.userName != null)
				return false;
		} else if (!userName.equals(other.userName))
			return false;
		return true;
	}
	@Override
	public String toString() {
		return "User [userName=" + userName + ", headimage=" + headimage + "]";
	}
	

}

主页面index1.jsp

<%@page pageEncoding="utf-8" contentType="text/html; charset=utf-8"%>

<html>
	<head>
		<title>文件上传示例</title>
	</head>
	<body>
		<a href="toUploadHead.do">上传用户头像且显示</a>
	</body>
</html>

上传表单页面uploadHead.jsp:

<%@page pageEncoding="utf-8" contentType="text/html; charset=utf-8"%>
<!-- 头像上传的页面 -->
<html>
	<head>
		<title>文件图片</title>
		<script type="text/javascript" src="js/jquery-1.11.1.js"></script>
		<script type="text/javascript">
			//在JS中判断上传文件  单个上传时候必须先选定文件,不能直接在没有文件的情况下上传,否则弹窗提示
			function checkSingleFile(){
				var file = $("#sub1").val();
				if(file == ""){
					//没有选择文件
					alert("请选择要上传的文件!");
					return false;
				}
				return true;
			}
		</script>
	</head>
	<body>
		<form action="uploadHead.do" method="post" enctype="multipart/form-data" onsubmit="return checkSingleFile();">
			<p>用户头像</p>
			<input id="sub1" type="file" name="headimage" />
			<input type="submit" value="上传单个"/>
		</form>
	</body>
</html>

上传成功后跳转到userInfo.jsp页面,显示头像和下载按钮

登录链接页面如下:

单击后:

此处选择单个文件上传,单个上传必须先选中文件,否则有提示,如下图所示:

userInfo.jsp文件获取后台传来的路径是经过UTF-8编码的,上传成功后会显示上传的头像图片,单击链接会下载该图片文件,最好不要采用超链接的方式下载,可以采用按钮+JS事件来处理,如代码:window.location = 'downImage.do?fileUrl='+fileUrl;

总结如下:

1.表单在提交前会校验文件,JS校验,必须有文件才能上传

2.在拦截器处理文件尺寸大小,将抛出的文件尺寸过大异常抛给@ExceptionHandler处理,限制上传文件大小,与案例(一)相同的处理方式,只是文件设置大小需小一点,一般头像就几十KB,

3.上传后将文件路径:例如D:\liferay\apache-tomcat-7.0.81\uploadImg\qq.jpg采用UTF-8的编码方式编码后传到头像显示页面(userInfo.jsp)

4.此时要在jsp页面的img标签中显示图片:

<img alt="用户头像" src="getImage.do?fileUrl=${fileUrl }" />

通过标签上的get请求,利用原始的IO流进行处理,处处参数fileUrl是后台传来且进过UTF-8编码的字符串,例如:

文件经过编码后的的真实路径:D%3A%5Cliferay%5Capache-tomcat-7.0.81%5CuploadImg%5Cqq.jpg 

这样可避免特殊字符的编码问题,此处显示头像发送请求,附带该参数传递,后台接收该参数,需处理一些编码方式如下:

String fileUrl = request.getParameter("fileUrl");//文件路径(不解码,否则+号变成了空格)   
File file = new File(fileUrl);
//以下载方式打开
FileInputStream fis = null;
OutputStream os = null;
String downName = new String(file.getName().getBytes("UTF-8"),"iso-8859-1");
response.setHeader("Content-Disposition", "attachment;filename=" + downName);

 文件名要用ISO-8859-1编码,否则弹出的下载框文件名乱码或部分识别不了

5.文件下载后保存的路径如下:

 下载方式可以采用传统的IO流也可以用如上已经注释的代码,均可成功

6.本篇博文介绍了SpringMvc上传和文件的功能,需要注意的地方就是对于文件上传包common-fileupload.jar包的使用,还有在配置文件上配置mulitipartResolver这个bean。下面又介绍了用java 实体类去映射上传文件的属性对应的文件,这点的好处就是它会自动映射,然后把对象放入到我们的请求域中,就可以展示给界面用户层,这也是mvc思想模式的体现。接下来是介绍去下载文件,只需要从我们的写入的目标地址去取出文件,再进行responseEntity对象的封装,就可以实现下载功能

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

荒--

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值