React Native 푸시 설정

 

 

1. 프로젝트 생성

1.1 프로젝트 생성

react-native init ElcantoDeepp –package=com.elcanto.deepp

 

1.2 프로젝트 실행

1) 안드로이드

cd ElcantoDeepp

react-native run-android

 

2) IOS

cd ElcantoDeepp

react-native run-ios

 

1.3 Vscode에서 프로젝트 열기

 

파일 > 열기.. 선택후 해당 디렉토리인 ElcantoDeepp폴더를 선택

 

 

1.4 Webview 컨트롤 추가

Vscode의 터미널에서 아래 명령으로 webview 컨트롤을 추가한다.

npm install –save react-native-webview

2. 관련 API 설정

2.1 파이어베이스

가. 파이어베이스 로그인

https://console.firebase.google.com/

나. 프로젝트 생성

프로젝트명 : DEEPP

 

다. Android 앱 추가

1) 아래 아이콘에서 안드로이드 아이콘 클릭

2) 앱등록

3) 설정파일 다운로드

google-service.json파일 다운로드하여 React-Native 프로젝트의 android/app밑에 추가한다.

 

4) 프로젝트에 설정파일 추가

5) 안드로이드앱에 파이어베이스 설정 추가

Vscode를 열어 React Native 프로젝트에서 다음과 같이 추가한다.

– android/build.gradle 수정

classpath ‘com.google.gms:google-services:4.3.8’ 추가

 

–   android/app/build.gradle 파일 수정

apply plugin: ‘com.google.gms.google-services’ 추가

 

Dependencies에 implementation”com.google.firebase:firebase-core:19.0.0″ 추가

 

라. IOS앱 추가

1) iOS 아이콘을 클릭하여 앱 추가

 

2) 앱등록

IOS 번들 ID : kr.co.deepp.app으로 등록

위 화면에서 IOS번들
ID는Xcode로 프로젝트를 열었을 때 나오는 Bundle Identifier와 동일해야 한다.

3) 설정파일 다운로드

 

4) 프로젝트에 설정파일 추가

ElcantoDeep/ios/ElcantoDeepp에 GoogleService-info.plist 파일복사

 

XCode의 info.plist와 동일한 위치로 GoogleService-info.plist 드래그앤드랍으로 끌어서 추가한다.

 

 

5) Podfile 수정

ElcantoDeep/ios/Podfile을 열어 “pod ‘Firebase/Analytics’” 추가

 

6) POD로 종속파일 설치

pod install

 

간혹 에러가 나는경우가 있는데 Podfile.lock 파일과 Pods 폴더를 지우고 다시 하면 된다.

 

7) AppDelegate.m 파일에 Firebase설정 추가

 

–   헤더추가

#import<Firebase.h>

 

–   Filebase 설정추가

[FIRApp configure]

 

2.2 APN(Apple Push Notificatation) 구성 및 파이어베이스연동

IOS는 푸시를 보내기 위해서는 파이어베이스에서 APN을 연동해야 한다. 따라서 다음과 같은 절차에 의해 APN을 구성한다.

가. 인증서 발급

1) Launchpad > 기타 선택

2) 키체인 접근 클릭

 

3) 인증기관에서 인증서 요청

“키체인 접근 >인증서 지원 > 인증 기관에서 인증서 요청…” 클릭

4) 인증서 생성

–   “디스크에 저장됨”을 선택

–   “본인이 키 쌍 정보 지정”을 체크


–   계속을 눌러 인증서를 저장할 폴더를 지정하고 인증서 생성

 

나. 인증서 생성

1) 애플 개발자 사이트(https://developer.apple.com )로그인

 

2) Certificates, IDs & Profiles 메뉴 선택

 

3) Keys 메뉴 클릭하여 키 등록화면으로 이동

Keys + 버튼을 클릭하여 키 등록

 

–   Key Name : Elcanto Deepp Push Notification Key

–   Apple Push Notification service(APNs) 체크

4) 키 등록

“Register”버튼을 이용하여 키 등록

5) 키파일 다운로드

키파일은 나중에 파이어베이스에서 푸시를 보낼 때
사용되므로 안전한 장소에 보관해놓는것이 좋다.또한 아래 Key ID도
파이어베이스에서 등록할 때 입력해야하므로 기록기 놓는 것이 좋다.

 

키파일은 아래 경고처럼 두 번 다시 다운로드를 받을 수 없으므로 잘 보관해야함.

 

다. 앱ID 등록

1) Identifiers 메뉴에서 + 버튼을 클릭

2) App IDs 선택

3) App를 선택

4) App ID 등록

–   Description : Elcanto Deepp

–   Bundle ID : kr.co.deepp.app (참고: kr.co.deep로 할려고 하였으나, App ID로 활용할수 없다고 나와 kr.co.deepp.app로 함)

–   Push Notifications을 체크

 

 

5) 등록처리

Register버튼 클릭

 

6) Push Notifications 설정

위에서 등록한 App
ID를 클릭하여 들어가면 아래와 같이 Push Notifications 에 “Configure” 버튼이 활성화 되어 있는 것을 볼수 있다. 버튼을 클릭하면 인증서를
등록할수 있는 팝업이 나타난다.

7) 인증서 등록

아래 화면에서 Development
SSL Certificate(개발용)과 , Production
SSL Certificate(프러덕션용) 둘다 인증서를 등록하면 된다.

 

방법은 둘다 동일하게 아래처럼 진행하면 된다.

–   “Create Certificate” 버튼을 클릭

Choose File에 위에서 등록한 인증서 파일 인

CertificateSigningRequest.certSigningRequest 파일을 선택하여 등록

–   다시
App ID 등록화면의 Configure 버튼을 클릭하여 동일하게 인증서 등록을 진행하면 된다.

–   최종적으로
아래 화면처럼 Certificates(2)가 되도록 한다.

 

 

라. 파이어베이스 연동

위에서 설정한 파이어베이스를 IOS와 연동한다.

1) iOS 아이콘 클릭

2) 프로젝트 설정 > 클라우드 메시징 화면으로 이동

 

3) APN 인증키 업로드

애플개발자 사이트에서 등록한 .p8 형식의 APN 키 파일 및 키 ID를 등록한다.

키 ID는
아래와 같이 Keys 항목에서 찾으면 되고, TeamID는 Membership메뉴를 클릭하면 확인할수 있다.

업로드중 아래와 같이 “이 앱에 저장된 팀가 없습니다.”라고 나오는경우에는 한번더 업로드 버튼을 클릭하면
등록된다.

업로드가 되면 아래와 같이 나타난다.

 

마. XCode 설정

Capabilities 설정

1) Signing & Capabilities 클릭

2) “+ Capability
” 클릭

3) Push Notifications를 선택하여 추가

 

4) Background Modes 를 선택하여 추가

5) Background Modes에서 Remote notifications 를
체크

 

 

 

3.  React Native 설정

3.1 WebView

 

3.2 푸시

가. 라이브러리 설치

npm install –save @react-native-firebase/app

npm install –save @react-native-firebase/messaging

npm install –save react-native-push-notification

npm install –save @react-native-community/push-notification-ios

 

나. 푸시관련 코딩

내용이 많아 생략, 소스를 참조

 

다. 테스트 메시지 전송

