Tiny Bunny
본문 바로가기

2023-02 몰입형 SW 정규 교육/9월 프로젝트

[SpringBoot] Session 및 DB에 UUID 저장

728x90

오늘 할 건 DB에 회의룸ID, 사용자 no, sysdate, 파일 경로를 저장하는 걸 해볼 거다.

일단 지난 포스팅에서 상대 파일 경로를 저장하는 법을 했으니 오늘은 UUID를 생성해서 넣을 거다.

 

[SpringBoot & Vue.js] Axios post 요청

나는 DB를 다뤄본 적도 없고 네트워크나 서버 등의 배경 지식이 없을 뿐더러... 이번 프로젝트를 하면서 처음으로 백엔드를 맡았는데, DB 관리와 더불어 백엔드 프론트 간의 요청 및 응답까지 하

zero-talk.tistory.com

 

 

 

UUID 생성 확인

 

일단 기본적으로 UUID 생성이 잘 먹히는지부터 확인하려고 한다. UUID는 출시년도에 따라 총 5개의 버전이 있는데, 각자 상황에 맞는 버전을 쓰면 된다. 나는 보안성이 높고 생산속도가 빠른 4버전을 쓸 거다.

 

기존에 만들어줬던 상대 파일 경로 저장하는 파일에 버튼 하나를 더 추가해 클릭하면 uuid가 생성되도록 했다.

 

<!DOCTYPE html>
<html>
  <head>
    <title>mp3 file path save</title>
    <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
  </head>
  <body>
    <h1>mp3 file path save</h1>
    <form onsubmit="event.preventDefault(); uploadAndSavePath();">
      <input type="file" id="file" name="file" accept=".mp3" />
      <button type="submit">경로 저장</button>
    </form>
    <button onclick="generateUUID()">uuid</button>
    <script type="text/javascript">
      function uploadAndSavePath() {
        var formData = new FormData();
        formData.append("file", document.getElementById("file").files[0]);

        axios
          .post("/saveAudioFilePath", formData)
          .then(function (response) {
            alert("File uploaded and path saved successfully!");
          })
          .catch(function (error) {
            alert("Failed to upload file or save path!");
          });
      }

      function generateUUID() {
        axios
          .get("/generateUUID")
          .then(function (response) {
            alert(response.data);
          })
          .catch(function (error) {
            console.log(error);
          });
      }
    </script>
  </body>
</html>

 

 

 

GET 요청을 처리하는 MeetingRoomTest 클래스 생성

 

package com.gmovie.gmovie.controller;

import java.util.UUID;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class MeetingRoomTest {

    @GetMapping("/generateUUID")
    public String generateUUID() {
        UUID uuid4 = UUID.randomUUID();
        return "Version 4 UUID: " + uuid4;
    }
}

 

 

 

 

이제 uuid라는 버튼을 누르면 랜덤 문자열이 생성되어야 한다.

 

1 딸깍
2 딸깍
3 딸깍

세 번을 눌렀고 각각 다른 문자열이 생성된다. 일단 기본적인 테스트는 완료

 

 

 

데이터의 용량을 줄이기 위해 하이픈을 제거했다.

package com.gmovie.gmovie.controller;

import java.util.UUID;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class MeetingRoomTest {

    @GetMapping("/generateUUID")
    public String generateUUID() {
        UUID uuid4 = UUID.randomUUID();
        String noHyphenUUID = uuid4.toString().replace("-", "");
        return "METTING ROOM ID: " + noHyphenUUID;
    }
}

 

 

 

세션에 UUID 저장 후 DB에 저장

 

세션에 UUID를 저장하고 해당 UUID를 DB에 저장하려면 세션과 DB의 연동이 필요하다.

 

스프링부트에서는 HttpSession을 이용하여 세션을 관리할 수 있기 때문에 HttpSession과 JdbcTemplate을 이용하여 UUID를 생성하고 세션 및 DB에 저장할 것이다.

 

① HttpSession 객체는 Spring MVC가 요청 처리 메소드의 매개변수로 자동 제공함

② setMaxInactiveInterval(30 * 60)으로 세션이 최대 30분동안 유지되도록 설정함

③ JdbcTemplate 객체를 사용하여 생성된 UUID를 DB의 SUMMARY 테이블의 MITTING_ID 컬럼에 삽입하는 쿼리 실행

 

package com.gmovie.gmovie.controller;

import java.util.UUID;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import jakarta.servlet.http.HttpSession;

@RestController
public class MeetingRoomTest {

    @Autowired
    JdbcTemplate jdbcTemplate;

    @GetMapping("/generateUUID")
    public String generateUUID(HttpSession session) {
        UUID uuid4 = UUID.randomUUID();
        String noHyphenUUID = uuid4.toString().replace("-", "");

        // Store the generated UUID in session
        session.setAttribute("MeetingRoomTest", noHyphenUUID);

        // Set the maximum inactive interval to 30 minutes.
        session.setMaxInactiveInterval(30 * 60);

        // Save the generated UUID into database's METTING table.
        jdbcTemplate.update("INSERT INTO SUMMARY (METTING_ID, NO) VALUES (?, ?)", noHyphenUUID, 1);

        return "METTING ROOM ID: " + noHyphenUUID;
    }
}

 

이제 다시 버튼을 클릭하면

 

DB에 세션에 저장된 UUID 값이 삽입된다. 

 

 

 

세션 유지 상태일 때 DB에 여러 데이터 삽입

 

이제 세션 유지 상태일 때 파일을 업로드 하면 MEETING_ID와 RECORDING에 값이 삽입되게끔 하면 된다.

 

