본문 바로가기

개발/Java & Spring

[Springboot/S3] Spring boot , JSP , AWS S3 에 이미지 업로드하기! - 개발일기 A[6]

S3 기본 설정은 지난 다운로드 게시글에 있고 업로드 로직만 구현해주려고 한다.

검색해보면 다 AJAX를 이용하는데 ㅠ___ㅠ 아 저 에이젝스 모른단 말이에요 ..이 프로젝트 끝나면 자바스크립트랑 같이 공부할거란마리에요 ㅠ___ㅠ 


그래서 나는 form 태그만을 이용해서 구현해보았다.

에이젝스 안해도,, 되던데 ,,? 헤헷 ..


(사실 에이젝스 예제 보고 정말 똑같ㅇ ㅣ따라했는데도 안돼서 어쩔수 없던건 빔1)



S3Wrapper.java 에 업로드 함수를 추가한다.


    public String upload(MultipartFile multipartFile, String dirName) throws IOException {
        File uploadFile = convert(multipartFile)
                .orElseThrow(() -> new IllegalArgumentException("MultipartFile -> File로 전환이 실패했습니다."));

        return upload(uploadFile, dirName);
    }

    private String upload(File uploadFile, String dirName) {
        String fileName = dirName + "/" + uploadFile.getName();
        String uploadImageUrl = putS3(uploadFile, fileName);
        removeNewFile(uploadFile);
        return uploadImageUrl;
    }

    private String putS3(File uploadFile, String fileName) {
        amazonS3Client.putObject(new PutObjectRequest(bucket, fileName, uploadFile).withCannedAcl(CannedAccessControlList.PublicRead));
        return amazonS3Client.getUrl(bucket, fileName).toString();
    }

    private void removeNewFile(File targetFile) {
        if (targetFile.delete()) {
            logger.info("파일이 삭제되었습니다.");
        } else {
            logger.info("파일이 삭제되지 못했습니다.");
        }
    }

    private Optional<File> convert(MultipartFile file) throws IOException {
        File convertFile = new File(file.getOriginalFilename());
        if(convertFile.createNewFile()) {
            try (FileOutputStream fos = new FileOutputStream(convertFile)) {
                fos.write(file.getBytes());
            }
            return Optional.of(convertFile);
        }

        return Optional.empty();

다시한번 말하지만 이전 게시글의 S3 설정은 다 이루어졌다고 가정한다!

아 어떤 게시글을 봤는데 Spring boot를 사용하면 S3 bean 생성 안해줘도 자동 주입이 된다고 하던데, 그것도 나중에 알아보도록 해야겠다


그리고 컨트롤러,


@PostMapping("/manager/addTrainer")
	public String addTrainer(Trainer trainer,Model model,HttpServletRequest req,@RequestParam("file") MultipartFile multipartFile){
		Account account=new Account();
		account.setId(trainer.getId());
		account.setPassword(trainer.getPassword());
		trainer.setCenter_id(this.manager.getCenter_id());
		try{
			accountService.save(account, "ROLE_TRAINER", "TRAINER");
			trainerMapper.insertTrainer(trainer);
			s3Service.upload(multipartFile, "traienr");
		}catch(Exception ex){
			ex.printStackTrace();
			model.addAttribute("message","사용자 추가 에러!!!");
			return "/manager/addTrainer";
		}
		model.addAttribute("message","정상적으로 추가되었습니다!!");
		return "/manager/addTrainer";
	}



@RequestParam("file") MultipartFile multipartFile 이것과,

s3Service.upload(multipartFile, "traienr");

이것만 체크하도록 한다.

나머지는 내 프로젝트에서 사용하는 것이기 때문에 ㅎㅎ.

"traienr"는 저장된 폴더 명을 입력하면 된다. 일단은 임의로 설정해주었다.



이제 jsp파일


<form method="post" enctype="multipart/form-data">
   <div class="container" style="padding-top:5%">
 	<div class="row">
 	<div class="col-md-3"></div>
 		<div class="col-md-6">
		     <div class="card">
		  <h5 class="card-header">트레이너추가</h5>
  		<div class="card-body">
  		<!-- 사진 입력폼  -->
  		  <div class="form-group">
              <label for="InputId">아이디</label>
              <input type="text" class="form-control" id="id" name="id" placeholder="ID">
            </div>
            <!-- 사진 입력폼 -->
            <div class="form-group">
              <label for="InpuImage">사진</label>          
			  <input type='file' id="file" name="file" onchange="readURL(this);" /> 
		      <img id="ShowImage" src="#" placeholder="사진을 등록하세요" />
            </div>
            <div class="form-group">
              <label for="InputPassword">비밀번호</label>
              <input type="password" class="form-control" id="password"  name="password" placeholder="Password">
            </div>
            <div class="form-group">
              <label for="InputName">이름</label>
              <input type="text" class="form-control" id="name" name="name" placeholder="Name">
            </div>
              <div class="form-group">
              <label for="InputName">성</label>
              <input type="text" class="form-control" id="gender" name="gender" placeholder="Gender">
            </div>
    	<div class="form-group">
              <label for="InputName">생년월일</label>
              <input type="text" class="form-control" id="birth" name="birth" placeholder="BirthDate">
            </div>
             <div class="form-group">
              <label for="phoneNumber">휴대폰 번호</label>
              <input type="text" class="form-control" id="phone_number" name="phone_number" placeholder="Phone_number">
            </div>
               <div class="form-group">
              <label for="closedDay">휴무일</label>
              <input type="text" class="form-control" id="closed_day" name="closed_day" placeholder="Closed Day">
            </div>
            <button type="submit" class="btn btn-block btn-primary text-light">서비스 이용자 등록</button>
                  <input type="hidden" name="${_csrf.parameterName}"
				value="${_csrf.token}" />
		</div>
 	</div>
 	</div>
 	<div class="col-md-3"></div>
 	</div>
 	</div>
 	</form>
마찬가지로,

<form method="post">와,


 <div class="form-group">
              <label for="InpuImage">사진</label>          
			  <input type='file' id="file" name="file" onchange="readURL(this);" /> 
		      <img id="ShowImage" src="#" placeholder="사진을 등록하세요" />
            </div>

이것만 일치시켜주면 되겠다.

onchange 메소드는 무시부탁드립미당.



그런 뒤 실제 페이지를 들어가서 제출 버튼을 누르면 실수가 없는한 내 s3버킷에 사진이 들어가있다.

진작 이렇게할걸 ajax로 삽질하는 바람에 시간 많이 날려먹었다 ㅠ__________ㅠ



여기서 추가로 내가 하고 싶은건,

파일 명을 등록하는 이미지의 이름 말고 폼에 입력한 아이디 값으로 전송해주는 것!

으로 수정을 해보아야겠다. 어렵진 않을 것 같다 !  


인턴십이 생각보다 일이 생기기도 했고,, 다른 프로젝트도 시간을 많이 잡아먹어서 진도가 잘안나간다 ㅠ___ㅠ

부지런히 해서 이번달안엔 꼭 완료할 수 있도록! 


내일은 알고리즘 공부좀 해야지 ,, 카카오 코드 페스티벌 아주 마니 털렷서 내 멘탈,,