예외 처리 Exception Handling

  • 프로그램에서 예외가 발생했을 경우, 프로그램의 갑작스러운 종료를 막고, 정상 실행을 유지하기 위해 예외 처리를 해야 함
  • 자바 컴파일러는 일반 예외가 발생할 가능성이 있는 코드를 발견하면 컴파일 에러를 발생시켜 예최처리 코드를 개발자가 강제적으로 작성하도록 요구함
  • 실행 예외의 경우에는 개발자의 경험을 바탕으로 예외 처리 코드를 작성해야 함

자바 예외처리

 

예외 처리 코드

  • try-catch-finally 블록은 생성자 내부와 메소드 내부에서 작성되어 일반 예외와 실행 예외가 발생할 경우 예외 처리를 할 수 있도록 해줌

1. try 블록에는 예외 발생 가능 코드가 위치

2. try 블록의 코드가 예외 발생 없이 정상 실행되면 catch 블록의 코드는 실행되지 않고 finally 블록의 코드를 실행;

    try 블록의 코드에서 예외가 발생하면 즉시 실행을 멈추고 catch 블록으로 이동하여 예외 처리 코드 실행 -> finally 블록 코드 실행

3. finally 블록은 생략 가능; 예외 발생 여부와 상관 없이 항상 실행할 내용이 있을 경우에만 finally 블록을 작성함;

    try 블록과 catch 블록에서 return문을 사용하더라도 finally 블록은 항상 실행됨

 

예외 종류에 따른 처리 코드

 

다중 catch

  • 다중 catch 블록을 작성해서 블록5 내부 다양한 예외 처리
  • catch 블록의 예외 클래스 타입은 try 블록에서 발생된 예외의 종류를 말함
  • try 블록에서 해당 타입의 예외가 발생하면 catch 블록을 실행함
  • catch 블록이 여러 개일지라도 단 하나의 catch 블록만 실행 -> 하나의 예외가 발생하면 즉시 실행을 멈추고 해당 catch 블록으로 이동

 

catch 순서

  • 다중 catch 블록을 작성할 때 주의할 점: 상위 예외 클래스가 하위 예외 클래스보다 아래쪽에 위치해야함
  • 하위 예외는 상위 예외를 상속했기 때문에 상위 예외 타입도 되기 때문임

 

예외 떠넘기기

  • 경우에 따라서 메소드를 호출한 곳으로 예외를 떠넘길 수 있음 -> throw 키워드 사용
  • throw 키워드: 메소드 선언부 끝에 작성되어 메소드에서 처리하지 않은 예외를 호출한 곳으로 떠넘기는 역할
  • throw 키워드 뒤에 떠넘길 예외 클래스를 쉼표로 구분해서 나열해주면 됨

 

리턴타입 메소드이름(매개변수, ...) throws 예외클래스1, 예외클래스2, ... {
}

 

 

또는

 

리턴타입 메소드이름(매개변수, ....) throws Exception {
}

 

 

  • throw 키워드가 붙어있는 메소드는 반드시 try 블록 내에서 호출되어야 함
  • catch 블록에서 떠넘겨 받은 예외를 처리해야함

 

public void method1() {

try {

  method2();

} catch(ClassNotFoundException e){

  //예외 처리 코드

  System.out.println("클래스가 존재하지 않습니다.");

  }

}



public void method2() throws ClassNotFoundException {

 Class claszz = class.forName("java.lang.String2");

}



==> 호출한 곳에서 예외 처리 예시

 

 

확인문제

  • try{} 블록에는 예외가 발생할 수 있는 코드를 작성한다
  • catch {} 블록은 try {} 블록에서 발생한 예외를 처리하는 블록이다.
  • try{} 블록에서 return 문을 사용하면 finally {} 블록은 실행되지 않는다. (x)
  • catch{} 블록은 예외의 종류별로 여러 개를 작성할 수 있다.
  •  
  • 생성자나 메소드의 선언 끝부분에 사용되어 내부에서 발생된 예외를 떠넘긴다.
  • throws 뒤에는 떠넘겨야 할 예외를 쉼표(,)로 구분해서 기술한다.
  • 모든 예외를 떠넘기기 위해 간단하게 throws Exception으로 작성할 수 있다.
  • 새로운 예외를 발생시키기 위해 사용된다. (x)

 

 

