1. X Stream

 - IntStream 은 int를 지정한 범위 내에서 반복문을 동작함

 - LongStream dms Long을 지정한 범위 내에서 반복문을 동작함


2. range, rangeclosed

 - range는 endExclusive 값 전까지만 반복

 - rangeClosed는 endExclusive 를 포함하여 반복


3. IntStream

 - 소스

public class IntRangeTest {

public static void main(String[] args) {
int startNum = 1;
int endNum = 9;

intRangeTest(startNum, endNum);
System.out.println("\n");
intRangeClosedTest(startNum, endNum);

System.out.println("\n");
}

private static void intRangeTest(int startNum, int endNum) {
System.out.print("IntRange Test 1 : ");
IntStream.range(startNum, endNum).forEach(System.out::print);

System.out.println();

System.out.print("IntRange Test 2 : ");
for (int i = startNum; i < endNum; i++) {
System.out.print(i);
}
}

private static void intRangeClosedTest(int startNum, int endNum) {
System.out.print("IntRangeClosed Test 1 : ");
IntStream.rangeClosed(startNum, endNum).forEach(System.out::print);

System.out.println();

System.out.print("IntRangeClosed Test 2 : ");
for (int i = startNum; i <= endNum; i++) {
System.out.print(i);
}
}
}


 - 결과



4. LongStream

 - 소스

public class LongRangeTest {

public static void main(String[] args) {
long startNum = 1L;
long endNum = 9L;

longRangeTest(startNum, endNum);
System.out.println("\n");
longRangeClosedTest(startNum, endNum);

System.out.println("\n");
}

private static void longRangeTest(long startNum, long endNum) {
System.out.print("LongRange Test 1 : ");
LongStream.range(startNum, endNum).forEach(System.out::print);

System.out.println();

System.out.print("LongRange Test 2 : ");
for (long i = startNum; i < endNum; i++) {
System.out.print(i);
}
}

private static void longRangeClosedTest(long startNum, long endNum) {
System.out.print("LongRangeClosed Test 1 : ");
LongStream.rangeClosed(startNum, endNum).forEach(System.out::print);

System.out.println();

System.out.print("LongRangeClosed Test 2 : ");
for (long i = startNum; i <= endNum; i++) {
System.out.print(i);
}
}
}

 

 - 결과

업무 중에 엑셀 다운로드 기능에 "암호 걸기"가 필요해짐.


1. pom.xml에 필요한 dependencyt 추가

<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>3.16</version>
</dependency>


2. 샘플

 - 아래와 같이 설정해주면 잘 나온다.

EncryptionInfo encryptionInfo = new EncryptionInfo(EncryptionMode.agile);
Encryptor encryptor = encryptionInfo.getEncryptor();
encryptor.confirmPassword(password);


 - 결과


3. 전체소스

import lombok.extern.slf4j.Slf4j;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.poifs.crypt.EncryptionInfo;
import org.apache.poi.poifs.crypt.EncryptionMode;
import org.apache.poi.poifs.crypt.Encryptor;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.junit.Test;

import java.io.*;
import java.security.GeneralSecurityException;
import java.util.Arrays;
import java.util.List;

@Slf4j
public class ExcelTest {

@Test
public void 엑셀파일에_암호걸기() {
final String password = "1234";
final String savePath = "c:\\temp\\excel2.xlsx";

List<String> tmpData = Arrays.asList("Java", "JavaScript", "Python", "GoLang");

try (Workbook wb2 = new XSSFWorkbook();
ByteArrayOutputStream fileOut = new ByteArrayOutputStream();
FileOutputStream fos = new FileOutputStream(savePath);) {

Sheet sheet1 = wb2.createSheet("Sheet1");

//Write Excel File
for (int i = 0; i < tmpData.size(); i++) {
String data = tmpData.get(i);

Row row = sheet1.createRow(i);
Cell cell = row.createCell(0);

cell.setCellValue(data);

}

wb2.write(fileOut);

InputStream filein = new ByteArrayInputStream(fileOut.toByteArray());
OPCPackage opc = OPCPackage.open(filein);

POIFSFileSystem fileSystem = new POIFSFileSystem();

EncryptionInfo encryptionInfo = new EncryptionInfo(EncryptionMode.agile);
Encryptor encryptor = encryptionInfo.getEncryptor();
encryptor.confirmPassword(password);

opc.save(encryptor.getDataStream(fileSystem));
fileSystem.writeFilesystem(fos);

log.info("Create Excel File!!");

} catch (IOException e) {
log.error(e.getMessage(), e);

} catch (InvalidFormatException e) {
log.error(e.getMessage(), e);

} catch (GeneralSecurityException e) {
log.error(e.getMessage(), e);
}

}

}


1. 현상

 - Spring boot 1.5.14 로 프로젝트를 세팅하는 중 에러 발생.

 - Lombok Annotation 적용해놓은 class에서 컴파일 에러

 - Github 이슈함 검색... 버그...


@Data
@NoArgsConstructor
@AllArgsConstructor
public class Sample {
private String test1;
private String test2;

}


