반응형

frontend

image upload시 서버 전송 하기 전에 frontend 로직진행하는 부분

<input
        accept="image/*"
        id={`input_${type}`}
        type="file"
        className="logo_preview_input"
        onChange={e => {
          if (e.target.files && e.target.files.length >= 1) {
            const reader = new FileReader();
            const img = e.target.files[0];
            reader.readAsDataURL(img);
            reader.onload = e2 => {
              setImg(e2.target.result);
              setImgName(img.name);
            };
          }
        }}
      />
      <label htmlFor={`input_${type}`} className="btn_logo_preview">
        <Button component="span" className="btn_color4">
          Select File
        </Button>
      </label>
      <p className="file_name">{imgName}</p>

 

업로드된 파일을 서버전송할 때 new FormData()를 써서 이안에 image file이랑 다른 string이랑 같이넣어줌

        const bgImg = document.getElementById('input_bg').files[0];//undefined if not uploaded
        //if (!bgImg) alert('Please select a background image file to update !');
        const previewImg = document.getElementById('input_preview').files[0];//undefined if not uploaded
        //if (!previewImg) alert('Please select a preview image file to update !');
        const buttonImg = document.getElementById('input_button').files[0];
        requestBody = new FormData();
        requestBody.append('tabName', content.tabName);
        requestBody.append('tabOrder', content.tabOrder);
        requestBody.append('themeApply', content.themeApply ? 'Y' : 'N');
        if (bgImg) requestBody.append('bgImg', bgImg);
        if (previewImg) requestBody.append('previewImg', previewImg);
        if (buttonImg) requestBody.append('buttonImg', buttonImg);

전송시 header는 보통 multipart/form-data를 사용하는 것 같은데 왜인지 이렇게 보내면 에러가 났고 아예 설정안하고 보내니 정상동작하였음

//const headers = new Headers({ 'Content-Type': 'application/json' });
//const headers = new Headers({ 'Content-Type': 'multipart/form-data' });

backend

  • formData로 보낸 것들도 url?q=형식으로 get으로 보낸것을 받는 것처럼 @RequestParam으로 받음
  • 그 중 이미지는 org.springframework.web.multipart.MultipartFile로 받음
  • 이미지외에 string으로 보낸 것들은 Map<String, Object>로 몽땅 받음
  • 만약 이름은 bgImg, previewImg이렇게 맞춰서 보냈는데 실제로는 파일이 아니라 string을 보내면 null로 받아짐
@PatchMapping("tab_withImg/{tabId}")
  public Tab updateTabWithImg(@CurrentUser UserPrincipal currentUser, @PathVariable String tabId,
      @RequestParam Map<String, Object> data, @RequestParam(required = false) MultipartFile bgImg,
      @RequestParam(required = false) MultipartFile previewImg, @RequestParam(required = false) MultipartFile buttonImg)
      throws Exception {
    logger.info("#updateTab_WithImg|currentUser=" + currentUser.getProvider());
    return homeAppAdminService.updateTab(tabId, data, bgImg, previewImg, buttonImg);
  }

 

  • multipart file을 받아서 로컬내 저장하고 처리하는 부분
  • 일반적으로 File쓰는 방법으로 저장하면 에러가 나서 java.nio.file.Path/Paths 써서 처리했었던듯
import java.io.File;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.springframework.web.multipart.MultipartFile;


  private String uploadFile(String type, MultipartFile multipartFile) throws Exception {
    String uploadDirStr = UPLOAD_DIR == null ? "/engn001/tomcat/8.5/servers/portal_8180/uploads" : UPLOAD_DIR;
    File uploadDir = new File(uploadDirStr);
    if (!uploadDir.exists() && !uploadDir.mkdirs())
      throw new Exception("uploadDir mkdir Fail!");
    File uploadFile = new File(uploadDirStr + "/" + multipartFile.getOriginalFilename());
    if (!uploadFile.getAbsolutePath().equals(uploadFile.getCanonicalPath()))
      throw new Exception("파일경로 및 파일명을 확인하십시오.");

    Path path = Paths.get(uploadDirStr + "/" + multipartFile.getOriginalFilename()).toAbsolutePath();
    multipartFile.transferTo(path.toFile());
    // multipartFile.transferTo(uploadFile);//file not found error
    String resultGftsUrl = uploadGfts(type, "KIC", uploadFile);
    uploadGfts(type, "AIC", uploadFile);
    uploadGfts(type, "EIC", uploadFile);
    uploadFile.delete();
    return resultGftsUrl.replaceFirst("http://kic-", "");
  }

 

반응형

+ Recent posts