본문 바로가기

Java

StreamingResponseBody 사용시 주의점 파일 다운로드 API 기능을 개발하는 과정에서 삽질한 경험를 공유드립니다 ㅎ 목적​Streaming 형태의 Response로 제공하고 싶었습니다.그래서 구글링해보니 Spring에선 아래 3가지 Response를 제공합니다.​참고 : Spring 4.2 이상- ResponseBodyEmitter- SseEmitter- StreamingResponseBody​이 중 StreamingResponseBody는 비정형화된 Byte 응답을 Streaming형태로 줄 때 사용합니다.StreamingResponseBody를 이용해 Controller와 Service는 아래와 같이 구현했습니다.​Controller @GetMapping("/sample") public StreamingResponseBody downloa..
[Java] 여러 파일을 묶은 하나의 압축파일(Zip) 만들기 배경- 여러 File들을 읽어서 하나의 압축 파일로 만들 수 없을까? 참고- http://www.baeldung.com/java-compress-and-uncompress Junit Test 환경에서 로컬에 파일쓰기 @Test public void testWriteLocalZipFile() throws Exception { String path = "D:\\temp\\yst"; FileOutputStream zipFileOutputStream = new FileOutputStream(path + "/files.zip"); ZipOutputStream zipOutputStream = new ZipOutputStream(zipFileOutputStream); ZipEntry zipEntry = new Zip..
[Json] Jackson을 이용해 추상, 인터페이스 객체 별로 구현체 구분하기 Json String을 구현체별로 매핑할 수 없을까? - String 형태의 Json을 구현체 모델로 매핑하는 방법은 쉽습니다. - Json의 프로퍼티 이름과 모델의 필드(Setter/Getter) 이름을 자동으로 매핑해주기 때문입니다. ㄴ 기존 사용 방법은 생략하겠습니다. SampleModelImpl result = new ObjectMapper().readValue(json, SampleModelImpl.class); - 하지만 인터페이스나 추상클래스 타입이라면 이야기는 달라집니다. 왜냐하면 구현체가 아니다보니 어떤 하위클래스들을 사용할지 모르기 때문입니다. - 이를 해결하기 위해 Jack에서 다양한 어노테이션들을 제공해주고 있습니다. - A라는 인터페이스가 있고 B, C라는 구현체가 있다고 가정하면..
[Spring] Stream 형태로 Response 응답 주기 (feat. MyBatis, Observer) 환경 Spring Version : 4.2 이상 MySQL + MyBatis 문서 Http Stream Return은 총 3가지가 있는듯하다. (Spring 4.2부터) - ResponseBodyEmitter : https://docs.spring.io/autorepo/docs/spring-framework/4.3.5.RELEASE/javadoc-api/org/springframework/web/servlet/mvc/method/annotation/ResponseBodyEmitter.html - SseEmitter : https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/servlet/mvc/meth..
[Java] Executor를 이용한 병렬 처리 자바 내부에서 여러 쓰레드를 생성하여 병렬로 수행해야할 때가 있다. 이 경우 Runnable이나 Thread를 직접 생성하는 경우가 있는데 이럴 필요 없이 java.util.concurrent의 패키지에 있는 코어 기능을 사용하는게 더 편하다. JDK가 1.5이상이면 사용할 수 있다. 정말 오래된 프로젝트가 아닌 이상.. 있더라도 제네릭을 쓰기위해선 1.5라도 올리는게 좋을 것 같다 Executors, ExecutorService : ThreadPool이라고 생각하면 된다. Callable : Runnable과 유사하지만 Runnable은 return값이 void이고 Callable은 작업할 내용과 리턴 값을 지정할 수 있다. Future : 비동기로 수행한 쓰레드가 수행한 결과를 담는다. 전체 샘플 코..
[Spring] 기본 생성자가 없는 객체 바인딩시키기 참고) Bean 설정이 아닙니다. Controller에서 매핑된 URL로 메서드가 실행되는데요~ 이 경우 파라메터에 모델을 선언했다면 URL queryString에 있는 프로퍼티 값이 모델 멤버(setter)와 동일하다면 자동으로 Binding됩니다. public class Foo { private int id; public void setId(int id) { this.id = id; } public int getid() { return this.id; } } @Controller public class FooController { @RequestMapping("/foo") public String getFooView(Foo fooModel) { return "foo"; } } - 인자가 없는 기본 생..
모델 클래스에 인터페이스 구현 설계에 대한 내용 웹 프로그래밍에서 MVC패턴을 사용하는데 Model에 대해 인터페이스를 만드는 것이 과연.. 좋을까? StackOverflow The general answer is no, because you should never add code without having a specific, concrete reason for it, and there is no general reason for such an interface. 일반적인 대답은 "노"다. 모델에 인터페이스를 구현하는 것은 명확한 이유없이 코드를 추가하면 안되기 때문이다. 그리고 인터페이스 대한 일반적인 이유가 아니다. That being said, sometimes there can be a good reason. 그렇긴해도, 때때로 좋은 사유가 ..
package javax.crypto does not exist package javax.crypto does not exist 라는 에러는 JDK의 jce.jar를 찾지 못해 발생하는 에러입니다. 사실.. 윈도우 로컬 개발환경에선 Maven Test, Junit Test 모두 성공해서 실패하길래 당황했는데요~.. 이를 해결하기 위해선 컴파일 시점에 jce.jar의 경로를 주입시켜줘야합니다. bootclasspath="${java.home}/lib/rt.jar:${java.home}/lib/jce.jar" 혹은 메이븐의 pom으로도 수정이 가능합니다. Maven Pom.xml ${java.home}/lib/rt.jar:${java.home}/lib/jce.jar 참고 - http://stackoverflow.com/questions/14935447/why-am-i-g..
MySQL과 Java AES 128 암호/복호 동기화하기 (대칭키, 양방향) Java에서 AES 128 로 암호화한걸 MySQL 쿼리로 조회해야한다던지 DB 기존 데이터를 암호화 마이그레이션을 진행하기 위해 MySQL과 Java의 암/복호화가 필요합니다. 삽질끝에 ... MySQL은 AES 128bit만 적용이 가능합니다. 그리고 암호화모드는 ECB만 가능하며 CBC는 적용할 수 없습니다. (추가로 알아보니.!!! MySQL 5.5까지만 디폴드.. 5.6부터는 암호화 방식이 변경 가능합니다!) - MySQL 5.6부터는 block_encryption_mode 변수 값을 통해 암호화 방식을 변경할 수 있습니다. https://dev.mysql.com/doc/refman/5.6/en/server-system-variables.html#sysvar_block_encryption_mod..
AES 암호화/복호화 구글링으로 관련된 정보를 찾아보니 많이 나왔다. 이 중 나에게 필요한 것만 다시 추출하여 만들어보았다. import javax.crypto.Cipher; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; import org.apache.commons.codec.binary.Base64; /** * @author 윤성탁 */ public class EncryptionUtils { private static final String AES_CBC_PKCS5 = "AES/CBC/PKCS5Padding"; private static final String AES = "AES"; public static String e..