文件上传主要是对输入输出流的操作,如果对于此块不太了解的同学可以参考这篇文章:https://blog.csdn.net/qq_22063697/article/details/52137369
response.setContentType() 根据不同类型设置不同参数,可以参考这篇文章:
https://blog.csdn.net/qq_42108192/article/details/81938674
上传文件
数据库字段(我用的是MySQL数据库):
实体类对应字段:
import java.io.Serializable;
public class OrderPhoto implements Serializable {
private Integer id;
private Integer orderId;
private byte[] photo;
private String filename;
private String filetype;
private static final long serialVersionUID = 1L;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public Integer getOrderId() {
return orderId;
}
public void setOrderId(Integer orderId) {
this.orderId = orderId;
}
public byte[] getPhoto() {
return photo;
}
public void setPhoto(byte[] photo) {
this.photo = photo;
}
public String getFilename() {
return filename;
}
public void setFilename(String filename) {
this.filename = filename;
}
public String getFiletype() {
return filetype;
}
public void setFiletype(String filetype) {
this.filetype = filetype;
}
}
controller层接口实现:
@RequestMapping(value = "/uploadOrderFile")
@ResponseBody
public WebResultDto uploadImage(@RequestParam("file") MultipartFile file, @RequestParam("orderId") Integer orderId)
throws IOException, IllegalAccessException, InvocationTargetException, NoSuchMethodException {
WebResultDto result = new WebResultDto();
WorkOrderSelective workOrder = this.workorderService.loadById(orderId);
if (workOrder == null) {
result.setInfo("工单不存在!");
return result;
}
//获取文件名与文件类型
String fileName = file.getOriginalFilename();
String fileType = fileName.substring(fileName.lastIndexOf(".") + 1);
ByteArrayOutputStream bo = new ByteArrayOutputStream();
BufferedInputStream in = new BufferedInputStream(file.getInputStream());
byte[] buffer = new byte[1024];
int len = 0;
int size = 0;
//从文件中按字节读取内容,到文件尾部时read方法将返回-1
while ((len = in.read(buffer)) != -1) {
bo.write(buffer, 0, len);
size += len;
}
if (size > 0) {
OrderPhoto photo = new OrderPhoto();
photo.setOrderId(orderId);
photo.setPhoto(bo.toByteArray());
photo.setFilename(fileName);
photo.setFiletype(fileType);
int count = workorderService.insertOrderPhoto(photo);
JSONObject model = new JSONObject();
model.put("count", count);
model.put("photoId", photo.getId());
result.success(model);
} else {
result.setInfo("字节数为0!");
}
return result;
}
文件的下载
controller层的实现:
@RequestMapping(value = "/getFile")
public void getImage(@RequestParam("photoId") Integer photoId, HttpServletResponse response) throws IOException {
OrderPhoto photo = workorderService.getPhotoById(photoId);
if (photo == null)
return;
String fileName = photo.getFilename();
response.setHeader("Content-Disposition",
"attachment;Filename=" + URLEncoder.encode(fileName, "UTF-8"));
response.setContentType("application/octet-stream;charset=UTF-8");
ByteArrayInputStream bin = new ByteArrayInputStream(photo.getPhoto());
BufferedOutputStream bos = new BufferedOutputStream(response.getOutputStream());
byte[] buffer = new byte[1024];
int count;
while ((count = bin.read(buffer)) != -1) {
bos.write(buffer, 0, count);
}
bin.close();
bos.flush();
}
这里延申出一道面试题:close()和flush()的区别?
flush()
就是单纯的刷新缓冲区,流对象还是可以用的。close()
是关闭流对象,但是先刷新一次缓冲区,关闭之后,流对象不可以继续再使用了。
至此,后端功能已经实现,前端要实现上传文件可以借助Ajax
//可使用javascript的FormData对象将带有file字段的form作为ajax的data参数传入:
var form = new FormData(document.getElementById("uploadForm"));
$.ajax({
url:’http://ip:port/....../uploadOrderFile’,
type : 'post',
data:form,
processData : false,
contentType : false,
......
也可以使用layui控件
layui.use('upload', function(){
var $ = layui.jquery,
upload = layui.upload;
//普通图片上传
var uploadInst = upload.render({
elem: '#test1',
url: 'http://ip:port/......',
before: function(obj){
obj.preview(function(index, file, result){
$('#demo1').attr('src', result); //图片链接
});......