원래는 시퀀스(SEQUENCE) 값을 기준으로 하여 MEETING_ID와 RECORDING 데이터를 삽입해야하는데, 현재 로그인이 구현되지 않았으므로.. 임의로 MEETING_ID를 기준으로 하여  RECORDING에 데이터를 삽입할 것이다.

 

기존의 SaveAudioFilePath.java 파일에서 파일을 업로드 할 때마다 세션 UUID를 가져와서 사용자가 업로드한 파일의 경로를 DB에 저장하는 기능을 수행하도록 했다.

 

// SaveAudioFilePath.java

@RestController
public class SaveAudioFilePath {

    @Autowired
    private JdbcTemplate jdbcTemplate;

    @PostMapping("/saveAudioFilePath")
    public ResponseEntity<String> postAudioPath(@RequestParam("file") MultipartFile file, HttpSession session) {
        // Get the UUID from the current session.
        String mettingId = (String) session.getAttribute("meetingRoomId");

        if (!file.isEmpty()) {
            try {
                Path filePath = Paths.get("files/" + file.getOriginalFilename());

                if (!Files.exists(filePath.getParent())) {
                    Files.createDirectories(filePath.getParent());
                }

                Files.write(filePath, file.getBytes());

                // Update the RECORDING column for the row with the current mettingId.
                jdbcTemplate.update(
                        "UPDATE SUMMARY SET RECORDING = ? WHERE METTING_ID = ?",
                        filePath.toString(), meetingId);

                return new ResponseEntity<>("Path saved successfully.", HttpStatus.OK);
            } catch (Exception e) {
                return new ResponseEntity<>("Failed to upload file: " + e.getMessage(),
                        HttpStatus.INTERNAL_SERVER_ERROR);
            }
        } else {
            return new ResponseEntity<>("File is empty.", HttpStatus.BAD_REQUEST);
        }
    }
}

 

 

 

 

여기서 파일 경로를 저장할 때 세션에 UUID가 존재하지 않으면 로그인 후 이용하라는 팝업창이 뜨도록 했다.

 

<!DOCTYPE html>
<html>
  <head>
    <title>mp3 file path save</title>
    <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
  </head>
  <body>
    <h1>mp3 file path save</h1>
    <form onsubmit="event.preventDefault(); uploadAndSavePath();">
      <input type="file" id="file" name="file" accept=".mp3" />
      <button type="submit">경로 저장</button>
    </form>
    <button onclick="mettingRoom()">Create MettingRoom ID</button>

    <script type="text/javascript">
      function uploadAndSavePath() {
        var formData = new FormData();
        formData.append("file", document.getElementById("file").files[0]);

        axios
          .post("/saveAudioFilePath", formData)
          .then(function (response) {
            alert("File uploaded and path saved successfully!");
          })
          .catch(function (error) {
            if (error.response && error.response.status === 401) {
              alert(error.response.data);
              setTimeout(function () {
                alert(null);
              }, 3000);
            } else {
              alert("파일을 선택해주세요.");
            }
          });
      }

      function mettingRoom() {
        axios
          .get("/mettingRoom")
          .then(function (response) {
            alert(response.data);
          })
          .catch(function (error) {
            console.log(error);
          });
      }
    </script>
  </body>
</html>

 

 

 

MeetingRoom.java

package com.gmovie.gmovie.controller;

import java.util.UUID;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import jakarta.servlet.http.HttpSession;

@RestController
public class MettingRoom {

    @Autowired
    JdbcTemplate jdbcTemplate;

    @GetMapping("/mettingRoom")
    public String mettingRoom(HttpSession session) {
        UUID uuid4 = UUID.randomUUID();
        String noHyphenUUID = uuid4.toString().replace("-", "");

        session.setAttribute("mettingRoomId", noHyphenUUID);
        session.setMaxInactiveInterval(30 * 60);

        jdbcTemplate.update("INSERT INTO SUMMARY (METTING_ID, NO) VALUES (?, ?)", noHyphenUUID, 1);

        return "METTING ROOM ID: " + noHyphenUUID;
    }
}

 

 

 

SaveAudioFilePath.java

package com.gmovie.gmovie.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import jakarta.servlet.http.HttpSession;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

@RestController
public class SaveAudioFilePath {

    @Autowired
    private JdbcTemplate jdbcTemplate;

    @PostMapping("/saveAudioFilePath")
    public ResponseEntity<String> postAudioPath(@RequestParam("file") MultipartFile file, HttpSession session) {

        // Get the UUID from the current session.
        String mettingId = (String) session.getAttribute("mettingRoomId");

        if (mettingId == null) {
            return new ResponseEntity<>("로그인 후 이용해주세요.", HttpStatus.UNAUTHORIZED);
        }

        if (!file.isEmpty()) {
            try {
                Path filePath = Paths.get("files/" + file.getOriginalFilename());

                if (!Files.exists(filePath.getParent())) {
                    Files.createDirectories(filePath.getParent());
                }

                Files.write(filePath, file.getBytes());

                // Update the RECORDING column for the row with the current mettingId.
                jdbcTemplate.update(
                        "UPDATE SUMMARY SET RECORDING = ? WHERE METTING_ID = ?",
                        filePath.toString(), mettingId);

                return new ResponseEntity<>("Path saved successfully.", HttpStatus.OK);
            } catch (Exception e) {
                return new ResponseEntity<>("Failed to upload file: " + e.getMessage(),
                        HttpStatus.INTERNAL_SERVER_ERROR);
            }
        } else {
            return new ResponseEntity<>("File is empty.", HttpStatus.BAD_REQUEST);
        }
    }
}
728x90