✅네이버클라우드 캠프/개발일기

[네이버클라우드캠프] 53일차. Java Reflection API 사용, DAO 객체 메서드 호출 자동화 및 예외 처리 문법

우동한그릇 2023. 7. 10. 18:47
반응형

* 39. Reflection API를 사용해서 DAO 객체의 메서드 호출을 자동화하기

 

기존의 Case 문법으로 사용했던 추가,목록,조회,변경,삭제 등의 명령을 대체한다.

 

      // 데이터 이름과 메서드 이름 알아내기
      String[] values = command.split("/");
      String dataName = values[0];
      String methodName = values[1];
      // 데이터 이름으로 DAO 객체를 꺼낸다.
      Object dao = daoMap.get(dataName);
      if (dao == null) { // 만약 데이터를 처리 할 DAO를 찾지 못한다면 오류 정보를 클라이언트에게 보낸다.
        out.writeUTF(
            new ResponseEntity().status(ResponseEntity.ERROR).result("데이터를 찾을 수 없습니다.").toJson());
        continue;
      }
 // Dao객체에서 메서드 찾기
      Method method = findMethod(dao, methodName);
      if (method == null) {
        // 만약 클라이언트가 요청한 메서드를 찾지 못한다면 오류 정보를 클라이언트에게 보낸다.
        out.writeUTF(
            new ResponseEntity().status(ResponseEntity.ERROR).result("메서드를 찾을 수 없습니다.").toJson());
        continue;
      }
// DAO 메서드 호출하기
      Object result = call(dao, method, request);
      // 메서드 호출 결과를 클라이언트에게 보낸다.
      ResponseEntity response = new ResponseEntity();
      response.status(ResponseEntity.SUCCESS);
      response.result(result);
      out.writeUTF(response.toJson());
    }

 

 

public static Method findMethod(Object obj, String methodName) {
    // DAO에 해당 메서드가 있는지 알아낸다.
    Method[] methods = obj.getClass().getDeclaredMethods();
    for (int i = 0; i < methods.length; i++) {
      if (methods[i].getName().equals(methodName)) {
        return methods[i];
      }
    }
    return null;
  }

  public static Object call(Object obj, Method method, RequestEntity request) throws Exception {
    Parameter[] params = method.getParameters();
    if (params.length > 0) {
      Object arg = request.getObject(params[0].getType());
      return method.invoke(obj, request.getObject(params[0].getType()));
    } else {
      return method.invoke(obj);
    }

 

* 예외처리 문법 - 오류가 발생해도 JVM 실행을 멈추지 않게 하는 문법

 

* 예외 정보를 담는 크래스의 hierarchy (계층도)

Error

스택오버플로우와 같이 복구할 수 없는 것이다.

* 개발자가 사용하면 안된다 !

 

Exception ?

예외는 복구가 가능하며

적절한 조치 후에 계속 실행 가능한 에러이다.

 

checked 예외 unchecked 예외가 존재한다.

Exception은 checked 체크 예외이며 에러처리 코드를

명시적으로 작성했는지 컴파일러가 검사한다.

 

Runtime Exception 은 언체크 예외이며 

예외처리 코드를 작성했는지 컴파일러가 검사하지 않는다.

 

* Exception 예외 다루기

 

 

 

 

예외 타입이 어떤 것인지 반드시 예외정보 타입을 선언해야한다.

throws Throwable 

 

 

 

메인에서 test를 실행하고 test에서 m를 실행하는데 

m이 던진 예외를 test가 받을 수 없기 때문에 상위 호출자인

main에서 이 예외를 catch 하여 print문을 출력한 것이다.

 

 

 

 

모든 상위 호출자가 예외를 전달받지 못하고 JVM이 전달받게 된다면

예외가 발생한 메서드를 호출하기 까지의 모든 과정을 상세 출력한다.

그리고, JVM은 종료된다 !

 

 

 

RuntimeExcepiton 예외는 unchecked Exception 이기 때문에

메서드 선언부에 표시를 해주지 않아도 된다 !

아래 예제에서 선언을 해주는 것과 안해준 것의 차이가 없다 !

 

예제)

 

그러나 Checked Exception 의 하위 예외는 모두 메서드 선언부에

명시해주어야 한다. 컴파일러 이를 검사하기 때문이다.

 

예제)

또는 수퍼클래스인 Exception 을 명시하여 모든 메서드에 선언하지 않아도

되게 만들 수 있다. 하지만, 이것은 어떤 예외인지 알 수 없어 유지보수에 좋지 않다.

 

예제)

 

가장 정석적인 모범답안 !

아래에 순서대로 에서 예외가 발생하는 순서대로 메서드에 선언해준다.

 

그리고 catch로 예외 해당하는 오류가 발생하면 print문으로 어떤 예외인지를

사용자에게 알려준다 !

 

예제) 

 

Exception e 는 

throw new Exception()

throw new RuntimeException()

throw new IOException()

throw new SQLException() 

를 포함하는 에러이다.

 

단, throw new Error() 은 포함하지 않는다 .

 

 

scanner 같은 자원은 다른 프로그램에서 사용할 수 있게

반드시 사용 후에는 실행을 종료해주어야한다.

그런데, 오류(예외)가 발생하면 scanner를 close()를 하지 못한다.

그래서 반드시 실행되는 finally에서 close() 를 통해 자원을 해제해주어야 한다.

 

예제)

 

 

다른 방법으로는 try-with-resources 문법을 사용할 수 있다.

try 블럭 안에서 객체를 선언함으로써 그 객체가 실행되는 클래스의 자원을

자동으로 정리되게 할 수 있다.

 

예제)

 

 

반응형