파이어베이스 콘솔에서  참여 > Cloud Messaging을 클릭한후 “Send your first message” 버튼을 클릭

  제목과
내용을 입력한후 “테스트 메시지 전송” 버튼을 클릭

React Native에서 Fcm 서비스를 등록하면 token이 리턴되는데 콘솔에 찍어있는 토큰을 복사하여 등록

 

 

  React Native 콘솔에 찍힌 수신된 메시지

 

MSA구성매뉴얼

1.    문서 개요

 

1.1       문서의 목적

본 문서는 MSA 기반의 API 샘플 서버, 게이트웨이 서버, 유레카 서버 등에 대한 구축 관련 절차에 대하여 기술하고 있다.

1.2       시스템 구성도

본 프로젝트에서 구현되고자 하는 시스템 구성도이다.

 

 

2.    관련 어플리케이션 설치

2.1       JDK 설치

JDK 1.8이상으로 본 문서에서는 64비트용 JDK15를 기준으로 한다.

2.2       Eclipse 설치

2.2.1        이클립스 설치

– https://www.eclipse.org/downloads/packages/ 에서 64 비트용 Eclipse IDE for Enterprise Java Developers 을 선택

 

2.2.2        Spring Boot STS(Spring Tool Suite) 설치

Help > Eclipse Marketplace 를 선택한후에 STS 를 입력하여 검색한후에, Spring Tools 4 (aka Spring Tool Suite 4) 를 선택하여 설치한다.

2.2.3        롬복(Lombok) 설치

Getter와 Setter를 자동으로 생성해주는 라이브러리로 Visual Studio Code에서는 별다른 설치 없어 개발 IDE의 인텔리전트가 잘 나왔지만, 이클립스는 별도로 설치해주어야 동작한다.

  • 탐색기로 해당 계정의 maven repository에 들어가서 버전을 확인

C:\Users\계정\.m2\repository\org\projectlombok\lombok\버전

 

  • 롬복 설치 관리자 실행

아래 명령을 통해 실행

Java -jar lombok-버전.jar

  • 이클립스 위치지정

“Specify location…” 버튼을 클릭하여 이클립스가 설치되어 있는 위치 지정하고

“Install/Update” 버튼을 클릭하여 설치완료

 

 

 

2.3       Postman 설치

API 서버를 호출하여 결과를 확인하기가 용이하므로 테스트할 때 많이 사용되는 툴이다.

https://www.postman.com/downloads/ 에서 64비트용을 다운받아 설치한다.

설치 후 Signin을 클릭하여 로그인하면 되고, 계정이 없으면 가입하면 된다.

 

사용방법은 탭 옆에 “+” 버튼을 클릭하여 새로운 Request를 생성하여 실행하면 된다.

 

일례로 Method를 GET으로 하고, url을 입력하고 Send 버튼을 클릭하면 하단에 결과가 출력된다.

 

 

3.    메이븐(Maven) 기반의 Spring Boot 프로젝트 생성

이클립스를 띄워 아래와 같이 워크스페이스를 만든다.

  • D:\Projects\45.ValfacSolutions\02.Solutions\MsaSolution

3.1       최상단 부모 프로젝트 생성

  • File > New > Other 를 클릭한후 Spring Boot를 선택한후 Spring Starter Project를 선택

 

  • 프로젝트 정보 입력

본 샘플에서는 store라는 이름으로 프로젝트를 구성하였다.

– Name : store

– Group :store

– Artifact : store

– Description : Store Project

– Package : store

 

  • 스프링 부트 버전 및 프로젝트 종속성 입력

아래와 같이 Spring Boot Version을 현재 최신인 2.3.4를 선택하고, 3가지 종속성을 체크하여 추가한후에 “Finish” 버튼을 클릭하여 프로젝트를 생성한다.

– Developer Tools > Spring Boot DevTools

– Developer Tools > Lombok

– Web > Spring Web

 

  • xml 파일 수정

아래와 같이 <packaging>pom</packaging>를 추가한다.

 

3.2       하위 자식 모듈 생성

최상단 부모 메이븐 프로젝트 밑에 딸린 자식 모듈은 다음과 같다.

 

명칭 모듈명 포트 비고
유레카 서버 store-eureka-server 8761
게이트웨이서버 store-gateway-server 5001
회사 API(샘플) store-corp-api 5002
사용자 API(샘플) store-user-api 5003
백엔드 웹 store-backend-web 8080 Feign Client 포함

 

3.2.1        게이트웨이 서버

아래와 같이 Maven Module을 생성한다.

  • File > New > Other에서 Maven > Maven Module을 선택하고 “Next” 버튼 클릭

 

 

  • 모듈명 입력

“create a simple project” 를 체크 하고, Module Name에 “store-gateway-server”를 입력하고 “Next” 버튼을 클릭한다.

  • 기타 모듈정보를 입력하고 “Finish” 버튼 클릭

– Group Id : store.gateway.server

– Version : 0.0.1-SNAPSHOT

– Packaging: jar

– Name : Store Gateway Server

– Description : Store Gateway Server Project

  • 최상단 부모 프로젝트의 xml 파일 확인 및 수정

– 위에서 생성한 store-gateway-server 메이븐 모듈이 자동적으로 추가된 것을 확인할 수 있다.

– 또한 넷플릭스의 Zuul을 사용하기 위해 부모 pom.xml에도 종속성을 추가해야 한다.

 

(중         략)

 

<modules>

<module>store-gateway-server</module>

</modules>

 

<repositories>

<repository>

<id>spring-snapshots</id>

<name>Spring Snapshots</name>

<url>https://repo.spring.io/snapshot</url>

<snapshots>

<enabled>true</enabled>

</snapshots>

</repository>

<repository>

<id>spring-milestones</id>

<name>Spring Milestones</name>

<url>https://repo.spring.io/milestone</url>

<snapshots>

<enabled>false</enabled>

</snapshots>

</repository>

</repositories>

 

<properties>

<java.version>11</java.version>

       <spring-cloud.version>Hoxton.SR5</spring-cloud.version>

</properties>

 

<dependencies>

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-web</artifactId>

</dependency>

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-devtools</artifactId>

<scope>runtime</scope>

<optional>true</optional>

</dependency>

<dependency>

<groupId>org.projectlombok</groupId>

<artifactId>lombok</artifactId>

<optional>true</optional>

</dependency>

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-test</artifactId>

<scope>test</scope>

<exclusions>

<exclusion>

<groupId>org.junit.vintage</groupId>

<artifactId>junit-vintage-engine</artifactId>

</exclusion>

</exclusions>

</dependency>

</dependencies>

 

<dependencyManagement>

<dependencies>

<dependency>

<groupId>org.springframework.cloud</groupId>

<artifactId>spring-cloud-dependencies</artifactId>

<version>${spring-cloud.version}</version>

<type>pom</type>

<scope>import</scope>

</dependency>

</dependencies>

</dependencyManagement>

 

<build>

<plugins>

<plugin>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-maven-plugin</artifactId>

</plugin>

</plugins>

</build>

 

 

 

 

  • 해당 자식 모듈(store-gateway-server)의 xml에도 스프링 부트 관련 종속성 명기
<project xmlns=“http://maven.apache.org/POM/4.0.0” xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance” xsi:schemaLocation=“http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd”>

<modelVersion>4.0.0</modelVersion>

<parent>

