。゚(*´□`)゚。

코딩의 즐거움과 도전, 그리고 일상의 소소한 순간들이 어우러진 블로그

[네이버클라우드] 클라우드 기반의 개발자 과정 7기/웹프로그래밍

[NC7기-53일차(7월10일)] - 웹프로그래밍 34일차

quarrrter 2023. 7. 10. 17:31

클라이언트 앱에서 서버측에 잇는 dao를 사용할수있도록 proxy를 만듬

 

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

 

1) 클라이어트가 보낸 명령을 데이터이름과 메서드 이름으로 분리한다. serverapp 01
-1) 데이터 이름과 메서드 이름 알아내기

command 
 "데이터명/ 메서드명"
data 
 메서드의 파리미터

ServerApp class

1. 요청 ->
2. server앱을 분석하여


4. RequestEntity 파라미터의 deseiralize
5. Method call
3. Method에서 찾기 
  Reflectiono API를 활용하여 
DAO의 메서드 호출 자동화

// 2) 클라이언트가 요청한 DAO 객체와 메서드를 찾는다.
클라이언트 요청을 처리할 DAO를 맵에 보관한다.
DAO 객체 생성 및 보관
데이터 이름으로 DAO 객체를 꺼낸다.
DAO에 해당 메서드가 있는지 알아낸다.

 

3) 메서드의 파라미터와 리턴 타입을 알아내기
메서드의 파라미터와 리턴 타입 알아내기

 

4) 메서드 호출 및 리턴 값 받기 

메서드를 호출
=> 호출할 메서드가 파라미터를 가지고 있다면,
=> 클라이언트가 보낸 JSON 데이터를 메서드의 파라미터 값으로 deserialize 한다.
메서드 호출 결과를 클라이언트에게 보낸다.

 

5) 리팩토링

findMethod, /call 만들기
// DAO 객체에서 메서드 찾기
클래스 만들기// 메서드 찾기 메서드 호출하기

 

 

---

예외처리 문법- 오류가 발생하더라도 JVM을 멈추지 않고 계속 실행할 수 있게 도와주는 문법

 

try {
	예외가 발생할 수 있는 코드
    } catch (예외 정보(예외 정보를 담고 있는 객체 주소)를 받을 파라미터) {
    	예외를 처리하는 코드
    } catch ( -> { 
    	예외를 처리하는 코드
    } finally {
    	마무리를 수행하는 코드
    }
    	
        
//예전에는 return으로 예외처리 했음. 하지만 한계가 있음. 
//catch를 여러개 둘 수 있음
// finally: 마무리를 수행하는 코드
1. 유형1
try {
} catch() {
}

2. 유형2
try {
} finally{
}

3. 유형3
try {
} catch() {
} catch() {
 
 
 4. 유형4
 try {
 } catch {
 } finally

 

■ 예외정보를 담는 클래스의 hierachy(계층도)

Throuable : 1.catch 블록의 파라미터 타입으로 선안할 수 있다. 

                    2. throw 명령을 사용하여 오류 정보를 더너질 수 있다.(예외)

 

Throuable - Error - JVM이 발생한 오류 = ' 시스템 오류" = 개발자가  사용하면 안 된다, 복구 불가(절절한 조치 (로그 기록, 현 상태 저장 (세모)등)후 즉시 JVM 종료해야함

                 - Exception - App 에서 발생한 오류 => Application 오류, 복구 가능, 적절한 조치 후 계속 실행

 

checked Exception : 반드시 명시적으로 예외처리(코드) 필요. 작성햇는지 컴파일러가 검사함.

uncheched Exception : 에러 처리를 강제하지 않는 것 , 예외처리 코드를 작성했는지 컴파일러가 검사 안 함, 코드가 간결해진다. => 안정성이 떨어진다. (runtime Exception)

 

■ Exception 예외 다루기

1. 예외 처리 상황 1 

m1() -call-> m2() -call-> m3() { .....예외(Exception)발생.....}

예외발생한 코드를: try { 예외가 발생할 수 있는 코드 } catch(파라미터) {...}

 

2. 예외 처리 상황 2

m1() -call-> m2() {...try {  m3() } catch() { }  }// m3() throws 예외 {,,,} 

 

 

■ throw - 예외 상황을 맞이했을 때 예외 정보를 호출자에게 던지는 문법 

유효하지 않은 연산자인 경우 throw 명령을 이용하여 호출자에게 오류 상황을 알린다.

=> 오류 내용은 java.lang.Throwable 객체에 담아 넘긴다.

=> 이때 메서드 선언부에 Throwable 예외를 던지는 메서드임을 표시해야 한다.

public static int compute(String op, int a, int b) throws Throwable 

                                                                           이 메서드의 예외 타입을 반드시 표기해야함.

Throwable객체만 올 수 있음 Throwable(비추), Exception, IOException, 등등,, Error 는 안 돼!!!! 

 

void m1() { 
			...
            ...
            m2(); //작업 중 예외을 던질 수 있는 메서드. 확인 방법은?! - 메서드 선언부 보기!
            	  // throws throwable
                  
                  
                  
void m1() { 
			...
            ...
            try { m2(); 
            } catch(Throwable e) { //m2가 던지는 예외 타입레퍼런스, catch에는 object 못옴. Throwable만 올수있음 
            }

try에 정상코드 catch에 비정상 코드 

그래서 직관적임. 

 

 

예외 던지고 받기 (** RuntimeException 경우 선언부에 선언 안 해도됨(unchecked Exception )

첫번째 호출됐을때 예외를 안 받으면 다음 상위 호출자에서 예외 받음
printStrackTrace(); 마지막: JVM 종료
예외 관련하여

 

■ throw [java.lang.Throwable 타입의 객체];

java.lang.Throwable

=> Throwable에는 부류의 서브 클래스가 있다.

1) java.lang.Error (시스템 오류)

=> JVM에서 발생된 오류이다.

=> 개발자가 사용하는 클래스가 아니다.

=> 이 오류가 발생하면 현재의 시스템 상태를 즉시 백업하고, 실행을 멈춰야 한다.

=> JVM에서 오류가 발생한 경우에는 계속 실행해봐야 소용이 없다.

근본적으로 문제를 해결할없다.

=> 오류의 예:

스택 오버 플로우 오류, VM 관련 오류, AWT 윈도우 관련 오류, 스레드 종료 오류

 

2) java.lang.Exception (애플리케이션 오류)

=> 애플리케이션에서 발생시킨 오류이다.

=> 개발자가 사용하는 클래스이다.

=> 적절한 조치를 취한 후 계속 시스템을 실행하게 만들있다.

=> 오류의 예:

배열의 인덱스가 무효한 오류, I/O 오류,

 

 

예외 던지고 받기 - Throwable, Exception, RuntimeException

예외를 던질 때 Throwable 클래스를 직접 사용하지 말라!

그 하위 클래스를 사용하라.

특히 애플리케이션 오류를 의미하는 Exception 클래스를 사용하라.

에러도 선언부에 표시 안 해도 됨. (사용하면 안되지만)
선언부에 모두 나열해야함

 

■ 공통 분모를 사용하여 퉁치는 방법

=> 메서드에서 발생하는 예외의 공통 수퍼 클래스를 지정하여

여러 개를 나열하지 않을 수 있다.

=> 그러나 호출자에게 어떤 오류가 발생하는지 정확하게 알려주는 것이

유지보수에 도움이 된다.

따라서 가능한 그 메서드에서 발생하는 예외는 모두 나열하라!

 

■ 예외처리 방법 

1. 예외 처리 책임을 상위 호출자에게 위임 // 메인한테 넘겨버리고 jvm 멈춤; 

2. try catch

 2-1  여러 개의 예외를 받을 때 수퍼 클래스 변수로 먼저 받지 말라!
그 클래스의 모든 서브 클래스 객체도 다 받게 된다 // 자식 먼저 받고 부모로 올라가기. 부모 한개에 다 해당되면 부모 하나로 퉁칠 수 있음.

2-2 catch (RuntimeException | SQLException | IOException e) {// OR 연산자를 사용하여 여러 개의 예외를 묶어 받을 수 있다.} catch (Exception e) {   }

 

■ ERROR

catch (Throwable e) { System.out.println("애플리케이션 예외 발생!");

//catch 문을 작성할이처럼 무심코 Throwable 변수로 선언하면 시스템 오류인 Error 까지 받기 때문에 JVM에서 발생된 오류에 대해서도 예외 처리를 하는 문제가 발생한다. 시스템 오류는 애플리케이션에서 처리할 없다. 따라서 실무에서는 예외를 받을 Throwable 변수를 사용하지 않는다.

}

JVM이 Error를 받기 때문에 컴파일 오류가 아님

예외 처리 후 마무리 작업 - finally 블록

■ finally {

정상적으로 실행하든, 아니면 예외가 발생하여 catch 블록을 실행하든

finally 블록은 무조건 실행한다.

try ~ catch ~ 블록을 나가기 전에 반드시 실행한다.

그래서 블록에는

try 에서 사용한 자원을 해제시키는 코드를 주로 둔다.

=> 자원 해제 코드를 둔다.

=> 자원? 파일, DB 커넥션, 소켓 커넥션, 대량의 메모리

 

■ catch 블록이 없는 try ~ finally ~ 블록을 작성하는 상황:

- 예외가 발생하면 그 처리는 호출자에게 맡긴다.

- 그러나 이 메서드를 호출하는 동안 사용한 자원은 이 메서드를 종료하기 전에 해제시킨다.

- 예외처리를 호출자에게 맡기는데 그 전에 마무리 작업은 여기서 하고 싶을 때 사용.

 

main()에서 처리하지 않은 Error 예외는 main()의 호출자(JVM)에게 전달한다. 

이럴 때 finally 사용 !!!! - 오류 상황에도 finally가 무조건 실행돼서 오류 상황에 원하는 작업 가능. 

 

 

■ try-with-resources 라는 문법을 사용하면

굳이 finally 블록에서 close()를 직접 호출할 필요가 없다.

자동으로 처리한다.

=> 단 java.lang.AutoCloseable 구현체에 대해서만 가능하다!

try (java.lang.AutoCloseable 구현체) {...} // close 메서드를 갖고 있는 객체 

-마지막 문장에는 세미콜론을 붙이지 않아도 된다.
-예외가 발생하면 try{} 블록을 나가기 전에 close()가 먼저 호출된다.
-close()가 호출된 후 catch 블록이 실행된다.

-변수 선언은 반드시 괄호 안에 해야 한다.

 

■ FileReader 클래스도 java.lang.AutoCloseable 구현체이다.

FileReader in = new FileReader("Hello.java"); // OK!

try (Scanner keyScan = new Scanner(System.in); // OK!

 

 static class A {
  }

  static class B {
    public void close() throws Exception {
      System.out.println("B 클래스의 자원을 해제하였습니다.");
    }
  }

  static class C implements AutoCloseable {
    @Override
    public void close() throws Exception {
      System.out.println("C 클래스의 자원을 해제하였습니다.");
    }
  }
  
   public static void main(String[] args) throws Exception {

    try (
        // A 클래스는 AutoCloseable 구현체가 아니기 때문에 여기에 선언할 수 없다.
        //        A obj = new A(); // 컴파일 오류!

        // B 클래스에 close() 메서드가 있어도
        // AutoCloseable 구현체가 아니기 때문에 여기에 선언할 수 없다.
        //        B obj2 = new B(); // 컴파일 오류!
 
        C obj3 = new C(); // OK
        ) {
      System.out.println("try 블록 실행...");
    }
    // finally 블록에서 C의 close()를 호출하지 않아도,
    // 자동으로 호출될 것이다.
    // 실행하여 확인하라!
  }
}

 

■ 상위 상위 상위 호출자에게 예외를 던질 때,, 모든 상위 호출자들도 예외 선언을 해야함