JDBC는 java에서 Java.sql패키지에 내장되어 있는 DB 프로그래밍을 하기 위한 API이다. JDBC는 Java Application으로부터 사용되는 JDBC Driver Manager와 DBMS에 의존하는 JDBC Driver를 분리함으로써 DBMS에 의존하지 않고 개발이 가능하다는 장점이 있다. MySQL, Oracel 등 사용하는 DB의 Driver를 설치한 뒤 JDBC Driver Manager에 등록하면 Application에서 수행되는 SQL형태의 Query를 Driver가 DBMS가 이해할 수 있는 Query로 변환하여 전달한다. JDBC로 특정 쿼리문이 수행되기까지의 과정이 있다. 1. JDBC Driver 로드 2. DB 연결 3. Create a statement 4. 쿼리 처..
ORM ORM에 들어가기 앞서, Persistence 속성에 대해 먼저 알아보자. 영속성(Persistence) 특성은 프로그램이 종료되더라도 사라지지않는 비휘발성 데이터라는 특성을 말한다. 만약, 영속성 특성이 없는 데이터(휘발성)는 메모리상에서만 존재하기 때문에 프로그램이 종료되면 모두 날라간다. 1) Object Persistence(영구적인 객체) 메모리 상의 데이터를 file system, RDB(관계형 데이터베이스) or 객체 DB를 활용하여 영구적으로 저장(영속성) - java에서는 JDBC사용 - Spring JDBC - Hibernate, Mybatis 등의 프레임워크 이용 2) Persistence Layer 프로그램 상의 아키텍처에서 데이터에 영속성을 부여하는 계층이다. - JDBC를..
QuerySQL은 [SELECT * FROM TABLE;] 과 같은 쿼리를 java코드로 구현할 수 있는 기술이다. 복잡한 쿼리들도 구현이 가능한데, Spring Data JPA에서는 그것이 힘들었다. 그리고 java코드로 구현하기 때문에 컴파일 시 java코드로 구현한 쿼리에 대한 오류를 사전에 해소할 수 있다. 아래는 QueryDSL을 사용하기 위해 build.gradle을 세팅해준 것이다. //queryDSL이라고 되어 있는 부분이 해당한다. // queryDSL buildscript { ext { queryDslVersion = "5.0.0" } } plugins { id 'org.springframework.boot' version '2.6.6' id 'io.spring.dependency-ma..
h2는 java기반의 오픈소스 RDBMS이다. 가볍게 사용할 수 있기 때문에 개발 단계의 테스트 db로서 많이 이용된다고 한다. h2 설치파일을 다운받아서 하는 방법도 있지만, 나는 코드상으로만 이용하고자 한다. builc.gradle에 아래 추가 dependencies { // jdbc implementation 'org.springframework.boot:spring-boot-starter-jdbc' // jpa implementation 'org.springframework.boot:spring-boot-starter-data-jpa' // spring boot implementation 'org.springframework.boot:spring-boot-starter-web' implementa..
oidc는 OpenID Connect의 약자로, OAuth2.0기반으로 사용자에 대한 인증을 처리하는 프로토콜이다. 인증/인가의 개념에서 "인증"에 집중된다는 것이 기존의 OAuth2.0과의 차이점이라고 볼 수 있다. oidc는 OAuth2.0기반이기 때문에 비슷하게 처리가 되는데, 여기서 접속을 위한 토큰을 받을 때 id_token을 추가로 전달받는다. (이때 받은 id_token을 활용) 한 예로, OAuth2.0에서 토큰을 요청할 때 필요한 정보를 명시를 하는데, 이러한 정보들이 응답으로 받을 id_token안에 포함되어서 전달되는 시스템도 존재한다. 그렇기에, 단순히 유저 인증만을 하거나 정보들을 알고자 하는 설계라면 oidc사용을 하는 것이 좋다.
REST API는 HTTP의 메소드, URI로 이루어진 API서버이다. 그에 따라 Request와 Response가 필요한데, Request에 필요한 파라미터와 Response의 값들을 구성해야 한다. HTTP Method : 행위(Action) URI : 자원(Resource) HTTP Message Body : 표현(Representations) 보통 https://ip주소:port/api/items/~~ 로 주소를 만든다.(end-point) 이를 URI라고 하는데, URL과의 차이점은 URL : 특정 자원이 있을 때, 어떤 파일이나 자원의 위치를 나타내는 것 URI : 문자열 식별 URI는 HTTP에 대한 행휘에 대해서는 HTTP Method가 수행하고 있기 때문에 동사를 사용하지 않고 명사를 사..
Docker(도커)는 컨테이너 기반의 오픈소스 가상화 플랫폼이다. 컨테이너는 해운산업의 혁명적인 운송방식으로, 각 컨테이너들에 다양한 화물을 넣을 수 있으며 규격화 되어 있다. 이것을 IT적으로 표준 패키징과 배포 형식으로 생각해도 된다. 컨테이너를 사용함으로써 얻는 이점은 아래와 같다. - 운반 용량을 크게 늘림 - 비용을 절감 - 규모의 경제를 이루기 쉬움(규격화 되어 있기 때문) - 다루기 쉽다(규격화 되어 있기 때문에 규격에 맞는 방식 하나만 있어도 가능) 해운산업말고도 우리가 웹 애플리케이션 등을 서비스하기 위해 이용하고 있는 서버에도 적용할 수 있다. 다양한 프로그램, 실행환경을 컨테이너로 추상화하고 동일한 인터페이스를 제공하여 프로그램의 배포 및 관리를 용이하게 해준다. (위에서 말한 표준 ..
기본적으로 JWT양식을 작성할 때에는 탈취당했을 때를 대비하여(탈취를 안당하면 가장 좋지만) 보안상 문제가 되지 않는 수준까지의 정보만 담아야 한다. (비밀번호 같은 것을 Payload에 담게 된다면 큰일이겠지...) 만료시간 : 15분 아래 각 부분마다 base64인코딩 1. 헤더(Header) { "typ": "JWT", "alg": "HS256" } 2. 정보(Payload) { "iss": "우리 도메인", "iat": "현재 시각" "exp": "현재 시각 + 15분", "공개 클레임(public claim)": true, "userId": "유저 id", } 3개의 등록된 클레임(iss, iat, exp) 1개의 공개 클레임 1개의 비공개 클레임(userId) 3. 서명(Signature) 헤..
진짜 뭔놈의 에러가 이렇게 많지.... o.s.b.d.LoggingFailureAnalysisReporter application.properties에 아래 두 문구를 추가 spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration server.port=9090 Consider defining a bean of type 'com.study.study_project.mapper.UserMapper' in your configuration. application 파일에 아래 오너테이션 추가(매퍼 경로) @MapperScan(basePackages = {"com.study.study_pro..
JWT를 사용했을 때, DB나 Cache를 두지 않았다고 가정을 해보자.(완전히 stateless한 서버를 구성) 중복 로그인 처리 웹 서비스를 운영 중에 있을때, 사용자가 동시에 여러 곳에서 로그인을 할 수 없게 하려고 한다. ex) 기존에 A가 로그인을 한 상태에서 B가 로그인을 시도하면 A를 만료시킴 만약 세션을 서버에서 관리하고 있다면 서버에 저장되어 있는 해당 사용자의 세션을 초기화시키면 된다. 그러나 JWT를 이용한다면 서버는 현재 아무런 정보가 없는 상황이다. 따라서, 위 예시에서 B가 로그인을 시도해도 중복 로그인인지 확인할 수 있는 방법이 없다. (그렇다고 누군가 중복 로그인을 한 것 같다는 소식이 들려왔을 때 전체 토큰 세션을 날려버릴 순 없다...) 보통 만료시점을 넣어두지만 만료시점..
세션 Client가 Server로 로그인 요청을 하면 Server에서 세션을 생성하고 로그인이 정상적으로 처리되었다는 응답을 하게 된다. 그렇게 로그인이 성공한다. 현 상황에서 세션은 유지되고 있다. 이후, Client에서 서비스 요청 등을 Server로 하게되면 인증된 유저인지 확인하기 위해 Session을 읽는다. 해당 유저가 확인이 되면 정상 응답을 Client로 해준다. 만약 서버가 1대인 서비스라면 신경쓸 일이 적지만, 보통은 서버를 여러대로 둔다. 그런 상황에서 각 서버들이 Session 동기화가 되어야 한다. 근데 그런 방법이 정말 복잡하다. 서버가 Session 을 읽어야하는데 트래픽이 많아지면 무리가 발생한다. 보통 쿠키랑 세션을 함께 쓰는데, CORS문제가 발생할 수도 있다. 이러한 문..
참고 : https://nahwasa.com/entry/%EC%8A%A4%ED%94%84%EB%A7%81%EB%B6%80%ED%8A%B8-Spring-Security-%EA%B8%B0%EB%B3%B8-%EC%84%B8%ED%8C%85-%EC%8A%A4%ED%94%84%EB%A7%81-%EC%8B%9C%ED%81%90%EB%A6%AC%ED%8B%B0 Spring Security는 프로젝트에 있어서 로그인한 유저를 관리해주는 프레임워크다. 여기에서 관리란 애플리케이션의 보안(인증과 권한, 인가 등)을 말한다. 현재 프로젝트에서 적용할 사항은 아래와 같다. 1. ID, Passwd를 이용한 로그인(인증) 2. 사용자에 대한 권한부여(접근 제어) 3. 세션 관리 4. 위 정보들에 대한 보관 및 관리 Spring..
layered architecture layered architecture는 가장 일반적인 아키텍처 패턴이다. 대부분의 Java 애플리케이션에 대한 표준으로 널리 알려져 있기도 하다. 널리 알려진 이유는 많은 회사의 조직 구조와 밀접하게 일치하기 때문일지도 모른다. layered architecture는 수평 계층으로 구성되며, 각 계층은 특정 역할을 수행하도록 설계한다. 많은 방법이 있겠지만 지금은 4가지의 계층으로만 표현을 해보겠다. 1. Presentation Layer(프레젠테이션 계층)은 모든 사용자의 인터페이스 및 브라우저 통신을 처리 2. Business Layer(비지니스 계층)은 요청과 관련된 특정 비즈니스 규칙을 실행 3. Persistence Layer(지속성 계층)은 데이터를 저장하..
REST REST란 무엇일까? 업무를 하다보면 REST API를 만들어야 한다고 하지만 REST가 무엇인지에 대해서는 깊게 생각해보지 않은 것 같다. REST를 풀면 아래와 같다. REpresentational State Transfer 다른 곳에서는 REST를 아래와 같이 말한다. a way of providing interoperability between computer systems on the Internet (컴퓨터간의 상호 운용성을 제공하는 방법 중 하나) API를 다뤄보기 때문에 무슨 의미인지 감은 대강 잡히나, 여전히 다른 누군가에게 설명해줄 수 있을 만큼 이해하지는 못했다. 그래서 REST를 공부하기 전에 역사를 먼저 살펴보자 *WEB(1991) 인터넷에서 정보를 어떻게 공유할 것인지에..
소개 영상
람다식 사용법 ■ 람다식이란? 람다식은 메소드를 간결하게 표현하는 것으로 Java8부터 지원한다. 람다식을 사용하게 되면 코드가 간결해지는 것을 볼 수 있는데, 메서드를 람다식으로 표현하면 메서드의 이름과 반환타입이 없어지기 때문에 익명 함수라고도 한다. 모든 메소드는 클래스에 포함 되어야 하고 객체를 생성한 뒤 호출하지만, 람다식은 그러한 과정 없이 람다식 자체만으로 메소드의 역할을 대신할 수 있다는 것이 큰 장점이다. ■ 작성법 // 기존 방식 반환타입 메소드 이름(매개변수) { 처리 할 문장 } // 람다식 (매개변수) -> {처리 할 문장} 위의 작성법으로 간단한 예제를 만들어보자 int sum(int i, int j) { return i + j; } 이 메소드를 아래와 같이 변경할 수 있다. (..
제네릭 사용법 ■ 제네릭이란? Java에서 데이터 타입을 일반화하는 것을 의미 제네릭은 클래스나 메소드에서 사용할 내부 데이터 타입을 컴파일 시 지정 ■ 제네릭을 사용하는 이유 클래스나 메소드 내부에서 사용되는 객체의 타입 안정성을 높임 반환 값에 대한 타입 변환 및 타입 검사에 들어가는 노력 감소 JDK 1.5 이전에는 여러 타이비을 사용하는 클래스나 메소드에 인수나 반환 값으로 Object 타입을 사용 > 이 경우 반환된 Object 객체를 다시 원하는 타입으로 타입 변환을 해야하며, 이를 통한 오류가 발생할 가능성이 있음 따라서 제네릭을 사용하면 컴파일 시 미리 타입이 정해지므로, 타입 검사나 타임 변환의 작업을 생략 가능 ■ 제네릭의 선언 및 생성 Java에서 제네릭은 클래스와 메소드에만 선언할 ..
스트림(Stream) / 버퍼(Buffer) / 채널(Channel) 기반의 I/O ■ I/O란? I/O(Input/Output)은 입력과 출력으로, 간단히 입출력이라고 부른다. 입출력은 프로그램간 데이터를 주고 받는 행위를 말하는데, 기본적으로 키보드로 입력을 하는 것, 프로그래밍(System.out.println())을 통한 출력 등 컴퓨터 내부 또는 외부 장치를 통해 실현된다. 스트림(Stream) 스트림은 흐름이라는 뜻이다. 입출력에 비유하자면, 입력부터 출력까지의 흐름이며, 입력이 출력까지 가는 통로(?)로 생각하면 된다. 통로라고 생각해보면, 흐름은 단방향으로 이루어 진다는 것을 알 수 있다. 만약, 여러 개를 보내게 된다면 선입선출(FIFO)방식으로 진행이 된다. 버퍼(Buffer) 버퍼는 ..
애노테이션 정의하는 방법 ■ 애노테이션이란? 애노테이션은 Java5부터 등장한 기능으로 주석이라는 뜻을 가지고 있다. 그러나 우리가 알고 있는 주석의 의미와는 다르게 인터페이스를 기반으로 한 문법이며 특별한 의미를 부여하거나 기능을 하는 코드를 작성할 수 있다. ■ 애노테이션 정의 방법 public @interface Test { ... } @interface는 애노테이션 타입을 선언하는 키워드이다. 애노테이션 타입 선언을 일반적인 인터페이스(interface) 선언과 구분하기 위해 interface앞에 @를 붙인다. ■ 애노테이션 필드 애노테이션 안에 필드와 같은 요소들을 정의할 수 있다. - 요소의 타입은 기본형, Striing, enum, 애노테이션, Class만 가질 수 있음 - 매개변수 선언을 ..
enum 정의하는 방법 ■ enum이란? enum은 열거형이라고 부른다. 상수를 관리하는 키워드이며, 다수의 상수를 선언할 때 관련된 상수를 편리하게 선언하기 위해 사용한다. 또한, 정의된 값 이외는 허용하지 않는 특성을 가지고 있다. ※ java.lang.Enum 클래스 사용 ■ enum 정의 enum Test {ONE, TWO, THREE, ...} 위의 예시처럼 enum 키워드와 열거형 이름을 설정하고 상수명을 입력한다. enum을 정의하는 방법은 크게 3가지 정도로 나눌 수 있다. 1. 별도 java 파일 // 첫 번째 java(Enumtest.java) 파일 public enum Fruit { APPLE, BANANA, MANGO } // 두 번째 java 파일 public class Test ..
Thread 클래스와 Runnable 인터페이스 ■ 쓰레드란? 컴퓨터로 프로그램을 실행시키는 것이 하나의 프로세스이다. 프로세스는 프로그램을 수행하는 데 필요한 데이터와 메모리 등의 자원과 쓰레드로 구성이 되어 있는데, 이때 쓰레드는 프로세스의 자원을 이용해서 실제 작업을 수행하는 역할을 한다. 하나의 프로세스는 하나 이상의 쓰레드를 가지고 있으며, 둘 이상의 쓰레드를 가진 프로세스를 멀티쓰레드 프로세스라고 한다. 멀티쓰레드를 잘 사용하면 자원을 효율적으로 사용할 수 있으며, 작업이 분리되어 프로그램 코드가 간결해진다. 이때, 교착상태와 같은 문제들을 잘 고려해야 한다. 보통, 사람들이 한 번에 여러 가지 일을 처리할 때 멀티 태스킹이 된다고 곧 잘 말하곤 하는데, 이 부분과 같이 멀티쓰레드도 카카오톡에..
자바에서 예외 처리 방법(try, catch, throw, throws, finally) ■ 예외처리란? 프로그램이 실행되고 있는 도중에 발생할 수 있는 예외 발생에 대한 처리를 작성한 것 ■ 목적 프로그램 실행 중의 예외 발생으로 인한 프로그램의 비정상적인 종료를 막고 상태를 유지하는 것 ■ Java에서의 예외처리 방법 1. try - catch - finally (예외가 발생한 메소드내에서 직접 처리) // try - catch - finally try { // 예외 발생 가능성이 존재하는 코드 }catch(예외 타입 매개변수명) { // 예외 타입의 예외가 발생한 경우 처리할 코드 }finally { // 항상 처리할 코드 } ※ Java 예외 타입 예시 - ArithmeticException - ..
인터페이스 ■ 인터페이스란? 객체의 사용 방법을 정의 코드와 객체의 중간 다리 역할이며, 코드에서 인터페이스의 메소드를 호출하면 인터페이스는 객체의 메소드를 호출하는 구조 사용자는 객체의 내부 구조를 몰라도 인터페이스의 메소드만 알면 사용 가능 ■ 인터페이스를 왜 사용할까? - 설계시 미리 선언해두면 개발할 때 기능 구현에 초점을 맞출 수 있다. - 프로젝트 시 개개인의 능력과 관계없이 메소드의 이름과 매개변수의 선언 등의 규칙이 유지된다. - 공통 인터페이스와 추상 클래스를 선언해 놓으면, 선언과 구현을 구분할 수 있다. ■ 인터페이스와 추상 클래스의 차이? 가장 큰 차이점은 인터페이스는 모든 메소드가 추상 메소드이고, 추상 클래스는 클래스 내 추상 메소드가 하나 이상 포함되는 경우이다. 조금 더 자세..