2019의 게시물 표시

[Spring] spring-boot 2.1(SpringFramework 5.1)에서 없어진 기능, JSONP 간단하게 구현하기

안녕하세요, 하마연구소입니다. SpringFramework에서 JSONP 처리를 기본 기능으로 제공하였지만, 스프링부트 2.1(스프링프레임워크 5.1)부터 없어졌습니다. 이미 Deprecated 처리되어 언제가는 없어질 것을 예상했지만, 담당하고 있는 시스템에서는 아직 JSONP가 필요한 상황입니다. 없어진 AbstractJsonpResponseBodyAdvice.java 소스 https://github.com/spring- projects /spring-framework/blob/5.0.x/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/AbstractJsonpResponseBodyAdvice.java Spring에서는 기본 기능으로 빠졌어도 3rd 파트 라이브러리가 있겠지 싶어 폭풍검색을 했지만 찾을 수 없었습니다. 그래서 그냥 직접 구현하려고 하였지만, 은근히 스프링 코어쪽 소스를 이곳저곳 건드려야하는 복잡함을 느꼈습니다. 그래서 최소한의 소스로 최대한 직관적으로 JSONP를 처리할 수 있도록 구현했습니다. JsonpAdvice.java ControllerAdvice로 request 파라미터에 jsonp 또는 callback이 있으면 JSONP로 처리하기 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 import org.apache.commons.lang3.StringUtils ; import org.springframework.core.MethodParameter ; import org.springframework.http.MediaType ; import org.springframework.http...

[Spring] spring-vault에서 @VaultPropertySource 여러개 사용하면 안되는 이유

안녕하세요, 하마연구소 입니다. 스프링 기반의 어플리케이션을 개발할 때, 환경설정으로 보안정보를 다루기 위하여 Vault를 이용합니다. 일반적으로 가장 간단하게 Vault를 이용하는 방법은 @VaultPropertySource 또는 @VaultPropertySources 어노테이션을 사용하는 것입니다. 1 2 3 4 5 6 7 8 9 10 11 12 import org.springframework.context.annotation.Configuration ; import org.springframework.vault.annotation.VaultPropertySource ; @Configuration @VaultPropertySource (value = { "secret/hippolab/wallet1" , "secret/hippolab/wallet2" , "secret/hippolab/wallet3" , "secret/hippolab/wallet4" }) public class VaultConfig { } 위 샘플코드에서는 wallet1, wallet2, wallet3, wallet4에 선언된 모든 환경설정은 어플리케이션 로딩시에 스프링 MutablePropertySources에 포함되어 ${vault.properties1}과 같이 쉽게 사용할 수 있습니다. 그러나 어플리케이션을 만들다보면 여러개의 @VaultPropertySource 어노테이션을 서로 다른 파일에 작성해야할 경우가 있습니다. 이럴때는 아래와 같이 VaultConfig1.java와 VaultConfig2.java 파일에 나눠서 코딩하였습니다. 1 2 3 4 5 6 7 8 9 10 11 12 import org.springframework.context.annotation.Configuratio...

[뉴스] 인류가 최초로 관측한 블랙홀 모습

이미지
안녕하세요, 하마연구소입니다. 블랙홀이 실제로 존재하는지 처음으로 발견되었다네요. 지구에서 거리가 5천5백만 광년 거리에 있다니, 얼마나 먼지 전혀 감이 않오네요. 빛의 속도로 5500만년 떨어져 있는것을 어떻게 촬영한 것일까? 정말 신기하고 대단하네요. 무엇보다 지금으로부터 104년전인 1915년에 제시된 아인슈타인의 일반상대성이론이 이번 블랙홀 관측으로 입증되었다고 합니다. 아인슈타인도 대단합니다. 원문: https://news.v.daum.net/v/20190410221158578 참고로 아래는 블랙홀이 무엇인지 설명한 기사입니다. 원문: https://news.v.daum.net/v/20190410221356600 또한, 위키에 정리된 블랙홀과 일반상대성일론 설명입니다. Wikipedia 블랙홀: https://ko.wikipedia.org/wiki/블랙홀 Wikipedia 일반상대성이론: https://ko.wikipedia.org/wiki/일반_상대성이론

YouTube(유튜브) 동영상의 썸네일 이미지 추출하는 방법