2. 해결법

 - @NoArgsConstructor 를 @Data 보다 위에 선언해야한다.


@NoArgsConstructor
@AllArgsConstructor
@Data
public class Sample {

private String test1;
private String test2;

}


* 관련 문서

https://github.com/rzwitserloot/lombok/issues/1703

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.


해당 내용은 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일 경우 해당 옵션으로 아이템 수를 체크할 수 있다.


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. json-schema-validator란?

 - xml의 DTD 와 유사함.

 - Json 스키마(http://json-schema.org/) 포멧이 유효한지 확인해줌.

 - 웹사이트에서 해당 내용을 테스트해볼 수 있다.(링크)


2. library

 - 기존에 jackson을 많이 사용하므로, fasterxml에서 제공하는 jsonSchema 라이브러리를 사용하려고함.

 1) pom.xml

<dependency>
<groupId>com.github.java-json-tools</groupId>
<artifactId>json-schema-validator</artifactId>
<version>2.2.8</version>
</dependency>


3. 간단한 Json 설명

{
"$schema": "http://json-schema.org/draft-04/schema#",
"title": "/etc/fstab", /* JSON에 대한 제목 */
"description": "JSON representation of /etc/fstab", /* JSON에 대한 설명 */
"type": "object", /* 해당 Json의 최상위 객체 타입, http://json-schema.org/latest/json-schema-validation.html#rfc.section.6.1.1 참고 */
"properties": {
"swap": {
"$ref": "#/definitions/mntent" /* 하단 definitions내용을 참조 합니다. */
}
},
"patternProperties": {
"^/([^/]+(/[^/]+)*)?$": {
"$ref": "#/definitions/mntent"
}
},
"required": /* 필수 값에 대한 속성 정의 */ [
"/",
"swap"
],
"additionalProperties": false,
"definitions": {
"mntent": {
"title": "mntent",
"description": "An fstab entry",
"type": "object", /* 객체 타입 */
"properties": {
"device": {
"type": "string"
},
"fstype": {
"type": "string"
},
"options": {
"type": "array",
"minItems": 1, /* 아이템의 최소 단위 */
"items": {
"type": "string"
}
},
"dump": {
"type": "integer",
"minimum": 0,
"maximum": 0 /* 아이템의 최대 단위 */
},
"fsck": {
"type": "integer",
"minimum": 0
}
},
"required": [
"device",
"fstype"
],
"additionalItems": false
}
}
}