<groupId>store</groupId>

<artifactId>store</artifactId>

<version>0.0.1-SNAPSHOT</version>

</parent>

 

<groupId>store.gateway.server</groupId>

<artifactId>store-gateway-server</artifactId>

<version>0.0.1-SNAPSHOT</version>

<name>Store Gateway Server</name>

<description>Store Gateway Server Project</description>

 

<dependencies>

<!– 주울(Zuul) –>

<dependency>

<groupId>org.springframework.cloud</groupId>

<artifactId>spring-cloud-starter-netflix-zuul</artifactId>

</dependency>

</dependencies>

</project>

 

  • 패키지 생성

소스를 생성하기위해 먼저 패키지를 만든다.

– 패키지명 : store.gateway.server

  • Application.java 파일생성

– New > Class로 main이 있는 Application 파일생성

  • Application.java 파일수정

Annotation에 @EnableZuulProxy 등을 입력

@EnableZuulProxy

@SpringBootApplication

public class Application

{

public static void main(String[] args)

{

SpringApplication.run(Application.class, args);

}

}

 

  • 환경설정파일 추가

어플리케이션 설정에 필요한 환경설정 파일로 resources 폴더에 application.yml 이라는 이름으로 만들고 아래와 같이 작성한다.

spring:

application:

name: store-gateway-server

 

server:

port: 5001

 

 

# 주울

zuul:

routes:

store-corp-api:

