<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>henry_choi.log</title>
        <link>https://velog.io/</link>
        <description>삽질은 한번만... 제발...</description>
        <lastBuildDate>Mon, 04 Sep 2023 00:42:48 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <copyright>Copyright (C) 2019. henry_choi.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/henry_choi" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[Spring Cloud Data Flow #2 설치하기]]></title>
            <link>https://velog.io/@henry_choi/Spring-Cloud-Data-Flow-2-%EC%84%A4%EC%B9%98%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@henry_choi/Spring-Cloud-Data-Flow-2-%EC%84%A4%EC%B9%98%ED%95%98%EA%B8%B0</guid>
            <pubDate>Mon, 04 Sep 2023 00:42:48 GMT</pubDate>
            <description><![CDATA[<ul>
<li>mac os 기반으로 작성되었습니다. </li>
<li>homebrew 설치는 작성하지 않습니다.</li>
<li>2023.09.04 일자를 기준으로 작성되었습니다. ( 최신버전이 다를수 있음 )</li>
</ul>
<h3 id="1-wget-설치">1. wget 설치</h3>
<pre><code>brew install wget</code></pre><h3 id="2-spring-cloud-data-flow-설치">2. Spring Cloud Data Flow 설치</h3>
<pre><code>wget https://repo.maven.apache.org/maven2/org/springframework/cloud/spring-cloud-dataflow-server/2.10.2/spring-cloud-dataflow-server-2.10.2.jar
wget https://repo.maven.apache.org/maven2/org/springframework/cloud/spring-cloud-dataflow-shell/2.10.2/spring-cloud-dataflow-shell-2.10.2.jar
wget https://repo.maven.apache.org/maven2/org/springframework/cloud/spring-cloud-skipper-server/2.9.2/spring-cloud-skipper-server-2.9.2.jar</code></pre><h3 id="3-install-messaging-middleware--rabbitmq-">3. Install Messaging Middleware ( RabbitMQ )</h3>
<pre><code># 설치
brew install rabiitmq
</code></pre><pre><code># 실행
rabbitmq-server </code></pre><p><img src="https://velog.velcdn.com/images/henry_choi/post/28c6152c-c49f-4d1f-ad2f-f3992542a7de/image.png" alt=""></p>
<pre><code># 백그라운드 실행
brew services start rabbitmq
</code></pre><p><img src="https://velog.velcdn.com/images/henry_choi/post/fe358bae-c1e4-4ec2-8070-eb8b2c5db0b8/image.png" alt=""></p>
<pre><code># 유저 및 권한생성
➜  SCDS rabbitmqctl add_user user user
Adding user &quot;user&quot; ...
Done. Don&#39;t forget to grant the user permissions to some virtual hosts! See &#39;rabbitmqctl help set_permissions&#39; to learn more.
➜  SCDS rabbitmqctl set_user_tags user administrator
Setting tags for user &quot;user&quot; to [administrator] ...</code></pre><pre><code># GUI환경의 관리화면
http://localhost:15672
guest/guest</code></pre><p><img src="https://velog.velcdn.com/images/henry_choi/post/d4a2f9db-fd41-487f-a651-a39b43bb9bef/image.png" alt=""></p>
<h3 id="4-data-flow-실행">4. Data Flow 실행</h3>
<pre><code>java -jar spring-cloud-skipper-server-2.9.2.jar
java -jar spring-cloud-dataflow-server-2.10.2.jar
java -jar spring-cloud-dataflow-shell-2.10.2.jar</code></pre><p><a href="http://localhost:9393/dashboard/">http://localhost:9393/dashboard/</a>
<img src="https://velog.velcdn.com/images/henry_choi/post/0cb2e495-5b7f-440e-8ceb-dad44ce595cd/image.png" alt=""></p>
<h3 id="5-data-flow-실행--작성대기중-">5. Data Flow 실행 ( 작성대기중 )</h3>
<ul>
<li>Cloud Foundry</li>
<li>Kubernetes</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[Spring Cloud Data Flow #1 시작하기]]></title>
            <link>https://velog.io/@henry_choi/Spring-Cloud-Data-Flow-1-%EC%8B%9C%EC%9E%91%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@henry_choi/Spring-Cloud-Data-Flow-1-%EC%8B%9C%EC%9E%91%ED%95%98%EA%B8%B0</guid>
            <pubDate>Sun, 03 Sep 2023 06:27:13 GMT</pubDate>
            <description><![CDATA[<p><a href="https://spring.io/projects/spring-cloud-dataflow">https://spring.io/projects/spring-cloud-dataflow</a>
<a href="https://dataflow.spring.io/getting-started/">https://dataflow.spring.io/getting-started/</a>
<a href="https://docs.spring.io/spring-cloud-dataflow-samples/docs/current/reference/htmlsingle/#spring-cloud-data-flow-samples-overview">https://docs.spring.io/spring-cloud-dataflow-samples/docs/current/reference/htmlsingle/#spring-cloud-data-flow-samples-overview</a></p>
<blockquote>
<h3 id="overview">OVERVIEW</h3>
<p>Microservice based Streaming and Batch data processing for Cloud Foundry and Kubernetes.
Spring Cloud Data Flow provides tools to create complex topologies for streaming and batch data pipelines. The data pipelines consist of <strong>Spring Boot</strong> apps, built using the <strong>Spring Cloud Stream</strong> or <strong>Spring Cloud Task</strong> microservice frameworks.
Spring Cloud Data Flow supports a range of data processing use cases, from ETL to import/export, event streaming, and predictive analytics.</p>
</blockquote>
<blockquote>
<h3 id="1-특징">1. 특징</h3>
</blockquote>
<ul>
<li>Spring 포트폴리오에 속한 Java와 Spring Boot 기반 프레임웍</li>
<li><strong>복잡한 데이터 통합과 처리 파이프라인을 구축, 배포, 운영</strong>
( 여러 마이크로서비스 또는 데이터 처리 단위를 연결 )</li>
<li><strong>실시간 데이터 스트림 처리가 가능 ( Kafka, RabbitMQ 등과 연동 )</strong></li>
<li>Spring Batch와 연계하여 배치 처리도 지원</li>
<li><strong>클러스터 관리 플랫폼(쿠버네틱스)을 이용하여 자동으로 스케일링</strong></li>
<li>기본적으로 다양한 모니터링 도구와 통합</li>
<li>기본적인 자체 스케줄링을 제공하지 않으며, 외부 스케줄러와 통합
( Quartz, Tivoli, Cron... )</li>
<li>트랜잭션 : Spring Batch와의 통합을 통해 관리 가능</li>
<li>대시보드 : 지원</li>
</ul>
<blockquote>
<h3 id="2-vs-airflow">2. vs AirFlow</h3>
</blockquote>
<ul>
<li>Python으로 개발되었고, 워크플로우도 Python 스크립트로 작성</li>
<li><strong>워크플로우를 DAG 형태로 모델링하며, 이를 통해 복잡한 의존성과 실행 순서를 관리</strong></li>
<li>쉽게 통합할 수 있는 풍부한 플러그인 시스템을 제공</li>
<li><strong>자체 스케줄러 내장</strong></li>
<li>주로 배치 처리에 사용되지만, 일부 사용 사례에서는 스트리밍 데이터 처리 가능</li>
<li>트랜잭션 : Python 스크립트나 외부 도구를 통해 구현 가능</li>
<li>대시보드 : 지원</li>
</ul>
<blockquote>
<h3 id="3-파이프라인">3. 파이프라인</h3>
</blockquote>
<ul>
<li>컴포넌트
   <strong>Source</strong>: 데이터의 출발점입니다. 예를 들어, HTTP 요청을 받거나, 메시지 큐에서 메시지를 수신하는 등의 역할을 수행합니다.
  <strong>Processor</strong>: 중간 처리 단계에서 데이터를 변환하거나 필터링합니다. 예를 들어, 데이터를 정제하거나 복잡한 계산을 수행할 수 있습니다.
  <strong>Sink</strong>: 데이터의 최종 목적지입니다. 예를 들어, 데이터베이스에 데이터를 저장하거나, 다른 시스템에 메시지를 보내는 등의 역할을 수행합니다.</li>
<li>작동 방식
  <strong>데이터 흐름</strong>: Source에서 데이터가 생성되고, Processor를 거쳐서 Sink로 전달됩니다. 이 과정이 파이프라인입니다.
  <strong>메시지 브로커</strong>: Source, Processor, Sink 사이의 데이터 통신은 일반적으로 메시지 브로커(예: Apache Kafka, RabbitMQ)를 통해 이루어집니다.
  <strong>스케일링</strong>: 각 컴포넌트는 독립적으로 스케일링이 가능합니다. 이는 매우 높은 수준의 유연성을 제공합니다.</li>
<li>정의와 배포
  <strong>DSL</strong>: SCDF에서는 스트림 DSL(Dataflow DSL)을 통해 파이프라인을 정의합니다. 이를 통해 간단한 텍스트 기반의 언어로 복잡한 데이터 흐름을 설계할 수 있습니다.
  <strong>대시보드 및 CLI</strong>: SCDF는 웹 대시보드와 명령어 줄 인터페이스를 통해 파이프라인을 쉽게 생성, 배포, 관리할 수 있습니다.</li>
</ul>
<blockquote>
<h3 id="4-실시간-데이터-스트림-처리">4. 실시간 데이터 스트림 처리</h3>
</blockquote>
<ul>
<li>데이터가 연속적으로 처리되는 파이프라인을 의미합니다.</li>
<li>웹 기반 대시보드를 통해 실시간 스트림을 모니터링할 수 있습니다.</li>
<li>스트림의 상태, 메트릭, 로그 등을 실시간으로 확인할 수 있습니다.</li>
<li>ex1) 실시간으로 로그를 분석해서 특정 패턴이나 에러 식별</li>
<li>ex2) 여러 데이터 소스에서 데이터를 실시간으로 수집해서 대시보드에 표시</li>
</ul>
<blockquote>
<h3 id="5-자동-스케일링">5. 자동 스케일링</h3>
</blockquote>
<ul>
<li>런타임 환경이나 인프라스트럭처에서 제공하는 스케일링 메커니즘을 활용</li>
<li>Kubernetes ( 자동 스케일링 )</li>
<li>Cloud Foundry ( App Autoscaler )</li>
<li>메시지 브로커를 통한 스케일링 ( 큐 사이즈나 레이턴시 )</li>
<li>Source, Processor, Sink 독립적인 앱으로 배포</li>
</ul>
<p>결과적으로 실시간 처리와 높은 병렬성이 필요한 경우에는 SCDF가, 
복잡한 워크플로우와 일정 기반의 배치 작업에는 Airflow가 더 적합할 수 있습니다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[mariadb 에서 원하는 날짜를 만들어보자]]></title>
            <link>https://velog.io/@henry_choi/mariadb-%EC%97%90%EC%84%9C-%EC%9B%90%ED%95%98%EB%8A%94-%EB%82%A0%EC%A7%9C%EB%A5%BC-%EB%A7%8C%EB%93%A4%EC%96%B4%EB%B3%B4%EC%9E%90</link>
            <guid>https://velog.io/@henry_choi/mariadb-%EC%97%90%EC%84%9C-%EC%9B%90%ED%95%98%EB%8A%94-%EB%82%A0%EC%A7%9C%EB%A5%BC-%EB%A7%8C%EB%93%A4%EC%96%B4%EB%B3%B4%EC%9E%90</guid>
            <pubDate>Thu, 27 Jul 2023 01:54:06 GMT</pubDate>
            <description><![CDATA[<ol>
<li><p>일별 계산 </p>
<pre><code># count : 기준날짜 기준으로 적용하려는 일수
select date_sub(now(), interval /*count*/ 5 day); # 빼기
select date_add(now(), interval /*count*/ 5 day); # 더하기</code></pre></li>
<li><p>월별 계산</p>
<pre><code># count : 기준날짜 기준으로 적용하려는 월수
select date_sub(now(), interval /*count*/ 1 month);
select date_add(now(), interval /*count*/ 1 month);</code></pre></li>
<li><p>주별 계산</p>
<pre><code>select
 date_sub
     (date_add
         (date_add(date(now()), interval -weekday(date(now())) day)
             , interval ((convert(/*3주전특정요일*/3, signed)) - weekday(date_add(date(now()), interval -weekday(date(now())) day))) day)
     ,interval
         case
             when weekday(date(now())) &lt; convert(/*주시작요일*/0, signed) then /*count*/3 + 1
             else /*count*/3
         end week) as 특정일</code></pre></li>
</ol>
<p>이상~~</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[springboot 기능플래그 설정]]></title>
            <link>https://velog.io/@henry_choi/springboot-%EA%B8%B0%EB%8A%A5%ED%94%8C%EB%9E%98%EA%B7%B8featureflag-%EC%84%A4%EC%A0%95</link>
            <guid>https://velog.io/@henry_choi/springboot-%EA%B8%B0%EB%8A%A5%ED%94%8C%EB%9E%98%EA%B7%B8featureflag-%EC%84%A4%EC%A0%95</guid>
            <pubDate>Wed, 26 Jul 2023 09:23:33 GMT</pubDate>
            <description><![CDATA[<ol>
<li><p>Component 생성</p>
<pre><code>@Component
@ConfigurationProperties(prefix=&quot;feature.flag&quot;)
@Getter
public class FeatureFlags {

 @Value(&quot;${feature.flag.isLocal}&quot;)
 private boolean isLocal;

 @Value(&quot;${feature.flag.isDev}&quot;)
 private boolean isDev;

 @Value(&quot;${feature.flag.isStg}&quot;)
 private boolean isStg;

 @Value(&quot;${feature.flag.isPrd}&quot;)
 private boolean isPrd;
}</code></pre></li>
<li><p>yml 파일 설정</p>
<pre><code>feature:
flag:
 isLocal: true
 isDev: true
 isStg: false
 isPrd: false</code></pre></li>
<li><p>Controller 설정 ( Service 동일 )</p>
<pre><code>// 생성자 선언 어노테이션
@RequiredArgsConstructor
public class Controller명 {
...
 // 생성자 선언
 private final FeatureFlags featureFlags;
...
     // 소스코드에 적용
     if(featureFlags.isDev()) {
         modelAndView.addObject(&quot;changeRoundBookingDateBtn&quot;, true);
     }</code></pre></li>
</ol>
<p>완료~~</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[영어공부 잘하는 법 - chatGPT4]]></title>
            <link>https://velog.io/@henry_choi/%EC%98%81%EC%96%B4%EA%B3%B5%EB%B6%80-%EC%9E%98%ED%95%98%EB%8A%94-%EB%B2%95-chatGPT4</link>
            <guid>https://velog.io/@henry_choi/%EC%98%81%EC%96%B4%EA%B3%B5%EB%B6%80-%EC%9E%98%ED%95%98%EB%8A%94-%EB%B2%95-chatGPT4</guid>
            <pubDate>Sat, 18 Mar 2023 11:48:59 GMT</pubDate>
            <description><![CDATA[<p>chatGPT가 알려준 영어 잘하는 법이에요 ㅎ</p>
<hr>
<p>나) 영어 잘하는법 있어?</p>
<hr>
<p>chatGPT) 
영어를 잘하는 방법은 매우 다양하지만, 몇 가지 추천해드릴 수 있습니다.</p>
<p>영어 공부를 지속적으로 해라: 영어를 잘하려면 지속적인 학습이 필요합니다. 매일 일정량의 공부 시간을 확보하고, 꾸준히 학습하는 것이 중요합니다.</p>
<p>영어 말하기 연습: 영어를 잘하기 위해서는 말하기 연습이 필수입니다. 친구들과 대화를 나누거나, 영어 스터디 그룹에 참여하여 자신의 말하기 실력을 향상시킬 수 있습니다.</p>
<p>영어 듣기 연습: 영어를 잘하기 위해서는 듣기 실력도 매우 중요합니다. 영어 드라마나 영화를 보면서 듣기 연습을 하거나, 뉴스나 팟캐스트를 들으면서 청취 능력을 향상시킬 수 있습니다.</p>
<p>영어 쓰기 연습: 영어 쓰기 연습을 통해 문법과 어휘를 확장하고 글쓰기 능력을 향상시킬 수 있습니다. 블로그를 쓰거나 편지를 써보는 것도 좋은 방법입니다.</p>
<p>영어 매체 활용: 영어 신문, 잡지, 책, 영어 웹사이트, 유튜브 등 다양한 매체를 활용하여 자신의 영어 실력을 향상시킬 수 있습니다.</p>
<p>영어 문화에 관심 가져라: 영어권 국가의 문화에 관심을 가져보면서 문화와 언어를 함께 이해해 나가는 것도 좋은 방법입니다. 영어권 영화나 음악, 문화 프로그램을 즐기는 것도 좋은 방법입니다.</p>
<p>이러한 방법들을 조합하여 영어 실력을 향상시킬 수 있습니다. 하지만 중요한 것은 꾸준한 노력과 열정입니다. 영어를 잘하고 싶다면 매일매일 조금씩 노력해보세요!</p>
<hr>
<p>나) 고마워요 ^^</p>
<hr>
<p>chatGPT) 별말씀을요! 언제든지 도움이 필요하시면 또 문의해주세요. 함께 응원합니다!</p>
<hr>
<p>신기하면서도 소름끼치는 이놈...</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[RSA KeyGenerator Set]]></title>
            <link>https://velog.io/@henry_choi/RSA-KeyGenerator-Set</link>
            <guid>https://velog.io/@henry_choi/RSA-KeyGenerator-Set</guid>
            <pubDate>Mon, 06 Feb 2023 07:12:07 GMT</pubDate>
            <description><![CDATA[<ol>
<li><p>암호화 처리</p>
<pre><code> /**
  * 암호화 처리
  * @param publicKey
  * @param plainText
  * @return
  * @throws InvalidKeyException
  * @throws NoSuchPaddingException
  * @throws NoSuchAlgorithmException
  * @throws IllegalBlockSizeException
  * @throws BadPaddingException
  * @throws UnsupportedEncodingException
  */
 public static String encryptRSA(PublicKey publicKey, String plainText)
         throws InvalidKeyException, NoSuchPaddingException, NoSuchAlgorithmException, IllegalBlockSizeException, BadPaddingException, UnsupportedEncodingException {

     Cipher cipher = Cipher.getInstance(&quot;RSA&quot;);
     cipher.init(Cipher.ENCRYPT_MODE, publicKey);

     byte[] ecryptedBytes = cipher.doFinal(plainText.getBytes(&quot;utf-8&quot;));
     String ecryptedString = Base64.getEncoder().encodeToString(ecryptedBytes);

     logger.info(&quot;##### ecryptedString {}&quot;, ecryptedString);

     return ecryptedString;
 }</code></pre><p>.</p>
</li>
<li><p>복호화 처리</p>
<pre><code> /**
  * 복호화 처리
  * @param privateKey
  * @param securedText
  * @return
  * @throws Exception
  */
 public static String decryptRSA(PrivateKey privateKey, String securedText) throws Exception {
     Cipher cipher = Cipher.getInstance(&quot;RSA&quot;);
     cipher.init(Cipher.DECRYPT_MODE, privateKey);

     byte[] securedBytes = Base64.getDecoder().decode(securedText.getBytes());
     String securedString = new String(securedBytes, &quot;utf-8&quot;);

     byte[] decryptedBytes = cipher.doFinal(securedBytes);
     String decryptedString = new String(decryptedBytes, &quot;utf-8&quot;);

     logger.debug(&quot;##### decryptedString {}&quot;, decryptedString);

     return decryptedString;
 }</code></pre><p>.</p>
</li>
<li><p>테스트 케이스 작성</p>
<pre><code>@Slf4j
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {RSAKeyGenerator.class})
public class RSAKeyGenerator {

 @Test
 public void testRSAKeyGenerator() throws Exception {

     KeyPairGenerator generator = KeyPairGenerator.getInstance(&quot;RSA&quot;);
     generator.initialize(512); // key size 설정
     KeyPair keyPair = generator.generateKeyPair();

     KeyFactory keyFactory = KeyFactory.getInstance(&quot;RSA&quot;);
     PublicKey  publicKey  = keyPair.getPublic();
     PrivateKey privateKey = keyPair.getPrivate();

     RSAPublicKeySpec publicKeySpec = (RSAPublicKeySpec) keyFactory.getKeySpec(publicKey, RSAPublicKeySpec.class);

     // publicKey / UI에서 사용가능 - 4번 참고
     String publicKeyModulus = publicKeySpec.getModulus().toString(16);
     String publicKeyExponent = publicKeySpec.getPublicExponent().toString(16);

     String e_username = SecurityUtils.encryptRSA(publicKey, &quot;admin1&quot;);
     String e_password = SecurityUtils.encryptRSA(publicKey, &quot;1&quot;);

     String de_username = SecurityUtils.decryptRSA(privateKey, e_username);
     String de_password = SecurityUtils.decryptRSA(privateKey, e_password);
 }
}</code></pre></li>
<li><p>UI(화면) 암호화 전송 ( html / script )</p>
<pre><code> &lt;!--순서에 주의--&gt;
 &lt;script src=&quot;/assets/js/rsa/rsa.js&quot;&gt;&lt;/script&gt;
 &lt;script src=&quot;/assets/js/rsa/jsbn.js&quot;&gt;&lt;/script&gt;
 &lt;script src=&quot;/assets/js/rsa/prng4.js&quot;&gt;&lt;/script&gt;
 &lt;script src=&quot;/assets/js/rsa/rng.js&quot;&gt;&lt;/script&gt;

 ... 

 const rsaPublicKeyModulus = document.getElementById(&quot;publicKeyModulus&quot;).value;
 const rsaPublicKeyExponent = document.getElementById(&quot;publicKeyExponent&quot;).value;

 const rsa = new RSAKey();
 rsa.setPublic(rsaPublicKeyModulus, rsaPublicKeyExponent);

 // 사용자ID와 비밀번호를 RSA로 암호화한다.
 var securedUsername = rsa.encrypt(username);
 var securedPassword = rsa.encrypt(password);</code></pre></li>
</ol>
<p>끝~~</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[SpringBoot Swagger Set]]></title>
            <link>https://velog.io/@henry_choi/SpringBoot-Swagger-Set</link>
            <guid>https://velog.io/@henry_choi/SpringBoot-Swagger-Set</guid>
            <pubDate>Wed, 01 Feb 2023 07:56:34 GMT</pubDate>
            <description><![CDATA[<h3 id="1-buildgradle-설정">1. build.gradle 설정</h3>
<pre><code>dependencies {    
    implementation(&quot;io.springfox:springfox-boot-starter:3.0.0&quot;)
    implementation(&quot;io.springfox:springfox-swagger-ui:3.0.0&quot;)
}    </code></pre><p>.</p>
<h3 id="2-applicationyml-설정">2. application.yml 설정</h3>
<p>SpringBoot 2.6 이상인 경우 없으면 해당 오류 발생</p>
<blockquote>
<p>org.springframework.context.ApplicationContextException: Failed to start bean &#39;documentationPluginsBootstrapper&#39;; nested exception is java.lang.NullPointerException: Cannot invoke &quot;org.springframework.web.servlet.mvc.condition.PatternsRequestCondition.getPatterns()&quot; because &quot;this.condition&quot; is null</p>
</blockquote>
<pre><code>spring:
  mvc:
    pathmatch:
      matching-strategy: ant_path_matcher</code></pre><p>.</p>
<h3 id="3-swagger-적용--작성중-">3. swagger 적용 ( 작성중 )</h3>
<p>.</p>
<h3 id="참고사항--작성중-">참고사항 ( 작성중 )</h3>
]]></description>
        </item>
        <item>
            <title><![CDATA[SpringBoot Lombok Set]]></title>
            <link>https://velog.io/@henry_choi/SpringBoot-Lombok-Set</link>
            <guid>https://velog.io/@henry_choi/SpringBoot-Lombok-Set</guid>
            <pubDate>Wed, 01 Feb 2023 07:49:32 GMT</pubDate>
            <description><![CDATA[<h3 id="1-buildgradle-설정">1. build.gradle 설정</h3>
<pre><code>dependencies {        
    compileOnly &#39;org.projectlombok:lombok:1.18.24&#39;
    annotationProcessor &#39;org.projectlombok:lombok:1.18.24&#39;

    testCompileOnly &#39;org.projectlombok:lombok:1.18.24&#39;
    testAnnotationProcessor &#39;org.projectlombok:lombok:1.18.24&#39;
}</code></pre><p>.</p>
<h3 id="2-lombokconfig-설정--buildgradle과-같은위치-">2. lombok.config 설정 ( build.gradle과 같은위치 )</h3>
<pre><code># 참고 - https://projectlombok.org/features/configuration
lombok.data.flagUsage=error
lombok.allArgsConstructor.flagUsage=error
...</code></pre><p>.</p>
<h3 id="참고사항">참고사항</h3>
<ul>
<li>build.gradle 에서 버전을 반드시 명시해야함 ( 없으면 오류 발생 )</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[SpringBoot MessageSource Set]]></title>
            <link>https://velog.io/@henry_choi/SpringBoot-MessageSource-Set</link>
            <guid>https://velog.io/@henry_choi/SpringBoot-MessageSource-Set</guid>
            <pubDate>Wed, 01 Feb 2023 07:32:45 GMT</pubDate>
            <description><![CDATA[<h3 id="dependencies-생략">dependencies 생략</h3>
<p>.</p>
<h3 id="1-config-추가">1. Config 추가</h3>
<p>MessageConfig - ReloadableResourceBundleMessageSource 설정이 중요
( SpringBoot 기본값인 ResourceBundleMessageSource는 오류 발생 )</p>
<pre><code>@Configuration
public class MessagesConfig {

    @Bean
    public MessageSource messageSource() {
        ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();

        messageSource.setBasenames(new String[]{&quot;classpath:/messages/messages&quot;});
        messageSource.setDefaultEncoding(&quot;UTF-8&quot;);
        messageSource.setCacheSeconds(5);

        return messageSource;
    }
}</code></pre><p>.</p>
<h3 id="2-messages-생성">2. messages 생성</h3>
<p>/resources/messages/messages_ko_KR.properties</p>
<pre><code>succeses=정상적으로 처리되었습니다.</code></pre><p>.</p>
<h3 id="3-testcase-생성">3. TestCase 생성</h3>
<pre><code>@Slf4j
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {MessagesConfig.class})
public class MessageConfigTest {

    @Autowired
    MessageSource messageSource;

    @Test
    public void getMessageSourceTest() {
        log.info(&quot;##### message {}&quot;, messageSource.getMessage(&quot;succeses&quot;, new String[] {}, LocaleContextHolder.getLocale()));
    }
}</code></pre><p>.</p>
<h3 id="4-결과">4. 결과</h3>
<p>#####message 정상적으로 처리되었습니다.
.</p>
<h3 id="참고사항">참고사항</h3>
<ul>
<li>intellij 개발툴 사용</li>
<li>properties &gt; utf-8 적용</li>
</ul>
]]></description>
        </item>
    </channel>
</rss>