결론부터 말하면 두가지 방법이 있다. 1. X-Forwarded-For헤더에 직접 접근하여 가져오는 방법 2. HttpServletRequest의 getAddr()이 클라이언트 IP를 전달하도록 스프링 설정을 하는 방법 API를 호출한 사용자의 IP를 얻기 위해서 HttpServletRequest의 getAddr() 함수를 사용한다. 그러나 API요청이 Forward Proxy에 의해 전달 될 경우 HttpServletRequest의 getAddr() 호출 시 Forward Proxy의 IP가 찍히게 된다. 이런 경우 X-Forwarded-For라는 HTTP 헤더를 통해 프록시 서버를 통해 요청을 전달 받더라도, 진짜 Client IP를 전달 받을 수 있다. (proxy에서 X-Forwarded-For에..
서킷브레이커는 뭐고 왜 써야 하는지 짧게 정리한 글입니다. 서킷 브레이커 왜 사용 할까?Circuit Breaker 직역하자면 회로 차단기라는 뜻을 가지고 있습니다.MSA환경에서는 서비스들이 모듈로 분리되고, 요청 서비스와 응답 서비스가 있습니다.서비스 A가 서비스 B를 호출 했을 때, 서비스 B의 상태가 비정상적이라 응답을 해줄 수 없는 경우서비스 A는 서비스 B의 응답을 계속해서 기다리는 상태가 됩니다. 서비스 B의 장애가 서비스 A까지 전파될 수 있습니다. 이를 방지하기 위해서 서킷 브레이커를 사용합니다. 대표적인 서킷브레이커 라이브러리로는 Resilience4J가 있습니다. 요청 서비스와 제공 서비스사이에 Resilice4J를 두고 통신합니다.서킷브레이커 패턴서킷브레이커 패턴은 서비스 A와 서비스..
Transactional 전파레벨 관련 실험 실험 환경 로컬에서 docker를 띄워 Slave, Master DB를 구성하였다. Read-Only True시 Slave DB와 연결, Read-Only False시 Master DB와 연결 하도록 구성 Transactional Read-Only False 메소드 안에서 Read-Only True인 메소드가 실행된다면? 호출 한 메소드 (Read-Only False)에서 연결 된 Master DB와의 Connection을 사용한다. 즉, 조회 쿼리 (Read-Only True)도 Slave를 찌르지 않고, Master DB와의 커넥션을 통해 가져오게 된다. Transactional Read-Only True 메소드 안에서 Read-Only False인 메소드..
타임스탬프를 RFC 3339의 형태로 보내 달라는 요구사항을 받았다. 그리고 어떤 값은 밀리세컨드 단위까지, 어떤 값은 세컨드 값 까지만 전달해 달라는 요구사항을 받았다. 어카지? ISO 8601 날짜와 시간과 관련된 데이터 교환을 다루는 국제 표준 https://ko.wikipedia.org/wiki/ISO_8601 RFC 3339 ISO 8601을 인터넷 프로토콜로 어떻게 다룰지 규정한 RFC RFC 3339에서는 'T'의 생략을 허용하지 않고, 날짜와 시간 사이의 공백을 허용한다. ISO 8601과 RFC 3339의 차이 UTC 시간대를 기준으로 여러 포맷이 사용 될 수 있지만 대부분 아래와 같은 형태 일 것이다. 2020–08–28T09:20:26.187+09:00 LocalDateTime(Loc..
컬렉션 프레임워크 란? 다수의 데이터를 쉽고 효과적으로 처리할 수 있는 표준화된 방법을 제공하는 클래스의 집합을 의미한다. 자료구조와 알고리즘을 구조화 하여 클래스로 구현해 놓은 것 구분 종류 중복 허용 순서 존재 정렬 여부 THREAD-SAFE LIST ArrayList O O X X LinkedList O O X X Vector O O X O SET HashSet X X X X Linked HashSet X O X X TreeSet X X O X MAP HashMap X X X X Linked HashMap X O X X Hashtable X X X O TreeMap X X O X List는 중복이 가능하고, 순서가 있는 데이터의 집합이다. ArrayList - 특정 원소 조회가 많은 경우 사용하는 ..
토비의 스프링 vol2 챕터 1.3 프로토타입과 스코프를 읽고 정리한 글 입니다. 스코프 존재할 수 있는 범위 빈 오브젝트가 만들어져 존재할 수 있는 범위이다. 스프링 빈은 기본적으로 싱글톤으로 만들어 진다. 애플리케이션 컨텍스트마다 빈의 오브젝트는 한 개만 만들어진다. 요청이 있을 때마다 매번 애플리케이션 로직을 담은 오브젝트를 새로 만드는 건 비효율적이기 때문이다. 하나의 빈 오브젝트에 동시에 여러 스레드가 접근하기 때문에 상태 값을 인스턴스 변수에 저장해 두고 사용할 수 없다. 싱글톤으로 설정된 빈은 DI, DL시 항상 같은 오브젝트가 리턴됨이 보장된다. DL (Dependency Lookup) : 컨테이너에서 getBean()을 통해 조회하는 것, 주입 받는 것이 아니라 직접 필요한 의존관계를 찾..
에이든의 트랜잭션 매커니즘, 샐리, 예지니어스의 트랜잭션 테코톡을 듣고 정리한 글 입니다. 트랜잭션 여러 쿼리를 논리적으로 하나의 작업으로 묶어주는 것 하나의 트랜잭션은 커밋 혹은 롤백된다. 데이터베이스에 저장된 데이터베이스의 무결성과 동시성의 성능을 지키기위해 트랜잭션의 설정이 중요 ACID 트랜잭션이 안전하게 수행된다는 것을 보장하기 위한 성질 Atomicity 트랜잭션은 DB에 모두 반영되거나, 전혀 반영되지 않아야 한다. 완료되지 않은 트랜잭션의 중간 상태를 DB에 반영해서는 안 된다. Consistency 트랜잭션 작업처리결과는 항상 일관성 있어야 한다. 데이터베이스는 항상 일관된 상태로 유지되어야 한다. Isolation 둘 이상의 트랜잭션이 동시 실행되고 있을 때, 어떤 트랜잭션도 다른 트랜..
[LV.1]우아한테크코스 한달 생활기 매일 만나는 데일리 미팅 우아한테크코스는 한 명의 코치와 13~14명 정도의 크루들이 함께 데일리 미팅을 진행한다. 내가 속한 데일리 조는 매일 마스터가 정해진다. 마스터들이 대화 할 주제를 마련해 온다. 코로나때문에 온라인으로 크루들을 만나야 했다. Gather라는 가상공간과 아바타를 이용한 화상 미팅 서비스를 알게 되었다. 그렇게 우리의 모임은 Gather안에서 진행 되었다. 그곳에서 크루들이 만들어 놓은 해변가도 같이 거닐고 OX게임도 진행하였다. 첫 시작 부터 크루들을 못만나는 것이 아쉬웠었다. 그러나 Gather 덕분에 매일 아침을 즐겁게 시작할 수 있었다. 나름 대로 코로나 시국을 잘 헤쳐나가고 있었다! 연극 대신 보라 우아한 테크코스 3기에서는 "연극" ..
TCP/IP를 주제로 테코톡을 준비하였다. 네트워크를 공부할 때 각각의 계층을 따로따로 공부하는 것 보다 하나의 흐름을 통해 공부를 하면 이해가 쉬웠다. 테코톡에서도 과정을 중심으로 발표를 구성하였다.
@EnableScheduling Scheduling 관련 Bean들을 등록해 준다. @Configuration @EnableScheduling public class ScheduledConfig { } @Scheduled 메서드 위에 @Schedule 어노테이션을 붙혀 해당 로직을 스케줄링 할 수 있다. @Scheduled(cron = "0 45 20 2 * *") public String executeWithScheduled() { log.info("executeWithScheduled : 매달 2일 저녁 8시 45분"); return "execute"; } Cron표기법 초 분 시 일 월 요일 연도 0 ~ 59 0 ~ 59 0~23 1~31 1~12 0~6 생략가능 요일의 경우 0이 일요일이며 6이 ..
인수테스트시 DirtiesContext로 테스트 격리를 해주고 있다. @DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_EACH_TEST_METHOD) 273테스트 1min 1sec 오래 걸리는 테스트시간을 줄일 수 있는 방법이 없을 까 고민하던 중 좋은 블로그글을 발견했다..! DirtiesContext를 사용하지 않고 테스트 격리를 해서 매번 모든 Context가 새로 생성되는 비효율성을 줄일 수 있다. 테스트에서는 공유자원으로 사용되는 데이터베이스에 대한 격리가 이루어져야 하므로, TRUNCATE를 통해 데이터베이스 초기화를 시켜주는 방법으로 테스트 격리를 하는 것이다. https://newwisdom.tistory.com/95 @Dirtie..
이번 데모데이 전 까지는 정산 플로우에 대한 구현이 주요 이슈가 되었다. 정산 플로우를 어떻게 진행해야 할까.. 백엔드와 프론트의 긴 회의가 있었다. 정해진 플로우는 아래와 같다. '창작자'는 정산을 신청하기 위해 실명, 계좌번호와 통장사본과 함께 '정산 계좌 승인 요청'을 진행한다. '관리자 페이지'에서 해당 요청을 검토하고 승인, 반려한다. 승인 시 창작자는 정산을 신청할 수 있게 된다. 후원 받은 포인트는 '후원자'가 후원을 하게 되면 증가한다. 정산 가능 포인트는 '후원자'가 후원을 한 뒤 7일이 지난 뒤 증가한다. 7일 까지 후원자가 우리 서비스를 통해 환불을 진행 할 수 있기 때문이다. 정산 완료 포인트는 지금 까지 '창작자'가 정산을 요청하고 완료된 포인트이다. 이번 스프린트에서는 우아한 테..
Cloud 정확히는 인터넷을 통해 원격으로 접근할 수 있는 모든 것 인터넷으로 제공되는 서비스(메일, 드라이브 등)을 의미 Cloud Computing 서버, 데이터베이스, 네트워킹 컴퓨팅 리소스를 인터넷을 통해 관리하는 것을 의미 VPC 독립된 가상의 클라우드 네트워크 VPC는 Virtual Private Cloud의 약자로 AWS 클라우드 내 논리적으로 독립된 섹션을 제공 사용자가 정의한 가상의 네트워크상에서 다양한 AWS 리소스 실행 퍼블릭 서브넷 공인 네트워크 개념으로 외부 인터넷 구간과 직접적으로 통신할 수 있는 공공 네트워크 프라이빗 서브넷 사설 네트워크 개념으로 외부 인터넷 구간과 직접적인 통신을 할 수 없는 폐쇄적인 네트워크 통신확인하기 Ping Check IP 정보만으로 서버에 요청이 가..
비즈니스 로직과 외부라이브러리 우리 서비스는 결제모듈이 들어간다. 결제 모듈을 제공하는 서비스는 다양하다. 우리는 그중 '아임포트'라는 결제 모듈을 택했다. 그러나 우리의 비즈니스 로직에 '아임포트' 결제모듈로 특정지어서는 안된다. 외부 라이브러리와 도메인 로직이 깔끔하게 분리되길 원했다. 어댑터 패턴 Client는 써드파티 라이브러리나 외부 시스템을 사용하려는 쪽 우리 Thank you for다. Adaptee는 써드파티 라이브러리나 외부시스템 쪽 아임포트 결제모듈이다. TargetInterface.. Client는 Adaptee대신 TargetInterface를 바라봐야한다. 우리의 도메인 로직은 프론트 엔드에서 우리에게 후원하길 원하는 창작자의 페이지 이름, 후원자의 이메일, 후원 금액을 보내면 P..
와우 벌써 3주차라니. 우리팀은 2주 단위였던 스프린트를 1주 단위로 줄이고 회고하는 방식으로 변경했다. 다음 데모데이 까지 핵심기능 개발이 목표인데 좀 더 효율적으로 보인다~ 깃 서브모듈 하나의 저장소 안에 있는 또 다른 별개의 저장소 서브모듈 시작하기 Git에 팀 Operation을 만들고, Private 레포지토리를 만들었다. 해당 레포지토리를 아래 명령어로 서브모듈로 만들어준다 git submodule add {내가 서브모듈로 사용하고 싶은 레포의 URL} 서브모듈을 포함한 프로젝트 Clone 비어있다.. 아래 명령어를 실행해서 git 저장소를 초기화 해주고, 원격 저장소에서 파일을 가져온다. git submodule init git submodule update https://sgc109.git..
클라우드 인터넷을 통해서 언제 어디서든지 원하는 때 원하는 만큼의 IT리소스 (컴퓨팅, 스토리지, 네트워크)를 손쉽게 사용할 수 있게하는 서비스 IaaS Infrastructure as a Service 가장 기본적인 IT 자원인 '서버, 네트워크, 스토리지' 자원을 클라우드 사업자가 제공하고 운영관리 사용자는 가상 서버에 필요한 프로그램을 설치하여 사용 및 운영 관리 EC2(컴퓨팅), VPC(네트워크), EBS(스토리지) PaaS Platform as a Service AWS Elastic Beanstalk(애플리케이션 배포) Serverless 애플리케이션 개발에 필요한 대부분을 클라우드 사업자가 제공하고 운영관리 사용자는 오직 개발에만 집중 Lambda, API Gateway SaaS Sofrwar..
배포자동화 애플리케이션을 개발하면서 feature 브랜치에서 develop 브랜치로 PR을 날리는 작업은 계속 될 것이다. 이때마다 서버로 접속하여 develop 브랜치의 소스를 pull 받고, build 하고 배포하는 작업을 해야 할까? 이럴 땐 배포자동화를 하면 된다. 젠킨스 이번 팀프로젝트에서는 배포자동화 도구로 Jenkins를 선택했다. 팀프로젝트를 시작하기 전 Jenkins를 한번 연습해 보았기도 하고 제공 되는 문서가 GitHub Actions 보다 많다. 또한 팀프로젝트 전 Jenkins를 연습할 때 프리티어 EC2에서 돌린적이 있었다. 지옥이었다. 배포자동화를 담당하는 서버는 어느정도 스펙를 갖추어야 한다고 한다. 이번 우테코 3기 팀프로젝트에서 medium 스펙의 EC2까지 생성할 수 있..
팀 결성 우아한 테크코스 레벨 3가 시작되고, 팀프로젝트를 진행하게 되었다. 나는 누구나 쉽게 창작자를 응원할 수 있는 간편 도네이션 서비스 Thank you for _ _ _프로젝트를 하게 되었다. 백엔드 4명 프론트엔드 2명이 한팀이 되어 프로젝트를 진행한다!👏 1주차에서는 팀 레포지토리가 만들어졌다. Thank you for _ _ _ 은 "창작자의 정성이 깃든 모든 저작물에 대해서 감사를 표한다" 라는 뜻을 담고 있다. 다만.. 이름이 너무 길어서 레포지토리 명은 tyf 인걸로.. 🥲 https://github.com/woowacourse-teams/2021-tyf woowacourse-teams/2021-tyf Thank You For ___ ! 누구나 쉽게 창작자를 응원할 수 있는 간편 도네이..
Naver Developers 방문 Naver Developers에 방문해서 애플리케이션 등록을 해준다. 애플리케이션 등록을 하면 Client ID와 Client Secret을 얻을 수 있다. https://developers.naver.com/docs/login/devguide/devguide.md#2-2-1-%EC%86%8C%EC%85%9C-%EB%A1%9C%EA%B7%B8%EC%9D%B8 네이버아이디로그인 개발가이드 - LOGIN 네이버아이디로그인 개발가이드 1. 개요 4,200만 네이버 회원을 여러분의 사용자로! 네이버 회원이라면, 여러분의 사이트를 간편하게 이용할 수 있습니다. 전 국민 모두가 가지고 있는 네이버 아 developers.naver.com 서비스 URL과 네이버아이디로그인 Call..
카카오 Developers 방문 https://developers.kakao.com/ Kakao Developers 카카오 API를 활용하여 다양한 어플리케이션을 개발해보세요. 카카오 로그인, 메시지 보내기, 친구 API, 인공지능 API 등을 제공합니다. developers.kakao.com 카카오 Developers에 방문한 뒤 애플리케이션을 추가해 준다. 카카오 로그인을 활성화 해준다. 동의 항목 관련 설정을 해준다. 발급 된 키들을 기억 해 둔다. 내 애플리케이션 > 제품설정 > 카카오 로그인 > 보안에서 Client Secret키를 발급 받는다. Client Secret 값은 절대 노출하면 안 된다. (Admin키) 인가코드 받기 카카오 로그인은 인가 코드 요청 단계에서 클라이언트에 카카오 계정..
자바 소스파일이 JVM으로 실행하는 과정 Hello.java를 생성한다. Java Compiler를 통해 Hello.class파일이 생성된다. Byte Code는 플랫폼 독립적이다. OS관계 없이 동일하다. (javac 명령어) JVM의 Java Interpreter는 Byte Code를 한줄씩 기계어로 변환하며 그때그때 실행한다. (java 명령어) ClassPath JVM이 프로그램을 실행할 때 Class 파일을 찾는데 기준이 되는 경로 InteliJ에서는 Project Structure의 Resource에서 설정가능 JIT컴파일러 란 우리가 작성한 자바 코드는 컴파일러를 통해 바이트 코드로 컴파일이 되고, 이 바이트코드는 인터프리터를 통해 한 줄 씩 기계어로 번역되어 실행이 된다고 위에서 설명하였다..
우테코에서 미션을 진행하면서 아니 왜 스프링 인터셉터에서 토큰을 검증하니 CORS 에러가 뜨면서 로그인이 안되는 거지? 이번에 사이드 프로젝트를 진행하면서 아니 왜 JsessionID가 쿠키로 안 들어오는거야? CORS와 엮이면 아니 왜부터 튀어나오게 되는데.. 이번에 정리해보자 CORS SOP 브라우저는 스크립트에서 생성된 HTTP 요청에 SOP를 적용한다. SOP란 다른 출처의 리소스를 사용하는 것을 제한 하는 보안 방식이다. URL의 프로토콜, Host, Posrt를 통해 같은 출처인지 다른 출처인지 판단 할 수 있다. CORS 추가적인 HTTP header를 사용해서 애플리케이션과 다른 Orgin의 리소스에 접근할 수 있도록 하는 매커니즘 문제적 상황 1 프론트 엔드 애플리케이션 (localhos..
클래스와 인스턴스 클래스 인스턴스를 생성하기 위한 틀 클래스 자체만으로는 상태가 없다. 클래스 메서드 인스턴스의 상태와는 관련이 없다. 인스턴스를 생성하지 않은 상태에서도 호출이 가능하다. 클래스 메소드는 유틸리티 메소드라고 부른다. 클래스 필드 여러 인스턴스에서 공유하는 정보가 있는 경우 사용한다. 인스턴스 단수 의미로의 객체 클래스를 통해 실체화되어 생성된다. 인스턴스는 상태를 가지며, 메서드를 통해 인스턴스의 상태가 변경된다. 인스턴스 메서드 인스턴스의 상태를 변경하거나 상태 정보를 반환할 때 사용하는 메소드 인스턴스를 생성한 후 메시지를 보낼 수 있다. 인스턴스 필드 인스턴스의 상태 정보를 가지고 있는 변수 상태변수라고도 이야기 한다. 메모리 구조 클래스 필드와 메소드 클래스 필드와 메소드는 Me..
우테코 레벨2 마지막 미션은 프론트엔드 크루들과 함께 미션을 진행하는 '협업 미션'이 주어졌다. 프론트엔드 크루들이 우리가 만든 서버를 사용할 수 있도록 배포를 해야 했다. 이번 포스팅에서는 협업미션을 하면서 AWS, nginx, HTTPS를 적용하여 개발환경을 구축한 것을 정리해 보려고 한다. 서버 생성 서버로 사용 할 EC2를 만든다. EC2는 AWS로 부터 컴퓨터 한대를 임대해서 사용 할 수 있는 서비스 EC2를 생성했다면 EC2서버에 접속해서 환경을 꾸린다. EC2에 도커 설치 $ sudo apt-get update && \ sudo apt-get install -y apt-transport-https ca-certificates curl software-properties-common && \ ..
목적 이전 미션의 PR들을 보고 있다. 레벨 2가 끝나가는 시점에 잘 지켜지는 피드백도 있고, 그렇지 않은 피드백도 있다. 잘 이해가 되는 개념도 있고 그렇지 않은 개념도 있다. 그런 것들을 정리해 보려고 한다. 객체를 객체스럽게 사용해라 이번 지하철 미션에서도 한번 피드백을 받았다. 한번 더 리마인드 하면 좋을 것 같다. Line line = findById(id); Sections sections = line.getSections(); List deleteSections = sections.deleteSection(stationId); Line line = findById(id); List deleteSections = line.deleteSection(stationId); 객체는 캡슐화된 상태와 외..
도커는 너무 어려워요 우아한테크코스 Level2에서 배포하기라는 큰 산을 만났다. 가이드 대로 따라하면 동작하기는 했지만 명령어가 무슨 의미인지 모르고 진행하니 답답했다. 이번 포스팅에서는 도커에 대한 간단한 설명과 배포하기를 하면서 만난 도커 명령어의 의미를 정리해 볼 것이다. 도커를 왜 사용 할까? snowflak server 이슈 스노우 플레이크 서버 한번 설치한 서버에 계속해서 설정을 변경하고 패치를 적용하는 등의 업데이트를 지속적으로 적용하여 운영하는 서버 스노우 플레이크 서버는 다시 똑같이 설정하기가 매우 어렵다. 장비를 업그레이드 하거나 OS를 새로 인스톨해서 같은 환경을 꾸미고자 할 때 예전 환경과 동일한 환경을 구성하기가 어렵다. 이미지와 컨테이너 도커를 사용하면 개발 환경을 이미지화 시..
Optional null을 대신 하도록 자바 8에서 추가된 코어 자바 라이브러리 데이터 형식 Optional 왜 쓸까 null을 사용하게 되면 NPE가 발생 null인 변수를 참조하면 프로그램이 즉시 종료 Optional을 사용하면 개발자가 변수에 값이 있는지 없는지 체크가능 리턴 값이 없을 수 있다는 사실을 Optional을 통해 문서화 한다. Optional 어떻게 쓸까 of() 팩토리 메서드로 Optional 인스턴스를 만든다. get()으로 안에 있는 값을 꺼낼 수 있다. Optional a = Optional.of("a"); assertEquals("a", a.get()); 그러나 get()으로 얻어오는 경우 값이 없다면 NoSuchElementException을 발생시킨다. null 이건 em..
브라우저에서 google.com를 요청할 때 통신 과정이 어떻게 이루어질까요? 그러게요...? 이제 알아봅시다. 1. 브라우저에 google.com을 입력한다. 우리는 하이퍼텍스트를 주고받을 수 있는 WWW라는 서비스를 사용할 것입니다. WWW서비스의 클라이언트가 되는 브라우저를 사용할 것입니다. http://www.google.com은 google의 www 서버(웹서버)를 가리킵니다. http는 www 서비스를 나타냅니다. www서비스는 HTTP 프로토콜을 사용합니다. 2. 브라우저는 DNS 프로토콜을 사용하여 www.google.com의 IP주소를 얻어온다. nslookup 이라는 명령어를 통해 www.google.com의 실제 IP를 볼 수 있습니다. 저의 경우 142.250.76.142가 나옵니다..
Dependency Injection 의존 주입 한 클래스가 다른 클래스의 메서드를 실행할 때 이를 '의존'한다고 한다. 의존은 변경에 의해 영향을 받는 관계를 의미한다. 의존 주입은 의존하는 객체를 직접 생성하는 대신 의존 객체를 전달받는 방식을 사용 변경에 유연해 질 수 있다. public MemberRegisterService(MemberDao memberDao) { this.memberDao = memberDao 객체를 생성하고 의존 객체를 주입하는 것은 스프링 컨테이너 설정 파일을 정의한 후 AnnotationConfigApplicationContext를 이용해서 스프링 컨테이너를 생성해야 한다. 스프링 컨테이너로 부터 getBean()을 사용하여 Bean 객체를 얻어올 수 있다. @Config..
Web Server, Web Application 웹서버 HTTP Server(아파치) URL 및 HTTP를 이해하는 소프트웨어 저장하는 웹 사이트의 도메인 이름을 통해 액세스 할 수 있으며 이러한 호스팅 된 웹사이트 콘텐츠를 최종 사용자의 장치로 전달 정적타입(HTML, CSS, 이미지등)의 데이터만 처리 -> jsp파일이라면? 톰캣 WAS (Web Application Server) 스프링의 내장 WAS가 톰캣이다. JSP와 Servelt, 스프링 MVC을 구동하기 위한 서블릿 컨테이너 역할을 수행한다. 아파치서버와는 다르게 DB연결, 다른 응용프로그램과 상호 작용 등 동적인 기능 사용가능 자바코드를 컴파일하여 html파일로 만들어 준다. 서블릿 Servlet 클라이언트의 요청을 받고 요청을 처리하여..
어떤 어노테이션 들이 있을까 @NotNull 어노테이션이 붙은 프로퍼티가 Null이 아닌지 검증한다. @NotEmpty 어노테이션이 붙은 프로퍼티가 Null 이거나 빈 값인지 검증한다. String, Collection, Map, Array에 적용 될 수 있다. @NotBlank 어노테이션이 붙은 값이 Null 이거나 공백인지 체크한다. TextValue에만 적용 될 수 있다. @AssertTrue 어노테이션이 붙은 프로퍼티가 True인지 검증한다. @Size 어노테이션이 붙은 프로퍼티가 min과 max 속성 사이의 값을 가지는지 검증한다. String, Collection, Map, Array에 적용 될 수 있다. @Size(min = 10, max = 100) @Min 어노테이션이 붙은 프로퍼티가 가..
스프링은 프레임워크이다. 프레임워크 소프트웨어의 구체적인 부분에 해당하는 설계와 구현을 재사용가능 하게끔 일련의 협업화 된 형태로 클래스들을 제공하는 것 라이브러리 활용 가능한 도구들의 집합 프레임워크는 자체적인 흐름을 가지고 있어 사용자가 그에 맞춰 개발하는 것 라이브러리는 사용자의 흐름에 따라서 개발 도중 필요한 기능을 라이브러리 가져다 쓰는 것 스프링은 IoC 컨테이너를 가진다. IoC (Inversion of Controll) 제어의 역전 클래스의 관리자가 개발자가 아니라 프레임워크가 된다. 스프링이 Spring Bean을 인스턴스화 한다. 싱글톤으로 관리가 된다. 스프링은 DI를 지원한다. Spring Bean으로 등록 된 객체들의 의존성 주입이 쉬워진다. @AutoWired를 이용한 자동 의존..
우테코 체스 미션에 스프링을 도입했다. 어노테이션을 통한 의존성 주입은 신세계 였다. InteliJ에서 노란줄을 띄웠음에도 필드 주입을 주로 사용했다. (간결해..!) 리뷰어 분께서 필드 주입에 관해서 피드백을 주셨다. 이번 포스팅은 피드백 주신 대로 필드 주입이 무엇인지, 왜 권장하지 않는지, 대안은 무엇인지 학습해 볼 것이다. 필드 주입 이란 @Autowired를 필드에 직접 사용하는 경우를 필드 주입이라고 한다. @AutoWired private ChessService chessService; 왜 필드 주입을 권장하지 않는가? 순환참조 A가 B를 참조하고, 다시 B가 A를 참조하는 경우를 말한다. class A { @Autowired private B b; public void do() { b.do..
우테코에서 스프링을 공부하면서 아래 내용을 참고하여 정리한 글 입니다. docs.spring.io/spring-framework/docs/current/reference/html/web.html#mvc-ann-requestmapping Web on Servlet Stack Spring Web MVC is the original web framework built on the Servlet API and has been included in the Spring Framework from the very beginning. The formal name, “Spring Web MVC,” comes from the name of its source module (spring-webmvc), but it is m..
주말이 짧은 이유는 진짜 짧기 때문이다. 레벨1이 벌써 끝난 이유는 진짜 짧기 때문이다. 두달이다. 두달이 순식간에 지나갔다. 이 시간동안 많은 것을 했고, 많은 일들이 벌어졌다. 그리고 많이 성장했다. 값진 시간을 보냈다고 자부 할 수 있다. 레벨 1에서 수행한 미션 레벨 1의 첫 미션인 자동차 경주 미션 TDD와 MVC패턴을 적용 해 보았다. Stream에 대해 알게 되었고 처음 써 보았다....! github.com/woowacourse/java-racingcar/pull/241 [2단계 - 자동차 경주 리팩토링] 수리(이다원) 미션 제출합니다. by DWL5 · Pull Request #241 · woowacourse/ 안녕하세요! 제이 2단계 미션 제출 합니다. 1단계에서 페어 프로그래밍을 할 ..
DAO Entity Bean의 퍼시스턴스 지원 기능을 대체하는 동시에 비즈니스 로직과 퍼시스턴스 로직의 명확한 분리를 위해 퍼시스턴스 로직을 캡슐화하고 도메인 레이어에 객체 지향적인 인터페이스를 제공하는 객체를 DAO(Data Access Object) 라고 한다. DAO는 데이터 퍼시스턴트의 추상화 이다. 테이블 중심의 데이터베이스와 가깝게 고려 된다. 그래서 DAO는 데이터 베이스 테이블과 매치 된다. 데이터 CRUD를 위한 방법을 제공한다. 도메인 클래스 - User public class User { private Long id; private String userName; private String firstName; private String email; // getters and setter..
두둥 너무 어려워 보이는 SQL 미션 CRUD를 배웠기 때문에 관련 미션이 나올 거라는 착각 문제보니 여러 테이블을 짬뽕해서 데이터 추출 해야하는 느낌이듬 이제 막 CRUD를 뗀 개발자에게 너무 어려운 미션 아니오!! 미션은 요기 https://www.w3schools.com/sql/trymysql.asp?filename=trysql_func_mysql_concat 첫번째 문제 문제 파악 문제 : 200개 이상 팔린 상품명과 그 수량을 수량 기준 내림차순으로 보여주세요. OrderDeatail 테이블에 ProductId와 Quantity라는 컬럼이 존재 이것을 이용해서 같은 ProductId를 가지는 Quantitiy를 모두 더 해 200개 이상인 ProductId를 추출 어떻게 하지? 추출 된 Prod..
JDBC UPDATE @Test public void updateUserName() throws Exception { String userId = UserTest.TEST_USER.getUserId(); String updatedName = "updatedName"; userDao.updateUserName(userId, updatedName); User updatedUser = new User(userId, updatedName); User realUpdateUser = userDao.findByUserId(userId); assertEquals(realUpdateUser, updatedUser); } public void updateUserName(String userId, String name) ..
JDBC READ @Test public void findByUserId(String userId) { User user = userDao.findByUserId("userId"); assertEquals(UserTest.TEST_USER, user); } 객체 비교를 위하여 User의 hashcode, equals를 재정의 해 준다. public User findByUserId(String userId) { String sql = "select * from USERS where userId = ?"; PreparedStatement pstmt = getConnection().prepareStatement(sql); pstmt.setString(1, userId); ResultSet rs = pstmt...
데이터베이스 생성하기 CREATE DATABASE db_name DEAFAUT CHARCTER SET utf8 COLLATE utf_8general_ci; 테이블 생성하기 CREATE TABLE USERS( userIdvarchar(12) NOTNULL, passwordvarchar(12) NOTNULL, namevarchar(20) NOTNULL, emailvarchar(50), NOTNULL, PRIMARY KEY (userId) ); 데이터 CREATE INSERT INTO USERS VALUES('1', 'password', 'nickname', 'email@naver.com'); JDBC CONNECTION 자바에서 데이터베이스와 연동을 하기 위해 사용하는 표준 DAO(Data Access Ob..
처음 우아한 테크코스에 미션을 수행하면서 Git을 사용할 때, 헤맸던 부분에 대해서 정리하고자 한다. 우아한 테크코스의 프로그래밍 미션 수행 과정 우아한 테크코스에서 미션을 시작하면 woowacourse 저장소에 자신의 github아이디로 브랜치가 생성된다. 크루들은 미션을 진행 한 뒤, 이곳으로 PR을 보내야 한다. woowacourse의 미션 프로젝트를 자신의 계정으로 fork fork : 저장소를 자신의 계정으로 복사하는 기능 fork한 저장소를 자신의 컴퓨터로 clone clone : git 서버에 존재하는 저장소를 자신의 로컬에 복사하는 기능 기능 구현을 위한 브랜치 생성 (ex step1) 해당 브랜치에서 작업 후 add, commit, push 1단계 미션 제출 PR 보내기 PR merge ..
우아한 테크코스 3기 한 달 회고 - 벌써 LV1의 반이 지나가 버렸다. 우아한 테크코스를 시작 하기 전 "매주 마다 주간 회고를 해야지" 라고 다짐 했던 나는 어디 갔을까.. 반성을 하며 늦게나마 한달 회고를 작성해 본다. 매일 만나는 데일리 조 코치 1분에 크루 12명 정도가 데일리 조로 편성이 되었다. 코치님 왈 "호그와트 기숙사 처럼 데일리 조가 계속 유지 되는 것이 좋을 것 같다." 라고 하신 것을 보면 레벨이 바뀔 때 마다 데일리조도 재 편성이 되나보다. 우리 데일리 조는 매일 마스터가 정해져서 마스터가 대화 할 거리들을 마련해 온다. Gather에서 미팅을 하는데, 어느 순간 부터 데일리 주제들이 주로 게임이 되어버려서 아침마다 승부욕이 짱짱하게 채워질 수 있었다. Gather Gather ..
지원 "성장 할 수 있는 10개월 이다" 우아한 테크코스 속에서 보낸 10개월이 내 인생에 꾸준하게 긍정적인 영향을 미칠 것 같다는 생각이 들었다. 아니 확신이 들었다. 인트로에 나오는 문구하나하나가 성장세포를 깨우는 느낌이 들었다. 3시간 정도되는 영상을 시청하고 드는 생각은 지금 당장 바로 지원하자 였다. 그렇게 나는 우아한 테크코스 지원에 한발짝 다가가게 되었다. 코딩테스트 2020년 11월 7일 12시부터 16시 까지 4시간 동안 총 7문제를 풀었다. 나는 주로 알고리즘 공부를 할 때 사용했던 언어인 python3를 사용하여 코딩테스트를 보았다. 문제를 읽고 코드로 구현해서 해결 할 수 있는 기본능력을 보는 것 같았다. 구현을 한 뒤, 테스트 케이스가 2~3개 밖에 주어지지 않아 제출을 한 뒤에도..
안드로이드의 아키텍쳐들은 MVC, MVP, MVVM, MVI가 있지만, 이를 이루는 것에 'MV'은 필수 적으로 들어가 있다. M이란 Model, V란 View를 의미한다. View에는 사용자와 바로 인터렉션 할 수 있는 UI를 제공해주는 부분을 말한다. 안드로이드에서는 Acitivity, Fragment등 이라고 할 수 있다. 안드로이드를 처음 배우고, 아키텍처를 적용하지 않는다고 하면 이 View단에서 Data관련 로직을 처리하도록 구현하기 쉽다. 안드로이드 개발 공식 문서에서 '책임의 분리'를 강조하며 아키텍처를 사용하여 구현하는 것을 추천하는데, 이렇게 View 단에 View와 상관없는 로직을 추가하는 것은 '책임의 분리'를 적용하지 않는 것이다. 이번 포스팅에서는 안드로이드 아키텍처 스터디를 하..
implementation dependency를 추가할 때 implementation을 사용하면 테스트 소스 세트를 포함한 모든 소스 세트에서 사용 할 수 있다. testImplementation dependency를 추가할 때 testImplementation을 사용하면 test source set에서만 사용할 수 있다. androidTestImplementation dependency를 추가할 때 androidTestImplementation을 사용하면 androidTest source set에서만 사용할 수 있다.
이번에 Flutter로 앱을 출시해보려고 했는데, 안드로이드 버전코드, 버전네임을 업데이트 하는 방법에서 조금 헤메었다. 이번 포스팅에서는 그 내용을 다뤄보도록 할 것이다. 처음에 나는 local.properties에서 값을 바꿔야 한다고 생각해서 바꿔보았다. 그러나 build를 할 때 마다 값이 되돌아 오는 것이었다. 알고보니 pubspec.yaml에서 바꿔주어야 했다. version: 1.0.1+2에서 1.0.1이 version name, 2가 version code가 되겠다. pebspec.yaml 주석에도 내용이 잘 설명되어 있었다. ㅠ # The following defines the version and build number for your application. # A version num..
여러 아이템 중 하나를 고를 수 있는 콤보박스 형태의 위젯입니다. value 프로퍼티에 인스턴스들을 담은 리스트로 지정해야 합니다. 상태를 가지므로 StatefulWidget으로 작성합니다. map()함수를 사용하여 _valueList 리스트의 문자열 3개를 DropdownMenuItem인스턴스 3개로 변환했습니다. 그리고 toList() 함수를 사용하여 다시 리스트로 변환 시켜서 items 프로퍼티에 이 리스트를 지정했습니다. class _MyHomePageState extends State { final _valueList = ['첫 번째', '두 번째', '세 번째']; var _selectedValue = '첫 번째'; @override Widget build(BuildContext context..
Radio는 그룹 내에서 하나만 선택할 때 사용합닏. 그룹이 되는 항목을 열거형(enum)으로 정의하고, groupValue 프로퍼티에 열거형으로 정의한 Gender 타입의 변수를 지정하고, onChanged이벤트에서 변경된 값을 반영합니다. 현재는 ListTile을 사용했기 때문에 라디오 버튼을 터치해야 인식됩니다. enum Gender {MAN, WOMEN} class _MyHomePageState extends State { int _counter = 0; var _isChecked = false; Gender _gender = Gender.MAN; void _incrementCounter() { setState(() { _counter++; }); } @override Widget build(Bu..
CheckBox와 Switch value : 상태를 나타낼 불리언 타입의 변수 onChanged : 체크값이 변할 때 마다 발생하는데, 여기서 변경된 값이 불리언 value 인수로 넘어온다. setState() 함수를 통해 value 프로퍼티에 지정한 변숫값을 변경하며 UI를 다시 그린다. 현재 _isChecked가 CheckBox와 Switch에 동시에 사용되고 있으므로 CheckBox를 변경해도 Switch의 상태 또한 변하게 된다. var _isChecked = false; child: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Checkbox( value: _isChecked, onChanged: ..
` TextField 글자를 입력받는 위젯 InputDecoration 클래스와 함께 사용하면 힌트 메시지나 외곽선 등의 꾸밈 효과 간단히 추가 가능 decoration 프로퍼티를 활용하면 다양한 효과를 줄 수 있다. labelText는 안드로이드 EditText의 hint 속성이라고 보면 된다. TextField( obscureText: true, decoration: InputDecoration( border: OutlineInputBorder(), labelText: 'Password', ), )