보라코딩

Day102_230523_스프링부트 파일 업로드 (+ 업로드 후 이미지 보여주기) 본문

코딩/Spring

Day102_230523_스프링부트 파일 업로드 (+ 업로드 후 이미지 보여주기)

new 보라 2023. 5. 23. 22:27

경로 때문에 고생했다.

일단 저장하는 경로를 C:\\upload 로 했는데

파일 저장은 MultiPartFile 타입의 oriFilename 이용해서 하고

파일 이름은 String 타입의 filename에 저장해놓는다.

 

 

근데 문제는 C아래 upload 에 파일은 저장되었는데

바로 불러오는게 되지 않는다.

절대경로와 상대경로가 달라서 뭔 처리를 해줘야 하는 것 같다..

 

C에 저장하는 것은 쉽고

불러오는 것은 상대경로로 프로젝트 안에 있어야 쉬운데

두개가 다르니 어렵다;;

 

뻘짓하다가 하루 날림............ㅠㅠ

내일은 꼭 해결하고 다른거 공부해야지!!!

 

파일 업로드 어렵네................

 

 

=> WebConfig로 해결완료!!!!

 

 

 

 

 

StoreVO

oriFilename 타입을 MultiPartFile로 하고 (파일로 저장해야함!!)

filename은 String으로 한다. (경로 저장해야함!!)

package com.tastemate.domain;

import lombok.Data;
import org.springframework.web.multipart.MultipartFile;

@Data
public class StoreVO {

private String storeIdx;
private String userIdx;
private String storeName;
private String category1;
private String storeAddress;

private double storeLati;
private double storeLongi;

private String phoneNumber;
private String storeCount;

private String filename;
private MultipartFile oriFilename;



}

 

 

 

register.html

 

핵심은 form에서 아래와 같이 써줘야 하는 것!

enctype="multipart/form-data"

 

<form th:action="@{/store/register}" method="post" enctype="multipart/form-data">


<div class="row">
<div class="col-md-8 mb-3">
<label for="storeName">맛집 이름</label>
<input type="text" class="form-control" id="storeName" name="storeName" required>
</div>


<!--
userIdx 세션에서 넣어줘. 등록한 사람만 수정, 삭제할 수 있게 insert 해야함
-->

<div class="col-md-4 mb-3">
<label for="userIdx">사용자 ID</label>
<input type="text" class="form-control" id="userIdx" name="userIdx" required>
<input type="hidden" class="form-control" id="userName" name="userName">
</div>
</div>

<div class="form-group">
<label for="category1">카테고리</label>

<div class="mb-3">
<div class="form-group">
<select class="form-control" id="category1" name="category1">
<option selected disabled>FOOD STYLE</option>
<option value="한식">한식</option>
<option value="중식">중식</option>
<option value="일식">일식</option>
<option value="양식">양식</option>
<option value="퓨전">퓨전</option>
<option value="푸드코트">푸드코트</option>
</select>
</div>
</div>
</div>

<div class="mb-3">
<label for="storeAddress">가게 주소</label>
<input type="text" class="form-control" id="storeAddress" name="storeAddress" required>
</div>
<div class="row">
<div class="col-md-6 mb-3">
<label for="storeLati">위도</label>
<input type="text" class="form-control" id="storeLati" name="storeLati" required>
</div>
<div class="col-md-6 mb-3">
<label for="storeLongi">경도</label>
<input type="text" class="form-control" id="storeLongi" name="storeLongi" required>
</div>
</div>
<div class="mb-3">
<label for="phoneNumber">맛집 전화번호</label>
<input type="text" class="form-control" id="phoneNumber" name="phoneNumber" required>
</div>

<div class="mb-3">
<label for="oriFilename">이미지 파일명</label>
<input type="file" class="form-control" id="oriFilename" name="oriFilename"
accept="image/png, image/gif, image/jpeg" multiple="multiple" required>
</div>
<div class="text-center mt-5 mb-3">
<button class="btn btn-primary" type="submit">맛집 등록 요청</button>
<a class="btn btn-success" th:href="@{/store/list}">목록으로</a>
</div>

