대망의 글쓰기를 구현할 시간이 다가왔다.
사실 프로필 화면을 먼저 작성하긴 했는데, 이건 프론트엔드에 가깝기도 하고...
또 글쓰기가 먼저 구현 되어야 프로필을 얼추 만들 수 있을 것 같아서 도중에 그만두고 글쓰기를 먼저 구현했다.
우선 게시물 작성 화면은 위와 같다.
뭐... 보면 알 수 있겠지만 굉장히 간단하게 만들었다.
사진 업로드는 <input type=file>을 이용해서 MultipartFile로 업로드되게 만들었다. 물론 이미지만 올릴 수 있게 해야 하는데 그거까지는 로직을 짜기 귀찮아서(...) 생략했다. 물론 이미지는 최대 10개 까지 올릴 수 있다.
function previewImages(event) {
var preview = document.getElementById('imageBox');
var files = event.target.files;
if (files.length + images.length > 10) {
alert('이미지는 최대 10개까지 업로드 가능합니다.');
event.target.value = '';
return;
}
// 업로드될 때마다 비우기
preview.innerHTML = '';
for(var i = 0; i < files.length; i++) {
var file = files[i];
oriImages.push(file);
var reader = new FileReader();
reader.onload = function (e) {
var image = new Image();
image.src = e.target.result;
image.className = 'uploadedImage';
images.push(image);
// 이미지 개수 업데이트
document.getElementById('totalImages').innerText = images.length;
showImage(currentIndex);
};
reader.readAsDataURL(file);
}
}
이미지 미리보기 로직은 대략 이렇게 되어있는데, showImage()나 showNext(), showPrev() 등은 생략한다.
여하튼 이렇게 이미지를 업로드하고 커멘트를 작성한 후 업로드 버튼을 누르면, ajax 요청을 통해 서버로 데이터가 전송된다.
여기서 막혔던 점은, 단순히 이미지와 커멘트를 data라는 변수에 담아 JSON으로 전송하면, 서버에서는 이미지를 제대로 받을 수 없다는 것이었다. JSON은 텍스트 기반 데이터 전송 양식이라서, 이미지와 같은 이진 데이터는 전송할 수 없다는 것이다.
그래서 찾아본 끝에, FormData()를 활용하여 이미지를 보내면 HTTP의 multipart/form-data 형식으로 전송되어 이미지를 온전히 전송할 수 있다는 것이었다. 그래서 결국 내가 작성한 업로드 로직은 아래와 같다.
function postUpload() {
let data = new FormData();
data.append('userId', principal.id);
data.append('comment', document.getElementById('contentBox').value);
for (let i=0; i<oriImages.length; i++) {
data.append('pictures', oriImages[i], 'image'+i);
}
$.ajax({
type: "POST",
url: "/upload",
data: data,
contentType: false,
processData: false
}).done(function (resp){
alert("글이 작성되었습니다.");
location.href = "/index";
}).fail(function(error){
alert(JSON.stringify(error));
});
}
이렇게 POST 요청이 ajax를 통해 날아오면, 컨트롤러에서는 변수들을 받아서 업로드 로직을 실행한다.
@PostMapping("/upload")
public int upload(@RequestParam("userId") int userId,
@RequestParam("comment") String comment,
@RequestPart("pictures") List<MultipartFile> pictures) throws IOException {
int result = homeService.upload(userId, comment, pictures);
return 1;
}
public int upload(int userId, String comment, List<MultipartFile> pictures) throws IOException {
Account user = accountRepository.findById(userId).get(); // 유저
System.out.println("sadfasdfasdfasdf " + user.getId());
int pic_size = pictures.size();
Post post = new Post();
post.setComment(comment);
post.setLikecount(0);
post.setAccount(user);
post.setPic_size(pic_size);
for (int i=0; i<pic_size; i++) {
MultipartFile picture = pictures.get(i);
// posts 폴더에 postId 폴더를 만든 후 그 안에 사진 저장
File path = new File("C:/Users/kimdev/Desktop/Java/kimstagram/src/main/resources/static/posts/" + Integer.toString(post.getId()) + "/");
// 경로 생성
if (!path.exists()) {
path.mkdirs();
}
File file = new File(path, i+".jpg");
picture.transferTo(file);
}
postRepository.save(post);
return 0;
}
아 참고로 여기서 사용되는 @RequestPart는 'multipart/form-data'형식 데이터를 받기 위한 어노테이션이라고 한다!
여하튼 이런 로직으로 작성하면, 글이 업로드되면서 DB에 post가 insert된다.
https://ssdragon.tistory.com/99
스프링에서 파일저장하기
https://ssdragon.tistory.com/82 [Spring] IntelliJ 파일 업로드 주의사항 @PostMapping("/filetest") public String addImage2(@RequestParam("Photo") MultipartFile uploadFile, HttpServletRequest request) { String fileName = uploadFile.getOriginalFilenam
ssdragon.tistory.com
https://helloinyong.tistory.com/275
input type="file" 커스터마이징 하는 방법
Input File 태그의 기본적인 사용 File 필드를 사용하기 위해선 일반적으로 input type="file" 태그를 사용하게 된다. #Input File 태그 코드 # 각 브라우저 상에 나타나는 file 필드 해당 필드를 선언하면 각
helloinyong.tistory.com
https://velog.io/@gun_123/java-%ED%8C%8C%EC%9D%BC-%EC%97%85%EB%A1%9C%EB%93%9C-%EC%B2%98%EB%A6%AC
[SpringBoot] 파일 업로드 처리
업로드 결과 반환과 화면 처리 브라우저에서 이미지를 전송받고 결과 데이터를 JSON으로 전송할 것임. 따라서 어떤 구조의 데이터를 전송할 것인지 결정해야 함. 브라우저에 필요한 정보를 정리
velog.io
'프로젝트 > Kimstagram' 카테고리의 다른 글
[내멋대로 만드는 Kimstagram] 6. 게시글 화면 구현과 댓글 작성하기 (0) | 2024.01.21 |
---|---|
[내멋대로 만드는 Kimstagram] 5. 프로필 화면 만들기 (0) | 2024.01.21 |
[내멋대로 만드는 Kimstagram] 3.Spring Security + JWT 로그인 구현하기 (1) | 2024.01.09 |
[내멋대로 만드는 Kimstagram] 2. 로그인, 회원가입 구현하기 (0) | 2024.01.07 |
[내멋대로 만드는 Kimstagram] 1. 준비물 세팅 (2) | 2024.01.07 |