✅ 구현 화면
폼 화면에서 - 이미지 첨부파일 하고 제출시 이후에 detail 에서 나오는 화면
✅[1단계 : properties 수정]
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/mybo_db2?serverTimezone=UTC&useSSL=false
spring.datasource.username=root
spring.datasource.password=1234
spring.jpa.database=mysql
spring.jpa.database-platform=org.hibernate.dialect.MySQLDialect
spring.jpa.hibernate.ddl-auto=update
spring.jpa.generate-ddl=true
spring.jpa.show-sql=true
logging.level.org.hibernate=info
#파일 한개 당 최대사이즈
spring.servlet.multipart.maxFileSize=20MB
#요청당 최대 파일 크기
spring.servlet.multipart.maxRequestSize=100MB
#상품 이미지 업로드 경로
ImgLocation=D:/c402/sts4/upload3
#리소스 업로드 경로
uploadPath=file:///D:/c402/sts4/upload3/
spring.servlet.multipart.enabled=true
✅[2단계 : Question 컬럼 추가하기]
private String filepath;/*파일저장경로*/
private String filename;/*파일이름*/
✅[3단계 : form.html 수정하기]
-. enctype 선언하기
<form th:object="${questionForm}" method="post" enctype="multipart/form-data">
-. input type="file name="file" 작성하기
<div class="mb-3">
<label for="subject" class="form-label">제목</label>
<input type="text" th:field="*{subject}" name="subject" class="form-control">
</div>
<div class="mb-3">
<label for="content" class="form-label">내용</label>
<textarea name="content" th;field="*{content}" class="form-control" rows="10"></textarea>
</div>
<table>
<tr>
<td><input type="file" name="file" /></td>
</tr>
</table>
<input type="submit" value="저장하기" class="btn btn-primary my-2">
</form>
✅[4단계 : Controller 수정하기] - form이 submit될때 로직을 처리 해줌
-. QuestionForm 객체를 통해 사용자의 입력 데이터를 받아오고, BindingResult를 통해 유효성 검사 결과를 확인합니다. Principal 객체는 현재 사용자의 정보를 제공하며, @RequestParam("file") MultipartFile file은 업로드된 파일을 받아온다.
@PreAuthorize("isAuthenticated()")
@PostMapping("/create")
public String questionCreate(@Valid QuestionForm questionForm, BindingResult bindingResult, Principal principal, @RequestParam("file") MultipartFile file) throws Exception{
if (bindingResult.hasErrors()) {
return "question_form";
}
SiteUser siteUser = this.userService.getUser(principal.getName());
this.questionService.create(questionForm.getSubject(), questionForm.getContent(), siteUser, questionForm.getCategory(), file);
return "redirect:/question/list";
}
-. this.questionService.create(questionForm.getSubject(), questionForm.getContent(), siteUser, questionForm.getCategory(), file);: questionService를 통해 새로운 질문을 생성합니다. questionForm에서 주제, 내용, 사용자, 카테고리 및 업로드된 파일 등의 정보를 전달
✅[5단계 : Service 컬럼 추가하기]
-. properties에 미리 설정해둔 ImgLocation의 저장 위치를 설정해줌.
@Value("${ImgLocation}")
private String imgLocation;
public void create(String subject, String content, SiteUser user, String category, MultipartFile file) throws Exception{
String projectPath = imgLocation; //파일저장위치 = projectPath
UUID uuid = UUID.randomUUID(); //식별자.랜덤으로 이름만들어줌
String fileName = uuid + "_" + file.getOriginalFilename(); //저장될파일이름지정=랜덤식별자_원래파일이름
File saveFile = new File(projectPath, fileName); //빈껍데기생성 이름은 fileName, projectPath라는 경로에담김
file.transferTo(saveFile);
Question q=new Question();
q.setSubject(subject);
q.setContent(content);
q.setCreateDate(LocalDateTime.now());
q.setAuthor(user);
q.setCategory(category);
/*파일 업로드 추가*/
q.setFilename(fileName);//파일이름
q.setFilepath(projectPath + fileName); //저장경로,파일이름
this.questionRepository.save(q);
}
-. DB에 폼 데이터를 저장하는 로직
✅[6단계 : WebMvcConfig.java파일 생성하기]
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
//uploadPath프로퍼티값을 읽어온다
@Value("${uploadPath}")
String uploadPath;
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/photo/**")
//웹브라우저에 입력하는 url에 /photo 로 시작하는 경우 uploadPath에 설정한 폴더 기준으로 파일을 읽어오도록 설정
.addResourceLocations(uploadPath);
//로컬컴퓨터에 저장된 파일을 읽어올 root경로
}
}
이 코드는 Spring MVC 프로젝트에서 정적 리소스(예: 이미지 파일)를 처리하기 위한 설정 클래스인 WebMvcConfig입니다. 여기서 addResourceHandlers 메소드를 사용하여 정적 리소스의 핸들러를 추가하고, 이를 통해 해당 리소스의 위치를 지정합니다.
- @Configuration: 이 어노테이션은 해당 클래스가 Spring 설정 클래스임을 나타냅니다.
- WebMvcConfig implements WebMvcConfigurer: WebMvcConfigurer 인터페이스를 구현한 클래스로, Spring MVC의 설정을 커스터마이징할 수 있게 해줍니다.
- @Value("${uploadPath}"): 프로퍼티 파일에서 uploadPath라는 키에 대응하는 값을 읽어옵니다. 이는 정적 리소스의 저장 경로를 나타냅니다.
- addResourceHandlers(ResourceHandlerRegistry registry): 이 메소드는 정적 리소스 핸들러를 추가하는 역할을 합니다. ResourceHandlerRegistry를 사용하여 어떤 URL 패턴으로 시작하는 요청이 정적 리소스로 처리될지 설정합니다.
- registry.addResourceHandler("/photo/**"): "/photo"로 시작하는 URL 패턴을 정적 리소스로 처리하도록 설정합니다.
- addResourceLocations(uploadPath): 해당 URL 패턴으로 들어온 요청이 처리될 정적 리소스의 위치를 설정합니다. 즉, uploadPath에 지정된 디렉토리에서 해당 리소스를 찾아오게 됩니다.
이렇게 설정된 핸들러를 통해 "/photo"로 시작하는 URL 요청이 프로퍼티 파일에서 지정한 uploadPath 디렉토리에서 정적 리소스를 찾아 제공할 수 있습니다.
✅[7단계 : detail.html파일 수정하기] - 출력될 데이터 값 가져오기
<!-- 질문 -->
<div class="border-bottom py-2" th:text="${question.category}"></div>
<h2 class="border-bottom py-2" th:text="${question.subject}"></h2>
<div class="card my-3">
<div class="card-body">
<div class="detail-img">
<img onerror="this.style.visibility='hidden'" th:src="@{|/photo/${question.filename}|}"/>
</div>
<div th:text="${question.content}"></div>
-. th:src="@{/photo/${question.filename}|}"
이미지를 표시하는 <img> 태그입니다. th:src 속성을 통해 서버에서 받아온 question.filename 값을 사용하여 이미지의 경로를 동적으로 지정합니다. 또한, onerror 속성을 사용하여 이미지 로딩에 실패할 경우 이미지를 숨기도록 처리하고 있습니다.
✅ 실제 Form화면 및 구현
'2.프레임워크 > Spring Boot' 카테고리의 다른 글
[스프링부트] 게시판 조회수 추가하기 (0) | 2024.01.24 |
---|---|
[스프링부트] 게시판 만들기 - 카테고리 추가하기 (0) | 2024.01.23 |
[스프링부트] 게시판 만들기 - 페이지 0이 아닌 1번 부터 출력 변경하기 (0) | 2024.01.22 |
[스프링부트] 게시판 만들기 [1] - 프로젝트 구조 이해 및 기초 개념 (1) | 2024.01.11 |