附件的上传和下载【前后端分离】

一、附件的上传。

1、此方法适用于图片的上传和查看。

① Controller层。 

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.RequestPart;

// 上传附件【每次上传一个附件】
	@RequestMapping(value = "/uploadAttachment", method = RequestMethod.POST)
	public ReturnResult uploadAttachment(@RequestPart("file") MultipartFile file,
			HttpServletRequest request){
        try {
        	String fileId = IDUtils.getTimeUuid();
//        	String fileType = file.getContentType().substring(file.getContentType().lastIndexOf("-")+1);
        	Assert.hasText(FILE_UPLOAD_PATH, "文件上传路径未配置");
        	
        	File destDir = new File(FILE_UPLOAD_PATH + File.separator + HOMEWORK_FILE_PATH);
        	if(!destDir.exists()) destDir.mkdirs();
        	
        	File destFile = new File(destDir, file.getOriginalFilename());
        	file.transferTo(destFile);
        	
        	HomeworkAttachment ha= new HomeworkAttachment();
        	ha.setId(fileId);
        	ha.setOriginalName(file.getOriginalFilename());
        	ha.setHomeworkId("");
        	ha.setType(file.getContentType());
        	ha.setPath(HOMEWORK_FILE_PATH + File.separator + fileId);
        	
        	workNoticeService.addHomeworkAttachment(ha);
            return ReturnResult.success("OK", ha);
        }catch (Exception e) {
            log.error(e.getMessage(), e);
            return ReturnResult.fail(e.getMessage());
        }
	}

② ReturnResult类。

import java.io.Serializable;
import java.util.ArrayList;

import lombok.Data;

/**
 * 自定义响应结构
 *  200 业务办理成功
 *  300 业务办理失败(业务逻辑处理层)
 *  400 业务参数错误(接口参数错误)
 *  999 业务办理异常(数据库方面的异常)
 */

@Data
public class ReturnResult implements Serializable{
	
	private static final long serialVersionUID = -4254726102616289056L;
    private Integer status;		// 响应业务状态
    private String msg;			// 响应消息
    private Object data;		// 响应中的数据
    private long total;			//总条数
    private int pages; 			//总页数
    
    public ReturnResult(){
    }
    
    // 办理业务成功(有返回信息和数据)
    public static ReturnResult success(String msg, Object data){
    	return new ReturnResult(200, msg, data);
    }
    
    // 办理业务成功(只返回数据,无信息)
    public static ReturnResult success(Object data){
    	return new ReturnResult(200, null, data);
    }
    
    // 办理业务成功(只返回状态码)
    public static ReturnResult success(){
    	return new ReturnResult(200, null, null);
    }
    
    // 返回数据和相应的分页信息
    public static ReturnResult pageOk(String msg, Object data, long total, int pages){
    	return new ReturnResult(200, msg, data, total, pages);
    }
    
    // 返回数据和相应的分页信息
    public static ReturnResult pageOk(Object data, long total, int pages){
    	return new ReturnResult(200, null, data, total, pages);
    }
    
    // 办理业务失败
    public static ReturnResult fail(String msg){
    	return new ReturnResult(300, msg, new ArrayList());
    }
    
    // 办理业务失败
    public static ReturnResult fail(String msg, Object data){
    	return new ReturnResult(300, msg, data);
    }
    
    // 参数错误
    public static ReturnResult error(String msg) {
        return new ReturnResult(400, msg, null);
    }
    
    // 插入数据出现异常或者运行时产生的异常
    public static ReturnResult exception(String msg) {
        return new ReturnResult(999, msg, new ArrayList());
    }

    public ReturnResult(Integer status, String msg, Object data) {
        this.status = status;
        this.msg = msg;
        this.data = data;
    }
    
    public ReturnResult(Integer status, String msg, Object data,String session) {
        this.status = status;
        this.msg = msg;
        this.data = data;
    }
    
