1. Content Type

 - 파일명에 따라 ContentType을 설정한다.


ObjectMetadata objMeta = new ObjectMetadata();
objMeta.setContentType(Mimetypes.getInstance().getMimetype(saveFileNm));


2. Content Length

 - byte length를 추가한다.

ObjectMetadata objMeta = new ObjectMetadata();

byte[] bytes = IOUtils.toByteArray(targetIS);
objMeta.setContentLength(bytes.length);

ByteArrayInputStream byteArrayIs = new ByteArrayInputStream(bytes);

PutObjectRequest putObjReq = new PutObjectRequest(bucketName, key, byteArrayIs, objMeta);
s3client.putObject(putObjReq);

 - 해당 소스처리를 안할 경우 아래와 같은 warning 메시지가 뜬다.

[WARN ] c.a.services.s3.AmazonS3Client:1714 - No content length specified for stream data.  Stream contents will be buffered in memory and could result in out of memory errors.


3. 임시파일로 업로드

 - 서버 내 파일을 저장하지않고, 바로 S3에 업로드할 때 사용하면 좋다.

File file = File.createTempFile("test", ".txt");
file.deleteOnExit();


1. 약수

 -  어떤 수를 나누어 떨어지게 하는 수.


2. Python 소스

if __name__ == "__main__":
number = int(input("숫자를 입력해주세요. : "))

divisors = []

for i in range(1, number + 1):
if number % i == 0:
divisors.append(i)

print(divisors)


'프로그래밍 > Python' 카테고리의 다른 글

10진수 n진수로 변환하기.  (0) 2018.07.30
[Basic] 약수  (0) 2018.06.04

해당 내용은 https://github.com/java-json-tools/json-schema-validator 를 사용하면서 적은 내용입니다.


1. NodeType

{.... "type": "string or array...."}


 - NodeType 목록

 ARRAY("array"),

 BOOLEAN("boolean"),

 INTEGER("integer"),

 NULL("null"),

 NUMBER("number"),

 OBJECT("object"),

 STRING("string")


 - 해당 Library에서는 "com.github.fge.jackson.NodeType"를 참고하시면 편하게 코딩할 수 있다.


2. minItems, maxItems

{.... "minItems":0, "maxItems":2....}


 - 아이템 수롤 지정할 수 있다.

 - type이 array일 경우 해당 옵션으로 아이템 수를 체크할 수 있다.


1. Json 파일 import 하기.

<script>
import externalJsonFile from './externalJsonFile.json'
export default{
data(){
return{
jsonFile: externalJsonFile
}
}
}
</script>


2. 가져다 쓰기

<ul v-for="tmp in jsonFile">
<li>{{tmp}}</li>
</ul>


AWS, java, S3

1. 기존 메소드


AmazonS3 s3Client = new AmazonS3Client(new BasicAWSCredentials(accessKey, secretKey));

 - 해당 메소드 수석을 참고하면 아래와 같다.

/**
* Constructs a new Amazon S3 client using the specified AWS credentials to
* access Amazon S3.
*
* @param awsCredentials
* The AWS credentials to use when making requests to Amazon S3
* with this client.
*
* @see AmazonS3Client#AmazonS3Client()
* @see AmazonS3Client#AmazonS3Client(AWSCredentials, ClientConfiguration)
* @deprecated use {@link AmazonS3ClientBuilder#withCredentials(AWSCredentialsProvider)}
*/
@Deprecated
public AmazonS3Client(AWSCredentials awsCredentials) {
this(awsCredentials, configFactory.getConfig());
}


2. 변경된 메소드

BasicAWSCredentials creds = new BasicAWSCredentials(accessKey, secretKey);
AmazonS3 s3client = AmazonS3ClientBuilder.standard().withCredentials(new AWSStaticCredentialsProvider(creds)).build();


 - 리전을 추가할 경우

.withRegion(Regions.valueOf("AP_NORTHEAST_2"))


'프로그래밍 > JAVA' 카테고리의 다른 글

AWS s3 upload source Tip  (0) 2018.06.05
json schema validator 사용하기 - 02  (0) 2018.05.23
AmazonS3Client, deprecated!!!  (0) 2018.05.21
json schema validator 사용하기 - 01  (0) 2018.04.18
시스템 종료 후 File 삭제  (0) 2018.04.12
Java에서 Tuple 사용하기.  (0) 2018.04.11

