
요놈은 내 블로그 우측상단에 있는 아이콘으로 웹페이지 헤더로 설정되어 내 닉네임과 설정했던 프로필 사진을 보여주는 공간이다.
웬만해서 거의 모든 홈페이지에 계정이 있는 경우에 프로필 사진을 등록하고 사용하는 경우가 많다.
그래서 해당 게시물에서는 웹페이지에 계정이 등록될 때, 계정 정보와 더불어 프로필 사진에 대해 처리하고 웹페이지에 출력되는 기능을 알아보자.
[기능]
1. 회원가입 시, 계정 프로필 등록가능
2. 티스토리 블로그와 동일하게 fixed 형태의 헤더 우측상단위에 로그인된 계정닉네임과 프로필 사진 보이도록 하기
MemberApiController 회원가입 요청 처리 메서드를 살펴보자.

해당 메서드는 api/board 요청에 대해서 POST 방식으로 왔을 때, 실행되는 join() 메서드이다.
일단 해당 메서드에서는 사용자 웹 브라우저에서 사용자가 입력한 데이터, 그리고 첨부한 프로필 사진파일을 받아들여 db에 등록해주는 작업을 진행해야한다. 그래서 fetch 함수로 패킷을 전달할 때, body내에 담긴 formData 객체를 파라미터 로 받아서 메서드를 실행할 것이다. (Map은 신경 꺼주세요 !!!!)
파라미터에 MemberVo vo에는 직접 타이핑해서 적은 아이디 비밀번호 닉네임에대한 정보가 들어있을 것이고, MultipartFile f 객체에는 파일이 담겨져 있다.

String divPath는 서버측 디렉토리 경로로 사용자가 업로드한 파일을 어느 디렉토리에 저장할지에 대한 경로 문자열이 담겨있다.

String changeName은 FileUploader 클래스에 save라는 메서드에 사용자가 전달한 파일 객체, 그리고 서버측에서 파일을 저장할 경로를 파라미터로 사용하고 실행되어 반환받은 값이 들어간 변수이다. 사용자가 업로드 했을때의 파일명이 아닌 랜덤값을 합쳐서 만든 문자열과 업로드 했을 때의 확장자 일치를 위해서 사용된다.
해당 메서드에서는 정확히 어떤 작업을 하는지 알아보자.

사용했던 save() 메서드이다. 해당 함수에서는 일단 사용자가 올릴 때의 파일 확장자와 동일하게 서버측에서도 파일이 생성되어야 하므로 확장자를 추출하는 코드가 적혀있다. f.getOriginalFilename() 메서드를 통해서 사용자가 파일 첨부할 때의 원본 파일 명을 가져와서 "\\." 으로 split() 메서드를 사용하였다. XXXX.png 와 같은 파일명 형식일 것이므로 "\\." 으로 나누게 되면
{"XXXX", "png"} 와 같이 맨 마지막 인덱스에 확장자가 오게될 것이다.
여기서 "."이 아니라 "\\."으로 나눈 이유는, split() 메서드는 내부적으로 정규표현식을 사용하는데, 정규표현식에서 "모든 문자"를 의미하기 때문이다. 그래서 자바에서는 점을 기준으로 나누기 위해서는 이스케이프 문자 "\"을 앞에 추가로 달아주어야 하고 "\\."으로 해주어야 한다.
다시 돌아와서, 그렇게 ext 변수에는 .png .jpg 와 같은 문자열이 담기게 된다.
그리고 아까 말했던 동일한 파일명이 저장되지 않도록 난수문자열에 확장자(ext)을 더해주어 파일명(changeName)을 초기화한다.
savePath는 서버측 디렉토리에 파일을 어느 경로에 어느 파일명으로 저장할지에 대한 전체 경로 + 파일명으로 File() 생성자에 파라미터로 savePath를 설정해주어 해당 경로에 파일을 생성하고

f.transferTo(파일객체) 를 통해서 f에 담긴 파일내용을 전달한다. 마지막으로 반환으로는 경로없는 난수파일명(changeName)을 반환한다.

다시 MemberApiController로 돌아와서, 사용자가 회원가입시 입력한 데이터가 들어있는 vo에 방금 save() 메서드를 통해서 새롭게 만든 난수파일명이 없으므로, profile이라는 필드에 setter를 통해서 changeName을 할당하였다.
그리고 다음은 이전에 했던 회원가입 로직과 동일하게 Mapper까지 vo를 전달하여 Insert 명령문을 통해서 DB에 사용자가 설정한 아이디 비밀번호 닉네임 그리고 서버 디렉토리에 저장된 난수파일명까지 저장한다. 쿼리문 실행 결과를 다시 자바스크립트로 응답을 보내면서 서버측에서 메서드를 마무리한다.
이제 그러면 서버측으로 요청을 보내고 서버측 응답을 받아들이는 자바스크립트 코드를 확인해보자