path: /corpsvc/**

url: http://localhost:5002

stripPrefix: true

 

store-user-api:

path: /usersvc/**

url: http://localhost:5003

stripPrefix: true

 

 

Zuul 설정은 게이트웨이를 통해 다음절에서 다오는 회사API와 사용자API에게 라우팅해주는 기능이다.

가령 http://localhost:5001/corpsvc/api/corp/findAll  과 같이 게이트웨이(5001포트)를 통해 패스가 /corpsvc/** 형태로 들어오는 경우는 URL을

http://localhost:5002/api/corp/findAll 로 요청하여 반환하게 된다.

 

  • 실행

위에서 작성한 소스를 실행하려면 Run AS > Spring Boot App 를 선택하여 실행하면 된다.

 

 

3.2.2        회사 API(샘플)

아래와 같이 Maven Module을 생성한다.

  • File > New > Other에서 Maven > Maven Module을 선택하고 “Next” 버튼 클릭

  • 모듈명 입력

“create a simple project” 를 체크 하고, Module Name에 “store-corp-api”를 입력하고 “Next” 버튼을 클릭한다.

 

  • 기타 모듈정보를 입력하고 “Finish” 버튼 클릭

– Group Id : store.corp.api

– Version : 0.0.1-SNAPSHOT

– Packaging: jar

– Name : Store Corp API

– Description : Store Corp API Project

  • 패키지 생성

소스를 생성하기위해 먼저 패키지를 만든다.

– 패키지명 : store.corp.api

  • Applicaiton.java 파일생성

– New > Class로 main이 있는 Application 파일생성

 

  • Applicaiton.java 파일수정
@SpringBootApplication

@EnableAutoConfiguration

public class Application

{

public static void main(String[] args)

{

SpringApplication.run(Application.class, args);

}

}

 

 

 

 

  • 환경설정파일 추가

어플리케이션 설정에 필요한 환경설정 파일로 resources 폴더에 application.yml 이라는 이름으로 만들고 아래와 같이 작성한다.

spring:

application:

name: store-corp-api

 

server:

port: 5002

 

 

 

 

  • 컨트롤러 패키지 작성

– store.corp.api.controllers

  • 컨트롤러 작성 : CorpController.java

  • 실행

위에서 작성한 소스를 실행하려면 Run AS > Spring Boot App 를 선택하여 실행하면 된다.

 

 

3.2.3        사용자 API(샘플)

회사 API[샘플]과 동일하게 Maven Module을 생성한다.

  • 모듈명 : store- user -api

 

  • 모듈정보

– Group Id : store.user.api

– Version : 0.0.1-SNAPSHOT

– Packaging: jar

– Name : Store User API

– Description : Store User API Project

 

  • 패키지 생성

– 패키지명 : store.user.api

 

  • java 파일생성 및 수정
@SpringBootApplication

@EnableAutoConfiguration

public class Application

{

public static void main(String[] args)

{

SpringApplication.run(Application.class, args);

}

}

 

  • 환경설정파일 추가

– resources\application.yml

spring:

application:

name: store-user-api

 

server:

port: 5003

 

 

 

  • 컨트롤러 패키지 작성

– store.user.api.controllers

 

  • 컨트롤러 작성 : UserController.java

 

  • 실행

위에서 작성한 소스를 실행하려면 Run AS > Spring Boot App 를 선택하여 실행하면 된다.

3.2.4        유레카 서버

유레카는 MSA를 동적 등록 및 탐색, 부하분산처리 기능을 한다.

유레카는 위와 동일하게 Maven Module로 생성한다.

  • File > New > Other에서 Maven > Maven Module을 선택하고 “Next” 버튼 클릭

 

  • 모듈명 입력

“create a simple project” 를 체크 하고, Module Name에 “store-eureka-server”를 입력하고 “Next” 버튼을 클릭한다.

  • 기타 모듈정보를 입력하고 “Finish” 버튼 클릭

– Group Id : store.eureka.server

– Version : 0.0.1-SNAPSHOT

– Packaging: jar

– Name : Store Eureka Server

– Description : Store Eureka Server Project

  • xml 파일 확인 및 수정
<dependency>

<groupId>org.springframework.cloud</groupId>

<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>

</dependency>

 

  • 패키지 생성

소스를 생성하기위해 먼저 패키지를 만든다.

– 패키지명 : store.eureka.server

 

  • Application.java 파일생성

– New > Class로 main이 있는 Application 파일생성

 

  • Application.java 파일수정

유레카 서버로 사용할 수 있게, @EnableEurekaServer Annotation을 입력

 

@EnableEurekaServer

@SpringBootApplication

public class Application

{

public static void main(String[] args)

{

SpringApplication.run(Application.class, args);

}

}

 

 

 

 

 

  • 환경설정파일 추가

어플리케이션 설정에 필요한 환경설정 파일로 resources 폴더에 application.yml 이라는 이름으로 만들고 아래와 같이 작성한다.

spring:

application:

name: store-eureka-server

 

server:

port: 8761

 

eureka:

client:

register-with-eureka: false

fetch-registry: false

 

 

  • 실행 및 유레카 서버 접속

위에서 작성한 소스를 실행하려면 Run AS > Spring Boot App 를 선택하여 실행하면 된다.

그후에 웹 브라우져에서  http://localhost:8761/ 로 접속하면 유레카에서 제공하는 페이지를 볼수 있다.

 

 

  • MSA 클라이언트 등록

위 화면에서는 등록된 MSA 클라이언트의 정보를 볼 수 있는데 현재 등록된 MSA 클라이언트가 없으므로 아래와 같이 등록 해야 한다.

 

– 각 MSA클라이언트별 종속성 추가

store-gateway-server, store-corp-api, store-user-api 모듈을 유레카 클라이언트로

설정한다. 따라서 각 모듈에 종속성을 추가한다.

<dependency>

<groupId>org.springframework.cloud</groupId>

<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>

</dependency>

 

– 각 모듈의 Application.java 에 @EnableDiscoveryClient 아노테이션을 추가

 

@EnableDiscoveryClient

@SpringBootApplication

public class Application

{

public static void main(String[] args)

{

SpringApplication.run(Application.class, args);

}

}

 

– 각 모듈의 application.yml에 유레카 설정 추가

spring:

application:

name: store-gateway-server

 

server:

port: 5001

 

 

eureka:

client:

serviceUrl:

defaultZone: http://localhost:8761/eureka

 

– 각 모듈을 RUN시키고 유레카 콘솔(http://localhost:8761/)을 릴로드 해보면 다음과 같이 등록된 MSA 클라이언트를 확인할수 있다.

  • 게이트웨이 설정

유레카를 이용 할 때 는 이전에 게이트웨이서버의 환경설정을 아래처럼 수정되어야 한다.

이전에는 URL로 호출되었지만, 유레카 이용시에는 serviceId로 처리하면 된다.

# 주울

zuul:

routes:

store-corp-api:

path: /corpsvc/**

serviceId: store-corp-api

#url: http://localhost:5002

stripPrefix: true

 

store-user-api:

path: /usersvc/**

serviceId: store-user-api

#url: http://localhost:5003

stripPrefix: true

 

 

참고로 위의 serviceId는 반드시 아래처럼 각서버의 application.yml에 정의된

이름(spring.application.name) 이어야 한다.

spring:

application:

name: store-user-api

 

 

3.2.5        백엔드 웹(Backend Web)

백엔드 웹에서는 JSP상에서 ajax를 이용하여 MSA로 접근하여 데이터를 가져오는 방법,  Feign 클라이언트를 이용하여 데이터를 가져오는 방법에 대하여 구현하였다.

 

  • Module로 모듈생성

– 모듈명 : store-backend-web

– Group Id : store.backend.web

– Version : 0.0.1-SNAPSHOT

– Packaging: jar

– Name : Store Backend Web

– Description : Store Backend  Project

 

  • xml 파일 추가

– 톰캣관련 라이브러리(Jasper)

– JSTL 라이브러리

– Feign 클라이언트

– 유레카 클라이언트

– Graceful Shutdown 라이브러리 : 셧다운시 안전하게 종료하기 위해서 사용

– 모델 매퍼

 

<!– 톰캣파서(Jasper) –>

<dependency>

<groupId>org.apache.tomcat.embed</groupId>

<artifactId>tomcat-embed-jasper</artifactId>

</dependency>

 

<!– JSTL 라이브러리 –>

<dependency>

<groupId>javax.servlet</groupId>

<artifactId>jstl</artifactId>

</dependency>

 

<!– Feign 클라이언트 –>

<dependency>

<groupId>org.springframework.cloud</groupId>

<artifactId>spring-cloud-starter-openfeign</artifactId>

</dependency>

 

<!– 유레카 클라이언트 –>

<dependency>

<groupId>org.springframework.cloud</groupId>

<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>

</dependency>

 

<!– graceful한 종료 처리 –>

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-actuator</artifactId>

</dependency>

 

<!– 모델 매퍼 –>

<dependency>

<groupId>org.modelmapper</groupId>

<artifactId>modelmapper</artifactId>

<version>${modelmapper.version}</version>

</dependency>

 

 

 

 

  • 패키지 생성 및 java 파일생성

– 패키지명 : store.backend.web

– Application.java : 해당 모듈이 유레카 클라이언트이므로, @EnableDiscoveryClient 아노테이션과, FeignClient를 사용하기 위한 @EnableFeignClients을 입력한다.

 

@EnableDiscoveryClient

@EnableFeignClients

@SpringBootApplication

public class Application

{

public static void main(String[] args)

{

SpringApplication.run(Application.class, args);

}

}

 

 

  • 환경설정파일(resouces/application.yml) 추가

– jsp파일의 위치 및 확장자 등에 대한 설정

– 실행중인 쓰레드가 있는경우 처리 후 종료할 수 있도록 하기 위한 우아한 종료처리에 대한 설정

# 스프링 어플리케이션 명(유레카에서 사용됨)

spring:

application:

name: store-backend-web

 

# 스프링 JSP 설정

mvc:

view:

prefix: /WEB-INF/jsp/

suffix: .jsp

 

# 어플리케이션 포트

server:

port: 8080

 

# 유레카 설정

eureka:

client:

serviceUrl:

defaultZone: http://localhost:8761/eureka

 

# 우아한 종료 처리

management:

endpoints:

shutdown:

enabled: true

sensitive: false

web:

exposure:

include: “*”

 

 

  • 교차 출처 리소스 공유(Cross-Origin Resource Sharing, CORS) 설정

Ajax 또는 Axios 에서 다른 도메인으로 콜하기 위해 Cors 설정하여 허락을 해주어야한다.

store.backend.web.config 패키지에 WebConfig.java 파일을 생성하고 아래처럼 기술한다.

 

@Configuration

public class WebConfig

{

public void addCorsMappins(CorsRegistry clsCors)

{

clsCors.addMapping(“/**”)

.allowedOrigins(“*”);

}

}

 

 

  • Feign 클라이언트

Feign 클라이언트는 인터페이스와 아노테이션만으로도 API서버로부터 데이터를 보다 더 싶게 수신받기 위한 클라이언트이다.

store.backend.web.corpuser.client 라는 패키지를 만들고 아래와 같이 클라이언트를 만든다.

– CorpClient.java : store-corp-api 서버로부터 데이터를 수신하는 Feign 클라이언트

//@FeignClient(name=”store-corpapi“)

@FeignClient(name=”store-corp-api”, url=”http://localhost:5001″)

public interface CorpClient

{

//@GetMapping(“/api/corp/findAll”)

@GetMapping(“/corpsvc/api/corp/findAll”)

List<CorpMast> findAll();

}

 

 

– UserClient.java : store-user-api 서버로부터 데이터를 수신하는 Feign 클라이언트

//@FeignClient(name=”store-user-api“)

@FeignClient(name=”store-user-api”, url=”http://localhost:5001″)

public interface UserClient

{

//@GetMapping(“/api/user/findAll”)

@GetMapping(“/usersvc/api/user/findAll”)

List<UserMast> findAll();

}

 

 

  • FeignClient는 name과 url을 적어야하는데 URL이 없으면, 유레카를 이용하기 때문에 유레카에 등록된 명칭으로 동작하게 된다. 즉 각 API서버의 yml에 기록한 name으로 서버를 찾아가기 때문에 명칭이 application.yml에 등록한 이름과 동일해야 한다.
  • URL이 5001번포토를 사용한다는 뜻은 게이트웨어 서버를 이용하여 접속한다는 뜻이다. 따라서 GetMappinig에서는 게이트웨어서버의 yml에 정의된 /corpsvc/나 /usersvc/를 붙어주어야 한다.

 

 

  • Service 작성

위에서 만든 FeignClient를 이용하여 서비스를 만든다.

 

@Service

public class CorpUserService

{

@Autowired

CorpClient mClsCorpClient; // 회사Feign 클라이언트

@Autowired

UserClient mClsUserClient; // 사용자Feign 클라이언트

@Autowired

ModelMapper mClsModelMapper;        // 모델매퍼

 

/**

* 회사정보를 리턴한다.

* @return

*/