1. safari 11.1 update

 - 기존 Safari (mac or ios)에서는 정상적으로 동작하던 ajax가 safari 11.1 버전 업데이트를 진행한 후로 오류가 발생함.

 - ajax 내 error 메시지가 다음과 같다

Failed to load resource: The operation couldn’t be completed. Protocol error

 - Chrome이나 Firefox 등 최신버전에서는 문제가 없었다.


2. 원인 

 - Webkit 버그!!!! (Webkit 빌드 r230963)

 - input[type=file] 또는 formData 내에 file 

<input type="file"/>

 - ajax 내 data에 빈 파일 필드가 전송되면 발생함.

 - (전 IOS 11.3에서 발생하여 수정 했습니다.)


3. 해결책

 - https://trac.webkit.org/changeset/230963/webkit : 수정됨.

 - 임시 해결책


frmData.delete("file"); //var frmData = new FormData() 를 사용할 경우

or

$("input[type=file]").each(function () {
var tmpValue = $(this).val();
if (tmpValue === undefined || tmpValue === "") {
$(this).remove();
}
});


그냥 평소에 자주 쓰는 툴 및 사이트 공유...


1. 웹사이트

 1) jwt.io

 - 바로가기

 - jwt 를 손쉽게 decoded 할 수 있는 곳


 2) jsonlint.com

 - 바로가기

 - JSON Validation 해주고, beautify 해준다.


2. Chrome Extension

 1) Css viewer

- 바로가기

- 웹페이지 내 css를 손쉽게 볼 수 있다.


 2) postman

- 바로가기

- 너무 유명한 Rest Client


 3) editthiscookie

- 바로가기

- 쿠키값을 조작하기 편한 extension


 4) JWT Analyzer & Inspector

- 바로가기

- 위에 웹사이트 탭에 있는 jwt.io처럼 jwt 값을 손쉽게 decoded 해주는 툴


 5) JSONView

- 바로가기

- Json 파일을 이쁘게 보여줌.


1. Job 정보 가지고 오기.

 - 개발하는 중에 ItemReader, ItemProcessor, ItemWriter 등에서 job정보를 가지고 와야 할 때가 있다.

 - 간단한 소스 추가로 사용 가능하다.


2. 소스

private Long jobId;

@BeforeStep
public void getInterstepData(StepExecution stepExecution) {
JobExecution jobExecution = stepExecution.getJobExecution();
this.jobId = jobExecution.getJobId();
}

 - 비슷한 방식으로 확장해서 사용 가능 할 듯.


* 참고 링크


해당 내용은 공부하면서 간단하게 만들어본 블록체인 입니다.


1. Block 만들기

 - BlockChain을 구성하는 Block 을 생성한다,

 - Block은 BlockChain 내에서 고유한 Hash(Digital Signature)값을 가지고 있다.

 - Block 내에는 이전 Block의 Hash 값과 데이터들이 포함되어 있다.


 1) 소스코드

package kr.geun.o.bc.basic;

import java.util.Date;

/**
* Block Class
*
* @author akageun
*/
public class Block {

private String hash;
private String previousHash;

private String data;
private long timeStamp;

private Block() {

}

/**
* Block Constructor
*
* @param data
* @param previousHash
*/
public Block(String data, String previousHash) {
this.data = data;
this.previousHash = previousHash;

this.timeStamp = new Date().getTime();
}

/**
* get previousHash
*
* @return
*/
public String getPreviousHash() {
return previousHash;
}

/**
* get Hash
* - digital signature
*
* @return
*/
public String getHash() {
return hash;
}

/**
* get TimeStamp
*
* @return
*/
public long getTimeStamp() {
return timeStamp;
}

/**
* get Data
*
* @return
*/
public String getData() {
return data;
}
}

2. Hash(Digital Signature) 생성 메소드 만들기

 - Sha256을 사용.

package kr.geun.o.bc.basic;

import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