자바스프링 너무 좋아!!

Spring Security 흐름

  1. 사용자는 회원가입을 진행한다.
    • 해당 URI 요청은 permitAll 처리하고 사용자의 입력값으로 service에서 회원가입을 진행한다.
  2. 사용자의 정보를 저장할 때 비밀번호를 암호화하여 저장한다.
    • PasswordEncoder를 사용하여 비밀번호를 암호화 한 후 저장한다.
  3. 사용자는 로그인을 진행한다.
    • 해당 URI 요청은 permitAll 처리하고 사용자의 입력값으로 service에서 회원 인증을 진행한다. (비밀번호 일치여부 등)
  4. 사용자 인증을 성공하면 사용자의 정보를 사용하여 JWT 토큰을 생성하고 Header에 추가하여 반환한다. Client 는 이를 쿠키저장소에 저장한다.
  5. 사용자는 게시글 작성과 같은 요청을 진행할 때 발급받은 JWT 토큰을 같이 보낸다.
  6. 서버는 JWT 토큰을 검증하고 토큰의 정보를 사용하여 사용자의 인증을 진행해주는 Spring Security 에 등록한 Custom Security Filter 를 사용하여 인증/인가를 처리한다.
  7. Custom Security Filter에서 SecurityContextHolder 에 인증을 완료한 사용자의 상세 정보를 저장하는데 이를 통해 Spring Security 에 인증이 완료 되었다는 것을 알려준다.

 

 OAuth

OAuth 2.0

  • Open Standard for Authorization 의 줄임말로 개방형 Authorization의 표준형
  • JSON형식으로 API 허가 목적으로 개발된  HTTP 기반의 보안 프로토콜
  • 사용하려는 웹사이트 및 애플리케이션에 비밀번호를 제공하지 않고 접근 권한을 부여 받을 수 있게 해주는 공통적 수단
  • 위 그림은 인증/인가의 위임방법을 제공 -> 클라이언트에게 접근토큰(Access Token)을 발급 하는 구조

@Authentication -> HttpSecurity

.authorizeRequests() : 요청에 대한 권한 지정

.anyRequest().authenticated() : 어떠한 요청이든지 인증되어야 함

.formLogin() : 폼을 통한 로그인 이용

.antMatchers.hasRole() 또는 .antMatchers().access() : 해당 경로에 대해 특정 권한을 가져야 접근 가능

 

.antMathcher(). 

 

  • anonymous() : 인증되지 않은 사용자가 접근할 수 있습니다.
  • authenticated() : 인증된 사용자만 접근할 수 있습니다.
  • fullyAuthenticated() : 완전히 인증된 사용자만 접근할 수 있습니다(?)
  • hasRole() or hasAnyRole() : 특정 권한을 가지는 사용자만 접근할 수 있습니다.
  • hasAuthority() or hasAnyAuthority()\ : 특정 권한을 가지는 사용자만 접근할 수 있습니다.
  • hasIpAddress() : 특정 아이피 주소를 가지는 사용자만 접근할 수 있습니다.
  • access() : SpEL 표현식에 의한 결과에 따라 접근할 수 있습니다.
  • not() : 접근 제한 기능을 해제
  • permitAll() or denyAll() : 접근을 전부 허용하거나 제한
  • rememberMe() : 리멤버 기능을 통해 로그인한 사용자만 접근 가능

 

 

[Spring/Security] 초보자가 이해하는 Spring Security - 퍼옴

https://okky.kr/article/382738 # 초보자가 이해하는 Spring Security (좋은 글)저의 스프링 시큐리티 관련 예제는 깃허브 에서 제공합니다. (주석이 포함된 프로젝트는 주석이 너무 지저분하여 제외...)1. 스

postitforhooney.tistory.com

JUnit

단위 테스트 도구;

프로그램을 작은 단위로 쪼개서 각 단위가 정확하게 동작하는지 검사하고 이를 통해 문제 발생시 어느 부분이 잘못되었는지 정확하고 빠르게 확인 할 수 있게 해줌

 

