브랜치란?
독립적인 여러 작업을 진행하기 위한 개념
여러 명이서 동시에 작업을 할 때에 다른 사람의 작업에 영향을 주거나 받지 않도록, 먼저 메인 브랜치에서 자신의 작업 전용 브랜치를 만듭니다. 그리고 각자 작업을 진행한 후, 작업이 끝난 사람은 메인 브랜치에 자신의 브랜치의 변경 사항을 적용합니다. 이렇게 함으로써 다른 사람의 작업에 영향을 받지 않고 독립적으로 특정 작업을 수행하고 그 결과를 하나로 모아 나가게 됩니다. 이러한 방식으로 작업할 경우 '작업 단위', 즉 브랜치로 그 작업의 기록을 중간 중간에 남기게 되므로 문제가 발생했을 경우 원인이 되는 작업을 찾아내거나 그에 따른 대책을 세우기 쉬워집니다.
>>결국 개발자들이 서로에 작업에 영향을 주지 않으면 독립된 공간에서 다양한 작업을 진행할 수 있게 도와주는 것 같음
master - 최종 배포용
develop - 개발용
feature - develop에서 새로운 기능을 만들때 쓰는 브랜치?
*************************************
출처
https://backlog.com/git-tutorial/kr/stepup/stepup1_1.html
브랜치 설명
https://mylko72.gitbooks.io/git/content/branch/branch_type.html
**********************************************
쓰는 흐름은
develop에서 feature를 따서 작은 기능을 개발 -> 작은 기능이 개발완료되면 develop으로 merge -> 반복 -> 모든 기능들이 완료되어 develop으로 합쳐지고, 정상적으로 동작하면 master에 올려서 최종배포
인듯 하다.
2018년 2월 8일 목요일
2018년 1월 21일 일요일
git에서 공유받은 maven dependencies / missing artifact 문제
http://parkpurong.tistory.com/133
깃으로 받은 프로젝트의 maven dependencies가 제대로 안받아지는것같다 ㅠ
위 블로그 방법으로해서 Missing artifact 는 없앴는데 계속안되서 그냥 내 로컬프로젝트 중 하나 pom.xml에서 버전 바꿔서 새버전 다시 받고 했음...
깃으로 받은 프로젝트의 maven dependencies가 제대로 안받아지는것같다 ㅠ
위 블로그 방법으로해서 Missing artifact 는 없앴는데 계속안되서 그냥 내 로컬프로젝트 중 하나 pom.xml에서 버전 바꿔서 새버전 다시 받고 했음...
2017년 11월 29일 수요일
토비의 스프링 공부/정리 [3]
회사에서 토비의 스프링 스터디를 시작하였다.
새로운 기분으로 정독하고 있으며, 정리한 내용을 학습목적으로 git에 올리고 있다.
이해가 가지 않는 내용도 있지만, 일단 1회독을 마치는 것을 목표로 진행하자!
//////////////////////////////////////////////////////////////////////////////////////////////
3. 템플릿
3.1 다시 보는 초난감 DAO
3.1 다시 보는 초난감 DAO
리소스 반환과 close()
3.2 변하는 것과 변하지 않는 것
분리와 재사용을 위한 디자인 패턴 적용
3.3 JDBC 전략 패턴의 최적화
3.4 컨텍스트와 DI
3.4 컨텍스트와 DI
3.5 템플릿과 콜백
3.5 템플릿과 콜백
3.6 스프링의 JdbcTemplate
3.6 스프링의 JdbcTemplate
2017년 11월 6일 월요일
토비의 스프링 공부/정리 2장
회사에서 토비의 스프링 스터디를 시작하였다.
새로운 기분으로 정독하고 있으며, 정리한 내용을 학습목적으로 git에 올리고 있다.
이해가 가지 않는 내용도 있지만, 일단 1회독을 마치는 것을 목표로 진행하자!
2. 테스트
저자는 스프링이 개발자에게 제공하는 것들 중 객체지향과 테스트가 가장 중요한 가치라고 하며 2장을 시작한다.
스프링으로 개발을 하면서 테스트를 만들지 않는다면 이는 스프링이 지닌 가치의 절반을 포기하는 셈이다.
테스트란?
- 코드의 결함 제거(디버깅) --> 의도한대로 나올 수 있도록 수정해 나가는 작업
- 내가 예상하고 의도했던 대로 코드가 정확히 동작하는지를 확인해서 만든 코드를 확신할 수 있게 해주는 작업
책에서는 웹을 통한 DAO테스트 방법의 2가지 문제점에 대해 말하고 있다.
1. 수동 확인 작업의 번거로움: 테스트 결과를 확인하는 작업을 사람의 눈으로 해야함.
2. 실행 작업의 번거로움: 전체 기능을 테스트해보기 위해 main 메소드를 수백 번 실행하는 수고가 필요함.
- ++DAO뿐만 아니라 서비스 클래스, 컨트롤러, 뷰 등 모든 레이어의 기능을 다 만들고 나서야 테스트가 가능 (이 경우 오류가 발생했을 때 어느부분에서 오류가 발생하였는지 파악이 어렵고, 빠르고 정확히 대응하기 어려움)
단위테스트란?(Unit Test)
- 작은 단위의 코드에 대해 테스트를 수행한 것
- 테스트의 관심이 다르다면 테스트할 대상을 분리하고 집중해서 접근해야한다.
- 단위 테스트를 하는 이유는 개발자가 설계하고 만든 코드가 원래 의도한 대로 동작하는지를
개발자 스스로 빨리 확인 받기 위해서이다.
이 후 이 2가지 문제점에 대해 개선하는 작업을 보여주고 있다.
- 테스트 검증의 자동화
- 테스트의 결과 값들을 사람의 눈으로 직접 확인하는 것이 아닌 테스트 수행과 기대하는 결과에 대한 확인까지 해주는 코드로 된 자동화된 테스트를 해야한다고 하고있다.
- 테스트의 효율적인 수행과 결과 관리
- main() 메소드를 이용한 테스트 작성 방법만으로는 애플리케이션 규모가 커지고 테스트 개수가 많이지면 테스트를 수행하는 일이 점점 부담이 된다며, JUnit 을 소개하고있다.
JUnit 프레임워크
자바 테스팅 프레임워크로 JUnit을 통해 단위테스트가 가능하다.
책에서는 스프링을 학습하고 제대로 활용하려면 최소한의 JUnit 테스트 작성 방법과 실행방법은 알고있어야한다고 하고있다.
스프링의 핵심 기능 중 하나인 스프링 테스트 모듈도 JUnit을 이용하고 있다고 한다.
JUnit의 간단한 사용법과 테스트 방법을 설명한 후 테스트 결과의 일관성을 설명하고 있다.
(책에서는 사용자를 추가하는 테스트를 수행하고있는데, 한번 수행 후 또 다시 테스트를 실행시키면 사용자가 중복되기 때문에 문제가 발생하기 때문에 테스트 전에 등록된 사용자 정보를 초기화 시켜주는 작업을 하여 동일한 테스트 결과를 나타날 수 있게 하는 과정을 설명하고있다.)
- 반복적으로 테스트를 수행하였을 때, 항상 동일한 결과가 나와야한다.
- 단위테스트는 코드가 바뀌지 않는다면 매번 실행할 때마다 동일한 테스트 결과를 얻을 수 있어야 한다.
"항상 네거티브 테스트를 먼저 만들라"
부정적인 케이스를 먼저 만드는 습관을 들이는게 좋다.
테스트 주도 개발(Test Driven Development-TDD)이란?
만들고자 하는 기능의 내용을 담고 있으면서 만들어진 코드를 검증도 해줄 수 있도록
테스트 코드를 먼저 만들고, 테스트를 성공하게 해주는 코드를 작성하는 방식의 개발 방법
("실패한 테스트를 성공시키기 위한 목적이 아닌 코드는 만들지 않는다")
TDD의 장점
코드를 만들어 테스트를 실행하는 그 사이의 간격이 매우 짧다.
(오류를 빨리 발견할 수 있다.)
( TDD참조 http://www.hoons.net/Lecture/View/644 )
스프링은 JUnit을 이용하는 테스트 컨텍스트 프레임워크를 제공한다. 라고하며, 의존성 주입을 이용한 테스트를 소개하고 있다. (이 부분은 직접 실습을 해보면서 하는 게 좋을 듯 하다.)
@Autowired가 잠깐 나오는데, 2권에서 자세하게 설명한다고 되어 있다.
- Autowired 가 붙은 인스턴스 변수가 있으면, 테스트 컨텍스트 프레임워크는 변수 타입과 일치하는 컨텍스트 내의 빈을 찾는다.
타입이 일치하는 빈이 있으면 인스턴스 변수에 주입해준다.
학습테스트(learning test)란?
자신이 만들지 않은 프레임워크나 다른 개발팀에서 만들어서 제공한 라이브러리 등에 대해서는 테스트를 작성해야한다.
-목적: 자신이 사용할 API나 프레임워크의 기능을 테스트로 보면서 사용 방법을 익히려는 것
-장점
1. 다양한 조건에 따른 기능을 손십게 확인 가능
2. 학습 테스트 코드를 개발 중에 참고할 수 있음.
3. 프레임워크나 제품을 업그레이드할 때 호환성 검증을 도와줌.
4. 테스트 작성에 대한 좋은 훈련이 됨.
5. 새로운 기술을 공부하는 과정이 즐거워짐.
버그테스트(bug test)란?
코드에 오류가 있을 때 그 오류를 가장 잘 드러내줄 수 있는 테스트
(일단 실패하도록 만들어야함. 그 후 성공할 수 있도록 애플리케이션 코드를 수정함.)
필요성과 장점
1. 테스트의 완성도를 높여줌
2. 버그의 내용을 명확하게 분석하게 해줌
3. 기술적인 문제를 해결하는 데 도움이 됨
동등분할: 같은 결과를 내는 값의 범위를 구분해서 각 대표값으로 테스트 하는 방법
경계값 분석: 에러는 동등분할 범위의 경계에서 주로 많이 발생한다는 특징을 이용해서 경계의 근처에 있는 값을 이용해 테스트하는 방법.
//////////////////////////////////////////////////////////////////////////////////////////////
저자는 스프링이 개발자에게 제공하는 것들 중 객체지향과 테스트가 가장 중요한 가치라고 하며 2장을 시작한다.
스프링으로 개발을 하면서 테스트를 만들지 않는다면 이는 스프링이 지닌 가치의 절반을 포기하는 셈이다.
테스트란?
- 코드의 결함 제거(디버깅) --> 의도한대로 나올 수 있도록 수정해 나가는 작업
- 내가 예상하고 의도했던 대로 코드가 정확히 동작하는지를 확인해서 만든 코드를 확신할 수 있게 해주는 작업
책에서는 웹을 통한 DAO테스트 방법의 2가지 문제점에 대해 말하고 있다.
1. 수동 확인 작업의 번거로움: 테스트 결과를 확인하는 작업을 사람의 눈으로 해야함.
2. 실행 작업의 번거로움: 전체 기능을 테스트해보기 위해 main 메소드를 수백 번 실행하는 수고가 필요함.
- ++DAO뿐만 아니라 서비스 클래스, 컨트롤러, 뷰 등 모든 레이어의 기능을 다 만들고 나서야 테스트가 가능 (이 경우 오류가 발생했을 때 어느부분에서 오류가 발생하였는지 파악이 어렵고, 빠르고 정확히 대응하기 어려움)
단위테스트란?(Unit Test)
- 작은 단위의 코드에 대해 테스트를 수행한 것
- 테스트의 관심이 다르다면 테스트할 대상을 분리하고 집중해서 접근해야한다.
- 단위 테스트를 하는 이유는 개발자가 설계하고 만든 코드가 원래 의도한 대로 동작하는지를
개발자 스스로 빨리 확인 받기 위해서이다.
이 후 이 2가지 문제점에 대해 개선하는 작업을 보여주고 있다.
- 테스트 검증의 자동화
- 테스트의 결과 값들을 사람의 눈으로 직접 확인하는 것이 아닌 테스트 수행과 기대하는 결과에 대한 확인까지 해주는 코드로 된 자동화된 테스트를 해야한다고 하고있다.
- 테스트의 효율적인 수행과 결과 관리
- main() 메소드를 이용한 테스트 작성 방법만으로는 애플리케이션 규모가 커지고 테스트 개수가 많이지면 테스트를 수행하는 일이 점점 부담이 된다며, JUnit 을 소개하고있다.
JUnit 프레임워크
자바 테스팅 프레임워크로 JUnit을 통해 단위테스트가 가능하다.
책에서는 스프링을 학습하고 제대로 활용하려면 최소한의 JUnit 테스트 작성 방법과 실행방법은 알고있어야한다고 하고있다.
스프링의 핵심 기능 중 하나인 스프링 테스트 모듈도 JUnit을 이용하고 있다고 한다.
JUnit의 간단한 사용법과 테스트 방법을 설명한 후 테스트 결과의 일관성을 설명하고 있다.
(책에서는 사용자를 추가하는 테스트를 수행하고있는데, 한번 수행 후 또 다시 테스트를 실행시키면 사용자가 중복되기 때문에 문제가 발생하기 때문에 테스트 전에 등록된 사용자 정보를 초기화 시켜주는 작업을 하여 동일한 테스트 결과를 나타날 수 있게 하는 과정을 설명하고있다.)
(책에서는 사용자를 추가하는 테스트를 수행하고있는데, 한번 수행 후 또 다시 테스트를 실행시키면 사용자가 중복되기 때문에 문제가 발생하기 때문에 테스트 전에 등록된 사용자 정보를 초기화 시켜주는 작업을 하여 동일한 테스트 결과를 나타날 수 있게 하는 과정을 설명하고있다.)
- 반복적으로 테스트를 수행하였을 때, 항상 동일한 결과가 나와야한다.
- 단위테스트는 코드가 바뀌지 않는다면 매번 실행할 때마다 동일한 테스트 결과를 얻을 수 있어야 한다.
"항상 네거티브 테스트를 먼저 만들라"
부정적인 케이스를 먼저 만드는 습관을 들이는게 좋다.
테스트 주도 개발(Test Driven Development-TDD)이란?
만들고자 하는 기능의 내용을 담고 있으면서 만들어진 코드를 검증도 해줄 수 있도록
테스트 코드를 먼저 만들고, 테스트를 성공하게 해주는 코드를 작성하는 방식의 개발 방법
("실패한 테스트를 성공시키기 위한 목적이 아닌 코드는 만들지 않는다")
TDD의 장점
코드를 만들어 테스트를 실행하는 그 사이의 간격이 매우 짧다.
(오류를 빨리 발견할 수 있다.)
( TDD참조 http://www.hoons.net/Lecture/View/644 )
스프링은 JUnit을 이용하는 테스트 컨텍스트 프레임워크를 제공한다. 라고하며, 의존성 주입을 이용한 테스트를 소개하고 있다. (이 부분은 직접 실습을 해보면서 하는 게 좋을 듯 하다.)
@Autowired가 잠깐 나오는데, 2권에서 자세하게 설명한다고 되어 있다.
- Autowired 가 붙은 인스턴스 변수가 있으면, 테스트 컨텍스트 프레임워크는 변수 타입과 일치하는 컨텍스트 내의 빈을 찾는다.
타입이 일치하는 빈이 있으면 인스턴스 변수에 주입해준다.
학습테스트(learning test)란?
자신이 만들지 않은 프레임워크나 다른 개발팀에서 만들어서 제공한 라이브러리 등에 대해서는 테스트를 작성해야한다.
-목적: 자신이 사용할 API나 프레임워크의 기능을 테스트로 보면서 사용 방법을 익히려는 것
-장점
1. 다양한 조건에 따른 기능을 손십게 확인 가능
2. 학습 테스트 코드를 개발 중에 참고할 수 있음.
3. 프레임워크나 제품을 업그레이드할 때 호환성 검증을 도와줌.
4. 테스트 작성에 대한 좋은 훈련이 됨.
5. 새로운 기술을 공부하는 과정이 즐거워짐.
버그테스트(bug test)란?
코드에 오류가 있을 때 그 오류를 가장 잘 드러내줄 수 있는 테스트
(일단 실패하도록 만들어야함. 그 후 성공할 수 있도록 애플리케이션 코드를 수정함.)
필요성과 장점
1. 테스트의 완성도를 높여줌
2. 버그의 내용을 명확하게 분석하게 해줌
3. 기술적인 문제를 해결하는 데 도움이 됨
동등분할: 같은 결과를 내는 값의 범위를 구분해서 각 대표값으로 테스트 하는 방법
경계값 분석: 에러는 동등분할 범위의 경계에서 주로 많이 발생한다는 특징을 이용해서 경계의 근처에 있는 값을 이용해 테스트하는 방법.
2. 테스트
2.1 UserDaoTest 다시보기
웹을 통한 DAO테스트 방법의 문제점
작은 단위의 테스트
자동수행 테스트 코드
지속적인 개선과 점직적인 개발을 위한 테스트
책에서 소개한 UserDaoTest의 문제점을 서술하고 있다.
책에서 소개한 UserDaoTest의 문제점을 서술하고 있다.
2.2 UserDaoTest 개선
테스트 검증의 자동화
테스트의 효율적인 수행과 결과 관리
JUnit 테스트로 전환
테스트 메소드 전환
테스트 메소드 전환
검증 코드 전환
2.3 개발자를 위한 테스팅 프레임워크 JUnit
테스트 결과의 일관성
테스트 주도 개발(Test Driven Development, TDD)
JUnit이 하나의 테스트 클래스를 가져와 테스트를 수행하는 방식
픽스처
2.4 스프링 테스트 적용
테스트를 위한 애플리케이샨 컨텍스트 관리
@Autowired
침투적 기술과 비침투적 기술
침투적 기술과 비침투적 기술
2.5 학습 테스트로 배우는 스프링
2.5 학습 테스트로 배우는 스프링
학습테스트의 장점
학습테스트의 장점
버그테스트
버그테스트
2017년 11월 5일 일요일
Node.js 공부[6]
6챕터-데이터베이스 사용하기
웹 서버가 사용자 요청을 받으면 데이터베이스에 있는 데이터를 조회하여 응답하거나 또는 사용자가 보낸 데이터를 데이터베이스에 저장한다. 데이터베이스 유형은 데이터를 메모리에 저장하는 형태부터 오라클이나 MySQL 같은 관계형 데이터베이스, 몽고디비와 같은 NoSQL에 이르기까지 다양하다. 특히 몽고디비는 자비스크립트 객체를 그대로 저장할 수 있어서 자바스크립트 언어를 사용하는 노드에서 데이터를 저장하기 좋은 데이터베이스이다. 책에선 몽고디비로 데이터를 저장하고 조회하는 방법을 소개하고 있다.
몽고디비 시작하기
실무에서는 오라클이나 MySQL과 같은 관계형 데이터베이스를 많이 사용한다. 그러나 최근 비관계형 데이터베이스를 적용하는 곳이 늘고 이쓰며, 이런 시스템을 NoSQL 또는 Not Only SQL 이라고 한다.
관계형 데이터베이스는 시스템의 신뢰도를 높이는데 필요한 장치를 많이 가지고 있다. 또 SQL문을 읽어 들이고 실행하는 데 많은 리소스를 사용하며 이 떄문에 성능이 떨어지는 경우가 많다. 이에 반해 NoSQL 데이터베이스는 성능을 최우선으로 생각하기 때문에 실시간으로 처리해야 하는 경우나 대용량 트래픽을 감당할 수 있는 메시징 시스템 등에 활용된다. 특히 클라우드 서비스로 서버를 구성하는 경우가 많아지면서 많은 사용자를 수용하거나 시스템 자원을 적게 소모하는 NoSQL 데이터베이스에 점점 더 관심을 갖게 되었다고 한다.
몽고디비는 NoSQL이기 때문에 관계형데이터베이스의 테이블의 개념이 없다. 그 대신 몽고디비는 여러 데이터가 모인 하나의 단위를 컬렉션(Collection)이라고 부른다. 테이블과 달리 데이터를 정해 놓은 칼럼의 형태대로 컬렉션에 넣어야 한다는 제약이 없다.
설치 후 시스템 환경 변수 추가를 한다.
익스프레스에서 몽고디비 사용하기
앞서 사용한 코드들을 이용하여 Databaseexample 폴더에 app.js 파일을 생성한다.
폴더에 npm init 을 통해 package.json 파일을 생성한 후 필요한 모듈들을 설치한다.
(npm install express --save 등등)
package.json
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
{
"name": "package",
"version": "1.0.0",
"description": "",
"main": "app.js",
"dependencies": {
"body-parser": "^1.18.2",
"cookie-parser": "^1.4.3",
"errorhandler": "^1.5.0",
"express": "^4.16.2",
"express-error-handler": "^1.1.0",
"express-session": "^1.15.6",
"http": "0.0.0",
"mongodb": "^2.2.33",
"path": "^0.12.7",
"serve-static": "^1.13.1"
},
"devDependencies": {},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC"
}
| cs |
이 파일의 dependencies 정보는 새로운 프로젝트를 생성할때 그대로 사용 가능하다. 새 프로젝트를 만들었을때 이 파일과함께 npm install 명령을 해주면 이 정보대로 설치가 된다.
<mongodb를 이용한 간단한 아이디 체크,추가>
login.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>로그인 테스트</title>
</head>
<body>
<h1>로그인</h1>
<br>
<form method="POST" action="/process/login">
<table>
<tr>
<td><label>아이디</label></td>
<td><input type="text" name="id"></td>
</tr>
<tr>
<td><label>비밀번호</label></td>
<td><input type="password" name="password"></td>
</tr>
</table>
<input type="submit" value="전송" />
</form>
</body>
</html>
| cs |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>사용자추가 테스트</title>
</head>
<body>
<h1>사용자추가</h1>
<br>
<form method="post" action="/process/adduser">
<table>
<tr>
<td><label>아이디</label></td>
<td><input type="text" name="id" /></td>
</tr>
<tr>
<td><label>비밀번호</label></td>
<td><input type="password" name="password" /></td>
</tr>
<tr>
<td><label>사용자명</label></td>
<td><input type="text" name="name" /></td>
</tr>
</table>
<input type="submit" value="전송" name="" />
</form>
</body>
</html>
| cs |
app.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
|
/**
* 데이터베이스 사용하기
*
* 몽고디비에 사용자 추가하기
* 웹브라우저에서 아래 주소의 페이지를 열고 웹페이지에서 요청
* http://localhost:3000/public/adduser.html
*
* @date 2016-11-10
* @author Mike
*/
// Express 기본 모듈 불러오기
var express = require('express')
, http = require('http')
, path = require('path');
// Express의 미들웨어 불러오기
var bodyParser = require('body-parser')
, cookieParser = require('cookie-parser')
, static = require('serve-static')
, errorHandler = require('errorhandler');
// 에러 핸들러 모듈 사용
var expressErrorHandler = require('express-error-handler');
// Session 미들웨어 불러오기
var expressSession = require('express-session');
// 몽고디비 모듈 사용
var MongoClient = require('mongodb').MongoClient;
// 익스프레스 객체 생성
var app = express();
// 기본 속성 설정
app.set('port', process.env.PORT || 3000);
// body-parser를 이용해 application/x-www-form-urlencoded 파싱
app.use(bodyParser.urlencoded({ extended: false }))
// body-parser를 이용해 application/json 파싱
app.use(bodyParser.json())
// public 폴더를 static으로 오픈
app.use('/public', static(path.join(__dirname, 'public')));
// cookie-parser 설정
app.use(cookieParser());
// 세션 설정
app.use(expressSession({
secret:'my key',
resave:true,
saveUninitialized:true
}));
//===== 데이터베이스 연결 =====//
// 데이터베이스 객체를 위한 변수 선언
var database;
//데이터베이스에 연결
function connectDB() {
// 데이터베이스 연결 정보
var databaseUrl = 'mongodb://localhost:27017/local';
// 데이터베이스 연결
MongoClient.connect(databaseUrl, function(err, db) {
if (err) throw err;
console.log('데이터베이스에 연결되었습니다. : ' + databaseUrl);
// database 변수에 할당
database = db;
});
}
//===== 라우팅 함수 등록 =====//
// 라우터 객체 참조
var router = express.Router();
// 로그인 라우팅 함수 - 데이터베이스의 정보와 비교
router.route('/process/login').post(function(req, res) {
console.log('/process/login 호출됨.');
// 요청 파라미터 확인
var paramId = req.body.id || req.query.id;
var paramPassword = req.body.password || req.query.password;
console.log('요청 파라미터 : ' + paramId + ', ' + paramPassword);
// 데이터베이스 객체가 초기화된 경우, authUser 함수 호출하여 사용자 인증
if (database) {
authUser(database, paramId, paramPassword, function(err, docs) {
if (err) {throw err;}
// 조회된 레코드가 있으면 성공 응답 전송
if (docs) {
console.dir(docs);
// 조회 결과에서 사용자 이름 확인
var username = docs[0].name;
res.writeHead('200', {'Content-Type':'text/html;charset=utf8'});
res.write('<h1>로그인 성공</h1>');
res.write('<div><p>사용자 아이디 : ' + paramId + '</p></div>');
res.write('<div><p>사용자 이름 : ' + username + '</p></div>');
res.write("<br><br><a href='/public/login.html'>다시 로그인하기</a>");
res.end();
} else { // 조회된 레코드가 없는 경우 실패 응답 전송
res.writeHead('200', {'Content-Type':'text/html;charset=utf8'});
res.write('<h1>로그인 실패</h1>');
res.write('<div><p>아이디와 패스워드를 다시 확인하십시오.</p></div>');
res.write("<br><br><a href='/public/login.html'>다시 로그인하기</a>");
res.end();
}
});
} else { // 데이터베이스 객체가 초기화되지 않은 경우 실패 응답 전송
res.writeHead('200', {'Content-Type':'text/html;charset=utf8'});
res.write('<h2>데이터베이스 연결 실패</h2>');
res.write('<div><p>데이터베이스에 연결하지 못했습니다.</p></div>');
res.end();
}
});
// 사용자 추가 라우팅 함수 - 클라이언트에서 보내오는 데이터를 이용해 데이터베이스에 추가
router.route('/process/adduser').post(function(req, res) {
console.log('/process/adduser 호출됨.');
var paramId = req.body.id || req.query.id;
var paramPassword = req.body.password || req.query.password;
var paramName = req.body.name || req.query.name;
console.log('요청 파라미터 : ' + paramId + ', ' + paramPassword + ', ' + paramName);
// 데이터베이스 객체가 초기화된 경우, addUser 함수 호출하여 사용자 추가
if (database) {
addUser(database, paramId, paramPassword, paramName, function(err, result) {
if (err) {throw err;}
// 결과 객체 확인하여 추가된 데이터 있으면 성공 응답 전송
if (result && result.insertedCount > 0) {
console.dir(result);
res.writeHead('200', {'Content-Type':'text/html;charset=utf8'});
res.write('<h2>사용자 추가 성공</h2>');
res.end();
} else { // 결과 객체가 없으면 실패 응답 전송
res.writeHead('200', {'Content-Type':'text/html;charset=utf8'});
res.write('<h2>사용자 추가 실패</h2>');
res.end();
}
});
} else { // 데이터베이스 객체가 초기화되지 않은 경우 실패 응답 전송
res.writeHead('200', {'Content-Type':'text/html;charset=utf8'});
res.write('<h2>데이터베이스 연결 실패</h2>');
res.end();
}
});
// 라우터 객체 등록
app.use('/', router);
// 사용자를 인증하는 함수
var authUser = function(database, id, password, callback) {
console.log('authUser 호출됨 : ' + id + ', ' + password);
// users 컬렉션 참조
var users = database.collection('users');
// 아이디와 비밀번호를 이용해 검색
users.find({"id":id, "password":password}).toArray(function(err, docs) {
if (err) { // 에러 발생 시 콜백 함수를 호출하면서 에러 객체 전달
callback(err, null);
return;
}
if (docs.length > 0) { // 조회한 레코드가 있는 경우 콜백 함수를 호출하면서 조회 결과 전달
console.log('아이디 [%s], 패스워드 [%s] 가 일치하는 사용자 찾음.', id, password);
callback(null, docs);
} else { // 조회한 레코드가 없는 경우 콜백 함수를 호출하면서 null, null 전달
console.log("일치하는 사용자를 찾지 못함.");
callback(null, null);
}
});
}
//사용자를 추가하는 함수
var addUser = function(database, id, password, name, callback) {
console.log('addUser 호출됨 : ' + id + ', ' + password + ', ' + name);
// users 컬렉션 참조
var users = database.collection('users');
// id, password, username을 이용해 사용자 추가
users.insertMany([{"id":id, "password":password, "name":name}], function(err, result) {
if (err) { // 에러 발생 시 콜백 함수를 호출하면서 에러 객체 전달
callback(err, null);
return;
}
// 에러 아닌 경우, 콜백 함수를 호출하면서 결과 객체 전달
if (result.insertedCount > 0) {
console.log("사용자 레코드 추가됨 : " + result.insertedCount);
} else {
console.log("추가된 레코드가 없음.");
}
callback(null, result);
});
}
// 404 에러 페이지 처리
var errorHandler = expressErrorHandler({
static: {
'404': './public/404.html'
}
});
app.use( expressErrorHandler.httpError(404) );
app.use( errorHandler );
//===== 서버 시작 =====//
// 프로세스 종료 시에 데이터베이스 연결 해제
process.on('SIGTERM', function () {
console.log("프로세스가 종료됩니다.");
app.close();
});
app.on('close', function () {
console.log("Express 서버 객체가 종료됩니다.");
if (database) {
database.close();
}
});
// Express 서버 시작
http.createServer(app).listen(app.get('port'), function(){
console.log('서버가 시작되었습니다. 포트 : ' + app.get('port'));
// 데이터베이스 연결을 위한 함수 호출
connectDB();
});
| cs |
예제를 홈페이지에서 받았는데 책과 다르다 ;;;; 위는 완성된 예제
피드 구독하기:
글 (Atom)
-
포폴로 제출한 홈페이지를 잠깐 들어가봤는데 내가 설정하지 않은 alert창이 떠서 당황하였다. 인사담당자님께서 테스트하신 것같았는데 글 제목들은 공백이었고 내가 입력한적이 없는 alert창이 자꾸 발생하였다. 어디서 자꾸 발생하나 개발자도구로...
-
로그란? (log) 애플리케이션의 상태를 관찰할 수 있도록 애플리케이션이 제공하는 정보 log4j, logback, log4j2 셋 다 java 로깅 유틸리티이다. 스프링프레임워크에서는 예전에는 commons.logging을 기...
-
김영한님의 JPA 프로그래밍 기본기 강의 회사에 입사한 지 얼마 안됬을 때 사수가 ORM에 대해 한번 훑어보라며, 책을 추천해준 적이 있었다. 그 때는 정신도 없어서 나중에 봐야겠다... 라고만 생각했는데, 인프런 인강과 다른 블로그에 있는 스...