/**
* BlockChain Utils
*
* @author akageun
*/
public class BcUtils {

/**
* Hash 생성
*
* @param inputValues
* @return
*/
public static String generateHash(String... inputValues) {
try {
StringBuffer sb = new StringBuffer();
for (String inputValue : inputValues) {
sb.append(inputValue);
}

String input = sb.toString();

MessageDigest digest = MessageDigest.getInstance("SHA-256");

byte[] hash = digest.digest(input.getBytes("UTF-8"));
StringBuffer hexString = new StringBuffer();

for (int i = 0; i < hash.length; i++) {
String hex = Integer.toHexString(0xff & hash[i]);
if (hex.length() == 1) {
hexString.append('0');
}

hexString.append(hex);
}
return hexString.toString();

} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
throw new RuntimeException(e);

} catch (UnsupportedEncodingException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
}


3. Hash 계산로직 추가.

 - 위 BcUtils 를 이용하여 Block 안 Hash값을 만드는 로직을 추가해보자.

 - Block 내 메소드 추가(소스코드)

/**
* Hash값 계산하기!
*
* @return
*/
public String calculateHash() {
return BcUtils.generateHash(previousHash, Long.toString(timeStamp), data);
}

 - 생성자 내에 해당 메소드 호출 추가


/**
* Block Constructor
*
* @param data
* @param previousHash
*/
public Block(String data, String previousHash) {
this.data = data;
this.previousHash = previousHash;

this.timeStamp = new Date().getTime();
this.hash = calculateHash(); //추가!!
}


4. Genesis Block 호출하기!

 - 첫번째 블럭 생성

Block genesisBlock = new Block("이건 Genesis Block 입니다.", "0");
System.out.println("Genesis Block Hash : " + genesisBlock.getHash());

 - 메인 메소드를 만들어 호출하면 아래와 같은 결과를 얻을 수 있다.(호출할 때마다 Hash값이 달라진다.)

Genesis Block Hash : f57e2c72feba62234118d1356799c367a802c342156a43ac2774698bb316941e


 - 몇개를 더 추가해서 출력해보면.... 아래와 같다.

Block genesisBlock = new Block("이건 Genesis Block 입니다.", "0");
System.out.println("Genesis Block Hash : " + genesisBlock.getHash());

Block secBlock = new Block("이건 두번째 블럭 입니다.", genesisBlock.getHash());
System.out.println("Second Block Hash : " + secBlock.getHash());

Block thirdBlock = new Block("이건 세번째 블럭 입니다.", secBlock.getHash());
System.out.println("Hash for block 3 : " + thirdBlock.getHash());

Genesis Block Hash : f57e2c72feba62234118d1356799c367a802c342156a43ac2774698bb316941e

Second Block Hash : 082902f4d78eab658b964d9743532178073da2b9d529b00752fa5588034fb2a2

Hash for block 3 : 97a821109da7ed12fc3263452670d42b392d71772dd70b81720a23e1d898bf15


5. 블록체인 만들기.

 - 간단하게 static List를 만들어서 블럭들을 생성해 보자.

/**
* BlockChain 메인 클래스
*
* @author akageun
*/
public class BlockChain {

public static List<Block> BLOCK_CHAIN = new LinkedList<>();

public static void main(String[] args) {

BLOCK_CHAIN.add(new Block("이건 Genesis Block 입니다.", "0"));
BLOCK_CHAIN.add(new Block("이건 두번째 블럭 입니다.", BLOCK_CHAIN.get(BLOCK_CHAIN.size() - 1).getHash()));
BLOCK_CHAIN.add(new Block("이건 세번째 블럭 입니다.", BLOCK_CHAIN.get(BLOCK_CHAIN.size() - 1).getHash()));

for (Block block : BLOCK_CHAIN) {
System.out.println("=========");

System.out.println("hash : " + block.getHash());
System.out.println("previousHash : " + block.getPreviousHash());
System.out.println("timeStamp : " + block.getTimeStamp());
System.out.println("Data : " + block.getData());
}

System.out.println("=========");
}

}