TDD Test-Driven Development

  • 테스트 코드를 먼저 작성하고 실제 동작하는 코드를 개발
  • 설계 -> 테스트 -> 개발 순서로 개발함
  • 단계별로 테스트 코드를 나누어서 작성함
    • Given - 준비
    • When - 실행
    • Then - 검증

 

Mock Object

  • 가짜 객체를 만들어서 분리해서 테스트함
  • Mokito mock을 사용해서 가짜 객체 이용 테스트
    • @Mock 어노테이션으로 Mocking할 객체를 주입 -> 서비스 리포지터리에 가짜 객체가 들어감
    • when() 메서드를 통해 mocking한 객체들이 특정 조건으로 특정 메서드 호출 시 동작하도록 지정

 

AOP Aspect Oriented Programming

  • 핵심기능과 부가기능이 있으면 변경이 쉽게 AOP를 이용해서 부가기능을 모듈화 한다.
  • 부가기능은 핵심기능과 관점(Aspect)가 달라서
  • 핵심기능과 분리해서 부가기능 중심으로 설계 하고 구현
  • 스프링 AOP 어노테이션
    • @Around: '핵심기능' 수행 전과 후 (@Before + @After)
    • @Before: '핵심기능' 호출 전 (ex. Client 의 입력값 Validation 수행)
    • @After: '핵심기능' 수행 성공/실패 여부와 상관없이 언제나 동작 (try, catch 의 finally() 처럼 동작)
    • @AfterReturning: '핵심기능' 호출 성공 시 (함수의 Return 값 사용 가능)
    • @AfterThrowing: '핵심기능' 호출 실패 시. 즉, 예외 (Exception) 가 발생한 경우만 동작 (ex. 예외가 발생했을 때 개발자에게 email 이나 SMS 보냄)

 

 

심화 주차 강의 완강

위의 내용은 강의를 요약만 한것이고 강의는 스프링을 요약의 요약의 요약을 한 것이라서 공부는 더 해야한다.

 

 

 

자바도 모르는데 스프링하는 개발자지망생

분기문 aka 조건문

어떠한 조건에 따라 다른 명령을 실행하게 하는 문법으로, 가장 대표적인 분기문에는 if문이 있습니다.

분기문은 조건문과 같은 의미로 사용됩니다.

 

분기문 (조건문) 종류

java 자바 언어에서 분기문은 if, else if, switch 가 있습니다.

if문은 분기를 처리할 때 가장 많이 쓰이는 문법입니다.

 

조건을 분기하여 처리할 때 사용합니다.

 

분기처리

분기문을 이용해 선택적으로 조건에 따라 코드를 실행하게 만드는 것을 의미합니다.

 

 

 

 

 

CRUD를 제대로 하는 것이 더 중요하지 지금 spring security 좀 덜 이해하고 못해도 이전 주차 것들을 완전히 익혀야 합니다. 

라고 하네요.

security

 

이것도 듣고 저것도 듣는 게 좋다고 생각합니다.

기초부터 차근차근이 되니까 좋네요.

 

속성도 좋지만 가끔은 토대를 쌓는 일도 필요합니다.

 

충고를 가장한 비난은 듣지않습니다. 거부!

 

 

BFS 너비 우선 탐색 Breadth First Search

최단거리 구하는 문제를 풀 때 유용합니다.

 

  • BFS는 시작 지점에서 가까운 노드부터 차례대로 그래프의 모든 노드를 탐색
  • BFS는 같은 레벨에 있는 노드들을 먼저 탐색하고 그다음 레벨 노드를 탐색함
  • 특정 노드에서 다른 노드까지 최단값 또는 임의의 경로를 찾을 때 사용
  • 스택이 아닌 큐(Queeu) 구조를 활용
  • FIFO 원칙으로 탐색

BFS 수행 과정

  1. 현재 레벨에 있는 root Node를 Q.offer에 넣어서 Q.size, 큐의 길이 계산
  2. 큐에서 꺼낸 노드와 인접한 노드들을 모두 방문
  3. 인접한 노드가 없으면 큐의 앞에서 노드를 꺼냄 (dequeue)
  4. 큐에 방문된 노드를 삽입 한다
  5. 큐에 가 공백 상태가 될 때까지 계속 한다 Q.isEmpty() = true 일 때 종료

 