    public ReturnResult(Integer status,String msg, Object data, long total, int pages) {
        this.status = status;
        this.msg = msg;
        this.data = data;
        this.total = total;
        this.pages=pages;
    }

    public ReturnResult(Integer status, String msg) {
        this.status = status;
        this.msg = msg;
    }

}

2、使用Postman工具测试上传。

注意:key必须与Controller层接收的参数名一致,且类型为File,使用POST方式。

二、附件的下载。

1、此方法对应于图片为查看,对应于word、excel、ppt等类型格式即为下载,Controller层如下所示。

import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.util.Assert;
import org.springframework.util.FileCopyUtils;
import org.springframework.web.bind.annotation.PathVariable;

@RequestMapping(value = "/getAttachmentById/{attachmentId}", method = RequestMethod.GET)
	public ResponseEntity<byte[]> getAttachmentById(@PathVariable("attachmentId")String attachmentId, HttpServletRequest request){
        try {
        	Assert.hasText(FILE_UPLOAD_PATH, "文件上传路径未配置");
        	HomeworkAttachment homeworkAttachment = workNoticeService.getHomeworkAttachment(attachmentId);
        	if(null == homeworkAttachment) throw new IllegalArgumentException("不存在附件["+attachmentId+"]");
        	
         	File destFile = new File(FILE_UPLOAD_PATH + File.separator + HOMEWORK_FILE_PATH + File.separator + homeworkAttachment.getOriginalName());
        	if(!destFile.exists()) throw new RuntimeException("未找到附件["+destFile.getAbsolutePath()+"]");
        	
        	HttpHeaders headers = new HttpHeaders();    
        	MediaType mediaType = null;
        	try {
        		mediaType = MediaType.valueOf(homeworkAttachment.getType());
        	}catch (Exception e) {
        		log.error(e.getMessage(), e);
			}
        	
        	if(null == mediaType) mediaType = MediaType.APPLICATION_OCTET_STREAM;
        	
        	if(MediaType.APPLICATION_OCTET_STREAM.equals(mediaType)) {
        		headers.setContentDispositionFormData("attachment", homeworkAttachment.getOriginalName());
        	}
            headers.setContentType(mediaType);
            return new ResponseEntity<byte[]>(FileCopyUtils.copyToByteArray(destFile), headers, HttpStatus.OK);
        }catch(IllegalArgumentException e) {
        	log.error(e.getMessage(), e);
        	return new ResponseEntity<byte[]>(HttpStatus.BAD_REQUEST);
        }catch (Exception e) {
            log.error(e.getMessage(), e);
            return new ResponseEntity<byte[]>(HttpStatus.INTERNAL_SERVER_ERROR);
        }
	}

2、互联网媒体类型MediaType即MIME有多种,如果类型为APPLICATION_OCTET_STREAM即二进制流,则使用headers.setContentDispositionFormData()方法将其下载,否则就直接显示【图片】。

① 在HTTP协议头中,请求的媒体类型通常用Content-Type来表示。常见媒体格式类型如下:

text/html HTML格式
text/plain 纯文本格式
text/xml XML格式
image/gif GIF图片格式
image/jpeg JPG图片格式
image/png PNG图片格式

② 其它常用媒体格式如下:

application/xhtml+xml XHTML格式
application/xml XML格式
application/atom+xml Atom XML聚合格式
application/json JSON格式
application/pdf PDF格式
application/msword WORD格式
application/octet-stream 二进制流数据【文件下载】
application/x-www-form-urlencoded FORM表单提交数据默认格式key/value
multipart/form-data 表单上传文件

3、注意:word中doc格式类型为application/msword,但docx格式类型为application/vnd.openxmlformats-officedocument.wordprocessingml.document,大于50字符,可以在数据库中设置type的varchar为100左右,以免报错com.mysql.jdbc.MysqlDataTruncation: Data truncation: Data too long for column 'type'。

----- END -----

猜你喜欢

转载自blog.csdn.net/a515557595_xzb/article/details/81333471
今日推荐