</form>

 

 

 

 

 

StoreController

 

MultipartFile을 이용한다!

 

@PostMapping("/register")
public String registerStoreVO(StoreVO storeVO, MultipartFile oriFilename){

service.saveFile(storeVO, oriFilename);

return "redirect:/store/list";
}

 

 

 

 

application.properties
file.dir=C:\\upload

 

 

 

StoreService

 

public void saveFile(StoreVO storeVO, MultipartFile multipartFile) {

if(multipartFile.isEmpty()){
return;
}

String oriFilename = multipartFile.getOriginalFilename();
String uuid = UUID.randomUUID().toString();

String extension = oriFilename.substring(oriFilename.lastIndexOf("."));

oriFilename = oriFilename.substring(oriFilename.lastIndexOf("\\")+1);

String savedName = uuid + "_" + oriFilename;

String savedPath = fileDir + "/" +savedName;

log.info(savedPath);

File saveFile = new File(savedPath);

try {
multipartFile.transferTo(saveFile);
} catch (Exception e) {
log.error(e.getMessage());
}

StoreVO storeVO1 = new StoreVO();


storeVO1.setFilename(savedName);
//storeVO1.setFilename(savedPath);
storeVO1.setUserIdx(storeVO.getUserIdx());
storeVO1.setStoreName(storeVO.getStoreName());
storeVO1.setCategory1(storeVO.getCategory1());
storeVO1.setStoreAddress(storeVO.getStoreAddress());
storeVO1.setStoreLati(storeVO.getStoreLati());
storeVO1.setStoreLongi(storeVO.getStoreLongi());
storeVO1.setPhoneNumber(storeVO.getPhoneNumber());

log.info("Service 잘 변환되었나?" + storeVO1);

int result = mapper.store_register(storeVO1);

}

 

 

 

 

 

StoreMapper.xml

 

<insert id="store_register" parameterType="com.tastemate.domain.StoreVO">
INSERT INTO STORE (STORE_IDX, USER_IDX, STORE_NAME, CATEGORY1,
STORE_ADDRESS, STORE_LATI, STORE_LONGI, PHONE_NUMBER, STORE_COUNT,
FILENAME
)
VALUES (store_seq.NEXTVAL, #{userIdx}, #{storeName}, #{category1},
#{storeAddress}, #{storeLati}, #{storeLongi}, #{phoneNumber}, 0,
#{filename}
)
</insert>

 

 

 

 

WebConfig

 

첫번째 override는 파일업로드랑 연관된거 아니고

두번째가 핵심!!!!!

 

package com.tastemate;

import com.tastemate.interceptor.LogInterceptor;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class WebConfig implements WebMvcConfigurer {

@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new LogInterceptor())
.order(1)
.addPathPatterns("/**")
.excludePathPatterns("/css/**", "/*.ico", "/error");
}

private String resourcePath = "/store/**";
private String savePath = "file:///C:/upload/";

@Override
public void addResourceHandlers(ResourceHandlerRegistry registry){
registry.addResourceHandler(resourcePath)
.addResourceLocations(savePath);
}
}

 

매우 중요!!!!!!!!!!!!

private String resourcePath = "/store/**";
private String savePath = "file:///C:/upload/";

@Override
public void addResourceHandlers(ResourceHandlerRegistry registry){
registry.addResourceHandler(resourcePath)
.addResourceLocations(savePath);
}

 

 

 

=> 그리고 타임리프에서 아래와 같이 받아야함!!!

 

<img th:src="@{|/store/${storeVO.filename}|}" class="img-fluid <!--img-thumbnail-->" />

 

 

 

 

 

 


 

수정하기는 이렇게~~~

 

 

스프링부트 파일(이미지) 수정하기!!!

파일 업로드도 고생했는데 파일 수정하기도 고생함 ^^... 그래도 해결완료! update.html 우선 맨 위에 기존 이미지 한번 보여주고 그 아래에서 파일 업로드 할 수 있게 해놓고 만약 이미지 업로드 안

boracoding.tistory.com