 - 결과

=========

hash : 0f7e40c1f99be348a2a600f678ef6e64136d4ea6dc3d7457561e572129c628c9

previousHash : 0

timeStamp : 1532238023070

Data : 이건 Genesis Block 입니다.

=========

hash : b3a2226d4dafb77bfca41c2d792e7590df544e34450bfd5ecd69e71124f6baea

previousHash : 0f7e40c1f99be348a2a600f678ef6e64136d4ea6dc3d7457561e572129c628c9

timeStamp : 1532238023086

Data : 이건 두번째 블럭 입니다.

=========

hash : 57caa0507cbed37fbde89a4d80b2ea68450cff3698fba56856858093d8ac6982

previousHash : b3a2226d4dafb77bfca41c2d792e7590df544e34450bfd5ecd69e71124f6baea

timeStamp : 1532238023086

Data : 이건 세번째 블럭 입니다.



6. 무결성 검사

 - 계산한 Hash값이 같은지, Block 내 PreviousBlock 과 실제 이전 블럭 Hash값이 같은지를 검증하는 로직

 - 구현 소스

/**
* 블록 검증
*
*
* @return
*/
private static boolean isValidBlockChain() {
Block currentBlock;
Block previousBlock;

for (int i = 1; i < BLOCK_CHAIN.size(); i++) { //GenesisBlock 은 제외한다.
currentBlock = BLOCK_CHAIN.get(i);
previousBlock = BLOCK_CHAIN.get(i - 1);

if (currentBlock.getHash().equals(currentBlock.calculateHash()) == false) { //만들어 놓은 Hash값과 계산한 Hash값이 같은지 검증!
System.out.println("Not Equals Current Block Hash!!");
return false;
}

if (currentBlock.getPreviousHash().equals(previousBlock.getHash()) == false) {
System.out.println("Not Equals Previous Block Hash!!");
return false;
}

}

return true;
}


7. 채굴!(마이닝)

 - 작업증명'(Proof-of-Work) : BlockChain의 Block Hash는 `Difficulty`에 따라 선택된  Target 데이터 규격을 만족해야 한다.

  - Block Class 수정( nonce 값 추가)

private int nonce;

/**
* get nonce
*
* @return
*/
public int getNonce() {
return nonce;
}

  - Hash 값 연산하는 부분에 nonce 값 추가

/**
* Hash값 계산하기!
*
* @return
*/
public String calculateHash() {
return BcUtils.generateHash(previousHash, Long.toString(timeStamp), Integer.toString(nonce) , data);
}

  - 채굴 함수 추가

/**
* Mining
*/
public void mineBlock() {
char[] targetChar = new char[BlockChain.DIFFICULTY];
Arrays.fill(targetChar, '0');
String target = String.valueOf(targetChar);

while (hash.substring(0, BlockChain.DIFFICULTY).equals(target) == false) {
nonce++;
hash = calculateHash();
}

System.out.println("Block Mined!!! : " + hash);
}

  - 난이도 추가

public static int DIFFICULTY = 5;

  - 무결성 검증 코드 내 로직 추가

if (currentBlock.getHash().substring(0, DIFFICULTY).equals(hashTarget) == false) {
System.out.println("This block hasn't been mined");
return false;
}

  - 채굴해보기

BLOCK_CHAIN.add(new Block("이건 Genesis Block 입니다.", "0"));
BLOCK_CHAIN.get(0).mineBlock();

BLOCK_CHAIN.add(new Block("이건 두번째 블럭 입니다.", BLOCK_CHAIN.get(BLOCK_CHAIN.size() - 1).getHash()));
BLOCK_CHAIN.get(1).mineBlock();

BLOCK_CHAIN.add(new Block("이건 세번째 블럭 입니다.", BLOCK_CHAIN.get(BLOCK_CHAIN.size() - 1).getHash()));
BLOCK_CHAIN.get(2).mineBlock();

BLOCK_CHAIN.add(new Block("이건 네번째 블럭 입니다.", BLOCK_CHAIN.get(BLOCK_CHAIN.size() - 1).getHash()));
BLOCK_CHAIN.get(3).mineBlock();