활용 예제

 

Q. 그림과 같은 그래프에 대하여 정점의 개수 N, 연결선의 개수 M이 주어지고 그래프에 대한 연결 정보가 주어질 때, 시작정점 1에서 BFS 방문경로를 출력하시오.

 

그래프 정보

문제 풀이

 

시작 정점 1 bfs() 함수 실행, Queue를 이용하여 

다음 정점과 연결되어 있고 (map[x][i] ==1),

아직 방문하지 않은 정점 (visited[i] == false)

큐에 해당 정점을 넣어주고, 더 이상 방문할 저점이 존재하지 않으면 종료한다.

 

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
import java.util.Queue;
import java.util.LinkedList;

public class bfsprac {
    static int[][] map;
    static boolean[] visited;
    static StringTokenizer st;
    static int N, M, start, end;

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        N = Integer.parseInt(br.readLine()); // 정점의 개수
        M = Integer.parseInt(br.readLine()); // 간선의 개수

        map = new int[N+1][N+1];
        visited = new boolean[N+1]; // 방문 여부를 검사할 배열

        for (int m =0; m < M; m++){//그래프 정보 입력받기
            st = new StringTokenizer(br.readLine(), " ");
            start = Integer.parseInt(st.nextToken());
            end = Integer.parseInt(st.nextToken());
            map[start][end] =1;
            map[end][start] =1;
        }
        System.out.print("그래프 BFS 방문 순서 :");
        bfs(1);
    }

    static void bfs(int point) {
        Queue<Integer> queue = new LinkedList<>();
        queue.offer(point);
        visited[point] =true;

        while (!queue.isEmpty()) {
            int x = queue.poll();
            System.out.print(x+" ");

            for (int i =1; i<=N; i++){
                if (map[x][i] ==1 && visited[i]==false){ //다음 정점과 연결되어 있고 아직 방문하지 않았다면
                    queue.offer(i);
                    visited[i]=true;
                }
            }
        }
    }

}

Console

7
8
1 2
1 3
2 4
2 5
3 7
4 6
5 6
6 7
그래프 BFS 방문 순서 :1 2 3 4 5 7 6 

 

스프링을 사용할 때 스프링 MVC 흐름에 따라 코딩하는데 @Controller를 사용할 때도 있고 @RestController를 사용할 때가 있습니다. 이번 포스팅에서는 언제 @Controller를 사용하고 @RestController를 사용하는지 스프링 MVC 흐름과 함께 알아보겠습니다.

@Controller

Spring MVC의 컨트롤러는 View를 반환하기 위해 사용합니다. Client의 요청을 받아 View를 반환합니다. Spring MVC의 흐름은 아래와 같습니다:

  1. Client는 URI 형식으로 웹 서비스에 요청
  2. DispatcherServlet은 HandlerMapping에 요청 위임
  3. HandlerMapping을 통해 요청을 Controller로 위임
  4. Controller는 요청을 처리한 후에 ViewName을 반환
  5. DispatcherServlet은 ViewResolver를 통해 ViewName에 해당하는 View를 찾아 클라이언트에게 반환

View를 반환하기 때문에 데이터를 보낼 때는 @RequestBody 어노테이션을 붙여서 Json 형태로 반환해줍니다.

 

@RestController

  • @Controller에 @ResponseBody가 추가된 어노테이션입니다.
  • Json 형태로 객체 데이터를 반환합니다. 
  • @RequestBody를 사용할 필요가 없습니다.
  • REST API 를 개발할 때 주로 사용합니다.

데이터 형식으로 보내는지 반환할 view가 있는지 등을 생각해서 @RestController를 쓸지 @Controller를 사용할 지 선택하고 필요에 따라 @RequestBody를 붙여주면 되겠습니다.

 

 

 

IntelliJ 단축키

Expressions Command + option +v

자동으로 new 생성자 식(Expression)을 만들어 줍니다

 