4. 샘플 소스

 1) Basic ( https://github.com/java-json-tools/json-schema-validator/blob/master/src/main/java/com/github/fge/jsonschema/examples/Example1.java)

 - 소스

final String urlPrefix = "https://raw.githubusercontent.com/java-json-tools/json-schema-validator/"
+ "master/src/main/resources/com/github/fge/jsonschema/examples/";

final JsonNode fstabSchema = JsonLoader.fromURL(new URL(urlPrefix + "fstab.json"));
final JsonNode good = JsonLoader.fromURL(new URL(urlPrefix + "fstab-good.json"));
final JsonNode bad = JsonLoader.fromURL(new URL(urlPrefix + "fstab-bad.json"));
final JsonNode bad2 = JsonLoader.fromURL(new URL(urlPrefix + "fstab-bad2.json"));

final JsonSchemaFactory factory = JsonSchemaFactory.byDefault();

final JsonSchema schema = factory.getJsonSchema(fstabSchema);

ProcessingReport report;

report = schema.validate(good); //SUCCESS
print(report);

report = schema.validate(bad); //FAILURE
print(report);

report = schema.validate(bad2); //FAILURE
print(report);

 - 결과


 

 2) message custom(https://github.com/java-json-tools/json-schema-validator/blob/master/src/main/java/com/github/fge/jsonschema/examples/Example8.java)

 - 소스(valid)

final JsonNode customSchema = JsonLoader.fromURL(new URL(URL_PREFIX + "custom-fmt.json"));
final JsonNode good = JsonLoader.fromURL(new URL(URL_PREFIX + "custom-fmt-good.json"));
final JsonNode bad = JsonLoader.fromURL(new URL(URL_PREFIX + "custom-fmt-bad.json"));

//@formatter:off
final Library library = DraftV4Library
.get()
.thaw()
.addFormatAttribute("uuid", UUIDFormatAttribute.getInstance())
.freeze();
//@formatter:on

final String key = "invalidUUID";
final String value = "Not a valid UUID";
final MessageSource source = MapMessageSource.newBuilder().put(key, value).build();
final MessageBundle bundle = MessageBundles.getBundle(JsonSchemaValidationBundle.class).thaw().appendSource(source).freeze();

final ValidationConfiguration cfg = ValidationConfiguration.newBuilder().setDefaultLibrary("http://my.site/myschema#",
library).setValidationMessages(bundle).freeze();

final JsonSchemaFactory factory = JsonSchemaFactory.newBuilder().setValidationConfiguration(cfg).freeze();

final JsonSchema schema = factory.getJsonSchema(customSchema);

ProcessingReport report;

report = schema.validate(good);
print(report);

report = schema.validate(bad);
print(report);


  - 소스(UUIDFormatAttribute)

private static class UUIDFormatAttribute extends AbstractFormatAttribute {
private static FormatAttribute INSTANCE = new UUIDFormatAttribute();

private UUIDFormatAttribute() {
super("uuid", NodeType.STRING);
}

public static FormatAttribute getInstance() {
return INSTANCE;
}

@Override
public void validate(final ProcessingReport report, final MessageBundle bundle, final FullData data) throws ProcessingException {
final String value = data.getInstance().getNode().textValue();
try {
UUID.fromString(value);

} catch (IllegalArgumentException ignored) {
report.error(super.newMsg(data, bundle, "invalidUUID").put("input", value));
}
}
}

  - 결과


5. 전체소스



 * 참고링크

  - https://github.com/java-json-tools/json-schema-validator

  - http://json-schema.org/latest/json-schema-validation.html

  - http://json-schema-validator.herokuapp.com/

  - http://json-schema.org/example2.html

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

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
try-catch-resources  (0) 2018.04.11

1. 파일 삭제

 - 시스템이 종료될 때 파일 삭제하고 싶음


2. Thread를 생성해서 처리함.

 - jdk1.8 미만

Runtime.getRuntime().addShutdownHook(new Thread() {

@Override
public void run() {
new File("").delete(); //File Delete Code

}
});


 - jdk 1.8 이상

Runtime.getRuntime().addShutdownHook(new Thread(() -> {
new File("").delete(); //File Delete Code
}));

3. Apache Commons-io를 사용

 - 코드 샘플

try {
FileUtils.forceDeleteOnExit(new File("fileName"));
} catch (IOException e) {
e.printStackTrace();
}

 - 메소드

/**
* Schedules a file to be deleted when JVM exits.
* If file is directory delete it and all sub-directories.
*
* @param file file or directory to delete, must not be {@code null}
* @throws NullPointerException if the file is {@code null}
* @throws IOException in case deletion is unsuccessful
*/
public static void forceDeleteOnExit(final File file) throws IOException {
if (file.isDirectory()) {
deleteDirectoryOnExit(file);
} else {
file.deleteOnExit();
}
}


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

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
try-catch-resources  (0) 2018.04.11
public static void main(String[] args){}  (0) 2018.04.03

1. Tuple

 - 간단하게 만들어서 쓰고 싶다....


2. 소스

 - Tuple class


3. 라이브러리

 - jdk 7부터 javafx.util.Pair class 추가됨.

 - Common Lang 패키지 내에 있는 (org.apache.commons.lang3.tuple.Pair<L,R>)

 - https://www.javatuples.org/ 

1. try-catch-resources

 - try (...) 안에 선언된 입출력 스트림 등의 리소스 객체의 'close()' 메소드를 호출해줌. 자원관리를 잘 해줌.

 - java 7 에서 추가된 기능.


2. 소스 비교

 1) 1.6 이전

FileInputStream fs = null;
try {
fs = new FileInputStream("file.txt");

} catch (IOException e) {
System.out.println(e.getMessage());
} finally {
if (fs != null) {
try {
fs.close();
} catch (IOException e1) {
System.out.println(e1.getMessage());
}
}
}

 2) 1.7 이상

  - 단, 인터페이스인 java.lang.AutoCloseable를 구현해야 사용가능함.

  - 귀찮은 finally 안에 소스를 안만들어도 된다. 

try (FileInputStream fs = new FileInputStream("file.txt");) {

} catch (IOException e) {
System.out.println(e.getMessage());
}

 - 커스텀하게 구현할 수도 있다.

public class CustomFileInputStream implements AutoCloseable {

@Override
public void close() throws Exception {

}
}

3. Close 동작 확인

 1) 정상 동작시에 Close 메소드 호출 여부 확인

(1) 샘플 소스 확인

 - 실행 시킬 Main Class

public class Sample {

public static void main(String[] args) throws Exception {

try (CustomFileInputStream cfs = new CustomFileInputStream()) {
System.out.println("Try 안에 호출 잘 됩니다.");

} catch (Exception e) {
System.out.println("에외가 발생했습니다.");

}

System.out.println("완료!");
}

}


 - Custom한 Class

/**
* Custom 메소드
*
* @author akageun
*/
public class CustomFileInputStream implements AutoCloseable {

@Override
public void close() throws Exception {
System.out.println("Close 메소드가 호출 되었습니다.");
}
}

(2) 결과



 2) 예외가 발생 했을 때 Close 메소드 호출 여부 확인

(1) 샘플 소스 확인

 - 실행 시킬 Main Class

public class Sample {

public static void main(String[] args) throws Exception {

try (CustomFileInputStream cfs = new CustomFileInputStream()) {
System.out.println("Try 안에 호출 잘 됩니다.");
throw new RuntimeException("테스트 예외 호출 ");


} catch (Exception e) {
System.out.println("에외가 발생했습니다. " + e.getMessage());

}

System.out.println("완료!");
}

}

 - Custom한 Class는 위에 Class와 동일한걸로 사용

(2) 결과

 

+ Recent posts