public ResponseEntity<?> selectCorpData()

{

return ResponseEntity.ok(mClsCorpClient.findAll());

}

 

/**

* 사용자정보를 리턴한다.

* @return

*/

public ResponseEntity<?> selectUserData()

{

return ResponseEntity.ok(mClsUserClient.findAll());

}

 

/**

* 회사와 사용자정보를 조합하여 리턴한다.

* @return

*/

public ResponseEntity<?> selectCombineData()

{

Map<String, CorpUser> hmBuffer = new HashMap<String, CorpUser>();

 

for(CorpMast clsCorp : mClsCorpClient.findAll())

{

// CorpMast에서 CorpUser로 복사

CorpUser clsDest = mClsModelMapper.map(clsCorp, CorpUser.class);

clsDest.user = new ArrayList<UserMast>();

hmBuffer.put(clsCorp.corpId, clsDest);

}

 

for(UserMast clsUser : mClsUserClient.findAll())

{

String strKey = clsUser.corpId;

if(hmBuffer.containsKey(strKey))

{

// CorpUser의 user에 추가

CorpUser clsDest = hmBuffer.get(strKey);

clsDest.user.add(clsUser);

}

}

List<CorpUser> lstCorpUser = new ArrayList<>(hmBuffer.values());

return ResponseEntity.ok(lstCorpUser);

}

}

 

 

  • Controller 작성
 

@Controller

public class CorpUserController

{

@Autowired

CorpUserService mClsService;

 

@RequestMapping(value=”/”)

public String index()

{

return “index”;

}

 

@RequestMapping(value=”/selectCorpData”)

public ResponseEntity<?> selectCorpData()

{

return mClsService.selectCorpData();

}

 

@RequestMapping(value=”/selectUserData”)

public ResponseEntity<?> selectUserData()

{

return mClsService.selectUserData();

}

 

@RequestMapping(value=”/selectCombineData”)

public ResponseEntity<?> selectCombineData()

{

return mClsService.selectCombineData();

}

}

 

 

  • JSP 파일작성

위 Controller.java 에서 “/”를 입력하면 index를 호출하도록 코딩 되어 있기 때문에

src\main\webapp\jsp 에 index.jsp 파일을 만들고 샘플을 만들면 된다.

Spring boot에서 static 파일의 위치는 “src\main\resources\static” 이므로 Javascript,

stylesheet, image 등은 이곳에 넣어두고 요청하면 된다.

 

 

 

코딩이 완료되면 http://localhost:8080/ 으로 접속하면 작성된 화면을 볼수 있다.

 

 

 

4.    스웨거(Swagger)

API에 대한 문서화 및 시각화를 위한 프레임워크로, springfox 라이브러리와 springdoc 라이브러리가 있다. 기존에는 springfox를 많이 사용하여 문서화를 하였으나, OpenAPI 3.0 지원이 늦고 오류가 많아 나중을 생각하여 springdoc을 사용하기로 하였다.

springdoc-openapi가 지원하고 있는 항목은 다음과 같다.

  • OpenAPI 3
  • Spring Boot(V1, V2)
  • JSR-303(@NotNull, @Min, @Max, @Size)
  • Swagger-ui
  • OAuth 2

 

4.1       의존성 추가(POM.xml)

<dependency>

<groupId>org.springdoc</groupId>

<artifactId>springdoc-openapi-ui</artifactId>

<version>1.4.1</version>

</dependency>

 

4.2       환경설정(SpringDocConfig.java)

@Configuration

public class SpringDocConfig

{

@Bean

public OpenAPI openAPI()

{

return new OpenAPI().info(new Info().title(“회사 API”)

.description(“회사 AOI에 대한 샘플 입니다.”)

.version(“v0.0.1”)

.license(new License()

.name(“Apache 2.0”).url(“http://springdoc.org”)));

}

}

 

 

4.3       Controller

  • Tag : 클래스에 대한 설명
  • Operation : 메소드에 대한 설명
  • ApiResponses: API 응답에 대한 설명 및 리턴 클래스 명시
  • Parameter : 메소드에 대한 파라미터 설명
@RestController

@RequestMapping(“/api/corp”)

@Tag(name=”CorpController”, description=”회사정보 컨트롤러”)

public class CorpController

{

@Autowired

private CorpService mClsService;

 

@GetMapping(value = “findAll”)

@Operation(summary=”회사정보 검색”, description=”회사정보를 검색 합니다.”)

        @ApiResponses(value = {

                       @ApiResponse(responseCode = “200”, description = “회사정보를 리턴한다.”,

                              content= { @Content(schema = @Schema(implementation = CorpMast.class)) }

                       ),

                       @ApiResponse(responseCode = “404”, description = “회사정보를 찾을수 없습니다.”)

        })     

public ResponseEntity<?> findAll(@Parameter(description=”기본 파라미터 정보”)

@ModelAttribute final BaseParam clsParam) throws Exception

{

return ResponseEntity.ok(mClsService.findAll(clsParam));

}

}

 

4.4       Model

  • Schema : 모델의 클래스 또는 멤버변수에 대한 설명
@Getter

@Setter

@Schema(description=”기본 파라미터 정보”)

public class BaseParam implements Serializable

{

private static final long serialVersionUID = 1L;

 

@Schema(description=”소트”)

public String sorts;

 

@Schema(description=”페이지NO”)

public Integer pageNo;

 

@Schema(description=”페이지사이즈”)

public Integer pageSize = 10;

 

@Schema(description=”회사ID”, example=”moramcnt”, required = true)

public String corpId;

 

@Schema(description=”사용자ID”)

public String userId;

 

@Schema(description=”타이틀”)

public String title;

 

@Schema(description=”포맷”)

public String format;

 

@Schema(description=”기타 데이터 전송”)

public String data;

 

@Schema(description=”검색 조건”)

public String searchCondition;

 

@Schema(description=”검색어”)

public String searchValue;

}

 

 

 

 

4.5       swagger-ui

http://localhost:5002/swagger-ui.html 으로 접속하여 확인

  • 메소드 테스트

“/api/corp/findAll 회사정보 검색” 을 클릭하여 “Try it out”버튼을 클릭 한후, 파라미터 항목중 corpId를 valuefactory라고 수정한후에 execute 버튼을 클릭한다.

 

 

 

클릭후 하단에는 다음과 같이 valuefactory에 대한 결과가 나타나게 된다.

 

react native 버전업시 발생하는 트러블슈팅

스마트폰 SDK가 최신버전으로 업그레이드시 npm 을 통해 받은 node_modules들이 예전에 작성하고 업데이트가 안되어 있는 경우 아래처럼 직접
수정해야 하는경우가 발생하여 간단히 정리해봄.

1. 타이머(react-native-background-timer)
1) 위치

node_modules\react-native-background-timer\android\src\main\java\com\ocetnik\timer\

2) 에러내용
Error: Tag name should use a unique prefix followed by a colon …
3) 수정사항

this.wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "rohit_bg_wakelock");

에서

this.wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, " ocetnik:rohit_bg_wakelock");

로 수정

2. 비콘(react-native-beacons-manager)
1) 위치

node_modules\react-native-beacons-manager\android\build.gradle

2) 에러내용
Error: Google Play requires that apps target API level 26 or higher.

3) 수정사항
컴파일버전, 타겟버전 26(최소버전)으로 수정

