使用antd Upload+Java实现多张图片上传到服务器

使用antd Upload +Java实现多张图片上传到后端服务器

主要实现功能:

  1. 前端多图片上传,控制在10个以内
  2. 后端接收多图片,并将图片打成压缩包

实现思路:

  1. antd.upload的action仅支持一次上传一个图片,所以自定义上传功能,将图片列表汇总后统一上传,后端使用HttpServletRequest接收。

前端实现(基于ant.design)

ant.design官网
– routes层,即页面渲染的部分

import {Upload} form ‘antd’;

class PicturesWall extends React.Component{
  constructor(props){
    super(props);
  }
  state = {
    previewVisible:false,
    previewImage:'',
    fileList:[],
    upFiles:[]
  };
  
  handleCancel=()=>{
    this.setState({previewVisible:false});
  }
  
  handlePreview = async file =>{
    if(!file.url && !file.preview){
      file.preview = await getBase64(file.originFileObj);
    }
    this.setState({
      previewImage: file.url || file.preview,
      previewVisible: true
    });
  }
  
  handleChange = (info) => {
    this.setState({fileList: info.fileList});
  }
  
  beforeUpload = (file) => {
    const {upFiles} = this.state;
    upFiles.push(file);
    this.setState({upFiles: upFiles});
  }
  
  addOk = () => {
    const {upFiles, id} = this.state;
    const formData = new FormData();
    upFiles.forEach((file) => {
      formData.append('file', file);
    });
    formData.append('id', id);
    this.props.dispatch({
      type: 'upload/upImage',
      payload: {formData: formData}
    })
  }
  
  render() {
    const {previewVisible, previewImage, fileList} = this.state;
    const uploadButton = (
      <div>
        <Icon type="plus" />
        <div className="ant-upload-text">Upload</div>
      </div>
    )
    return (
      <div>
        <Button type="primary" onClick={this.addOk()}>确认</Button>
        <Upload
          accept=".png,,jpg,.jpeg,.pdf"
          listType="picture-card"
          multiple={true}
          fileList={fileList}
          onChange={this.handleChange}
          onPreview={this.handlePreview}
          beforeUpload={this.beforeUpload}
        >
          {fileList.length >10 ? null : uploadButton}
        </Upload>
        <Modal visble={previewVisible} footer={null} onCancel={this.handleCancel()}>
          <img alt="example" style={{width:'100%'}} src={previewImage}/>
        </Modal>
      </div>
    )
  }
}

function getBase64(file){
  return new Promise((resolve, reject) => {
    const reader = new FileReader();
    reader.readAsDataURL(file);
    reader.onload = () => resolve(reader.result);
    reader.onerror = error => reject(error);
  });
}

– 这里省略module层
– service层,即与controller交互部分

export async function uploadInamge(params) {
	return request(`/api/uploadImages`,
	{
		method: "POST",
		body: params.formData
	});
}

后端端实现(基于Java)

– controller层

@RequestMapping(value = "/uploadImages", method = RequestMethod.POST)
public RetCommon uploadImages(HttpServletRequest request) throws IOException{
    RetCommon ret = new RetCommon(1000, "success");
    MultipartHttpServletRequest params = ((MultipartHttpServletRequest) request);
    String id = params.getParameter("id");
    List<MultipartFile> files = ((MultipartHttpServletRequest) request).getFiles("file");
    if(files == null || files.size()==0){
        ret.setCodeMessage(1001,"未获取到有效文件");
    }
    try{
        uploadService.uploadImages(files, id);
    }catch (IOException e){
        ret.setCodeMessage(1002, e.getMessage());
        return ret;
    }
    return ret;
}

– uploadService层

public int uploadImages(List<MultipartFile> files, String id){
    UUID uuid = UUID.randomUUID();
    String filePath = path; // path为上传的路径
    String zipTmpfile = filePath + File.separator+uuid.toString()+"image.zip";
    ZipFile zipFile = new ZipFile(zipTmpfile);
    for (int i = 0; i < files.size(); i++) {
        MultipartFile file = files.get(i);
        String fileName = file.getOriginalFilename();
        if (fileName != null && !fileName.equals("")) {
            String tmpfile = filePath + File.separator + uuid.toString() + fileName;
            File tmpfileObj = new File(tmpfile);
            file.transferTo(tmpfileObj);

            ZipParameters parameters = new ZipParameters();
            parameters.setCompressionMethod(Zip4JConstants.COMP_DEFLATE);
            parameters.setCompressionLevel(Zip4JConstants.DEFAULR_LEVEL_MORMAL);

            zipFile.addFile(tmpfileObj, parameters);
            tmpfileObj.delete();
        }
    }
    File ZipFileObj = new File(zipTmpfile);
    String saveDirStr = filePath + File.separator + id; //id是关联的对象数据库中的id
    File saveDir = new File(saveDirStr);
    if(!saveDir.exists()){
        if(!saveDir.mkdirs()){
            logger.error("upload image mkdir error, dir path:"+saveDirStr);
            return -1;
        }
    }
    String newSavePath = saveDirStr + File.separator + "image.zip";
    File targetFile = new File(newSavePath);
    if(targetFile.exists()){
        logger.info("delete old file"+newSavePath);
        targetFile.delete();
    }
    if(!ZipFileObj.renameTo(new File(newSavePath))){
        logger.error("move file error");
    }
}

问题记录

  1. 对fileList理解有误,以为通过action会直接上传fileList,fileList是表示已上传的文件,但是定义是:新增一个图片时自动触发action操作上传,action只上传当前的file,不是fileList
  2. <Upload fileList={fileList}> 与HttpServletRequest接收到的类型不一致,一开始直接上传这个fileList后端解析出来的files为空,后添加beforeUpload,在文件上传之前保存文件到新的列表中。
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值