 - 결과

Block Mined!!! : 00000fdd8a35c69f5925051899635e1704af98bdd7da3504ed9bc36b5be30901

Block Mined!!! : 00000d8e9a9e735e8f7cbdae41458379ab8b4ac3de7826671eb10f2b7def35bd

Block Mined!!! : 000005dd4dc19710d82dda43d230ec6eabc8041af0fc0a489279802d172f8d41

Block Mined!!! : 000006ff67b1e5735d8891e3e389620f541aa3467e73471a4e2d7b11f841ed3a

=========

hash : 00000fdd8a35c69f5925051899635e1704af98bdd7da3504ed9bc36b5be30901

previousHash : 0

timeStamp : 1532240373740

Data : 이건 Genesis Block 입니다.

nonce : 465518

=========

hash : 00000d8e9a9e735e8f7cbdae41458379ab8b4ac3de7826671eb10f2b7def35bd

previousHash : 00000fdd8a35c69f5925051899635e1704af98bdd7da3504ed9bc36b5be30901

timeStamp : 1532240374917

Data : 이건 두번째 블럭 입니다.

nonce : 1603790

=========

hash : 000005dd4dc19710d82dda43d230ec6eabc8041af0fc0a489279802d172f8d41

previousHash : 00000d8e9a9e735e8f7cbdae41458379ab8b4ac3de7826671eb10f2b7def35bd

timeStamp : 1532240378568

Data : 이건 세번째 블럭 입니다.

nonce : 2130959

=========

hash : 000006ff67b1e5735d8891e3e389620f541aa3467e73471a4e2d7b11f841ed3a

previousHash : 000005dd4dc19710d82dda43d230ec6eabc8041af0fc0a489279802d172f8d41

timeStamp : 1532240383239

Data : 이건 네번째 블럭 입니다.

nonce : 504539

=========

This Blockchain is Valid : true



전체소스

1. Block 소스

package kr.geun.o.bc.basic;

import java.util.Arrays;
import java.util.Date;

/**
* Block Class
*
* @author akageun
*/
public class Block {

private String hash;
private String previousHash;

private String data;
private long timeStamp;

private int nonce;

private Block() {

}

/**
* Block Constructor
*
* @param data
* @param previousHash
*/
public Block(String data, String previousHash) {
this.data = data;
this.previousHash = previousHash;

this.timeStamp = new Date().getTime();
this.hash = calculateHash();
}

/**
* Hash값 계산하기!
*
* @return
*/
public String calculateHash() {
return BcUtils.generateHash(previousHash, Long.toString(timeStamp), Integer.toString(nonce), data);
}

/**
* Mining
*/
public void mineBlock() {
char[] targetChar = new char[BlockChain.DIFFICULTY];
Arrays.fill(targetChar, '0');
String target = String.valueOf(targetChar);

while (hash.substring(0, BlockChain.DIFFICULTY).equals(target) == false) {
nonce++;
hash = calculateHash();
}

System.out.println("Block Mined!!! : " + hash);
}

/**
* get previousHash
*
* @return
*/
public String getPreviousHash() {
return previousHash;
}

/**
* get Hash
* - digital signature
*
* @return
*/
public String getHash() {
return hash;
}

/**
* get TimeStamp
*
* @return
*/
public long getTimeStamp() {
return timeStamp;
}

/**
* get Data
*
* @return
*/
public String getData() {
return data;
}

/**
* get nonce
*
* @return
*/
public int getNonce() {
return nonce;
}
}


2. BcUtils

package kr.geun.o.bc.basic;

import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

/**
* BlockChain Utils
*
* @author akageun
*/
public class BcUtils {

/**
* Hash 생성
*
* @param inputValues
* @return
*/
public static String generateHash(String... inputValues) {
try {
StringBuffer sb = new StringBuffer();
for (String inputValue : inputValues) {
sb.append(inputValue);
}

String input = sb.toString();

MessageDigest digest = MessageDigest.getInstance("SHA-256");

byte[] hash = digest.digest(input.getBytes("UTF-8"));
StringBuffer hexString = new StringBuffer();

for (int i = 0; i < hash.length; i++) {
String hex = Integer.toHexString(0xff & hash[i]);
if (hex.length() == 1) {
hexString.append('0');
}

hexString.append(hex);
}
return hexString.toString();

} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
throw new RuntimeException(e);

} catch (UnsupportedEncodingException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
}


3. BlockChain

package kr.geun.o.bc.basic;

import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;

/**
* BlockChain 메인 클래스
*
* @author akageun
*/
public class BlockChain {

public static List<Block> BLOCK_CHAIN = new LinkedList<>();

public static int DIFFICULTY = 5;

public static void main(String[] args) {

BLOCK_CHAIN.add(new Block("이건 Genesis Block 입니다.", "0"));
BLOCK_CHAIN.get(0).mineBlock();

BLOCK_CHAIN.add(new Block("이건 두번째 블럭 입니다.", BLOCK_CHAIN.get(BLOCK_CHAIN.size() - 1).getHash()));
BLOCK_CHAIN.get(1).mineBlock();

BLOCK_CHAIN.add(new Block("이건 세번째 블럭 입니다.", BLOCK_CHAIN.get(BLOCK_CHAIN.size() - 1).getHash()));
BLOCK_CHAIN.get(2).mineBlock();

BLOCK_CHAIN.add(new Block("이건 네번째 블럭 입니다.", BLOCK_CHAIN.get(BLOCK_CHAIN.size() - 1).getHash()));
BLOCK_CHAIN.get(3).mineBlock();

for (Block block : BLOCK_CHAIN) {
System.out.println("=========");

System.out.println("hash : " + block.getHash());
System.out.println("previousHash : " + block.getPreviousHash());
System.out.println("timeStamp : " + block.getTimeStamp());
System.out.println("Data : " + block.getData());
System.out.println("nonce : " + block.getNonce());
}

System.out.println("=========");

System.out.println("This Blockchain is Valid : " + isValidBlockChain());

}

/**
* 블록 검증
*
*
* @return
*/
private static boolean isValidBlockChain() {
Block currentBlock;
Block previousBlock;

char[] target = new char[BlockChain.DIFFICULTY];
Arrays.fill(target, '0');

String hashTarget = String.valueOf(target);

for (int i = 1; i < BLOCK_CHAIN.size(); i++) { //GenesisBlock 은 제외한다.
currentBlock = BLOCK_CHAIN.get(i);
previousBlock = BLOCK_CHAIN.get(i - 1);

if (currentBlock.getHash().equals(currentBlock.calculateHash()) == false) { //만들어 놓은 Hash값과 계산한 Hash값이 같은지 검증!
System.out.println("Not Equals Current Block Hash!!");
return false;
}

if (currentBlock.getPreviousHash().equals(previousBlock.getHash()) == false) {
System.out.println("Not Equals Previous Block Hash!!");
return false;
}

if (currentBlock.getHash().substring(0, DIFFICULTY).equals(hashTarget) == false) {
System.out.println("This block hasn't been mined");
return false;
}

}

return true;
}
}



참고 페이지