자동완성 및 줄바꿈 Command + Shift + enter

줄 중간에 있어도 자동으로 괄호 안 완성 해주고 줄바꿈 해줍니다.

 

뒤로 가기 Command + e + enter

바로 전 코드 줄로 이동합니다.

 

폴더 목록으로 이동 Command +1

폴더 목록으로 이동 합니다.

 

기타 IntelliJ 🍯팁

- 북마크 설정해서 자주 보는 코드 또는 일하고 있던 코드 바로 가기가 가능합니다.

- //TODO 를 입력해도 마크가 되서 바로가기 할 수 있습니다. 작업하던 곳을 헷갈리지 않고 찾아갑니다.

 

BONUS 🤓 Spring 관련 인프런 강의 조언

- 김영한 Spring 무료 강의 + 핵심편

- ORM 표준 JPA 기본편

- Spring Web MVC 1편 (2편은 갠적으로 비추하심)

 

  • 예외(exception): 사용자의 잘못된 조작 또는 개발자의 잘못된 코딩으로 인해 발생하는 프로그램 오류
  • 예외 처리(exception handling): 프로그램을 종료하지 않고 정상 실행 상태가 유지되도록 할 수 있음
  • 자바는 예외 처리 유무를 확인하고 예외 처리 코드가 없다면 컴파일이 안됨

 

예외와 예외 클래스

  • 일반 예외: exception
  • 실행 예외:runtime exception
  • RuntimeException 클래스 기준으로 구분

 

실행 예외

  • 자바 컴파일러가 체크하지 않기 때문에 개발자가 예외 처리 코드를 작성해야 함

 

NullPointerException

  • 객체 참조가 없는 상태, 즉 null 값을 갖는 참조 변수로 객체 접근 연산자인 도트(.)를 사용했을 때 발생
  • 객체가 없는 상태에서 객체를 사용하려고 할때 생기는 예외

 

ArrayIndexOutOfBoundsException

  • 배열에서 인텍스 범위를 초과할 경우 생기는 실행 예외

 

NumberFormantException

  • 문자열을 숫자로 변환 할 때 숫자로 변환될 수 없는 문자가 포함되어 있을 때 발생

 

ClassCastException

  • 타입변환은 상위클래스와 하위 클래스 간에 발생하고 구현 클래스와 인터페이스 간에 발생하는데 이런 관계가 아닐 때 발생하는 예외
  • instanceof 연산자 사용해서 타입 변환 전에 변환 가능한지 확인하기

 

확인문제

  • 예외는 사용자의 잘못된 조작 개발자의 잘못된 코딩으로 인한 프로그램 오류를 말한다.
  • RuntimeException의 하위 클래스는 컴파일러가 예외처리 코드를 체크하지 않는다.
  • 예외는 클래스로 관리된다.
  • Exception의 하위 클래스는 모두 일반 예외에 해당한다. (x)

자바 혼공자 익명객체

익명 객체

  • 익명(anonymous) 객체: 이름이 없는 객체
  • 어떤 클래스를 상속하거나 인터페이스를 구현해야 만들 수 있음
[상속]
부모클래스 변수 = new 부모클래스(){....};

[구현]
인터페이스 변수 = new 인터페이스() {....};

 

 

익명 자식 객체 생성

  • 자식 클래스가 재사용되지 않고 오직 특정 위치에서 사용할 경우 -> 익명 자식 객체 사용

 

부모클래스 [필드|변수] = new 부모클래스(매개값, ...){

  //필드

  //메소드

};
  • 익명 자식 객체에 새로 정의된 필드와 메소드는 익명 자식 객체 내부에서만 사용하고 외부에서는 접근 x
  • 익명 자식 객체는 부모 타입 변수에 대입되므로 부모 타입에 선언된 것만 사용 가능

 

익명 구현 객체 생성

  • 구현 클래스가 재사용 되지 않고 오직 특정 위치에서 사용하는 경우, 익명 구현 객체 사용
인터페이스[필드|변수] = new 인터페이스(){ //인터페이스에 선언된 추상 메소드의 실제 메소드 선언 
	//필드 
	//메소드
};

 

 

+ Recent posts