1. nobody.png

2. 사진 업로드 그림 그리기
user/profile-form.mustache

{{> layout/header}}
<div class="container p-5">
<!-- 요청을 하면 localhost:8080/login POST로 요청됨
username=사용자입력값&password=사용자값 -->
<div class="card">
<div class="card-header"><b>프로필 사진을 등록해주세요</b></div>
<div class="card-body d-flex justify-content-center">
<img src="/nobody.png" width="200px" height="200px">
</div>
<div class="card-body">
<form>
<div class="mb-3">
<input type="file" class="form-control" name="profile">
</div>
<button type="submit" class="btn btn-primary form-control">사진변경</button>
</form>
</div>
</div>
</div>
{{> layout/footer}}
3. UserController 코드 수정
@GetMapping("/api/user/profile-form")
public String profileForm(){
return "user/profile-form";
}
4. header.mustache 수정
<li class="nav-item">
<a class="nav-link" href="/api/user/profile-form">프로필</a>
</li>

5. 화면 실행

6. 파일 처리 프로세스
6.1 WebConfig.java 수정하기
// 웹서버 폴더 추가
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
WebMvcConfigurer.super.addResourceHandlers(registry);
// 1. 절대경로 file:///c:/upload/
// 2. 상대경로 file:./upload/
registry
.addResourceHandler("/images/**")
.addResourceLocations("file:" + "./images/")
.setCachePeriod(60 * 60) // 초 단위 => 한시간
.resourceChain(true)
.addResolver(new PathResourceResolver());
}
6.2 images 폴더 만들기 (사진도 추가해두기 nobody.png)

6.3 파일 저장 프로세스 만들기
User
package org.example.springv3.user;
import jakarta.persistence.*;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import org.hibernate.annotations.CreationTimestamp;
import java.sql.Timestamp;
@Builder
@Setter
@Getter
@Table(name = "user_tb")
@NoArgsConstructor
@Entity
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
@Column(unique = true, nullable = false)
private String username; // 아이디
@Column(nullable = false)
private String password;
@Column(nullable = false)
private String email;
private String profile;
@CreationTimestamp
private Timestamp createdAt;
@Builder
public User(Integer id, String username, String password, String email, String profile, Timestamp createdAt) {
this.id = id;
this.username = username;
this.password = password;
this.email = email;
this.profile = profile;
this.createdAt = createdAt;
}
}
MyFile
package org.example.springv3.core.util;
import org.example.springv3.core.error.ex.Exception500;
import org.springframework.web.multipart.MultipartFile;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.UUID;
public class MyFile {
public static String 파일저장(MultipartFile file){
UUID uuid = UUID.randomUUID(); // uuid
String fileName = uuid+"_"+file.getOriginalFilename(); // 롤링
Path imageFilePath = Paths.get("./images/"+fileName);
try {
Files.write(imageFilePath, file.getBytes());
} catch (Exception e) {
throw new Exception500("파일 저장 오류");
}
return fileName;
}
}
UserService
@Transactional
public void 프로필업로드(MultipartFile profile, User sessionUser){
String imageFileName = MyFile.파일저장(profile);
// DB에 저장
User userPS = userRepository.findById(sessionUser.getId())
.orElseThrow(() -> new Exception404("유저를 찾을 수 없어요"));
userPS.setProfile(imageFileName);
} // 더티체킹 update됨
public String 프로필사진가져오기(User sessionUser) {
User userPS = userRepository.findById(sessionUser.getId())
.orElseThrow(() -> new Exception404("유저를 찾을 수 없어요"));
String profile = userPS.getProfile() == null ? "nobody.png" : userPS.getProfile();
return profile;
}
UserController
@PostMapping("/api/user/profile")
public String profile(@RequestParam("profile") MultipartFile profile){
User sessionUser = (User) session.getAttribute("sessionUser");
userService.프로필업로드(profile, sessionUser);
return "redirect:/api/user/profile-form";
}
@GetMapping("/api/user/profile-form")
public String profileForm(HttpServletRequest request) {
User sessionUser = (User) session.getAttribute("sessionUser");
String profile = userService.프로필사진가져오기(sessionUser);
request.setAttribute("profile", profile);
return "user/profile-form";
}
profile-form 그림 파일 수정 (머스테치)
{{> layout/header}}
<div class="container p-5">
<!-- 요청을 하면 localhost:8080/login POST로 요청됨
username=사용자입력값&password=사용자값 -->
<div class="card">
<div class="card-header"><b>프로필 사진을 등록해주세요</b></div>
<div class="card-body d-flex justify-content-center">
<img src="/images/{{profile}}" width="200px" height="200px">
</div>
<div class="card-body">
<form action="/api/user/profile" method="post" enctype="multipart/form-data">
<div class="mb-3">
<input type="file" class="form-control" name="profile">
</div>
<button type="submit" class="btn btn-primary form-control">사진변경</button>
</form>
</div>
</div>
</div>
{{> layout/footer}}
Share article