 - https://medium.com/programmers-blockchain/create-simple-blockchain-java-tutorial-from-scratch-6eeed3cb03fa

 - http://guruble.com/java-%EC%BD%94%EB%93%9C%EB%A1%9C-%EC%9D%B4%ED%95%B4%ED%95%98%EB%8A%94-%EB%B8%94%EB%A1%9D%EC%B2%B4%EC%9D%B8blockchain/

'BlockChain' 카테고리의 다른 글

Java로 배워보는 BlockChain  (0) 2018.05.02
블록체인 관련 기본 용어정리.  (0) 2018.02.23

1. --save

 - 응용 프로그램을 실행하는 데 필요한 패키지를 저장하는 데 사용

 - '-S'로 줄여 쓸 수 있음.

 - package.json 이 존재하면  dependencies 에 추가된다.


npm install [package_name] --save

or

npm install [package_name] -S


2. --save-dev

 - 개발 목적으로 패키지를 저장하는 데 사용

 - '-D'로 줄여 쓸 수 있다.

 - package.json 이 존재하면 devDependencies 에 추가된다.

 - mocha 등 unit test 등 추가할 때 사용...


npm install [package_name] -save-dev

or

npm install [package_name] -D


'프로그래밍 > Node.js' 카테고리의 다른 글

[Electron.js] Bootstrap 4 사용하기.  (0) 2018.09.11
npm에서 --save, --save-dev 옵션  (0) 2018.05.02
Mongoose 사용하기.  (0) 2016.08.22

+ Recent posts