본문 바로가기
Spring

[스프링부트] 6. 파일업로드 처리

by moca7 2024. 11. 6.

 

 

ㅁ 지금까지

- ~~를 진행했다.

 

- 근데 파일업로드 관련해서도 세팅한게 있었다.

라이브러리를 추가햇었고, root-context.xml에 파일업로드를 위한 빈을 하나 등록했었다. 

MultiPartResolver라는 빈.

여기서 파일 하나당 몇메가로 할건지 설정값을 했었다.

 

- 부트에서는 파일업로드 관련 라이브러리가 추가되어있어서 우리가 추가할 필요 없다.

MultiPartResolver  클래스도 이미 빈으로 등록되어서 부트에서 가지고 있다.

다만 설정값들이 존재하지 않아서 설정값만 aplication.properties에 작성한다.

 

 

ㅁ (스프링) root-context.xml

 

 
<?xml version="1.0" encoding="UTF-8"?>
 
  <!-- mybatis 사용을 위한 빈 3개 -->
  <bean class="org.apache.commons.dbcp2.BasicDataSource" id="dataSource" destroy-method="close">
    <!-- <property name="driverClassName" value="oracle.jdbc.driver.OracleDriver" />
         <property name="url" value="jdbc:oracle:thin:@localhost:1521:xe" /> -->
    <property name="driverClassName" value="net.sf.log4jdbc.sql.jdbcapi.DriverSpy" />
    <property name="url" value="jdbc:log4jdbc:oracle:thin:@localhost:1521:xe" />
    <property name="username" value="spring" />
    <property name="password" value="spring" />
  </bean>


  <bean class="org.mybatis.spring.SqlSessionFactoryBean" id="sqlSessionFactory">
    <property name="configLocation" value="classpath:config/mybatis-config.xml" />
    <property name="dataSource" ref="dataSource" />
  </bean>


  <bean class="org.mybatis.spring.SqlSessionTemplate" id="sqlSession">
    <constructor-arg ref="sqlSessionFactory" />
  </bean>  
 
 
 
  <!-- 트랜잭션 처리용 aop를 위한 구문 3개 -->
  <!-- AOP를 이용한 트랜잭션 처리 -->
  <!-- 1) 트랜잭션 매니저 빈으로 등록 (dataSource 객체 필요함) -->
  <bean class="org.springframework.jdbc.datasource.DataSourceTransactionManager" id="txManager">
    <property name="dataSource" ref="dataSource" />
  </bean>
 
 
  <!-- 2) 트랜잭션 Advice 등록 -->
  <tx:advice transaction-manager="txManager" id="txAdvice">
    <tx:attributes>
      <tx:method name="*" /> <!-- pointcut의 모든 메소드에서 실행하겠다. (삽입, 수정, 삭제, 목록조회, 상세조회 등의 메소드가 있음) -->
      <tx:method name="select*" read-only="true" />  <!-- 단, select로 시작하는 메소드는 실행하지 않는다. (삽입, 수정, 삭제 메소드만 실행됨) -->
    </tx:attributes>
  </tx:advice>
 
 
  <!-- 3) AOP 등록 -->
  <aop:config>
    <aop:pointcut expression="execution(* com.br.spring.service.*Impl.*(..))" id="txPointcut" />
    <aop:advisor advice-ref="txAdvice" pointcut-ref="txPointcut" />
  </aop:config>
 
 
 
  <!-- 파일 업로드를 위한 빈 등록 -->
  <!-- 주의사항 : 빈 이름을 내 마음대로 하면 안되고 반드시 multipartResolver로 해야 한다. -->
  <bean class="org.springframework.web.multipart.commons.CommonsMultipartResolver" id="multipartResolver">
    <property name="maxUploadSizePerFile" value="10485760" />
    <property name="maxUploadSize" value="104857600" />
    <property name="defaultEncoding" value="UTF-8" />
  </bean>
   
</beans>
 

 

 

 

 

ㅁ application.properties

 

 
spring.application.name=boot

# contextPath 등록
# server.servlet.context-path=/boot

# 사용할 포트번호 수정
server.port=8888

# 응답뷰 관련한 prefix, suffix : servlet-context.xml의 ViewResolver 빈 등록 설정 대체
spring.mvc.view.prefix=/WEB-INF/views/
spring.mvc.view.suffix=.jsp

# 마이바티스, 연결 db 정보 관련 구문 등록
spring.datasource.driver-class-name=net.sf.log4jdbc.sql.jdbcapi.DriverSpy
spring.datasource.url=jdbc:log4jdbc:oracle:thin:@localhost:1521:xe
spring.datasource.username=spring
spring.datasource.password=spring

# 마이바티스 관련 구문 등록 (기존의 mybatis-config.xml 파일 내용)
mybatis.mapper-locations=mybatis/mappers/*.xml
mybatis.type-aliases-package=com.br.boot.dto
mybatis.configuration.jdbc-type-for-null=NULL

# 파일업로드를 위한 구문 등록
spring.servlet.multipart.max-file-size=10MB
spring.servlet.multipart.max-request-size=100MB



 

- 인코딩 과정은 굳이 안해도 된다.

- 2줄만 추가하면 된다.

 

 

 

 

 

ㅁ fileutil 

 

 

 

- 스프링은 /만 해도 c를 찾았다. 스프링은 외부 톰캣을 사용했다

- 부트는 내장 톰캣을 쓰기때문에 /가 c를 가리키지 않고 내부 경로를 뜻한다.

 

 

 

 
package com.br.boot.util;

import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

@Component
public class FileUtil {
 

  public Map<String, String> fileupload(MultipartFile uploadFile, String folderName) {
   
   
    // (1) 업로드할 폴더 (/upload/yyyyMMdd)
    String filePath = "/upload/" + folderName + new SimpleDateFormat("/yyyyMMdd").format(new Date());
   
    File filePathDir = new File("C:" + filePath);
    if(!filePathDir.exists()) {   // 해당 경로의 폴더가 존재하지 않을 경우
      filePathDir.mkdirs();   // 해당 폴더 만들기
    }
   
   
    // (2) 파일명 수정 작업
    String originalFilename = uploadFile.getOriginalFilename(); // "xxxxx.jpg" | "xxxx.tar.gz" (파일 확장자가 2단계로 된 확장자도 있다)
   
    // 원본명으로부터 확장자 추출하기
    String originalExt = originalFilename.endsWith(".tar.gz") ? ".tar.gz"
                                  : originalFilename.substring(originalFilename.lastIndexOf("."));
   
    String filesystemName = UUID.randomUUID().toString().replace("-", "") + originalExt;
   
   
    // (3) 업로드 (폴더에 파일 저장)
    try {
      uploadFile.transferTo(new File(filePathDir, filesystemName));
    } catch (IllegalStateException e) {
      e.printStackTrace();
    } catch (IOException e) {
      e.printStackTrace();
    }
     
   
   
    // db에 기록할 데이터 다시 반환
    Map<String, String> map = new HashMap<>();
    map.put("filePath", filePath);
    map.put("originalName", originalFilename);
    map.put("filesystemName", filesystemName);
   
    return map;
   
   
  }
 
}
 

 

- new File("C:" + filePath);로 바꿨다.

- 참고로 지금은 개발 할 때 테스트를 위한거다. 배포할 땐 C가 아니다.

 

 

 

 

 

ㅁ 서버 start

 

- 첨부파일을 첨부해서 글을 작성해 본다.

잘 작성되고 다운도 된다.