7주차 금 1006 :: newb

ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 7주차 금 1006
    광주인력개발원 일일포스팅(메모장) 2023. 10. 10. 09:03
    728x90
    반응형

    오늘만 지나면 3일 쉰당

    # 잡담

     

    ★ 복습

    1. AOP (Aspect Oriented Programming)

      + 특정 기능을 작성한 후 여러 부분에 쉽게 적용하는 기술

      + advice(특정 기능), pointcut(여러 부분), aspect(advice + pointcut)

      + pointcut으로 메소드를 지정

      + 스프링의 제어 범위 내에서 모든 메소드를 제어할 수 있음

      + @Aspect, @Component 애노테이션을 적용한 1개 이상의 클래스만 있으면 적용 가능 

       Filter 

      + WAS(Web Application Server)의 기술 HTTP 요청과 응답에 대해 제어할 수 있는 기술

      + 스프링의 영역으로 진입하기 전에 동작 

      + request와 response 객체를 기본 제공하므로 (AOP에 비해) 웹과 관련된 기능을 쉽게 작성

      Interceptor

      + 스프링의 기술로 Controller에 들어오는 요청과 응답을 제어할 수 있는 기술 (Filter와 비슷함)

      + Filter와 달리 스프링의 영역으로 진입한 후 동작

      + request와 response 객체를 기본 제공하므로 (AOP에 비해) 웹과 관련된 기능을 쉽게 작성

     

       AOP  vs  Filter vs Interceptor

       + 클라이언트의 요청과 응답에 대한 처리 → 모두 가능

          단, AOP에서는 작성해야 하는 코드가 많고 어려움

           AOP에서는 request와 response가 기본으로 제공되지 않기 때문에..

       + Controller의 메소드가 아닌 특정 메소드가 실행되기 전이나 실행된 후 처리 → AOP만 가능

       + Filter는 스프링의 외부에서 동작하므로 스프링의 영향을 받지 않고 스프링의 기술을 사용할 수 없음

       + Interceptor는 스프링의 모든 기술 사용 가능 ex) @Autowired

     

    2.연관관계 (JPA > ORM)

       + N :1,  1: N, N : N, 1: 1

            ㄴ★  @Many To One 제일 많이 쓰고 쓰기도 쉬움 / 반대방향으로 @One To Many가 있다. 

     

        @ManyToOne Board board;
            Board board = new Board();
            board.setId(boardId);
            comment.setBoard(board);

    3. 댓글 작성 시 외래키(게시글) 처리

       + 게시글(Board) 객체를 생성한 후 기본키 (ID) 입력

       + 생성된 board 객체를 댓글 Comment의 setBoard() 메소드로 입력

       + commentRepository의 save() 메소드로 데이터 저장

     

    4. 비밀번호 암호화 - 스프링 시큐리티 이용

       + 의존성 추가

       + PasswordEncoder Bean 추가

       + @Autowired로 Bean을 가져온 후 사용

       + application.properties 추가

          spring.autoconfigure.exclude= org.springframework.boot.autoconfigure.security. servlet.SecurityAutoConfiguration

       + OOApplication.java 추가

         @SpringBootApplication( exclude = SecurityAutoConfiguration.class)

     

    5. Post를 반드시 사용해야 하는 경우 File Upload

     

    ★ 학습목표

    1. FileUpload

    2. FileDownload

    3. 

    ★ 학습

    FileUpload 해보기

    1) 설정 application.properties

        업로드되는 파일의 용량 > 제한

    2) html

        post, multipart/form-data

    3) controller

        MultipartHttpServletRequest

        @RequestParam

        @ModelAttribute

    + 저장장치에 저장

        transferTo()

     

    1. html 만들기

    <form action="" method="post"
        enctype="multipart/form-data">
        <input type="file" name="file" id="">
        <button>업로드</button>
    </form>

    업로드는 method="post" 를 꼭 해줘야함!

    2.그리고 application.properties에

    # file upload
    spring.servlet.multipart.max-file-size=2097152
    spring.servlet.multipart.max-request-size=2097152

    코드 입력해준다. 

    3.이제 controller에 가서 

    @Controller
    public class UploadController {
       
        @GetMapping("/upload1")
        public String upload1() {
            return "upload1";
        }

        @PostMapping("/upload1")
        @ResponseBody
        public String upload1Post(
            MultipartHttpServletRequest mRequest){
                MultipartFile mFile = mRequest.getFile("file");
                String filename = mFile.getOriginalFilename();
                long size = mFile.getSize();

                File folder = new File("c:/files"); // 폴더생성
                folder.mkdirs();

                File file = new File("c:/files/a.zip"); //폴더를 의미하고 / 뒤는 폴더 이름
                try {
                    mFile.transferTo(file);
                } catch (IllegalStateException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                return filename + size;
        }
       
    }

    이렇게 작성해주면

    upload 주소로 가면 파일 선택과 업로드 버튼이 있고 선택해서 넣고 업로드! 하면!!

    이렇게 나오게 된다.

    그러면 c:/files가 생성되고 그 안에 파일이 생긴다 지금 a.zip으로 작성해놔서 이렇게 나오는데 압축파일은 아니다...

     

    대체로 많이 쓰는 코드예시 // 

    html에 새로운 코드 작성

    <form method="post" enctype="multipart/form-data">
        <div id="input-files">
            <input type="file" name="file" multiple><br>
        </div>
        <button type="button">추가</button>
        <input type="submit" value="업로드">
    </form>
    <script>
        document.querySelector('button').addEventListener('click', () => {
            const div = document.querySelector('#input-files');
            const inputs = document.querySelectorAll('#input-files > input');
            const input = `<input type="file" name="file${inputs.length}" multiple>`;
            div.innerHTML += input + "<br>";
        });
    </script>

    파일선택에 여러개가 들어갈 수 있는데 추가가 있는경우 반복문으로 해결가능

    Controller 작성


        @PostMapping("/upload6")
        @ResponseBody
        public String upload6Post(MultipartHttpServletRequest mRequest) {
            String result = "";
            Iterator<String> fileNames = mRequest.getFileNames();
            while (fileNames.hasNext()) {
                String fileName = fileNames.next();
                List<MultipartFile> mFiles = mRequest.getFiles(fileName);
                for (MultipartFile mFile : mFiles) {
                    String oName = mFile.getOriginalFilename();
                    long size = mFile.getSize();
                    result += oName + " : " + size + "<br>";
                }
            }
            return result;
        }

    이런식으로 코드를 짜주면 된당..

     

    download 하기

    @Controller
    public class DownloadController {
    @GetMapping("/download")
    public ResponseEntity<Resource> download() throws Exception {
    File file = new File("C:/Users/user/Pictures/Screenshots/스크린샷 2023-10-06 105924.png");
    InputStreamResource resource =
    new InputStreamResource(new FileInputStream(file));
    return ResponseEntity.ok()
    .header("content-disposition",
    "filename=" + URLEncoder.encode(file.getName(), "utf-8"))
    .contentLength(file.length())
    .contentType(MediaType.parseMediaType("application/octet-stream"))
    .body(resource);
    }
    }

    contentType에 여러가지 종류 중 원하는 것으로 맞춰주면 된다. ex) mp3면 audio/mpeg

     

    +중복파일 업로드 처리

    파일명을 바꾸는데 단. 다운로드 할 때는 원래 파일명으로 바꿔줘야 함

        @PostMapping("/upload2")
        @ResponseBody // html name명과 같게 변수명은 따로
        public String upload2(@RequestParam("file") MultipartFile mFile) {
            String result = "";
            String oName = mFile.getOriginalFilename();
            result += oName + "<br>" + mFile.getSize();

            // 1) 중복 파일이 존재하는지 확인하기
            File file = new File("c:/files/" + oName);
            boolean isFile = file.isFile();
           
            // 2) 중복파일이 있다면 파일명을 변경하기
            String sName = oName;
            if(isFile) {
                String name = oName.substring(0,oName.indexOf('.'));
                String ext = oName.substring(oName.indexOf('.'));
                sName = name + System.currentTimeMillis() + ext;
            }

            try {
                mFile.transferTo(new File("c:/files/" + sName));
            } catch (IllegalStateException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return result;
        }

    우선 원본파일과 중복파일을 구분하기위해 System.currentTimeMillis() 를 이용해서  . . 사이에 넣어준다.

    #돌발 상황에 대한 것들은 추가해야하는 코드

    ex) . 이 여러개 있는경우....

     

    +업로드 파일 데이터베이스 저장

       +파일 정보 테이블(Entity) 

         id    original_name     save_name     board_id

    @Entity
    @Data
    public class FileAtch {
        @Id @GeneratedValue
        int id;
        String  originalName;
        String  saveName;  
       

        @ManyToOne
        Board board;
    }

    Entity를 만들고

        @PostMapping("/upload2")
        @ResponseBody // html name명과 같게 변수명은 따로
        public String upload2(@RequestParam("file") MultipartFile mFile) {
            String result = "";
            String oName = mFile.getOriginalFilename();
            result += oName + "<br>" + mFile.getSize();

            // 1) 중복 파일이 존재하는지 확인하기
            File file = new File("c:/files/" + oName);
            boolean isFile = file.isFile();
           
            // 2) 중복파일이 있다면 파일명을 변경하기
            String sName = oName;
            if(isFile) {
                String name = oName.substring(0,oName.indexOf('.'));
                String ext = oName.substring(oName.indexOf('.'));
                sName = name + System.currentTimeMillis() + ext;
            }

            try {
                mFile.transferTo(new File("c:/files/" + sName));
            } catch (IllegalStateException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }

            FileAtch fileatch = new FileAtch();
            fileatch.setOreiginalName(oName); //원본 파일명
            fileatch.setSaveName(sName);  //저장 파일명
            Board board  = new Board();
            board.setId(8);
            fileatch.setBoard(board);
            fileAtchRepository.save(fileatch);

            fileAtchRepository.save(fileatch);

            return result;
        }

    Controller에 코드에 save 코드를 넣어준다. 

    그러면 업로드를 했을 때

    h2에 저장된다.

     

    +데이터 조회 후 다운로드

    detail.html에 코드작성

        <ul th:each="fileAtch : ${board.fileAtchs}">
            <li>
                <a th:href="@{/download(id=${fileAtch.id})}">
                    [[${fileAtch.originalName}]]
                </a>
            </li>
        </ul>

    하면 이렇게 생기는걸 볼 수 있다.

    그럼 여기서 DownloadController로 가서 

    <div style="background-color: #1f1f1f; color: #ccc

    728x90
    반응형

    '광주인력개발원 일일포스팅(메모장)' 카테고리의 다른 글

    8주차 금 1013  (1) 2023.10.14
    8주차 화 1010  (3) 2023.10.10
    7주차 목 1005  (2) 2023.10.05
    7주차 수 1004 천사넹  (2) 2023.10.04
    6주차 수 0927  (2) 2023.09.27
Designed by Tistory.