| 외부 경로 Resource 접근하기
Spring 사용시 외부(프로젝트폴더 밖)에 존재하는 Resource를 사용하고 싶을때가 있다. 사용하는 방법을 알아보겠다
fileConfig
@Configuration
public class fileConfig implements WebMvcConfigurer {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/profile/**")
.addResourceLocations("file:///home/ubuntu/img/");
}
}
.addResourceHandler 를 통해 외부에서 Resource를 요청하는 경로를
.addResourceLocations 에 해당하는 경로로 매핑해줍니다.
즉, URI /profile/ 이하로 요청 될 경우 로컬에 존재하는 /home/ubuntu/img/ 경로에 있는 파일을 찾아서 제공한다.
ex) -> file:///home/ubuntu/img/1 로 매핑된다
.addResourceLoacations() 설정시 로컬 디스크 경로일경우 file:/// 접두어를 꼭 붙여야 합니다.
| 이미지업로드
html
<div class="profilePopupDiv">
<ul class="profilePopupUl">
<li th:attr="class=${profileImage=='/image/index/defaultProfileImg.jpeg' ? 'profilePopupLi set' : 'profilePopupLi'}"
onclick="setDefaultProfile()" id="defaultProfileImage">
<img src="/image/index/defaultProfileImg.jpeg" class="profilePopupLi_img" alt=""> <span>기본프로필</span></li>
<li th:attr="class=${profile!=null ? (profileImage!='/image/index/defaultProfileImg.jpeg'?'profilePopupLi set':'profilePopupLi'):'profilePopupLi none'}" onclick="setMyProfile()" id="myProfileImage"><img class="profilePopupLi_img" th:src="${profile}" alt="" > <span>나의프로필</span></li>
<hr>
<li class="profilePopupLi" onclick="openUploadImg()">
사진업로드
<form id="uploadForm">
<input type="file" onchange="uploadImg()" name="file" id="uploadInput"/>
<input type="text" name="memberId" th:value="${memberId}"/>
</form>
</li>
</ul>
</div>
JS
//기본프로필로설정
function setDefaultProfile(){
$.ajax({
type : 'GET', // 타입 (get, post, put 등등)
url : '/profileapi/default/'+memberId.value, // 요청할 서버url
async:false,
success : function() { // 결과 성공 콜백함수
$('#myProfileImage').removeClass('set');
$('#defaultProfileImage').addClass('set');
$('#profile_pic_img').attr('src','/image/index/defaultProfileImg.jpeg');
$('#userInfo_profileImage').attr('src','/image/index/defaultProfileImg.jpeg')
}}
)
}
//나의프로필로설정
function setMyProfile(){
$.ajax({
type : 'GET', // 타입 (get, post, put 등등)
url : '/profileapi/myprofile/'+memberId.value, // 요청할 서버url
async:false,
success : function() { // 결과 성공 콜백함수
$('#defaultProfileImage').removeClass('set');
$('#myProfileImage').addClass('set');
$('#profile_pic_img').attr('src',$('#myProfileImage>.profilePopupLi_img').attr('src'));
$('#userInfo_profileImage').attr('src',$('#myProfileImage>.profilePopupLi_img').attr('src'));
}}
)
}
//나의프로필등록
function uploadImg(){
let form = $('#uploadForm')[0];
let formData = new FormData(form);
let fileName = $('#uploadInput').val()
fileName = fileName.slice(fileName.indexOf(".")+1).toLowerCase();
if(fileName != "jpg" && fileName != "png" && fileName != "jpeg" && fileName != "gif" && fileName != "bmp"){
alert("이미지파일만 업로드 가능합니다.");
return false;
}
//contentType과 processData 옵션 모두 false로 넣어줘야만 잘 동작한다.
// 이게 없으면 오류가 발생하면서 서버에 제대로 안 날아감
// - contentType : false 로 선언 시 content-type 헤더가 multipart/form-data로 전송되게 함
// - processData : false로 선언 시 formData를 string으로 변환하지 않음
$.ajax({
url : '/profileapi',
type : 'POST',
data : formData,
contentType : false,
processData : false,
success: function(result) {
$('#myProfileImage').removeClass('none');
console.log(result.data.profileImageDirectory)
$('#myProfileImage>.profilePopupLi_img').attr('src',result.data.profileImageDirectory);
setMyProfile();
},
error: function(r) {
console.log('error');
}
})
}
ProfileImageApiController
@RestController
@RequestMapping("profileapi")
@RequiredArgsConstructor
public class ProfileImageApiController {
private final ProfileImageApiLogicService profileImageApiLogicService;
@GetMapping("{memberId}")
public String read(@PathVariable("memberId") Long memberId) {
return profileImageApiLogicService.searchid(memberId);
}
@PostMapping("")
public Header<ProfileImageApiResponse> create(
@RequestParam(name ="file") MultipartFile file,
@RequestParam(name="memberId") Long memberId) throws IOException {
return profileImageApiLogicService.create(file,memberId);
}
@GetMapping("default/{memberId}")
public String setDefault(@PathVariable("memberId")Long memberId, HttpServletRequest request){
HttpSession session = request.getSession();
profileImageApiLogicService.setDefault(memberId);
session.setAttribute("profileImage","/image/index/defaultProfileImg.jpeg");
return null;
}
@GetMapping("myprofile/{memberId}")
public String setMyProfile(@PathVariable("memberId")Long memberId, HttpServletRequest request){
HttpSession session = request.getSession();
String myprofile = profileImageApiLogicService.setMyProfile(memberId);
session.setAttribute("profileImage",myprofile);
return myprofile;
}
}
ProfileImageApiLogicService
@Service
@RequiredArgsConstructor
public class ProfileImageApiLogicService{
private final ProfileImageRepository profileImageRepository;
private final MoneyMemberRepository moneyMemberRepository;
public Header<ProfileImageApiResponse> response(ProfileImage profileImage){
ProfileImageApiResponse profileImageApiResponse = ProfileImageApiResponse.builder()
.profileImageDirectory(profileImage.getProfileImageDirectory())
.member(profileImage.getMember())
.id(profileImage.getId())
.build();
return Header.OK(profileImageApiResponse);
}
public String searchid(Long memberId){
// System.out.println("서비스단 userid:"+userid);
Optional<ProfileImage> profile = profileImageRepository.findByMemberId(memberId);
if(profile.isPresent()){
return profile.get().getProfileImageDirectory();
}else{
return null;
}
}
public String setDefault(Long memberId){
MoneyMember moneyMember = moneyMemberRepository.findById(memberId).get();
moneyMember.setProfileImage("/image/index/defaultProfileImg.jpeg");
moneyMemberRepository.save(moneyMember);
return "true";
}
public String setMyProfile(Long memberId){
Optional<ProfileImage> profile = profileImageRepository.findByMemberId(memberId);
MoneyMember moneyMember = moneyMemberRepository.findById(memberId).get();
moneyMember.setProfileImage(profile.get().getProfileImageDirectory());
moneyMemberRepository.save(moneyMember);
return profile.get().getProfileImageDirectory();
}
public Header<ProfileImageApiResponse> create(MultipartFile file,Long memberId) throws IOException {
String fileExtension = file.getOriginalFilename().split("[.]")[1];
String pdir = "profile";
String dir = "/home/ubuntu/";
String sdir = dir+pdir;
String timeInfo = "-" + LocalDateTime.now().toString();
String serverPath=null;
String fullPath=null;
if (!file.isEmpty()) {
serverPath = pdir+"/" + memberId+timeInfo+"."+fileExtension;
fullPath = sdir + "/" + memberId+timeInfo+"."+fileExtension;
}
MoneyMember moneyMember = moneyMemberRepository.findById(memberId).get();
moneyMember.setProfileImage(serverPath);
moneyMemberRepository.save(moneyMember);
Optional<ProfileImage> optProfileImage = profileImageRepository.findByMemberId(memberId);
ProfileImage profileImage = null;
if(optProfileImage.isPresent()){
File originfile = new File(dir+optProfileImage.get().getProfileImageDirectory());
boolean fileDeleted = originfile.delete();
System.out.println(fileDeleted);
file.transferTo(new File(fullPath));
profileImage = optProfileImage.get();
profileImage.setProfileImageDirectory(serverPath);
profileImageRepository.save(profileImage);
System.out.println("수정함");
}else{
file.transferTo(new File(fullPath));
profileImage= ProfileImage.builder()
.profileImageDirectory(serverPath)
.build();
profileImage.setMember(moneyMember);
profileImageRepository.save(profileImage);
System.out.println("새로등록함");
}
return response(profileImage);
}
}
파일업로드 크기 제한
application.yml에 아래를 추가하면 된다
maxFileSize: 파일 하나당 올릴 수 있는 최대크기
maxRequestSize: 서버에 전송되는 모든 파일의 최대크기
spring:
servlet:
multipart:
maxFileSize: 10MB
maxRequestSize: 20MB
결과물
반응형
'웹 개발 > 🍃 SpringBoot' 카테고리의 다른 글
SpringBoot | 새로고침없이 페이지 부분변경하기(Ajax) (0) | 2023.05.26 |
---|---|
SpringBoot | Thymleaf Fragment(공통영역처리) (0) | 2023.05.26 |
SpringBoot | 카카오톡 간편로그인 구현 OAuth 2.0 (0) | 2023.05.24 |
SpringBoot | 로그인,세션등록 (0) | 2023.05.24 |
SpringBoot | 연관관계가 있는 엔티티에서의 CRUD하는법 (0) | 2023.05.21 |