날아라쩡글이의 블로그입니다.

webapp/resource/images에 파일 올리기 본문

중앙 HTA (2106기) story/spring java framwork story

webapp/resource/images에 파일 올리기

날아라쩡글이 2022. 1. 7. 09:22
반응형
  • 먼저 파일 업로드를 지원하는 라이브러리 의존성을 추가한다. 
    • maven에서 commons을 검색한다. fileupload의 의존성을 다운받고, pom.xml에 추가한다. 
    • <dependency>
          <groupId>commons-fileupload</groupId>
          <artifactId>commons-fileupload</artifactId>
          <version>1.4</version>
      </dependency>
  • DispatcherServlet에서 Bean_name은 마음대로 설정해도 되지만 sping MVC가 사용할 수 있게 이름을 설정해두는 것이 몇가지가 존재한다. 
    • spring에서는 해당이름이 맞지 않으면 다른걸 bean으로 등록하기 때문에 마음대로 변경해서는 안된다. 
    • id를 꼭 잘 지정해야한다. 
    • 1. 파일업로드 multipartResolver 
    • 2. 국제화처리 localResolver
    • 3.HandlerAdapter
    • 4.HandlerMapping
  • context-web에 첨부파일 업로드 요청(Multipart 요청)을 처리하는 MultipartResolver 인터페이스의 구현객체를 스프링의 컨테이너 빈으로 등록시킨다
    • <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <property name="defaultEncoding" value="UTF-8"></property>
       </bean>
    • 컨테이너 빈으로 등록시키면 DispatcherServlet이  HttpServletRequest를 mutipartHttpServletRequest로 변환하여 ModelAndView에서 매개변수 HttpRequestServlet으로 전송이 될 수 있다.
    • maxInMemorySize는 메모리안에 쌓였다가 저장되는 값으로 10240의 사이즈로 설정되어 있다. 
    • maxUploadSize는 파일의 업로드 할 수 있는 사이즈를 의미한다. defaul값은 -1로 -1은 시간에 제한이 없고, 크기에도 제한이 없다는 것이다. -1는 무한대라는 의미이다. 
    • maxUploadSizePerFile은 파일 1개당의 사이즈를 의미한다. 
  • form태그에서 encType을 기본값인 application/x-www-form-urlencoded에서 multipart/form-data으로 변경해준다. 
    • encType은 application/x-www-form-urlencoded이 기본값으로 입력값을 key= value로 변환하여 전송한다. 
    • 문제는 첨부파일이 있을 때 파일의 내용안에 어떤 data가 들어있는지 알 수 없다는 것이다. 
    • 복잡한 구분자가 필요한데 그래서 multipart/form-data으로 변경을 해준다. 
    • 그럼 boundary라는 구분자가 생겨나서 사이에 값1개가 저장이 된다. 
    • 임의의 text를 조합해서 만들었기 때문에 동일한 값이 나올 수 없으며, filedata와 formdata의 구분이 가능하다. 
    • boundary로 경계로 나누고, 값을 꺼낼 수 있다. 
  • <div class="mb-3">
    <label class="form-label">책 사진</label>
    <input type="file" class="form-control" name="upfiles" />
    </div>
    <div class="mb-3">
    <label class="form-label">책 사진</label>
    <input type="file" class="form-control" name="upfiles" />
    </div>
    <div class="mb-3">
    <label class="form-label">책 사진</label>
    <input type="file" class="form-control"name="upfiles" />
    </div>
  • form 데이터가 동일할 경우 이름을 같게 만들어 주고 다른 경우 이름을 다르게 바꾸면 된다. 
  • DB에 table을 설정한다. 
  • 그리고 DB에서 table설정값을 vo로 만들어 준다. 
    • private int bookNo;
      private String picture;
    • getter/setter메소드와 생성자를 작성한다. 
  • BookInsertForm에 form데이터를 받게 입력했는데, form태그에 file을 추가 했기 때문에 추가를 한다. 
    • private String title;
      private String author;
      private String publisher;
      private int price;
      private int discountPrice;
      @DateTimeFormat(pattern="yyyy-MM-dd")  
      private Date pubDate;
      private int stock;
      private List<MultipartFile> upfiles;
    • 매개변수의 타입은 MultipartFile으로 설정해야한다. 
      • 2개 이상의 첨부파일이 같은 이름을 업로드될 때에는 배열 혹은 콜렉션 타입의 변수를 선언한다. 
      • MultipartFile객체는 업로드된 첨부파일의 정보를 제공하는 객체다.
      • MultipartFile객체는 첨부파일의 유무, 파일명, 파일 사이즈, 파일컨텐츠 타입, 파일데이터, 파일과 연결괸 스트림을 제공한다. 
      • getter/setter메소드를 생성한다. 
  • 사진 컨텐츠는 static컨텐츠에 속한다. css, js, images 은 전부 새로 요청하기 때문에 /WEB-INF/가 있으면 다시 요청할때 내려올 수 없다. 그래서 webapp/resource안에 넣어 주어야한다.
  • insertController을 수정해준다.
    • @PostMapping("/insert.do")
      public String save(BookInsertForm form) throws IOException {
      String saveDirectory = "C:\\spring-workspace\\spring-mybatis\\src\\main\\webapp\\resources\\images";
      //resource의 경로 위치를 지정한다. 

      List<BookPicture> bookPictures = new ArrayList<BookPicture>();
      //vo로 설정한 BookPicture의 배열을 만든다. 

      List<MultipartFile> upfiles = form.getUpfiles();
      //파일을 가져온다. 

      for(MultipartFile multipartFile : upfiles) {
      if(!multipartFile.isEmpty()) {
      //파일이 들어가지 않은 것이 걸려진다. 파일이 비어있지 않으면!!!!
      //MultipartFile의 isEmpty()메소드는 해당 객체에 첨부파일 정보가 없으면 true를 반환한다. 

      //MultipartFile객체에서 getOriginalFilename() 메소드로 가져와서 업로드된 첨부파일의 이름을 조회한다. 
      String filename = multipartFile.getOriginalFilename();

      //책의 사진정보를 저장하는 BookPicture객체를 생성하고, 첨부파일 이름을 저장한다. 
      BookPicture bookPicture = new BookPicture();
      bookPicture.setPicture(filename);
      bookPictures.add(bookPicture);

      //업로드된 첨부파일을 프로젝트내의 images 폴더에 저장하기
      //MultipartFile객체는 getInputStream();메소드로 임시 디렉토리에 임시 파일 상태로 저장된 첨부 파일을 읽어오는 스트림을 제공한다. 
      InputStream in = multipartFile.getInputStream(); //읽어오는 스트림

      // 지정된 폴더에 첨부파일명으로 파일을 출력하는 스트림 생성하기
      FileOutputStream out = new FileOutputStream(new File(saveDirectory, filename)); //출력하는 스트림
      //newFile을 생성해서, 저장하는 경로위치, 파일이름을 넣는다. 

      //스프링의 있는 객체로 저장한다. 저장하는 스트림이다. beanUtils와 비슷하게 FileCopyUtils가 존재한다. 
      FileCopyUtils.copy(in, out);
      }
      }

      Book book = new Book();
      // BookInsertFrom객체의 멤버변수에 저장된 값을 Book객체의 멤버변수에 복사한다. 
      // 멤버변수의 타입과 멤버변수의 이름이 일치하는 값이 복사되며, 이름은 같은데 타입이 서로 다르면 예외가 발생한다. 
      BeanUtils.copyProperties(form, book);
      //폼에 있는 모든 프라퍼티의 값을 전부 복사하고 보낸준다. 
      ///책정보와 책사진저옵를 서비스 메소드에 전달해서 저장시킨다. 
      bookService.addNewBook(book, bookPictures);
      return "redirect:list.do";

방법

  1. commons-fileUpload라이브러리를 pom.xml에 의존성을 추가한다. 
  2. context.web.xml스프링빈설정파일에 multipartResolver에 빈등록한다. 
  3. 첨부파일을 업로드하는 form태그에 method를 post enType을 multipart/form-data로 변경한다. 
  4. 첨부파일 업로드 필드를 form태그안에 추가한다. input파일로 
  5. 폼입력값을 저장하는 BookInsertForm클래스에 multipartFile타입의 변수를 정의한다. 
  6. src/main/webapp폴더안에 resources/images폴더를 생성한다. 
  7. BookController첨부파일의 파일명을 획득하고 첨부파일을 src/main/resource/images폴더에 저장한다.
반응형
Comments