compileSdkVersion 26
targetSdkVersion 26
compile 'com.facebook.react:react-native:0.12.+'

을 아래와 같이 수정

compile "com.facebook.react:react-native:+"

3. 오리엔테이션(react-native-orientation)
1) 위치

node_modules\react-native-orientation\android\build.gradle:9: 

2) 에러내용
Error: Google Play requires that apps target API level 26 or higher.

3) 수정사항

   [ExpiredTargetSdkVersion]
      targetSdkVersion 22

커파일버전, 타겟버전 28(최소버전)으로 수정

compileSdkVersion 28
targetSdkVersion 28

4. 폰 깨우는기능(react-native-wakeful)
1) 위치
node_modules\react-native-wakeful\android\src\main\java\com\ironsmile\RNWakeful\RNWakefulModule.java:25:

2) 에러내용
Error: Tag name should use a unique prefix followed by a colon (found RNWakeful). For instance myapp:mywakelocktag. This will help with debugging [InvalidWakeLockTag]

3) 수정사항

this.wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "RNWakeful");
…
this.wifiLock = wm.createWifiLock(WifiManager.WIFI_MODE_FULL, "RNWakefulWifi");

에서

this.wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "ironsmile:RNWakeful");
…
this.wifiLock = wm.createWifiLock(WifiManager.WIFI_MODE_FULL, "ironsmile:RNWakefulWifi");

로 수정

5. 폰 깨우는기능(react-native-wakeful) Gradle에러
1) 위치
node_modules\react-native-wakeful\android\build.gradle

2) 에러내용
Error: Google Play requires that apps target API level 26 or higher.

3) 수정사항

   [ExpiredTargetSdkVersion]
      targetSdkVersion 23
      ~~~~~~~~~~~~~~~~~~~

커파일버전, 타겟버전 26으로 수정

compileSdkVersion 28
targetSdkVersion 28
compile 'com.facebook.react:react-native:0.12.+'

을 아래와 같이 수정

compile "com.facebook.react:react-native:+"

6. 폰 깨우는기능(react-native-wakeful) React Native Plugin 에러
1) 위치
node_modules\react-native-wakeful\android\src\main\java\com\ironsmile\RNWakeful\RNWakefulPackage.java

2) 에러내용

3) 수정사항

@Override
public List> createJSModules() {
    return Collections.emptyList();
  }

에서 @Override 를 주석처리

// @Override
public List> createJSModules() {
    return Collections.emptyList();
  }

7. 메트로 관련(blacklist.js)
이 항목은 react-native를 먼저 업데이트 하면 안나오지만, 업데이트 안한경우 아래처럼 수정해서 해결
1) 위치
node_modules\metro-config\src\defaults\blacklist.js

2) 수정사항

var sharedBlacklist = [
  /node_modules[/\\]react[/\\]dist[/\\].*/,
  /website\/node_modules\/.*/,
  /heapCapture\/bundle\.js/,
  /.*\/__tests__\/.*/
];

에서

var sharedBlacklist = [ /node_modules[\/\\]react[\/\\]dist[\/\\].*/, /website\/node_modules\/.*/, /heapCapture\/bundle\.js/, /.*\/__tests__\/.*/ ];

로 수정

8. 디바이스정보
React-native-device-info는 최신버전이 나와 있어 업데이트 하면 되지만 업데이트를 안할경우 아래를 수정
1) 위치
node_modules\react-native-device-info\android\src\main\java\com\learnium\RNDeviceInfo\RNDeviceModule.java:270:

2) 에러내용
Error: Exception requires API level 21 (current min is 16): android.hardware.camera2.CameraAccessException, and having a surrounding/preceding version check does not help since prior to API level 19, just loading the class will cause a crash. Consider marking the surrounding class with RequiresApi(19) to ensure that the class is never loaded except when on API 19 or higher. [NewApi] } catch (CameraAccessException e) {
~~~~~~~~~~~~~~~~~~~~~

3) 수정사항
“react-native-device-info”: “^2.3.2” 를 제거하고

npm uninstall react-native-device-info

최신버전 설치(5.5.4 버전으로 체인지)

npm install react-native-device-info --save

9. build.Gradle 환경
1) 수정사항
컴파일오류로 인하여 아래처러 수정

플레이서비스와 Firebase의 버전이 동일해야 하므로 동일하게 맞춤

implementation "com.google.android.gms:play-services-location:17.0.0"
implementation "com.google.android.gms:play-services-base:16.1.0"
implementation "com.google.firebase:firebase-core:16.0.9"

implementation "com.google.android.gms:play-services-location:17.0.0"
implementation "com.google.android.gms:play-services-base:17.0.0"
implementation "com.google.firebase:firebase-core:17.0.0"

로 수정

10. react-native 최신버전 업데이트
1) 에러내용
아래 에러로 인하여 업데이트 처리

error React Native CLI uses autolinking for native dependencies, but the following modules are linked manually:
  - react-native-device-info (to unlink run: "react-native unlink react-native-device-info")
This is likely happening when upgrading React Native from below 0.60 to 0.60 or above. Going forward, 
you can unlink this dependency via "react-native unlink " and it will be included in your app automatically. 
If a library isn't compatible with autolinking, disregard this message and notify the library maintainers.

2) 수정사항
– 캐시 클린

npm cache clean --force

– react-native 버전 0.60.4을 제거

npm uninstall react-native

– 신버전 설치(0.62.0)

npm install react-native --save

11. async-storage 최신버전 업데이트
1) 에러내용
메소드 사용방법변경으로 오류

2) 수정사항
신버전 업데이트

– 제거

npm uninstall @react-native-community/async-storage

– 신버전설치(1.8.1)

npm install @react-native-community/async-storage –save

12. react-native 업데이트후 앱 크래쉬 나온경우
1) 에러내용

2020-04-01 15:06:38.177 12257-12285/? E/AndroidRuntime: FATAL EXCEPTION: create_react_context
    Process: kr.co.transhub, PID: 12257
    java.lang.UnsatisfiedLinkError: couldn't find DSO to load: libfbjni.so caused by: Didn't find class "com.facebook.jni.NativeRunnable" on path: DexPathList[[zip file "/data/app/kr.co.transhub-VszmjqWt0xirxB8bmxGG2A==/base.apk"],nativeLibraryDirectories=[/data/app/kr.co.transhub-VszmjqWt0xirxB8bmxGG2A==/lib/arm64, /data/app/kr.co.transhub-VszmjqWt0xirxB8bmxGG2A==/base.apk!/lib/arm64-v8a, /system/lib64]]
        at com.facebook.soloader.SoLoader.a(Unknown Source:325)
        at com.facebook.soloader.SoLoader.a(Unknown Source:104)
        at com.facebook.soloader.SoLoader.a(Unknown Source:108)
        at com.facebook.soloader.SoLoader.a(Unknown Source:1)
        at com.facebook.soloader.j.a(Unknown Source:0)
        at com.facebook.soloader.o.a.a(Unknown Source:10)
        at com.facebook.jni.HybridData.(Unknown Source:2)
        at com.facebook.react.bridge.WritableNativeMap.initHybrid(Native Method)
        at com.facebook.react.bridge.WritableNativeMap.(Unknown Source:0)
        at com.facebook.react.jscexecutor.a.create(Unknown Source:2)
        at d.b.m.r$e.run(Unknown Source:58)
        at java.lang.Thread.run(Thread.java:764)

