일정 관리 앱 만들기 - 트러블 슈팅2

coldrice99·2024년 10월 4일
0

TIL: 삭제 기능에서 비밀번호 검증 및 Null 값 문제 해결

이번 트러블 슈팅은 DELETE API에서 비밀번호 검증이 제대로 이루어지지 않아 발생한 문제를 해결한 과정을 기록한 것이다.

문제 발생

일정 삭제 API를 구현한 후 Postman에서 삭제 요청을 보냈을 때 500 Internal Server Error가 발생했다. 에러 메시지는 다음과 같았다:

java.lang.NullPointerException: Cannot invoke "String.equals(Object)" because the return value of "com.sparta.schedulemanagment.entity.Schedule.getPassword()" is null

이 문제는 schedule.getPassword()null을 반환하기 때문에 발생한 것이었다. 즉, 비밀번호가 제대로 저장되지 않거나 조회되지 않아 삭제 과정에서 검증이 실패하고 있었던 것이다.

문제 분석

  • 비밀번호 검증 로직은 이미 구현되어 있었다. 그러나 삭제 과정에서 schedule.getPassword()null을 반환하여 비밀번호가 설정되지 않았음을 알게 되었다.
  • 테이블을 확인해 보니 비밀번호는 제대로 저장되어 있었다. 문제는 조회 과정에서 비밀번호가 제대로 조회되지 않는 것에 있었다.

문제 해결

  1. findByID 메서드 수정:
    우선 findByID 메서드에서 DB 조회 시 비밀번호도 함께 가져오도록 코드를 수정했다. 기존에는 비밀번호가 조회되지 않아 문제가 발생했었다. 비밀번호 필드를 추가하여 DB에서 값을 가져오도록 수정했다.

    private Schedule findByID(Long id) {
        String sql = "SELECT * FROM schedules WHERE id = ?";
    
        return jdbcTemplate.query(sql, resultSet -> {
            if(resultSet.next()) {
                Schedule schedule = new Schedule();
                schedule.setUserName(resultSet.getString("userName"));
    
                // updateDate를 LocalDateTime으로 변환
                String updateDateString = resultSet.getString("updateDate");
                DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
                LocalDateTime updateDate = LocalDateTime.parse(updateDateString, formatter);
                schedule.setUpdateDate(updateDate);
    
                // 비밀번호 추가
                schedule.setPassword(resultSet.getString("password"));
    
                schedule.setContents(resultSet.getString("contents"));
                return schedule;
            } else {
                return null;
            }
        }, id);
    }
  2. 비밀번호가 null일 경우 예외 처리 추가:
    이제 조회된 비밀번호가 null인 경우를 처리하기 위해, 비밀번호가 설정되지 않았음을 명확히 확인하는 로직을 추가했다. 만약 조회된 비밀번호가 null이거나 요청으로 받은 비밀번호가 null일 경우 적절한 예외를 던지도록 수정했다.

    @DeleteMapping("/schedules/{id}")
    public Long deleteSchedule(@PathVariable Long id, @RequestBody Map<String, String> passwordMap) {
        Schedule schedule = findByID(id);
        if (schedule != null) {
            // 패스워드가 null인지 체크
            if(schedule.getPassword() == null || passwordMap.get("password") == null) {
                throw new IllegalArgumentException("비밀번호가 설정되지 않았습니다.");
            }
    
            // 패스워드 검증
            String inputPassword = passwordMap.get("password");
            if(!schedule.getPassword().equals(inputPassword)) {
                throw new IllegalArgumentException("비밀번호가 일치하지 않습니다.");
            }
    
            // 해당 스케줄 삭제하기
            String sql = "DELETE FROM schedules WHERE id = ?";
            jdbcTemplate.update(sql, id);
    
            return id;
        } else {
            throw new IllegalArgumentException("선택한 일정은 존재하지 않습니다.");
        }
    }
  3. Postman에서 삭제 요청 테스트:
    수정 후 Postman을 통해 다시 삭제 요청을 보내본 결과, 비밀번호가 올바르게 검증되고 일정이 정상적으로 삭제되었다. 비밀번호가 없거나 null인 경우 적절한 예외 메시지가 반환되었다.

최종 결과

이번 트러블 슈팅을 통해 삭제 API에서 비밀번호 검증과 관련된 문제를 해결했으며, 비밀번호가 null인 경우를 처리하여 코드의 안정성을 높일 수 있었다.

알게 된 것

  1. 데이터 조회의 완전성:
    데이터베이스에서 필요한 모든 필드를 정확히 조회해야 한다. 특히 중요한 보안 정보(예: 비밀번호)가 누락되지 않도록 주의해야 한다.

  2. null 값 처리:
    예상하지 못한 null 값으로 인해 발생하는 문제를 예방하기 위해, 반드시 null 체크를 포함하는 것이 중요하다. 검증 과정에서 예외 처리를 통해 사용자에게 명확한 에러 메시지를 반환하는 것도 중요하다.

이번 수정으로 삭제 API가 안정적으로 동작하게 되었으며, 더 나아가 다른 부분에서도 데이터 검증과 조회 로직을 개선할 수 있었다.


https://github.com/coldrice99/ScheduleManagerApp.git

profile
서두르지 않으나 쉬지 않고

0개의 댓글