이미지
안녕하세요, 하마연구소입니다. 살다보면 YouTue(유튜브) 동영상의 특정 장면을 얻어야 경우가 있습니다. 이럴때는 동영상을 정지 시켜두고 화면 캡쳐를 하거나, 별도 레코딩 프로그램으로 녹화한 후에 원하는 곳의 화면을 얻을 수 있습니다. 귀찮습니다. 특별히 원하는 위치의 장면을 이미지로 얻는 것이 아니라면, 기본 썸네일 이미지를 쉽게 얻을 수 있는 방법이 있습니다. 썸네일은 YouTube에서 자동 추출되거나 동영상 게시자가 업로드한 별도 이미지가 있으며, 이 썸네일을 얻기 위해서는 공식적으로 YouTube Developers에서 제공하는 API를 사용해야합니다. YouTube Developers: https://developers.google.com/youtube/ YouTube Data API (v3): https://developers.google.com/youtube/v3/getting-started?hl=ko 더 귀찮습니다. 아주 쉽고 간단하게 원하는 YouTube 동영상의 썸네일을 얻을 수 있는 방법을 소개합니다. 이 방법이 공식적인 것인지는 검토안해봤지만, 이미 널리 퍼졌고 많은 곳에서 사용하고 있는 것으로 보아 그냥 믿고 사용해도 될 듯 합니다.

[Java] Gson, Jackson(ObjectMapper)의 JSON 문자열을 pretty printing하는 방법

안녕하세요, 하마연구소입니다. 자바에서 JSON 파싱 및 변환을 위하여 많이 사용하는 Gson과 Jackson(ObjectMapper)에서 JSON 문자열을 출력할 때, 이쁘게 출력(pretty printing)하는 간단한 방법을 알려드리겠습니다. 먼저 Gson에서 pretty printing 설정하는 방법입니다. print( ' helloMyObject myObject = new MyObject(); Gson gson = new GsonBuilder() .setPrettyPrinting() .create(); String jsonString = gson.toJson(myObject); world ! ' ) 그리고 ObjectMapper에서 pretty printing 설정하는 방법입니다. MyObject myObject = new MyObject(); ObjectMapper objectMapper = new ObjectMapper(); String jsonString = objectMapper .writerWithDefaultPrettyPrinter() .writeValueAsString(myObject); 감사합니다.

[Spring] ConcurrentKafkaListenerContainerFactoryConfigurer를 사용하고 싶다.

안녕하세요, 하마연구소입니다. 스프링 어플리케이션에서 카프카 토픽에서 값을 쉽게 가져오기 위하여 @KafkaListener 어노테이션을 사용합니다. 여러개의 Kafka 서버에 접근해야할 필요가 있어서, 즉 @KafkaListener 어노테이션을 여러개 사용해야 해서, KafkaListenerContainerFactory를 수동으로 만들어야했습니다. 기왕 만드는김에 최대한 Spring에서 기본적으로 동작하는 방식으로 처리하려고 하니, ConcurrentKafkaListenerContainerFactoryConfigurer 이 녀석을 사용해야했습니다. (아따 이름 엄청 기네요~~~) spring-boot 버전 1.5.19를 사용하고 있으며, 그에따라 spring-boot-autoconfigure도 버전 1.5.19 입니다. 아래는 ConcurrentKafkaListenerContainerFactoryConfigurer.java 파일입니다. /* * Copyright 2012-2016 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, eithe...

[Spring] Hibernate에서 "Could not build ClassFile" 발생하는 오류 해결

안녕하세요, 하마연구소입니다. spring-boot 버전 1.4.2에서 현재 1.X 버전 최고인 1.5.19로 업데이트 하였습니다. 한 프로젝트에 Maven 모듈로 여러 어플리케이션이 존재하는 구성입니다. 2개 어플리케이션만 제외하고 나머지 어플리케이션은 잘 수행됩니다. 이 2개 어플리케이션에서는 처음 로딩 중 아래와 같은 예외가 발생합니다. 더 특이한 것은 IDE에서 바로 실행시키면(로컬환경) 잘 됩니다. 서버환경에서만 안 됩니다. 환장하겠습니다. Exception in thread "main" java.lang.ExceptionInInitializerError at com.hippolab.MyTopologyRunner.getApplicationContext(MyTopologyRunner.java: 39 ) at com.hippolab.AbstractTopologyRunner.run(AbstractTopologyRunner.java: 30 ) at com.hippolab.MyTopologyRunner.main(MyTopologyRunner.java: 34 ) Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name ' entityManagerFactory ' defined in class path resource [ com / hippolab / config / MyDatabaseConfig.class ] : Invocation of init method failed; nested exception is org.hibernate.boot.archive.spi.ArchiveException: Could not build ClassFile at org.springframework.beans.factory.support.Abstrac...