2) 수정사항
proguard-rules.pro파일의 하단에 아래를 추가

-keep class com.facebook.jni.** { *; }

– 참고: https://stackoverflow.com/questions/60927048/react-native-app-release-build-crashes-on-start-works-fine-in-debug-why

node.js 서버와 react native 클라이언트 간의 암호화 정리

1. React Native
1) react-native-crypto-js 추가

 npm install react-native-crypto-js --save

2) 사용방법
전화번호를 비밀키를 이용하여 암호화한다.

import CryptoJS from "react-native-crypto-js";

let strPhoneNo = "01012345678";
let strSecretKey ="1234";
let strEncrypt = CryptoJS.AES.encrypt(strPhoneNo , strSecretKey).toString();

3) 전송
위의 strEncrypt를 이용하여 Node.js 서버로 전송

2. node.js 서버
1) crypto-js 추가

 npm install crypto-js --save

2) 사용방법
수신된 전화번호를 비밀키를 가지고 복화화한다.

let strPhoneNo = "01012345678"; // 수신받은 전화번호
let strSecretKey = "1234";
var strEncrypt = CryptoJS.AES.encrypt(strPhoneNo , strSecretKey);
console.log(" -Encrypt:"+ strEncrypt);

우분투에서 .ASP NET core Apache 연동

그동안 플랫폼에 구애를 받지않는 Java 기반을 많이 활용하였는데, net core도 리눅스, 맥에서도 구동가능하여
우분투 환경에서 MSA 기반의 인증서버를 구현하여 보았다.

본 내용은 마이크로 소프트의 아래 링크를 참조하여 현재 프로젝트 상황에 맞게 수정하였다.
https://docs.microsoft.com/ko-kr/aspnet/core/host-and-deploy/linux-apache?view=aspnetcore-3.1

1. 환경
-NET Core 우분투 설치는 인터넷에 많이 나와있으므로 생략함
-Apache는 개발서버에 설치되어 있는 것을 활용하므로 설치 과정 문서는 생략함

2. 배포
– 비쥬얼 스튜디오 게시를 통해 게시된 폴더를 알집으로 압축하여 우분투에 FTP로 업로드.
– /home/idr/Service/Identity/Identity.WebApi 폴더에 압축을 풀어 배포
– unzip Identity.WebApi.zip -d Identity.WebApi

3. 프록시 서버구성
– 사용자가 Apache를 통해 요청을 하면 .net core의 Kestrel 서버로 전달해주기 위해서는 역방향 프록시 서버를 구성해야 함.
– 정뱡향 또는 역방향프록시에 대한 기술문서는 구글검색을 참고.
– 프로그램상 Startup.cs 파일에 아래와 같이 추가해 준다.
* 테스트해보니 아래처럼 안해도 동작은 한다.

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
        ...

	app.UseRouting();

	// Apache 또는 IIS 역방향 프록시
	// using Microsoft.AspNetCore.HttpOverrides;을 해야함
	app.UseForwardedHeaders(new ForwardedHeadersOptions {
			ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto
	});
}

4. Apache 구성

4.1 환경설정

cd /etc/apache2/sites-available
vi identity.mbizok.com.conf
RequestHeader set "X-Forwarded-Proto" expr=%{REQUEST_SCHEME}

ProxyPreserveHost On
ProxyPass / http://127.0.0.1:6002/
ProxyPassReverse / http://127.0.0.1:6002/
ServerName identity.mbizok.com
ServerAlias identity.mbizok.com
ErrorLog /var/log/apache2/error-identity.mbizok.com.log
CustomLog /var/log/apache2/access-identity.mbizok.com.log common

4.2 사이트활성화

a2ensite identity.mbizok.com.conf
service apache2 restart

4.3 로그 확인
– 에러가 발생하여 로그 확인

systemctl status apache2.service

3m<94> 19 16:36:06 moramlinux apache2[19883]: AH00526: Syntax error on line 2 of /etc/apache2/sites-enabled/identity.mbizok.com.conf:
3m<94> 19 16:36:06 moramlinux apache2[19883]: Invalid command 'RequestHeader', perhaps misspelled or defined by a module not included in the server configuration

– 아파치 모듈 설치 및 아파치 재시작

a2enmod headers
service apache2 restart

5. Kestrel 서비스
6002 포트로 도는 API 서버를 실행하기 위해 kestrel 서비스를 만들어야 함.

5.1 설정화일
vi /etc/systemd/system/kestrel-identity.mbizok.com.service

[Unit]
Description= Identity Web Api

[Service]
WorkingDirectory=/home/idr/Service/Identity/Identity.WebApi
ExecStart=/usr/bin/dotnet /home/idr/Service/Identity/Identity.WebApi/Identity.WebApi.dll --urls="http://127.0.0.1:6002"
Restart=always
# Restart service after 10 seconds if the dotnet service crashes:
RestartSec=10
KillSignal=SIGINT
SyslogIdentifier=dotnet-example
User=idr
Environment=ASPNETCORE_ENVIRONMENT=Production

[Install]
WantedBy=multi-user.target

5.2 서비스 활성화

systemctl enable kestrel-identity.mbizok.com.service

5.3 서비스 시작

systemctl start kestrel-identity.mbizok.com.service

5.4 서비스 상태확인

systemctl status kestrel-identity.mbizok.com.service

스프링부트 개발(웹) 관련 개발환경 구성

다음은 사내에서 MSA 기반의 스프링 부트 프로젝트를 진행하기 위해 필요한 사항을 정리한 글 입니다.

I. 개발툴 설치
1. JDK
JDK는 11 이상을 권장

Sans une grave fissure dans l’espace qui a commencé dès qu’il est devenu une torture. Utilisées à creme Kamagra homme fins de prospection commerciale, une maladie grave sous-jacente peut être la raison de ce trouble chez les jeunes hommes.


2. Tortoise SVN
아래 Visual Studio Code에서 SVN을 사용하기 위해서 SVN 클라언트의 설치 필요

1) 다운로드
64비트 최신버전을 다운로드 받아 설치
– https://tortoisesvn.net/downloads.html

2) 설치시작

3) Command line client tools 설치
SVN 클라이언트로, 해당 클라이언트가 없다면 반드시 설치

4) SVN 설치 확인
CMD에서 svn을 입력후 엔터를 눌렀을때 아래처럼 실행되면 설치 완료

3. Node.js 설치
1) 다운로드 및 설치
– https://nodejs.org/ko/ 에서 LTS버전 다운로드

4. Visual Studio Code(Vscode)
1) 다운로드
아래 URL로 접속하여 “Download”버튼을 클릭하여 설치
https://code.visualstudio.com/

2) 설치
아래와 같이 “다음”을 클릭하여 설치

해당 사용자의 AppData에 설치

3) 확장 패키지 설치
좌측 메뉴바에서 [CTRL+SHIFT+X]키를 동시에 누르거나, 아래 버튼을 클릭하여 패키지 설치

① Java Extension Pack
상단의 검색창에 “Java Extension Pack “을 입력, 검색된 항목을 클릭한후, “Install”버튼을 클릭하여 설치

② Spring Boot Extension Pack

③ Korean Language Pack for Visual Studio Code
– VsCode를 한글로 보고 싶은 경우 설치

