클라이언트 앱에서 서버측에 잇는 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 )
■ 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 변수를 사용하지 않는다.
}
예외 처리 후 마무리 작업 - 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()를 호출하지 않아도,
// 자동으로 호출될 것이다.
// 실행하여 확인하라!
}
}
■ 상위 상위 상위 호출자에게 예외를 던질 때,, 모든 상위 호출자들도 예외 선언을 해야함
'[네이버클라우드] 클라우드 기반의 개발자 과정 7기 > 웹프로그래밍' 카테고리의 다른 글
[NC7기-55일차(7월12일)] - 웹프로그래밍 36일차 (0) | 2023.07.12 |
---|---|
[NC7기-54일차(7월11일)] - 웹프로그래밍 35일차 (0) | 2023.07.11 |
[NC7기-52일차(7월7일)] - 웹프로그래밍 33일차 (0) | 2023.07.07 |
[NC7기-51일차(7월6일)] - 웹프로그래밍 32일차 (0) | 2023.07.06 |
[NC7기-50일차(7월5일)] - 웹프로그래밍 31일차 (0) | 2023.07.05 |