해당 코드는 회원가입 버튼에 onclick 속성으로 설정된 메서드 join() 메서드이다. 해당 메서드에서는 document.querySelector() 메서드를 통해서 사용자가 input태그에 입력한 아이디, 비밀번호, 닉네임 태그에 .value를 통해서 값을 변수에 받아낸다.
그리고 추가로 프로필 사진을 업로드하는 type = "file" 의 input 태그는 .files를 통해서 배열형태로 받아내고 해당 인풋태그에서는 다중 파일선택이 불가능 하고 하나의 파일만 선택 되도록 해놨으므로 0번 인덱스의 파일객체를 file에 할당한다.
서버에 회원가입 요청을 보내기 위해서 Post 방식의 url을 설정하는데 이때 body에 이때까지 넣었던 JSON 형태의 파일이 아닌 FormData 객체(fd)를 넣어 요청패킷을 보낸다. fd는 .append() 메서드를 통해서 (키, 밸류) 형태로 객체에 값을 담아줄 수 있다.
이떄 당연히 서버측 파라미터로 객체 데이터를 받을 때, 해당 객체의 필드명과 키 이름이 동일해야 참조가 가능하다.

그리고 fetch 함수를 통해서 서버에 회원가입 요청을 보내고 서버측 join() 메서드가 끝나면 resp를 응답받는다. ResponseEntity.status를 통해서 resp에서 status 추출이 가능하므로 alert() 메서드를 통해서 상태를 출력하고 다시 body에 담았던 결과에대한 데이터는 data로 설정하여 조건문을 통해서 성공과 실패에 대해서 메세지와 포워딩 해줄지 말지를 결정한다.

회원가입 페이지가 다음처럼 되어있을때 회원가입은 충분히 되지만 파일을 선택했을 때, 미리보기 기능이 있으면 좋을 것 같다. 그래서 파일 선택 인풋 태그에 onChange 메서드를 통해서 파일이 등록되면 사진을 보여줄 수 있도록 하는 기능을 js로 구현이 가능하다.

회원가입 페이지 jsp에 다음과 같이 onchange 속성을 통해서 메서드를 설정하였다.

해당 메서드는 input 태그에 있는 파일을 가지고 와서 FileReader()를 통해서 파일을 읽어낼 수 있다.
fr.readAsDataURL(file)을 통해서 업로드된 파일을 fr에 읽도록 시키고
파일리더 객체에 이벤트리스너를 통해서 파일을 모두 읽었을 때 ("load") preview 요소(img태그) 의 src 속성을 파일을 모두 읽은 fr객체의 결과로 설정한다. 그러면 다음과 같이 이미지 출력이 올바르게 잘 나온다.

회원가입 완료 후에 로그인을 통해서 fixed 헤더 우측 상단에 내 닉네임과 프로필사진을 보여주려는 기능이 필요했다.

로그인이 되었을때 HttpSession을 통해서 내가 로그인 했던 계정 정보를 토대로 서버에 위치해 있는 프로필 파일을 저장하고 있는 디렉토리 경로와 회원가입할때 같이 계정정보에 등록됐던 난수형태의 파일명을 더한 파일경로를 userVo 객체에 setter로 할당하고, 세션을 setAttribute() 메서드를 통해서 생성해 주면 된다.

그리고 헤더.jsp 파일에서 세션에 있는 파일 경로를 img태그의 src 속성으로 넣어주고 닉네임도 참조해서 불러오면 된다.
'Spring' 카테고리의 다른 글
| [Spring + Javascript] 게시물 목록 페이지네이션 구현하기(6) (1) | 2025.06.27 |
|---|---|
| [Spring + Javascript] fetch()를 활용한 api방식 웹페이지 파일처리 (4) (1) | 2025.06.23 |
| [Spring + Javascript] fetch()를 활용한 api방식 웹페이지 기초 (3) (0) | 2025.06.19 |
| [Spring + Javascript] fetch()를 활용한 api방식 웹페이지 기초 (2) (0) | 2025.06.17 |
| [Spring] Spring Initializr를 통한 기초 예제 다루기 (1) | 2025.06.11 |