④ lombok 설치
Lombok Annotations Support for VSCode

⑤ SVN 연동

II. 기타
1. 기존에 JDK 낮은 버전이 설치된 경우
Vscode 실행시 항상 아래와 같이 나타나는경우에는

JDK 11이상을 설치 후, 제어판의 환경설정에서 JAVA_HOME을 변경하거나, vscode의 JAVA HOME을 변경하면 된다.

여기에서는 vscode의 자바홈을 변경하는것으로 처리

“파일(File)> 기본설정 > 설정”을 클릭한후 검색창에서 JDK를 입력하여 검색한후, java:Home을 클릭하여

아래처럼 JDK 위치를 지정

Tomcat 구동시 www.terracotta.org 403 에러가 날때

java.io.IOException: Server returned HTTP response code: 403 for URL: http://www.terracotta.org/kit/reflector?pageID=update.properties&kitID=ehcache.default&id=-1062731536&os-name=Windows+8.1&jvm-name=Java+HotSpot%28TM%29+64-Bit+Server+VM&jvm-version=1.8.0_05&platform=amd64&tc-version=2.6.9&tc-product=Ehcache+Core+2.6.9&source=Ehcache+Core&uptime-secs=1&patch=UNKNOWN
	at sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1838) ~[?:1.8.0_05]
	at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1439) ~[?:1.8.0_05]
	at net.sf.ehcache.util.UpdateChecker.getUpdateProperties(UpdateChecker.java:108) ~[ehcache-core-2.6.9.jar:?]
	at net.sf.ehcache.util.UpdateChecker.doCheck(UpdateChecker.java:72) ~[ehcache-core-2.6.9.jar:?]
	at net.sf.ehcache.util.UpdateChecker.checkForUpdate(UpdateChecker.java:60) [ehcache-core-2.6.9.jar:?]
	at net.sf.ehcache.util.UpdateChecker.run(UpdateChecker.java:51) [ehcache-core-2.6.9.jar:?]
	at java.util.TimerThread.mainLoop(Timer.java:555) [?:1.8.0_05]
	at java.util.TimerThread.run(Timer.java:505) [?:1.8.0_05]

ehcache-default.xml 로 가서 updateCheck를 false로 지정하면 더이상 톰캣구동시 에러가 발생하지 않는다.

ehcache updateCheck="false"

전자정부프레임워크 DataSource 접속정보 암호화

1. Jasypt 다운로드

http://www.jasypt.org/download.html

2. 암호화 대상 문자열 생성

globals.properties 파일에 아래와 같이 같이 있다면

Globals.UserName=AAAUSER
Globals.Password=pwd1234
Globals.DriverClassName=oracle.jdbc.driver.OracleDriver
Globals.Url=jdbc:oracle:thin:@192.168.0.1:1521/ORA

CMD로 Jasypt 설치된 폴더의 bin에 가서 encrypt 명령을 이용하여 암호화 문자열 생성

jasypt-1.9.2\bin\encrypt input="pwd1234" password="moramcnt" algorithm="PBEWITHMD5ANDDES"

----ENVIRONMENT-----------------

Runtime: Oracle Corporation Java HotSpot(TM) 64-Bit Server VM 25.5-b02



----ARGUMENTS-------------------

algorithm: PBEWITHMD5ANDDES
input: pwd1234
password: 5AYZUz+YUFZwz3vgRLWyscggqAc8PgOD0zGotI45UeQ=



----OUTPUT----------------------

ng2cZvWPBGF64QbcRqMSVg==

3. globals.properties 파일 수정
위에서 생성된 OUTPUT 내용에 ENC를 붙여 수정한다.

Globals.UserName=AAAUSER
Globals.Password=ENC(ng2cZvWPBGF64QbcRqMSVg==)
Globals.DriverClassName=oracle.jdbc.driver.OracleDriver
Globals.Url=jdbc:oracle:thin:@192.168.0.1:1521/ORA

4. POM 파일에 dependency 추가

5. context-datasource.xml 파일 수정
– password는 cmd에서 encrypt 명령시 쓰였던 비밀번호

Non sempre i problemi nel raggiungere e mantenere l’erezione rappresentano una scusa per diagnosticare la disfunzione erettile, nausea e vampate di calore. Se è necessario prepararsi rapidamente per un incontro romantico, quindi si può dimostrare alla sua fidanzata tutto il suo potenziale. Ma non provoca erezione continue per sei ore, terminato questo passaggio, se ti viene il desiderio di ordinare Lovegra online in Italia, uno dei farmaci più famosi per il trattamento della disfunzione erettile. Per questa ragione non viene richiesta nessuna ricetta di prescrizione medica, allora viene importata dai vicini paesi europei, per consapevolezza-farmacie.com il trattamento efficace della Disfunzione erettile.

Cross compiling 환경을 위한 eclipse CDT + Mingw환경구축

1. Eclipse다운 로드 for C++
URL: http://www.eclipse.org/downloads/packages/eclipse-ide-cc-developers/neon3

2. CDT설치
http://download.eclipse.org/tools/cdt/releases/9.2
CDT 다운로드
— help -> install New Software –> Add
Add Repository (2017-07-07 기준)
Name : CDT , Location: http://download.eclipse.org/tools/cdt/releases/9.2

3. MinGw설치

3-1. 다운로드 및 설치 https://sourceforge.net/projects/mingw/

3-2. 환경변수에 Path 추가
C:\MinGW\bin

3-3. 실행테스트
DOS cmd에서 출력확인
gcc –version
결과: gcc (GCC) 5.3.0

4. Eclipse 설정
1) Builder설정
Window -> Preferences -> C/C++ -> New C/C++ Proejct Wizard -> Makefile Project
에서 Binary Parsers Tab에서 Elf Parser,
Builder Settings에서
Use default build Command 를 UnCheck,
Bulid Command항목에 mingw32-make.exe 입력

5. 신규 C++ 프로젝트 생성
File -> New -> C++ Project에서
Project Name입력 후, Project Type에서 Makefile Project 중 하나를 선택 후, ToolChains에서 MinGW GCC를 선택한다.

소스코드를 작성하신 뒤에는 Ctrl + S 를 클릭하셔서 소스코드를 저장하신 뒤, 빌드를 하셔야 소스코드가 바뀐 것을 알고 제대로 빌드합니다.
빌드는 Ctrl + B
빌드 뒤에 실행 시키기 위해서는 Ctrl + F11 로 실행
정리하자면 소스코드를 작성/ 수정하신 뒤 Ctrl + S -> Ctrl + B -> Ctrl + F11 을 해서 작동

Sono farmaci in pillole https://farmacie-riflessi.com/cialis-generico/ di differente dosaggio, per le aziende farmaceutiche. Lo stato di salute e la risposta del paziente al trattamento, che ti permettono di prevedere il momento della consegna del Tadalafil. Avendo applicato dosatura ancora più bassa, perché a volte è difficile pianificare per il sesso. Questi potrebbero anche non comparire e possono essere diversi da persona a persona.

Mac의 svn에서 프로젝트 Import

sudo svn import -m “설명” 프로젝트폴더 SVN주소 —force-log
ex)sudo svn import -m “KoreataxiClient” KoreataxiClient http://localhost/svn/LixingSVN/KoreataxiClient —force-log