<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>DevJong12</title>
    <link>https://devjong12.tistory.com/</link>
    <description>기술블로그</description>
    <language>ko</language>
    <pubDate>Thu, 27 Aug 2026 10:08:01 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>Jong12</managingEditor>
    <image>
      <title>DevJong12</title>
      <url>https://tistory1.daumcdn.net/tistory/4331182/attach/f2656adca6b446a28f16cfbb67daa8ce</url>
      <link>https://devjong12.tistory.com</link>
    </image>
    <item>
      <title>Electron 학습기록</title>
      <link>https://devjong12.tistory.com/125</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;카드 이벤트를 잡기위한 기록&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일반적으로 카드리더기를 잡으려면 USB를 통해 연결을 잡은 이후, 카드리더기인 경우 해당 카드정보를 Electron에서 React로 이벤트를 쏴주는 형태로 가야함.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 문제는 다음과 같음.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;Electron은 기본적으로 Node.js기반 Main Processor에서 실행이 된다.
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;해당 영역을 ipcMain이라고 칭하며, 해당 영역은 Node.js로 구동이 되고, Electron이 실행하는 main.js 또는 electron.js등등 실행에 필요한 소스코드 영역임.&lt;/li&gt;
&lt;li&gt;React Web(크로미움) 영역 에서는 Node.js를 통한 특정 라이브러리를 실행할 수가 없음.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;현재 내가 카드리더기를 읽기 위해 사용되는 모듈은 아래의 링크와 같음.(약간 변형은함)
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/tomkp/smartcard&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/tomkp/smartcard&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/tomkp/card-reader&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/tomkp/card-reader&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/tomkp/hexify&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/tomkp/hexify&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;위의 라이브러리들에서 PCSC관련 라이브러리는 Node.js를 통해 C++ 레벨의 코드를 실행한다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;문제의 해결방안은 다음과 같음.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;렌더링 영역은 React에서 실행한다.&lt;/li&gt;
&lt;li&gt;Node.js가 필요한 영역은 main영역으로 와서 실행한다.&lt;/li&gt;
&lt;li&gt;이를 위해서는 채널을 열어야 하며 다음의 방법을 활용한다
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;React
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1736745567238&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const {ipcRenderer} = window.require(&quot;electron&quot;);

// 보내고 받기.
export default function () {
	const handleChannel = (event, args) =&amp;gt; {
    	console.log('test');
    }
    useEffect(()=&amp;gt; {
        console.log('[ipcRenderer Effect] Renderer Effect')
        ipcRenderer.send('channel', 'hihi') // Data는 Optional , Json을 줘도 된다.
        ipcRenderer.on('channel', handleChannel);
    }, [ipcRenderer])
    
    return &amp;lt;&amp;gt;
        Test
    &amp;lt;/&amp;gt;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Main.js&lt;/p&gt;
&lt;pre id=&quot;code_1736746187406&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const ipcMain = require('electron').ipcMain;

// 둘중 편한방법을 사용하면됨.
ipcMain.on(&quot;channel&quot;, (event, data) =&amp;gt; {
  event.sender.send(&quot;channel&quot;, &quot;From Main Process&quot;);
});

ipcMain.on(&quot;channel&quot;, (event, data) =&amp;gt; {
  event.reply(&quot;channel&quot;, data);
});&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;차라리 라이브러리를.. &lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;a style=&quot;color: #2980b9; text-align: start;&quot; href=&quot;https://github.com/pokusew/nfc-pcsc#readme&quot;&gt;nfc-pcsc&lt;/a&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt;&amp;nbsp;나&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;a style=&quot;color: #2980b9; text-align: start;&quot; href=&quot;https://github.com/pokusew/node-pcsclite&quot;&gt;node-pcsclite&lt;/a&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt; 를 쓰는게 나아보이긴하는데... ㅠㅠ&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt;글은 나중에 정리하는걸로..&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>잡담</category>
      <author>Jong12</author>
      <guid isPermaLink="true">https://devjong12.tistory.com/125</guid>
      <comments>https://devjong12.tistory.com/125#entry125comment</comments>
      <pubDate>Mon, 13 Jan 2025 14:29:59 +0900</pubDate>
    </item>
    <item>
      <title>[JUnit] JUnit을 활용한 다양한 테스트방법</title>
      <link>https://devjong12.tistory.com/124</link>
      <description>&lt;div class=&quot;book-toc&quot; style=&quot;margin-top: 20px; margin-bottom: 30px;&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;목차&lt;/p&gt;
&lt;ul id=&quot;toc&quot; style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;&lt;/ul&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;글을 작성하기에 앞서서... 이 JUni이란게 뭔지에 대해서 앞의 아티클에 설명을 해놓았다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당글을 먼저 읽으면 좋을 듯하여 링크를 남겨놓는다..&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://devjong12.tistory.com/123&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://devjong12.tistory.com/123&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1727322997575&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[JUnit] JUnit 이란?&quot; data-og-description=&quot;목차&amp;nbsp;1️⃣ 글을 작성하기에 앞서..사실 글을 적을까 말까 고민했는데, 회사에서 JUnit에 대해서 교육을 하게 될 계기가 생겨서 작성을 하다 보니 너무 많은 지식을 망각했다는 것을 깨닫게 되었&quot; data-og-host=&quot;devjong12.tistory.com&quot; data-og-source-url=&quot;https://devjong12.tistory.com/123&quot; data-og-url=&quot;https://devjong12.tistory.com/123&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/zidev/hyXaG9UQWx/cU40gYEfcu4TiGxTdkgQa1/img.png?width=223&amp;amp;height=86&amp;amp;face=0_0_223_86,https://scrap.kakaocdn.net/dn/ejaXnE/hyXavHkiKp/wyFayznkkfeZT9yxX3pnDk/img.png?width=223&amp;amp;height=86&amp;amp;face=0_0_223_86,https://scrap.kakaocdn.net/dn/TuLrj/hyXaz31IdB/vrGYkbkzrTFc2SsgHWKKk0/img.jpg?width=3000&amp;amp;height=4000&amp;amp;face=0_0_3000_4000&quot;&gt;&lt;a href=&quot;https://devjong12.tistory.com/123&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://devjong12.tistory.com/123&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/zidev/hyXaG9UQWx/cU40gYEfcu4TiGxTdkgQa1/img.png?width=223&amp;amp;height=86&amp;amp;face=0_0_223_86,https://scrap.kakaocdn.net/dn/ejaXnE/hyXavHkiKp/wyFayznkkfeZT9yxX3pnDk/img.png?width=223&amp;amp;height=86&amp;amp;face=0_0_223_86,https://scrap.kakaocdn.net/dn/TuLrj/hyXaz31IdB/vrGYkbkzrTFc2SsgHWKKk0/img.jpg?width=3000&amp;amp;height=4000&amp;amp;face=0_0_3000_4000');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;[JUnit] JUnit 이란?&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;목차&amp;nbsp;1️⃣ 글을 작성하기에 앞서..사실 글을 적을까 말까 고민했는데, 회사에서 JUnit에 대해서 교육을 하게 될 계기가 생겨서 작성을 하다 보니 너무 많은 지식을 망각했다는 것을 깨닫게 되었&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;devjong12.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;추가적으로 모든 코드는 아래의 Repository에서 확인이 가능합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/donsonioc2010/my-junit-example&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/donsonioc2010/my-junit-example&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1727325173373&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;object&quot; data-og-title=&quot;GitHub - donsonioc2010/my-junit-example&quot; data-og-description=&quot;Contribute to donsonioc2010/my-junit-example development by creating an account on GitHub.&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/donsonioc2010/my-junit-example&quot; data-og-url=&quot;https://github.com/donsonioc2010/my-junit-example&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/9CSOH/hyXaIzTrXl/uxq61Ols9kgKZthqo6qDLk/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600&quot;&gt;&lt;a href=&quot;https://github.com/donsonioc2010/my-junit-example&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/donsonioc2010/my-junit-example&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/9CSOH/hyXaIzTrXl/uxq61Ols9kgKZthqo6qDLk/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;GitHub - donsonioc2010/my-junit-example&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Contribute to donsonioc2010/my-junit-example development by creating an account on GitHub.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;223&quot; data-origin-height=&quot;86&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/d5lRz8/btsJMet1VCh/GeZwtwjbEl0Ib5Uoh53Ku0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/d5lRz8/btsJMet1VCh/GeZwtwjbEl0Ib5Uoh53Ku0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/d5lRz8/btsJMet1VCh/GeZwtwjbEl0Ib5Uoh53Ku0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fd5lRz8%2FbtsJMet1VCh%2FGeZwtwjbEl0Ib5Uoh53Ku0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;223&quot; height=&quot;86&quot; data-origin-width=&quot;223&quot; data-origin-height=&quot;86&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;1️⃣ JUnit, 유닛테스트를 위한게 아니야?&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;맞다. 기본적으로는 유닛테스트에 목표를 두고 있기 때문에 테스트의 주된 목적은 제목그대로 유닛테스트를 위한 도구다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 필자의 경우에는 Java를 베이스로 해서 Spring을 사용하는 Java + Spring(일명 자프링) 생태계를 활용한 개발을 하고 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러다 보니 특정 외부 API에 대한 타임체크나, DB에 대한 세션변경 등등의 다양한 설정의 테스트 또는 특정환경에서만의 테스트등이 필요할 수도 있다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그런 특정환경 또는 특정 설정에 대한 테스트를 지원하고 있으며, 이 아티클은 어떠한 상황에서 활용이 가능한지를 기록해 보고자 한다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 style=&quot;color: #000000;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;2️⃣ Unit Test&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;JUnit이 존재하는 기본적인 이유인 유닛테스트부터 방법에 대해서 코드로 기록해보고자 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;유닛테스트는 간단하게 메소드의 기능에 대한 테스트를 하는 것입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;테스트타겟 코드는 간단한 계산 기능으로, 아래의 코드를 참조하시기 바랍니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1152&quot; data-origin-height=&quot;484&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cdlsQS/btsJL1nLobY/mKS4ZKKC9fsQdEkCoyOm60/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cdlsQS/btsJL1nLobY/mKS4ZKKC9fsQdEkCoyOm60/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cdlsQS/btsJL1nLobY/mKS4ZKKC9fsQdEkCoyOm60/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcdlsQS%2FbtsJL1nLobY%2FmKS4ZKKC9fsQdEkCoyOm60%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1152&quot; height=&quot;484&quot; data-origin-width=&quot;1152&quot; data-origin-height=&quot;484&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위와 같은 코드를 테스트를 해보고자 합니다. 간단하게 2개의 숫자를 더하고 더한 결과를 반환하는 코드입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1334&quot; data-origin-height=&quot;818&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/nVo0c/btsJM1HdeQO/HcIFaSkno0eNLazO3te4NK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/nVo0c/btsJM1HdeQO/HcIFaSkno0eNLazO3te4NK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/nVo0c/btsJM1HdeQO/HcIFaSkno0eNLazO3te4NK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FnVo0c%2FbtsJM1HdeQO%2FHcIFaSkno0eNLazO3te4NK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1334&quot; height=&quot;818&quot; data-origin-width=&quot;1334&quot; data-origin-height=&quot;818&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위의 코드는 이제 Calculator의 add메소드에 대한 테스트를 진행하는 테스트케이스 입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Calculator객체를 생성하고, 숫자 두개를 add메소드에 제공하여 결과물을 받고, 이 받은 결과물이 개발자가 의도한 결과와 동일하게 작동하는 가를 확인하는 검증단계로 흐름이 이뤄집니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이처럼 &lt;b&gt;단위테스트 자체는 간단하게 제작이 가능&lt;/b&gt;합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;단 위와같이 간단한 경우는 간단한 로직뿐이고... 실제 작업을 하면서 저런 케이스는 많이 없겠지만요  &lt;/p&gt;
&lt;hr data-ke-style=&quot;style5&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h2 style=&quot;color: #000000;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;3️⃣  다양한 OS환경에서의 테스트&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저도 자료들을 준비하면서 알게 된 방법중 하나입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;간단하게 Annotation만 추가하면 Jupiter에서는 OS별로 테스트를 실행할 수 있도록 환경을 제공해 주고 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;어노테이션은 &lt;b&gt;@EnableOnOS&lt;/b&gt;로 &lt;b&gt;org.junit.jupiter.api.condition&lt;/b&gt;패키지에 해당 어노테이션이 존재하고 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 어노테이션은 아래처럼 이뤄져 있으며, 클래스 또는 메소드에 선언이 가능합니다.&lt;/p&gt;
&lt;div style=&quot;background-color: #1e1f22; color: #bcbec4;&quot;&gt;
&lt;pre class=&quot;less&quot;&gt;&lt;code&gt;@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@ExtendWith({EnabledOnOsCondition.class})
@API(
    status = Status.STABLE,
    since = &quot;5.1&quot;
)
public @interface EnabledOnOs {
    OS[] value() default {};

    @API(
        status = Status.STABLE,
        since = &quot;5.9&quot;
    )
    String[] architectures() default {};

    @API(
        status = Status.STABLE,
        since = &quot;5.7&quot;
    )
    String disabledReason() default &quot;&quot;;
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실제 사용 방법은 아래의 코드를 보면 직관적으로 확인이 가능합니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1554&quot; data-origin-height=&quot;1904&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bMPVwP/btsJNrZX40f/qWKFbmYkXhmqKnOtbhbdwK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bMPVwP/btsJNrZX40f/qWKFbmYkXhmqKnOtbhbdwK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bMPVwP/btsJNrZX40f/qWKFbmYkXhmqKnOtbhbdwK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbMPVwP%2FbtsJNrZX40f%2FqWKFbmYkXhmqKnOtbhbdwK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1554&quot; height=&quot;1904&quot; data-origin-width=&quot;1554&quot; data-origin-height=&quot;1904&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;필자의 경우 메소드에 모든 케이스를 기록하였으나, 클래스에 기록할 경우 전체 메소드에 동일하게 적용 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위의 케이스를 실행하게 되면, 필자는 Mac을 사용하기 떄문에 Mac의 환경만 테스트가 진행됩니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-09-26 13.44.13.png&quot; data-origin-width=&quot;554&quot; data-origin-height=&quot;265&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dJr8lH/btsJMa5X18X/Yk4adX9FbiUB2Akqg5JRsk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dJr8lH/btsJMa5X18X/Yk4adX9FbiUB2Akqg5JRsk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dJr8lH/btsJMa5X18X/Yk4adX9FbiUB2Akqg5JRsk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdJr8lH%2FbtsJMa5X18X%2FYk4adX9FbiUB2Akqg5JRsk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;554&quot; height=&quot;265&quot; data-filename=&quot;스크린샷 2024-09-26 13.44.13.png&quot; data-origin-width=&quot;554&quot; data-origin-height=&quot;265&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;테스트를 구현해 보면서 현재 컨테이너, 리눅스기반의 자프링 개발이 아닌 특정 어플리케이션 같은 부분들 즉 OS를 고려한 개발을 하게 될 경우에 유용한 테스트 방식이라고 생각을 할 수 있었습니다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style5&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h2 style=&quot;color: #000000;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;4️⃣ 반복테스트&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여러번 동일한 테스트가 필요한 경우 사용할 수 있는 RepeatedTest입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;코드를 보면 바로 이해가 가능합니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1452&quot; data-origin-height=&quot;1194&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/4aMOd/btsJM1AB0vb/bqIfn5yi96s9tMpDLKkQj1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/4aMOd/btsJM1AB0vb/bqIfn5yi96s9tMpDLKkQj1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/4aMOd/btsJM1AB0vb/bqIfn5yi96s9tMpDLKkQj1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F4aMOd%2FbtsJM1AB0vb%2FbqIfn5yi96s9tMpDLKkQj1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1452&quot; height=&quot;1194&quot; data-origin-width=&quot;1452&quot; data-origin-height=&quot;1194&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위와 같이 명시가 가능하며, &lt;b&gt;@RepeatedTest&lt;/b&gt;어노테이션을 통하여 테스트가 가능합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;DisplayName은 제가 수정을 안했으나, 실제 10회 테스트를 하며 반복테스트 하위로 10개의 테스트가 @RepeatedTest의 name Format에 맞게 표시 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래의 결과처럼요.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-09-26 13.57.14.png&quot; data-origin-width=&quot;555&quot; data-origin-height=&quot;353&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bmyVfc/btsJM20zO9G/jImkxsmvGpgCCQFQk0Bvc0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bmyVfc/btsJM20zO9G/jImkxsmvGpgCCQFQk0Bvc0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bmyVfc/btsJM20zO9G/jImkxsmvGpgCCQFQk0Bvc0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbmyVfc%2FbtsJM20zO9G%2FjImkxsmvGpgCCQFQk0Bvc0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;555&quot; height=&quot;353&quot; data-filename=&quot;스크린샷 2024-09-26 13.57.14.png&quot; data-origin-width=&quot;555&quot; data-origin-height=&quot;353&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만, 이런 단순 반복테스트라면 저는 부하테스트를 할 것 같습니다. 성능을 확인해야 하는 경우도 많기 때문에요.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style5&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h2 style=&quot;color: #000000;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;5️⃣ 가정기반 테스트&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AssumptionsTest라고 하며, 특정 조건이 만족해야 테스트를 진행하도록 할 때, 사용하는 테스트입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;org.junit.jupiter.api&lt;/b&gt;의 &lt;b&gt;Assumptions&lt;/b&gt;를 사용해서 조건을 만족시키는 경우 테스트를 진행합니다. 간단한 예제는 아래 코드를 확인 가능합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1452&quot; data-origin-height=&quot;2770&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/2fUFT/btsJM9rSybk/HxLB4O3GtNCLnLukqUyr3K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/2fUFT/btsJM9rSybk/HxLB4O3GtNCLnLukqUyr3K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/2fUFT/btsJM9rSybk/HxLB4O3GtNCLnLukqUyr3K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F2fUFT%2FbtsJM9rSybk%2FHxLB4O3GtNCLnLukqUyr3K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1452&quot; height=&quot;2770&quot; data-origin-width=&quot;1452&quot; data-origin-height=&quot;2770&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위의 코드처럼 최초에 Property를 부여하고, 해당 값이 Test인경우, Test가 아닌 경우로 테스트 케이스를 진행합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실제 그러면 실행이 되어야 하는 테스트케이스는 두건이 됩니다. 또한, 아래의 이미지처럼&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-09-26 14.30.39.png&quot; data-origin-width=&quot;482&quot; data-origin-height=&quot;211&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/biwHup/btsJMeAKIKZ/eVrwzLkWk9JY32ntbsUqf1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/biwHup/btsJMeAKIKZ/eVrwzLkWk9JY32ntbsUqf1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/biwHup/btsJMeAKIKZ/eVrwzLkWk9JY32ntbsUqf1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbiwHup%2FbtsJMeAKIKZ%2FeVrwzLkWk9JY32ntbsUqf1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;482&quot; height=&quot;211&quot; data-filename=&quot;스크린샷 2024-09-26 14.30.39.png&quot; data-origin-width=&quot;482&quot; data-origin-height=&quot;211&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위처럼 특정 Value나 상황이 필요한 경우에만 Test를 진행하게 하는법이 필요하면 재고해 보면 좋을 듯 합니다.&lt;/p&gt;
&lt;hr data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 style=&quot;color: #000000;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;6️⃣ 타임아웃 테스트&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;특정 시간내에 기능이 실행되어야 하는 경우 테스트를 통과하게 하는 것 또한 가능합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;방법은 크게 두가지로, &lt;b&gt;@Timeout&lt;/b&gt;어노테이션을 사용하거나 &lt;b&gt;Jupiter의 Assertions&lt;/b&gt;의 assertTimeout통해 검증이 가능하며, 샘플코드는 아래와 같습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1452&quot; data-origin-height=&quot;3104&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/q4ZiU/btsJLXzyr5u/OtLebkKuJ8LhoK4yPClJU1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/q4ZiU/btsJLXzyr5u/OtLebkKuJ8LhoK4yPClJU1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/q4ZiU/btsJLXzyr5u/OtLebkKuJ8LhoK4yPClJU1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fq4ZiU%2FbtsJLXzyr5u%2FOtLebkKuJ8LhoK4yPClJU1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1452&quot; height=&quot;3104&quot; data-origin-width=&quot;1452&quot; data-origin-height=&quot;3104&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위처럼 assertTimeout의 경우에는 Duration을 인자로 받아, 특정 로직이 실행시 테스트시간의 검증이 가능합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;반면에 @Timeout어노테이션의 경우에는 희망하는 시간, 시간의 단위를 기록하여 로직의 검증이 가능합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약 시간의 단위를 기록하지 않으면 기본적으로 초단위로 지정이 되며, 실제 외부 API를 검증 테스트해야 하는 경우 또는 MSA환경에서 API콜을 통한 테스팅이 필요한 경우 유용하지 않을까 넌지시 생각이 들었던 방법입니다.&lt;/p&gt;
&lt;hr data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 style=&quot;color: #000000;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;7️⃣ &lt;b&gt;글을 마치며..&lt;/b&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;사실 필자 역시도 유닛테스트를 제외하고 거의 하고 있지는 않습니다만, 자주 활용이 가능할만한 것들도 많이 있다고 생각합니다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;해당 챕터에서는 어떠한 방식의 테스트 종류가 있고, 어떻게 활용해 볼 수 있을까에 대한 주관만 가져가면 좋지 않을까 합니다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;그 뒤에 자신에게 맞는 방법을 적용하는 것은 글을 읽는 독자들의 판단에 맡길 뿐이라고 저는 생각합니다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;또한 해당 포스트에서는 다루지 않은 방법이 많이 존재하는데요, TestContainers를 통한 특정환경 테스트라든가, @Tag어노테이션을 바탕으로 특정 빌드환경에서 특정 테스트만 실행되도록 하는 환경등 방식은 많이 존재합니다. 아니면 문서를 자동화 하기 위한 SpringRestDocs등의 환경등에 대해서도 추가가 가능합니다.&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;해당 아티클에는 제기준에서 활용이 가능할만한 항목들에 대해서만 기록을 해뒀기 때문에, 다른 기능들에 대해 더 설명이 필요하면 Third Party에 대해서 알아보시길 바랍니다.  &lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;다음 글은 JUnit의 유닛테스트에서 자주 사용하는 Jupiter의 Assertions와 AssertJ의 Assertions에 대해 기록하고자 합니다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;읽어주셔서 감사합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Java,Spring/Java</category>
      <category>AssertJ</category>
      <category>Java</category>
      <category>junit</category>
      <category>jupiter</category>
      <author>Jong12</author>
      <guid isPermaLink="true">https://devjong12.tistory.com/124</guid>
      <comments>https://devjong12.tistory.com/124#entry124comment</comments>
      <pubDate>Thu, 26 Sep 2024 15:32:54 +0900</pubDate>
    </item>
    <item>
      <title>[JUnit] JUnit 이란?</title>
      <link>https://devjong12.tistory.com/123</link>
      <description>&lt;div class=&quot;book-toc&quot; style=&quot;margin-top: 20px; margin-bottom: 30px;&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;목차&lt;/p&gt;
&lt;ul id=&quot;toc&quot; style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;&lt;/ul&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-09-21 오후 2.05.00.png&quot; data-origin-width=&quot;223&quot; data-origin-height=&quot;86&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/sq4i2/btsJHDfvKlF/rXTvHtlivnPdxkiVRemnnk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/sq4i2/btsJHDfvKlF/rXTvHtlivnPdxkiVRemnnk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/sq4i2/btsJHDfvKlF/rXTvHtlivnPdxkiVRemnnk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fsq4i2%2FbtsJHDfvKlF%2FrXTvHtlivnPdxkiVRemnnk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;223&quot; height=&quot;86&quot; data-filename=&quot;스크린샷 2024-09-21 오후 2.05.00.png&quot; data-origin-width=&quot;223&quot; data-origin-height=&quot;86&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;1️⃣ 글을 작성하기에 앞서..&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사실 글을 적을까 말까 고민했는데, 회사에서 JUnit에 대해서 교육을 하게 될 계기가 생겨서 작성을 하다 보니 너무 많은 지식을 망각했다는 것을 깨닫게 되었다..&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;잊으면 안되는데도... 심지어 최근에 코드를 작성할 일도 많이 없었어서 코드도 어떻게 작성하는거였지 하면서 약간씩 망각하게 되는걸 보고 잘쓰던거여도 기록을 해두자 생각을 하게 되어서 이렇게 글로 작성해두려 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 시리즈는 JUnit에 대해서, 그리고 JUnit을 바탕으로 무엇을 할 수 있는지, JUnit의 응용방법, 라이브러리에 대한 소개를 진행할 예정이다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 style=&quot;color: #000000;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;2️⃣ JUnit 그게 뭔데?&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;JUnit이란 Java 프로젝트에서 &lt;b&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;단위 테스트를 진행하기 위한 프레임워크&lt;/span&gt;&lt;/b&gt;로, 코드의 작동 방식을 확인하고 변경으로 인한 오류를 사전에 방지하는 도구이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;테스트 주도 개발론인 TDD를 자바진영에서 이루기 위해서는 꼭 필요한 프레임워크이며, Kent Beck과 Erich Gamma가 제작하였다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style5&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h2 style=&quot;color: #000000;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;3️⃣ JUnit의 의존성 구성&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;980&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/4nCU4/btsJIq7ASBR/NUgdPkKI3DPls9FsfyMQD1/img.webp&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/4nCU4/btsJIq7ASBR/NUgdPkKI3DPls9FsfyMQD1/img.webp&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/4nCU4/btsJIq7ASBR/NUgdPkKI3DPls9FsfyMQD1/img.webp&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F4nCU4%2FbtsJIq7ASBR%2FNUgdPkKI3DPls9FsfyMQD1%2Fimg.webp&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1280&quot; height=&quot;980&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;980&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위의 이미지는&lt;a href=&quot;https://www.lambdatest.com/learning-hub/junit-tutorial&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt; JUnit 5 Tutorial&lt;/a&gt; 에서 참조를 해왔다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;JUnit 5 =&amp;nbsp;JUnit Platform&amp;nbsp;+&amp;nbsp;JUnit Jupiter&amp;nbsp;+&amp;nbsp;JUnit Vintage&lt;/span&gt;&lt;/blockquote&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;JUnit의 공식문서와 같이 이미지를 보면서 이해를 하게 되었는데, JUnit은 Vintage, Jupiter와 Third Party로 구성이 되어있어 JUnit 5에서도 오래된 테스트를 돌릴 수 있는 이유가 JUnit 5가 Vintage를 포함하고 있어서 가능한것을 알수가 있다...&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한 Assertj는 Junit에 포함이 되지 않는 것 자체는 알고 있었는데, Third Party중 하나가 Third Party여서 실행이 가능한게 아닐까 하는 생각을 해볼 수 있었다.&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style5&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h2 style=&quot;color: #000000;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;4️⃣ JUnit의 필요성&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사실 해당 챕터에서 다룰 내용은 아니긴하다. 정확히는 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;JUnit보다&lt;/b&gt;는 &lt;b&gt;Unit테스트&lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;가 필요한 이유&lt;/span&gt;라고 볼 수 있겠다. 유닛테스트가 필요한 이유로 봐도 생각해도 된다. 또한 필요성이라고 기록은 했으나, 장점으로 보면 좋을듯 하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;첫번째로, 코드의 품질을 향상시켜 코드 자체의&amp;nbsp; 신뢰성을 높이고, 코드가 변경이 되거나 하면서 발생하는 오류에 대하여 조기에 발견이 가능하고 빠른 수정이 가능해진다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;두번째로, JUnit은 개발자에게 코드의 변경에 대한 확신을 제공해준다. 이런 심리적으로 확신감을 준다는 말은, 추후 리팩토링과 기능을 추가하는 과정에서 코드의 안정성을 유지시키고 개발의 효율을 증대시키는 점이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;세번째로, 개발자들간의 커뮤니케이션을 개선 할 수 있다. 테스트케이스는 테스트 자체의 목적도 있지만, 기능의 요구사항과 동작 방식을 명확하게 설명하는 문서의 역할도 할 수가 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이게 가능한 이유는, JUnit을 결국 작성하려면 코드의 동작을 명확하게 명시해야 하며, 예상되는 결과를 검증해야 하기 때문이며 이 모든게 코드로 이뤄져 있기 때문에 코드를 읽고 해석이 가능하다면 불필요한 커뮤니케이션을 감소하는게 당연하기 떄문이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;마지막으로 소프트웨어의 안정성을 높이게 되는데, 최근의 추세에 대부분의 프로젝트는 CI 와 CD가 당연하게 포함이 된다. 이런 자동화된 테스트와 배포의 과정에서 코드의 변경이 기존 시스템에 미치는 영향을 신속하게 파악하며, 안정적인 소프트웨어를 배포하는게 가능해지기 떄문이다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style5&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h2 style=&quot;color: #000000;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;5️⃣ JUnit의 사용방법 흐름&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;JUnit은 매우 단순하게 기능들에 대해서 테스트를 진행 할 수 있도록 되어있으며, 크게 아래의 4개의 단계를 거치면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;JUnit의 라이브러리를 프로젝트에 추가한다.&lt;/li&gt;
&lt;li&gt;@Test어노테이션을 활용하여 테스트 메소드를 작성한다.&lt;/li&gt;
&lt;li&gt;테스트 러너를 사용해 테스트 케이스를 실행하며, 보통 필자는 IDE를 활요한다.&lt;/li&gt;
&lt;li&gt;테스트가 실행된 결과를 확인&lt;/li&gt;
&lt;/ol&gt;
&lt;hr data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 style=&quot;color: #000000;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;6️⃣ 단위테스트 작성 방법&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1074&quot; data-origin-height=&quot;520&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bQdu6k/btsJH0uJPca/auv0HYT6wKkWFIKKzV0Luk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bQdu6k/btsJH0uJPca/auv0HYT6wKkWFIKKzV0Luk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bQdu6k/btsJH0uJPca/auv0HYT6wKkWFIKKzV0Luk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbQdu6k%2FbtsJH0uJPca%2Fauv0HYT6wKkWFIKKzV0Luk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1074&quot; height=&quot;520&quot; data-origin-width=&quot;1074&quot; data-origin-height=&quot;520&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위의 이미지처럼 @Test 어노테이션을 사용해 테스트 메소드를 정의한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;assert메소드의 경우에는 필수는 아니나, 없으면 검증의 의미가 없는 빈 메소드지 않겠는가?&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;assert메소드는 검증의 단계기 때문에 넣는걸 권장한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;순서는 다음과 같다. Calculator클래스 객체를 생성하고, 내부에 메소드를 호출해서 2와 3을 더했을때, 결과가 5가 나오는지를 확인하는 간단한 코드다.&lt;/p&gt;
&lt;hr data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 style=&quot;color: #000000;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;7️⃣ JUnit의 단점? 고려사항?&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;JUnit을 사용하지 않는 환경에서 갑작스레 도입을 진행하려고 할때 한번쯤 생각해봤으면 좋을 항목들이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1. 개발팀의 규모&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;개발팀 규모가 큰 경우다. 이런 경우 코드의 변경이 빈번할 수 있기 떄문에 품질을 유지하면서 개발이 가능해지는 장점이 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 기존에 JUnit을 활용하고 있지 않았던 환경이라면 모든 개발자가 전부 JUnit을 학습해야 하는 부분들이 발생하며, 실제 JUnit테스트케이스를 작성해보지 않은 사람들은 테스트케이스를 작성해보면서 도입 초기에 생산성이 낮아질 수도 있는 부분을 염두해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;도입기간 과정에서 학습의 편차가 다르기때문에 유닛테스트의 결과에 만족을 못하는 시기가 존재할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2. 프로젝트 규모&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로젝트의 규모가 크고 복잡한 경우이다. 모놀리식으로 여러 시스템을 묶어놓는다든가, 많은 모듈을 동시에 실행시켜야 하는 환경등등..&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;많은 종류가 존재할 수 있겠다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;테스트 케이스는 많아지면 많아질 수록 전체 테스트를 진행하는 시간이 길어지게 된다. 테스트는 자주 쉽게 실행을 해야하는데, 길어지는 테스트 진행시간을 해결할 방법을 찾아야 하게 된다는 점이 해결해야 할 문제라 필자는 생각한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;3. 코드의 복잡성&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;필자가 현재 재직중인 회사의 경우에는 오랜시간 개발을 하신 개발자님이 한분 계셨다. 그분은 트렌트에 맞게 개발하는 분은 아니셨다. 절차지향으로 개발을 하시던 분이었으며, 대부분 한개의 메소드에 모든 비즈니스로직이 포함되어 있었다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러다 보니 매우 복잡한 로직의 메소드만 제작을 하셨으며, 설명이 없으면 이해가 힘들정도였다. 테스트케이스 역시 존재하지 않았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이런 복잡한 코드로만 이루어진 경우에 JUnit을 도입하면 변경점이나 오류가 있을때 조기에 발견할 수 있는 장점이 있을 수는 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 이런 복잡한 로직의 분석이후 테스트케이스를 작성은 누가할것인가? 코드가 복잡할 수록 테스트케이스를 작성하는 상황이 배보다 배꼽이 더큰 즉 리소스가 더 많이들어가는 상황이 나와버릴 수도 있는 점을 유의해야 한다.&lt;/p&gt;
&lt;hr data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 style=&quot;color: #000000;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;8️⃣ 글을 마치며&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정리하면서, JUnit을 사용하면서 보니 이론을 실제로 경험해본 경우들이 대부분이라는게 눈에 보인다는게 신기하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;필자의 경우에도 실제로 확신을 갖고 개발을 할 수 있는 점 때문에라도 JUnit은 너무 필요하다고 생각을 하게 되었으나, 처음에 적응을 하는 과정에서는 생산성이 심각하게 떨어졌던 과거가 있었던 것 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;JUnit이 꼭 장점만 있는 것이 아니기 때문에 염두를 해두면서 사용하면 좋을 것 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음 아티클은 JUnit으로 할 수 있는 테스트 케이스의 종류에 대해서 정리해보고자 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Java,Spring/Java</category>
      <category>AssertJ</category>
      <category>Java</category>
      <category>junit</category>
      <category>jupiter</category>
      <author>Jong12</author>
      <guid isPermaLink="true">https://devjong12.tistory.com/123</guid>
      <comments>https://devjong12.tistory.com/123#entry123comment</comments>
      <pubDate>Sat, 21 Sep 2024 15:26:53 +0900</pubDate>
    </item>
    <item>
      <title>내가 오픈소스 기여자?</title>
      <link>https://devjong12.tistory.com/122</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;결론부터 말하자면 사실 기뻐서 자랑하고자 쓴 글이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;회사에서 성능테스트를 하면서 APM을 같이 붙여서 확인해 보고자 PinPoint를 같이 선택하였다. (편해서)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;도중에 Profiles설정을 해야할 일이 좀 생겨서 핀포인트 Client페이지에있는 Document와 Guide페이지를 참고하고있었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래와 같은 페이지다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-06-05 09.28.10.png&quot; data-origin-width=&quot;1882&quot; data-origin-height=&quot;616&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cn6yFg/btsHNqQ7r4u/G2F6WcVZFcOpp05I6kPTj1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cn6yFg/btsHNqQ7r4u/G2F6WcVZFcOpp05I6kPTj1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cn6yFg/btsHNqQ7r4u/G2F6WcVZFcOpp05I6kPTj1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcn6yFg%2FbtsHNqQ7r4u%2FG2F6WcVZFcOpp05I6kPTj1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1882&quot; height=&quot;616&quot; data-filename=&quot;스크린샷 2024-06-05 09.28.10.png&quot; data-origin-width=&quot;1882&quot; data-origin-height=&quot;616&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 페이지에서,&lt;u&gt; &lt;i&gt;&lt;b&gt;Pinpoint개발자가 작성한 Pinpoint 기술문서&lt;/b&gt; &lt;/i&gt;&lt;/u&gt;가 아래의 이미지처럼 &lt;u&gt;&lt;i&gt;&lt;b&gt;helloworld.naver.com&lt;/b&gt;&lt;/i&gt;&lt;/u&gt;으로 링크를 페이지탭을 추가하고 있었다..&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-06-05 09.28.39.png&quot; data-origin-width=&quot;583&quot; data-origin-height=&quot;184&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bHzXQn/btsHOm1uELo/OoNyH5KmWvQeDqrae5SvsK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bHzXQn/btsHOm1uELo/OoNyH5KmWvQeDqrae5SvsK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bHzXQn/btsHOm1uELo/OoNyH5KmWvQeDqrae5SvsK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbHzXQn%2FbtsHOm1uELo%2FOoNyH5KmWvQeDqrae5SvsK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;583&quot; height=&quot;184&quot; data-filename=&quot;스크린샷 2024-06-05 09.28.39.png&quot; data-origin-width=&quot;583&quot; data-origin-height=&quot;184&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;최근에 언제 한번 네이버 메일을 정리하면서 helloworld.naver.com의 도메인이 d2.naver.com으로 변경될 예정이라는 네이버 메일을 받은 적이 있던부분이 기억이 났고 도메인을 변경해서 링크를 실행해봤고 아래처럼 이미지가 출력되었다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-06-05 09.32.12.png&quot; data-origin-width=&quot;1642&quot; data-origin-height=&quot;662&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/vlvqB/btsHNFtI2cp/DzYGKyxcbcqhfxc345QBlk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/vlvqB/btsHNFtI2cp/DzYGKyxcbcqhfxc345QBlk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/vlvqB/btsHNFtI2cp/DzYGKyxcbcqhfxc345QBlk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FvlvqB%2FbtsHNFtI2cp%2FDzYGKyxcbcqhfxc345QBlk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1642&quot; height=&quot;662&quot; data-filename=&quot;스크린샷 2024-06-05 09.32.12.png&quot; data-origin-width=&quot;1642&quot; data-origin-height=&quot;662&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이걸 보고 들었던 생각이, '아 보기 불편하네'라는게 바로 들고서는 내가 바꿔봐야지 라는 생각을 했던 것 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이후 프로젝트를 포크떠서 변경을 진행했었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;링크만 고치면 되는 부분이기 때문에 별다른 테스트는 불필요 할거라는 생각이 들었었고, 그래도 한번만 실행해볼까 했는데... 의존성 문제로 실행해서 직접 확인까지는 실패했었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이후 PR로 컨트리뷰터가 되었고, 추후 3.0.1에 반영되어 나올 예정으로 보인다. (이게 진짜 되네;)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;edited_스크린샷 2024-06-05 09.37.04.png&quot; data-origin-width=&quot;852&quot; data-origin-height=&quot;1103&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/5JWLX/btsHPccKgm9/YaIe6sc6AwtVeQqPgpGhG1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/5JWLX/btsHPccKgm9/YaIe6sc6AwtVeQqPgpGhG1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/5JWLX/btsHPccKgm9/YaIe6sc6AwtVeQqPgpGhG1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F5JWLX%2FbtsHPccKgm9%2FYaIe6sc6AwtVeQqPgpGhG1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;852&quot; height=&quot;1103&quot; data-filename=&quot;edited_스크린샷 2024-06-05 09.37.04.png&quot; data-origin-width=&quot;852&quot; data-origin-height=&quot;1103&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;되게 간단한 부분이라 기여라고 하기도 민망하긴 하지만, 내 수정한 코드가 반영된다는게 되게 기분이 좋았던 하루였다. &lt;/p&gt;</description>
      <category>잡담</category>
      <category>핀포인트</category>
      <author>Jong12</author>
      <guid isPermaLink="true">https://devjong12.tistory.com/122</guid>
      <comments>https://devjong12.tistory.com/122#entry122comment</comments>
      <pubDate>Wed, 5 Jun 2024 09:41:39 +0900</pubDate>
    </item>
    <item>
      <title>[기능구현] Method의 실행 시간을 확인해보자</title>
      <link>https://devjong12.tistory.com/121</link>
      <description>&lt;div class=&quot;book-toc&quot; style=&quot;margin-top: 20px; margin-bottom: 30px;&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;목차&lt;/p&gt;
&lt;ul id=&quot;toc&quot; style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;&lt;/ul&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;1️⃣ 개요&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;회사에 입사하고 코드를 분석을 하고 있었는데, 도저히 분석만 하고 있을 수 없고 리팩토링을 진행할 수밖에 없는 환경이었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;회사 코드를 보여줄수 없으나, 발생하는 문제가 비즈니스 로직이 20N + 1, 15N + 1 을 로직에서 직접 구현을 하고 있었다(아니 JPA를 쓰면서, 왜 이해를 못하고 쓰는데..)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러다 보니 10개, 20개를 조회하는데도 쿼리가 200번, 400번 , 데이터가 좀 많으면 수만건의 Select절을 실행하고 있었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리 생긴 결과물은, 데이터가 거의 없음에도 API의 요청이 10초~ 15초~ 20초~ 가지각생으로 매우매우 느린상황이었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 내가 선언한 어노테이션이 달려있는 메소드들만의 실제 실행 시간을 확인해보고자 기능을 구현하게 되었다...&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;APM등의 부가적인걸 붙여볼 수 있는 환경이면 좋겠지만 아무런 모니터링툴도 설치하지 못하고 Local을 통해 테스트만 가능한 환경이어서 AOP를 채택하게 되었다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 style=&quot;color: #000000;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;2️⃣ 환경사항&amp;nbsp;&lt;/b&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;JDK 17&lt;/li&gt;
&lt;li&gt;Spring Boot 3.2.0&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-style=&quot;style5&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h2 style=&quot;color: #000000;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;3️⃣ 필요 의존성&lt;/b&gt;&lt;/h2&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;AOP가 필요하나, Security, JPA등 Spring프로젝트 대부분에 AOP가 존재하여 의존해 사용해도 상관은 없다.&lt;br /&gt;하지만 직접 관리하는게 용이하니, 필자의 경우 AOP를 추가하였다.&lt;/blockquote&gt;
&lt;pre class=&quot;nginx&quot;&gt;&lt;code&gt;dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-aop'
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style5&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h2 style=&quot;color: #000000;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;4️⃣  코드 구현&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다시보니 매우간단하네...ㅋㅋㅋㅋ&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2048&quot; data-origin-height=&quot;1456&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Wv7RA/btsD1aYu0yy/cnV6PWRGkn0XTv7qkz03C0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Wv7RA/btsD1aYu0yy/cnV6PWRGkn0XTv7qkz03C0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Wv7RA/btsD1aYu0yy/cnV6PWRGkn0XTv7qkz03C0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FWv7RA%2FbtsD1aYu0yy%2FcnV6PWRGkn0XTv7qkz03C0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2048&quot; height=&quot;1456&quot; data-origin-width=&quot;2048&quot; data-origin-height=&quot;1456&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr data-ke-style=&quot;style5&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h2 style=&quot;color: #000000;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;5️⃣ 사용방법 및 결과물&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사용방법은 아래의 이미지처럼 실제 실행 시간을 측정하고 싶은 메소드에 위에서 생성했던 어노테이션인 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;@TimeCheck &lt;/b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;어노테이션을 선언하면 된다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;668&quot; data-origin-height=&quot;414&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/qhBCk/btsD4V6rCPW/gAim5pWpPObPXExBGttka0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/qhBCk/btsD4V6rCPW/gAim5pWpPObPXExBGttka0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/qhBCk/btsD4V6rCPW/gAim5pWpPObPXExBGttka0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FqhBCk%2FbtsD4V6rCPW%2FgAim5pWpPObPXExBGttka0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;668&quot; height=&quot;414&quot; data-origin-width=&quot;668&quot; data-origin-height=&quot;414&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한 실제 요청을 발송하게 될 경우 아래처럼 실제 호출한 메소드와 실행 시간을 확인해 볼 수 있게 된다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-01-27 오후 5.26.00.png&quot; data-origin-width=&quot;3076&quot; data-origin-height=&quot;156&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cNiwar/btsD3e60GHB/iF9tUsIrrAkuXvU2mKMNV0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cNiwar/btsD3e60GHB/iF9tUsIrrAkuXvU2mKMNV0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cNiwar/btsD3e60GHB/iF9tUsIrrAkuXvU2mKMNV0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcNiwar%2FbtsD3e60GHB%2FiF9tUsIrrAkuXvU2mKMNV0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3076&quot; height=&quot;156&quot; data-filename=&quot;스크린샷 2024-01-27 오후 5.26.00.png&quot; data-origin-width=&quot;3076&quot; data-origin-height=&quot;156&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 style=&quot;color: #000000;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;6️⃣ 글을 마치며&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이게 세네번 할 때 까지는 별로 필요성을 못느꼈는데, 로직체크하려고 매번 작성하다보니 너무 불편함을 느껴서 만든 기능인데 너무 편했었다.&amp;nbsp; 기능자체가 간단해서 사실 별다르게 적을건 없는데..&amp;nbsp; 이걸 만들어서까지 확인해야 할 정도로 느린걸 주구장창 만들었다면... 다시 기본적인 개념을 공부해야 할 사람이지 않을까 싶다...&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;소스코드 레벨에서부터 자신의 코드가 얼마나 나쁜 습관의 코드인지를 모르는 것이니까... 해당 기능을 계속쓰면서 성능체크를 하면서 다시금 코드를 작성할 때는, 생각을 깊게 하면서 작성해야하는걸 체감했다...&lt;/p&gt;</description>
      <category>annotation</category>
      <category>AOP</category>
      <category>Java</category>
      <category>spring</category>
      <category>성능</category>
      <author>Jong12</author>
      <guid isPermaLink="true">https://devjong12.tistory.com/121</guid>
      <comments>https://devjong12.tistory.com/121#entry121comment</comments>
      <pubDate>Sat, 27 Jan 2024 17:34:32 +0900</pubDate>
    </item>
    <item>
      <title>[이슈] 파일 업로드시 OriginalFilename에 대한 고찰</title>
      <link>https://devjong12.tistory.com/120</link>
      <description>&lt;div class=&quot;book-toc&quot; style=&quot;margin-top: 20px; margin-bottom: 30px;&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;목차&lt;/p&gt;
&lt;ul id=&quot;toc&quot; style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;&lt;/ul&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;1️⃣ 개요&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;파일의 명칭에 대해서, 내가 간단하게 개발을 진행할 때 OriginalFileName에 대해서 저장을 하지 않았었다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;많은 웹사이트를 쓰면서 원본 파일명을 다시 돌려받은 경우가 거의 없다 보니, 신경을 쓰지 않았었으나 이와 관련되어 문제가 발생하여서 기록을 남겨보게 되었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;환경은 JDK 17, Spring 3.2.0을 사용하였다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 style=&quot;color: #000000;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;2️⃣ 이슈내용&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;Window나 Mac에서 파일을 업로드를 하게 될 경우&lt;/b&gt; &lt;/span&gt;들어오는 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;Multipart의 경우에는 별다른 문제없이 OriginalFileName이 기록&lt;/b&gt;&lt;/span&gt;이 되었으나, 이걸 &lt;b&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;DataBase에서 Query를 통해 OriginalFileName이 들어가있는 Column을 Like문으로 검색을 할 때&lt;/span&gt;&lt;/b&gt; &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;검색이 되지 않는 문제&lt;/b&gt;&lt;/span&gt;가 발생하였으며, 검색이 되지 않는 &lt;span style=&quot;color: #409d00;&quot;&gt;&lt;b&gt;파일들은 모두 한글&lt;/b&gt;&lt;/span&gt;이라는게 공통점이었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래의 이미지는 발생 증상이다. 두번째와 세번째는 쿼리가 같아보일 수 있으나, 유니코드의 타입이 다른 쿼리이다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-01-27 오후 4.45.05.png&quot; data-origin-width=&quot;2682&quot; data-origin-height=&quot;804&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/4iNcZ/btsD4Ie5f2X/WeCZKJx7rZcuHlUEeIQmBk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/4iNcZ/btsD4Ie5f2X/WeCZKJx7rZcuHlUEeIQmBk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/4iNcZ/btsD4Ie5f2X/WeCZKJx7rZcuHlUEeIQmBk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F4iNcZ%2FbtsD4Ie5f2X%2FWeCZKJx7rZcuHlUEeIQmBk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2682&quot; height=&quot;804&quot; data-filename=&quot;스크린샷 2024-01-27 오후 4.45.05.png&quot; data-origin-width=&quot;2682&quot; data-origin-height=&quot;804&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr data-ke-style=&quot;style5&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h2 style=&quot;color: #000000;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;3️⃣ 이슈 발생 코드&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래와 같이 이루어져 있으며, OriginalFileName을 넣을때 getAttach의 getOriginalFilename()을 사용해서 파일명을 넣는 것을 확인 할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;불필요해 보일 수 있는 Annotation은 모두 제거를 하였다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1296&quot; data-origin-height=&quot;2148&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/C6iiI/btsD3cg1C1p/qJG7ySBgMeSWNUqI3Awvq1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/C6iiI/btsD3cg1C1p/qJG7ySBgMeSWNUqI3Awvq1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/C6iiI/btsD3cg1C1p/qJG7ySBgMeSWNUqI3Awvq1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FC6iiI%2FbtsD3cg1C1p%2FqJG7ySBgMeSWNUqI3Awvq1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1296&quot; height=&quot;2148&quot; data-origin-width=&quot;1296&quot; data-origin-height=&quot;2148&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr data-ke-style=&quot;style5&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h2 style=&quot;color: #000000;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;4️⃣ 발생 원인 및 해결방법&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;유니코드에는 크게 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;NFC와 NFD가 존재&lt;/b&gt;&lt;/span&gt;하며, &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;운영체제마다 서로 다른 게 원인&lt;/b&gt;&lt;/span&gt;으로 판단되었으며, 해당 포스트에서 유니코드나 NFC, NFD까지 다루지는 않을 것이기 &lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;때문에&lt;span&gt; &amp;nbsp;&lt;/span&gt;&lt;/span&gt;더 알아보고 싶은 경우에는 따로 검색하는 것을 권장한다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;NFC&lt;/b&gt; : Window와 Linux계열에서 사용&lt;/li&gt;
&lt;li&gt;&lt;b&gt;NFD&lt;/b&gt; : Mac에서 주로 사용&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;추가적으로, Mac에서 Window로 파일을 이동하는 등 할때 문자열이 분리가 되는 이유도 이 유니코드가 다르기 때문이었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해결방안으로는 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;OriginalFileName을 NFC로 변환한 이후에 변환된 문자열&lt;/b&gt;&lt;/span&gt;을 DB에 삽입해 주면 된다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style5&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h2 style=&quot;color: #000000;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;5️⃣ 해결된 코드&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Entity나 DTO, Data등의 클래스는 무의미하기 때문에, ServiceLayer만 업로드를 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;OriginalFileName을 업로드 할 때 Normalizer로 감싼뒤, NFC로 변환을 하고 업로드를 하도록 하면된다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1296&quot; data-origin-height=&quot;1254&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cigeX5/btsD0LdpNXO/SC6Ki2ujS0PdIkbFqvk64k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cigeX5/btsD0LdpNXO/SC6Ki2ujS0PdIkbFqvk64k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cigeX5/btsD0LdpNXO/SC6Ki2ujS0PdIkbFqvk64k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcigeX5%2FbtsD0LdpNXO%2FSC6Ki2ujS0PdIkbFqvk64k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1296&quot; height=&quot;1254&quot; data-origin-width=&quot;1296&quot; data-origin-height=&quot;1254&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 style=&quot;color: #000000;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;6️⃣ 해결된 결과물&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이슈내용과 동일한 쿼리이며, 두번째가 직접 입력한 문구이고 세먼째 쿼리가 NFC로 이뤄진 문자열의 쿼리이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Like문이 정상적으로 실행되는 걸 볼 수 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-01-27 오후 5.01.40.png&quot; data-origin-width=&quot;2674&quot; data-origin-height=&quot;810&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/mDTE8/btsD3c2oZd0/GEEMga09YPtYXoHKCd42T0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/mDTE8/btsD3c2oZd0/GEEMga09YPtYXoHKCd42T0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/mDTE8/btsD3c2oZd0/GEEMga09YPtYXoHKCd42T0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FmDTE8%2FbtsD3c2oZd0%2FGEEMga09YPtYXoHKCd42T0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2674&quot; height=&quot;810&quot; data-filename=&quot;스크린샷 2024-01-27 오후 5.01.40.png&quot; data-origin-width=&quot;2674&quot; data-origin-height=&quot;810&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 style=&quot;color: #000000;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;7️⃣ 글을 마치며&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;원본 파일명을 검색할 수 있는 기능을 만들어 달라는 요청을 받다보니 처음 생각해보게 된 문제였는데, 쿼리가 제대로 실행이 안될때 매우 당황했었다..&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래도 나름 재밌었던 부분이었다. 코드는 아래의 Repository에서 확인이 가능하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/donsonioc2010/sample-spring-project&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/donsonioc2010/sample-spring-project&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1706342793594&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;object&quot; data-og-title=&quot;GitHub - donsonioc2010/sample-spring-project: 기능구현만 하는 스프링 프로젝트&quot; data-og-description=&quot;기능구현만 하는 스프링 프로젝트. Contribute to donsonioc2010/sample-spring-project development by creating an account on GitHub.&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/donsonioc2010/sample-spring-project&quot; data-og-url=&quot;https://github.com/donsonioc2010/sample-spring-project&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/8U5Eg/hyVb1BLU7l/Y7ygPFCTKLfJkOwyl6oMX0/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600&quot;&gt;&lt;a href=&quot;https://github.com/donsonioc2010/sample-spring-project&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/donsonioc2010/sample-spring-project&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/8U5Eg/hyVb1BLU7l/Y7ygPFCTKLfJkOwyl6oMX0/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;GitHub - donsonioc2010/sample-spring-project: 기능구현만 하는 스프링 프로젝트&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;기능구현만 하는 스프링 프로젝트. Contribute to donsonioc2010/sample-spring-project development by creating an account on GitHub.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Java,Spring/Java</category>
      <category>Java</category>
      <category>Multipartfile</category>
      <category>OriginalFileName</category>
      <category>spring</category>
      <category>Unicode</category>
      <category>첨부파일</category>
      <author>Jong12</author>
      <guid isPermaLink="true">https://devjong12.tistory.com/120</guid>
      <comments>https://devjong12.tistory.com/120#entry120comment</comments>
      <pubDate>Sat, 27 Jan 2024 17:06:57 +0900</pubDate>
    </item>
    <item>
      <title>2023년을 돌아보는 리뷰</title>
      <link>https://devjong12.tistory.com/119</link>
      <description>&lt;div class=&quot;book-toc&quot; style=&quot;margin-top: 20px; margin-bottom: 30px;&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;목차&lt;/p&gt;
&lt;ul id=&quot;toc&quot; style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;&lt;/ul&gt;
&lt;/div&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;1️⃣ 개요&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2023년을 돌이켜 보자면, &quot;내가 이길이 맞나?&quot;와 &quot;계속 할 수 있을까?&quot;, 그리고 무기력이었던것같다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;F-Lab이 끝난 이후, &quot;나 그래도 열심히 했고, 이제 어느정도 잘 할수 있어라는 마인드&quot;를 가지고 내가 주도적으로 해볼 가능성이 있겠다 싶은 회사에 취업을 했다고 생각했었다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;그리고 고생이란 쌩고생은 다했는데 3개월뒤 권고사직을 당했었을때, 내가 세상 보는 안목이 너무 없는거 같은데 계속 하는게 맞나 라는 생각을 좀 많이 했었다. 그리고 같이 찾아왔던게 정말 허탈해서 아무것도 하기 싫은 상태가 되버렸었다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;그냥 아무것도 하기싫었고, 실업급여나 받으면서 뭐하면서 살지 고민을 해보고 싶었던 시간이었다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;그럼 퇴사한 이후의 나에 대한 회고를 시작해보자&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 style=&quot;color: #000000;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;2️⃣ 네이버 클라우드 국비교육&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;쉬고자 했던 장소로 선택을 하게 되었다. 두가지의 이유가 있었는데 아래와 같다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;실업급여를 받을 수 있는 조건은 되었는데, 매번 이력서를 내고, 면접확인서 받아서 제출하기가 귀찮았다. 그래서 국비교육을 들으러 갔다.&lt;/li&gt;
&lt;li&gt;네이버 클라우드 비용을 300만원을 준다고해서 300만원으로 그냥 장난감마냥 가지고 놀아보자 생각을 했다.(개발을 계속하려 했다면)&lt;/li&gt;
&lt;/ul&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;애초부터, 처음 프로그래밍에 입문하는 사람들을 타겟으로 하다보니, 기술적인 발전과 성장 부분으로는 글쎄 잘모르겠다 라고 말할수 있을 것같다. (애초애 혼자 인프런보면서, 책보면서 공부한게 더 도움이 많이 되었다.)&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;근데 멘토/멘티의 관계마냥 멘토역할을 해야해주는 일이 많았고, 지식을 전파해주면서 내가 역으로 곤란했던, 즉 도움이 되었던 상황을 많이 겪게 되었고, 내가 지식을 전파해주면서 어떻게 해야 멘티에게 지식을 조금이라도 더 많이 깊이있게 알려줄 수 있을까를 생각하면서 말하게 되다 보니 기술적으로 말하는 방법들도 많이 겪어 볼 수 있었다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;또 개발자로서 내가 많이 부족하다고 항상 생각했는데, 오히려 내가 현재 연차에 비해서 너무 방대한 지식을 알고 있고 많은 걸 알려 줄 수 있는 사람이었다는걸 알게 되었던 시간이었다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style7&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;알고리즘 스터디&lt;/b&gt;&lt;/h4&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;심심해서 해보게된 스터디였다, 매주 입문하기 쉬운 난이도에서부터 알고리즘을 풀고 설명을 해봤었는데, 다양한 생각을 들어볼 수 있던 시간이었다고 말할 수 있다! (역시 수학과...)&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;아 근데 사진 너무귀엽다&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;2160&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ulAEb/btsCRgdW4eF/XPlSy7K80s8tYB1gPyHtU1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ulAEb/btsCRgdW4eF/XPlSy7K80s8tYB1gPyHtU1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ulAEb/btsCRgdW4eF/XPlSy7K80s8tYB1gPyHtU1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FulAEb%2FbtsCRgdW4eF%2FXPlSy7K80s8tYB1gPyHtU1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1920&quot; height=&quot;2160&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;2160&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;IMG_4667.JPG&quot; data-origin-width=&quot;2316&quot; data-origin-height=&quot;3088&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/CxOIG/btsCRflQwJn/DhaKrAfMW5ymUQsyKxpMD0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/CxOIG/btsCRflQwJn/DhaKrAfMW5ymUQsyKxpMD0/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/CxOIG/btsCRflQwJn/DhaKrAfMW5ymUQsyKxpMD0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FCxOIG%2FbtsCRflQwJn%2FDhaKrAfMW5ymUQsyKxpMD0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2316&quot; height=&quot;3088&quot; data-filename=&quot;IMG_4667.JPG&quot; data-origin-width=&quot;2316&quot; data-origin-height=&quot;3088&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style7&quot; /&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;프로젝트를 하면서&lt;/b&gt;&lt;/h4&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;프로젝트를 할때는 일부로 PM을 자처했다. 팀원과 나의 기술 격차가 크다는걸 알고 있었기 때문에, 빠른시간안에 쳐내면서 진행을 해야했기 때문이다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;그러면서도, 프로젝트 팀원들이 내가 하고싶었던 인원들과 하는 부분이다보니 챙겨주고 싶은 마음이 많았는데 그러다 보니 잔소리가 많아질 수밖에 없었다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;사용한 기술에대해서, 구현한 기능에 대해서 공유를 하거나, 피드백을 하던가 기능구현을 같이 얘기하면서 도움을 주고 받는 과정을 많이 시켜보려고 노력했다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;또한 나역시 프로젝트를 하면서 들게되었던 생각은.. 기능구현을 하던가 개발을 하는 과정자체가 아직도 너무 재밌게 느껴졌고, 타인과 같이 경험을 해나가는 그 과정 하나하나가 재밌다 보니 계속 도전해야 겠다는 생각을 굳힐 수 있던 시간이었다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Untitled image.jpeg&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;4320&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/brmCfb/btsCSBPE4d0/HOTYvsKzlhG8cZnhCivtok/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/brmCfb/btsCSBPE4d0/HOTYvsKzlhG8cZnhCivtok/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/brmCfb/btsCSBPE4d0/HOTYvsKzlhG8cZnhCivtok/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbrmCfb%2FbtsCSBPE4d0%2FHOTYvsKzlhG8cZnhCivtok%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1920&quot; height=&quot;4320&quot; data-filename=&quot;Untitled image.jpeg&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;4320&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style5&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h2 style=&quot;color: #000000;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;3️⃣ 공식으로 소개된 내 블로그&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;제목을 어떻게 지을지 잘 모르겠어서 그냥 이렇게 지었다. 프로젝트를 진행하면서 내가 기능구현한 내용들, 생각들을 블로그에 포스팅을 해놨었다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;그리고 그 글들은 네이버 클라우드를 기반으로 사용했던 경험들을 적어놨다보니 네이버 클라우드에서 게시물을 확인하게 되었던 것 같다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;그렇게 네이버 클라우드 기술을 활용해 게시물작성한  11월 글들중 베스트로 뽑혀서 네이버 클라우드 블로그에 공식으로 소개가 되었다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;최근에 지속적으로 글을 작성하려고 하다 보니 느낀게 한개 있었는데, &quot;아 내가봐도 옛날에 비해서 매우 확연하게 글을 잘 쓰게 되었네&quot; 였다. 글을 쓰면서 최대한 읽기 쉽게 해보려고 노력하자가 당첨된 큰 이유지 않을 까 싶다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;PS. 정말 기분 좋았습니다.&amp;nbsp; 감사합니다 NCP&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-01-01 15.36.59.png&quot; data-origin-width=&quot;2308&quot; data-origin-height=&quot;1832&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dbN8ws/btsCVJztwPq/gJfpbm7O7NnV5cWFmIcJBK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dbN8ws/btsCVJztwPq/gJfpbm7O7NnV5cWFmIcJBK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dbN8ws/btsCVJztwPq/gJfpbm7O7NnV5cWFmIcJBK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdbN8ws%2FbtsCVJztwPq%2FgJfpbm7O7NnV5cWFmIcJBK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2308&quot; height=&quot;1832&quot; data-filename=&quot;스크린샷 2024-01-01 15.36.59.png&quot; data-origin-width=&quot;2308&quot; data-origin-height=&quot;1832&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;제목을 어떻게 지을지 잘 모르겠어서 그냥 이렇게 지었다. 프로젝트를 진행하면서 내가 기능구현한 내용들, 생각들을 블로그에 포스팅을 해놨었다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;그리고 그 글들은 네이버 클라우드를 기반으로 사용했던 경험들을 적어놨다보니 네이버 클라우드에서 게시물을 확인하게 되었던 것 같다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;그렇게 네이버 클라우드 기술을 활용해 게시물작성한  11월 글들중 베스트로 뽑혀서 네이버 클라우드 블로그에 공식으로 소개가 되었다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;최근에 지속적으로 글을 작성하려고 하다 보니 느낀게 한개 있었는데, &quot;아 내가봐도 옛날에 비해서 매우 확연하게 글을 잘 쓰게 되었네&quot; 였다. 글을 쓰면서 최대한 읽기 쉽게 해보려고 노력하자가 당첨된 큰 이유지 않을 까 싶다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;PS. 정말 기분 좋았습니다.&amp;nbsp; 감사합니다 NCP&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-01-01 15.36.59.png&quot; data-origin-width=&quot;2308&quot; data-origin-height=&quot;1832&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dbN8ws/btsCVJztwPq/gJfpbm7O7NnV5cWFmIcJBK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dbN8ws/btsCVJztwPq/gJfpbm7O7NnV5cWFmIcJBK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dbN8ws/btsCVJztwPq/gJfpbm7O7NnV5cWFmIcJBK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdbN8ws%2FbtsCVJztwPq%2FgJfpbm7O7NnV5cWFmIcJBK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2308&quot; height=&quot;1832&quot; data-filename=&quot;스크린샷 2024-01-01 15.36.59.png&quot; data-origin-width=&quot;2308&quot; data-origin-height=&quot;1832&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr data-ke-style=&quot;style5&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h2 style=&quot;color: #000000;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;4️⃣ 다시 도전한 취업시장&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;거의 반년만에 이력서를 다듬고.. 회사에 지원하고 면접을 보러 다녔다. 시장이 안좋은 것은 알고 있었지만, 이렇게 연락이 안올줄은 생각도 못했다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;원티드에서 가고 싶은 회사를 리스트업하고 이력서를 넣어봤는데, 단 한곳도 연락이 오지를 않았다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;난 이제 놀고 있을 수 없는 상황인데....&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;어쩔 수 없이 좀 많이 범위를 넓혔다. 기술과 개발 중심, 유지보수는 약간 후자로 미뤄지는 장소들을 찾고자 했다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;이력서를 다듬으면서 항상 들었던 생각이 실제 회사에서 &quot;개발 포지션&quot;으로의 경력이 아얘 없는게 내 심각한 단점이라고 생각했기 때문이다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;채용과 관련된 사이트면 모두 사용을 했고, 일치해 보이는 조건의 채용공고는 다 지원해 봤다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;범위를 매우 넓히니 연락이 오기 시작했고, 면접을 보러 다니면서 아 내가 확실히 개발부터 오픈까지 해본 부분이 없다 보니, 관련된 부분으로 실제 경험의 면접답변을 할 수가 없구나를 더 절실히 느꼈던 것 같다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;회사를 구할때 전략중 하나로, 대부분의 채용 사이트가 추천순으로 되어 있어서 인기 있는 글들만 보이게 되어있는데, 마감일 순 등으로 소팅을 바꿔보면서 대부분의 모집공고를 다 보는 방식으로 바꿨고, 그렇게 지원자가 별로 없는 회사들도 많이 지원을 해보게 되면서 취업을 할 수 있었다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;비록 남들 눈에 봤을 때, 큰 서비스기업이라든가, 트래픽이라든가 그런 부분들은 없지만 일단 내가 &quot;개발 포지션&quot;으로 확실하게 갈 수 있고, &quot;팀으로 개발&quot;하는 요소만 봤기 때문에 크게 불만은 없다.&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;또 면접을 보러 다니면서, 내가 부족한게 느껴졌다보니 이전 회사보다 처우에서 깎아서 다니고 있었는데, 그냥 이전회사처럼 대우해 주겠다고 하는 모습을 보면서 사람을 많이 챙겨준다는 느낌을 강하게 받기도 했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style5&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h2 style=&quot;color: #000000;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;5️⃣ 올해의 실패들&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;크게 두가지가 있는것 같다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;첫번째는 네이버 클라우드 300만원 바우처를 받으면서 k8s를 바탕으로 한 어플리케이션 생태계를 구축하고 싶었다. 하지만 내 의지박약으로 실천까지 가지는 못했던게 일단 가장 큰 아쉬움 같다. 남들은 아까워서 못쓰는 서비스를 난 원없이 쓸 수 있는 절호의 기회였는데 말이다.&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;두번째는 채용과 관련된 부분 같다. 내가 너무 옛날을 생각하고 쉽게 봤던 것 같다. 채용시장이 안좋다 보니, 실제로 절대적인 지원자 수가 많을 수밖에 없었다. 몇년째 이어져온 국비학원들의 대규모 광고와 모집, IT서비스업들의 구조조정등으로 나보다도 뛰어난 개발자들도 많이 풀려있는 시장인데 얕잡아봐서 크게 실패한 것이지 않나 싶다.&lt;/p&gt;
&lt;hr data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 style=&quot;color: #000000;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;6️⃣ 2024의 다짐&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;항상 내가 생각하는 꿈중 하나인, &quot;타인이 일을 맡길 때, 내 이름을 들으면 최소한 나한테는 믿고 맡길 수 있다.&quot;라는 말또는 생각을 가지게 되는 순간이 올때까지 노력을해야하니... 목표를 잡아보고자 한다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;일단 다시 회사에 들어가게 된지 얼마 되지를 않다 보니.. 적응하는게 우선이지 않을까 싶다. (출퇴근이 왕복 세시간이 넘는다) 그러면서 회사원으로써 성과를 내고 회사의 구성원들과 화합을 이뤄보는 것을 일순위로 잡아볼 예정이다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;다음으로 블로그글을 꾸준히 쓰는걸 두번째 목표로 하고싶다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;이 의미는 나는 지속적으로 학습을 게을리 하지 않아야 하며, 회사를 다니면서도 꾸준히 토이프로젝트를 진행해야 한다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;내가 잡은 마음가짐은 실제 내가 개발한 기능, 기술, 그리고 작업을 하면서 했던 생각만 기록하기로 마음을 잡았다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;그 요소들을 회사에서 개발한걸 올릴 수는 없기 떄문에, 토이프로젝트에서 진행한 걸 올릴 수밖에 없다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;그러면서 써보고 싶은 기술들은 아쉬웠던 부분인 k8s와 Spring Cloud를 접목해서 MSA환경으로 구축을 해보고 싶고, 이걸 코틀린으로 진행하고 싶은게 내 토이프로젝트의 우선순위로 잡아 볼 예정이다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;또한 이론으로만 생각하고 있는 OOP의 장점들을 내가 작성하는 기능, 코드들에 계속 생각하면서 녹이면서 몸에 체득하는걸 목표로 잡고싶다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>잡담</category>
      <category>회고</category>
      <author>Jong12</author>
      <guid isPermaLink="true">https://devjong12.tistory.com/119</guid>
      <comments>https://devjong12.tistory.com/119#entry119comment</comments>
      <pubDate>Mon, 1 Jan 2024 16:10:28 +0900</pubDate>
    </item>
    <item>
      <title>[OrientalUnity] HookKiller팀의 OrientalUnity프로젝트 회고</title>
      <link>https://devjong12.tistory.com/118</link>
      <description>&lt;div class=&quot;book-toc&quot; style=&quot;margin-top: 20px; margin-bottom: 30px;&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;목차&lt;/p&gt;
&lt;ul id=&quot;toc&quot; style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;&lt;/ul&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;1️⃣ 프로젝트 소개&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로젝트의 시작을 알리는 아티클에서 적었지만 또 적어보면...&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;번역을 기반으로 피해자와 가해자들의 모임인&amp;nbsp;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;한.중.일&lt;/b&gt;&lt;/span&gt;이라는&amp;nbsp;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;언어도 틀리고&lt;/b&gt;,&amp;nbsp;&lt;b&gt;역사가 꼬여있는&lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&amp;nbsp;세개의 국가를 주제로&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #409d00;&quot;&gt;&lt;b&gt;동북아 커뮤니티&lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;이다&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;  &lt;a href=&quot;https://github.com/hook-killer&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;&lt;b&gt;깃허브 코드&lt;/b&gt;&lt;/a&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래 이미지처럼 글을 남길 경우 한국어, 영어, 일본어, 중국어 총 4개국어로 글들이 자동번역되어 타 국가의 사용자와 교류할 수 있는 커뮤니티다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;640&quot; data-origin-height=&quot;376&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/JWwfo/btsAD2iaiX2/vlnb0CS6mU2upKe6hiMaNK/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/JWwfo/btsAD2iaiX2/vlnb0CS6mU2upKe6hiMaNK/img.gif&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/JWwfo/btsAD2iaiX2/vlnb0CS6mU2upKe6hiMaNK/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/JWwfo/btsAD2iaiX2/vlnb0CS6mU2upKe6hiMaNK/img.gif&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;640&quot; height=&quot;376&quot; data-origin-width=&quot;640&quot; data-origin-height=&quot;376&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 style=&quot;color: #000000;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;2️⃣ 구현에 사용된 기술스택&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;Front&lt;/b&gt;&lt;/span&gt;의 경우에는 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;React를 채택&lt;/b&gt;&lt;/span&gt;하였고, 메인으로 집을만한 라이브러리는 &lt;b&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;다국어의 페이지를 만들기 위한 i18next&lt;/span&gt;&lt;/b&gt;과 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;게시물의 내용을 HTML로 받기 위한 React Quill&lt;/b&gt;&lt;/span&gt;을 짚어볼 수 있을 것 같다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;Back&lt;/b&gt;&lt;/span&gt;의 경우에는 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;Java + Spring을 기본으로 채택&lt;/b&gt;&lt;/span&gt;하였고, 추가적으로 짚어볼 만한 라이브러리는 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;Security와 JPA&lt;/b&gt;&lt;/span&gt;를 사용한 정도로 보인다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;사용한 외부 API&lt;/b&gt;&lt;/span&gt;의 경우에도 매우 핵심이라 짚을 만한건 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;Naver Cloud Platform의 Papago Translation&lt;/b&gt;&lt;/span&gt;이라 할 수 있다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style5&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h2 style=&quot;color: #000000;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;3️⃣ KPT방식의 회고?&lt;/b&gt;&lt;/h2&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;어떻게 이글을 작성해야 좋을까 계속 생각하면서 보게된게 KPT회고란걸 알게 되었다.&amp;nbsp;&lt;br /&gt;&lt;br /&gt;Keep, Problem, Try의 약자로 Keep은 만족을 했고, 계속해서 이어나가고자 하는 요소, Problem은 내가 불편하게 느꼈고 개선이 필요하다 생각되는 부분, Try는 Problem에 대한 해결책과 당장 실행가능한, 다음회고때 판별이 가능한 요소를 정의한다고 한다.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;근데 나는 KP만 할 수밖에 없는 환경같은데..?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;쩃든 KP에 대해 적어보도록 하며, Problem에서 기술적인 이슈 문제는 블로그에 포스팅한 내용에 대해서는 적지 않으려 한다..(이미 블로그에 그와 관련된 내용을 다 포스팅 한 것이기 때문)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;i&gt;&lt;b&gt;1. Keep&lt;/b&gt;&lt;/i&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;리뷰를 하면서 팀원들한테 지속적으로 &quot;왜 그렇게했어?&quot;를 물고 늘어졌었다. 팀원들의 성장이 눈에 띄게 빠르게 올라가는걸 보면서 정말 기뻤다. (다라고 말할 수는 없겠지만...)&lt;/li&gt;
&lt;li&gt;최대한 매일 일일스크럼을 하려고 했다, 그러면서 팀원들한테 자신이 배운 것, 익힌것을 스크럼시간에 다른 팀원한테 전파하도록 시키고자 하였고 그 시간이 매우 소중했다.&lt;/li&gt;
&lt;li&gt;Reference가 없는 서비스를 내가 직접 사용해 보면서 Reference를 만들어 버린 것. (&lt;a href=&quot;https://devjong12.tistory.com/112&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;NCP의 ELSA사용방법&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Docker를 바탕으로 실행하는 Spring Boot Application에 PinPoint Agent를 실행하는 방법을 알게 된 것&lt;/li&gt;
&lt;li&gt;서버의 모든 인프라 환경을 Private로 구축에 성공한것&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;i&gt;&lt;b&gt;2. Problem&lt;/b&gt;&lt;/i&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;k8s환경을 구축해보지 못했던 것&lt;/li&gt;
&lt;li&gt;부하테스트를 진행해보지 못한 것&lt;/li&gt;
&lt;li&gt;Front와 React의 지식이 BackEnd에 비하여 많이 부족했던 부분&lt;/li&gt;
&lt;li&gt;BackEnd에서의 아쉬웠던점 (일부로 하지 않은 부분이며, 팀원이 못따라 올 것이라 판단하여 하지 않음)
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;TestCase의 작성을 하지 못한 것&lt;/li&gt;
&lt;li&gt;QueryDSL을 사용해보지 못한 것&lt;/li&gt;
&lt;li&gt;Swagger나 Spring Rest Docs를 사용하지 못한 것&lt;/li&gt;
&lt;li&gt;BackEnd도 다국어 처리를 해야했는데 하지 못한 것&lt;/li&gt;
&lt;li&gt;RestAPI에서 Entity를 반환하는 기능들이 많다는 것?&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;FrontEnd에서의 아쉬웠던점
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;상태관리 Redux와 Redux Saga의 개념이 너무 부족했던 것&lt;/li&gt;
&lt;li&gt;한개의 컴포넌트에 어쩔 수 없이 모든 기능을 다 떄려박을 수 밖에 없던 것&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Jenkins에서 Pipeline을 통한 배포를 하지 못한 것&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이정도 인것 같다..&lt;/p&gt;
&lt;hr data-ke-style=&quot;style5&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h2 style=&quot;color: #000000;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;4️⃣ 프로젝트를 하면서 느낀 점?&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사실 매번 PM을 어쩔 수 없이 맡게 될 때마다 불편했다. 나도 그냥 팀원으로써 기능구현을 하고 PM마음고생시키면서 같이 작업하는게 더 재밌는데 말이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;어쨋든 토이프로젝트를 할 때면 같이 하게 되는 사람들이 다들 PM이 되는 것도 기피하고 실제 자신의 문제를 털어놓거나 자신의 의견을 강하게 밀어주는 사람들이 없었고,&amp;nbsp; 그냥 어떻게든 될대로 되겠지 하면서 의욕없어하는 팀원들을 보면서 늘 재미가 없었고 불편했다. (내가 팀운이 없는건지, 팀원들한테 의욕이 없어지도록 만드는건지 모르겠는데 매번 이러니까 후자같아보이기도 하다.. )&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 실력과 상관없이 마음맞는 사람끼리 하고자 싶어 했고, 심지어 잘 안되더라도 다들 끝까지 노력하는 모습을 보면서 처음으로 타인과 같이 하는 프로젝트가 재밌었었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한, 내가 재직할때 당시 팀장이 날 보던 모습이 이러지 않았을까 했던 생각도 많이 들었었고, 아 시니어의 고충이 이런거구나를 얄팍하게나마 느낄 수 있던 시간이었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;팀원의 전체 코드리뷰를 해주고, 코멘트를 달아주면서, 기능에 대해서 생각하고, 기능구현 못한걸 119마냥 가서 구급대처럼 구현해주고, 팀원들한테 내 말에 대한 신뢰를 주고자 했던 행동들을 생각해보면 정말... 많은걸 경험해 볼 수 있고 느꼈던 프로젝트다.  &lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 마지막으로 내 탱킹과 말빨이 그래도 나쁘지 않다는걸 많이 체감했었다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style5&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h2 style=&quot;color: #000000;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;5️⃣ 아쉬웠던 점?&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;되돌아 보면, 치열하게 싸우면서 논쟁을 했던 시간이 거의 없었다. 이게 좀 아쉬웠던 점이지 않을까 싶다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;매번 이슈가 발생하면 CS적으로, 코드적으로 문제를 추적하면서 이슈를 바로바로 해결했었다 보니 논쟁을 펼칠 일이 안생겨 버린게 아쉬웠지 않았나 생각이 든다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한, 프로젝트의 기간이 짧았던 것도 너무 아쉬운 요소라고 생각했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실제 구현해보고 싶은 것은 너무 많았는데 기능구현이 2주였나밖에 되지를 않았다. 이게 가장 아쉬웠던 요소라 생각이 지금은 든다.&lt;/p&gt;
&lt;hr data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 style=&quot;color: #000000;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;6️⃣ &lt;b&gt; 추가적인 리팩토링이 필요한 것?&lt;/b&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;FrontEnd의 코드를 전체적으로 기능단위를 잘게 잘라서 제작하는것과, KP의 Problem에 적은 BackEnd의 코드적인 부분을 좀 건드려보면 좋지 않을까 싶다~&lt;/p&gt;
&lt;hr data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 style=&quot;color: #000000;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;7️⃣ &lt;b&gt;&lt;b&gt;참고한 Reference&lt;/b&gt;&lt;/b&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;KPT회고에 대하여
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://brunch.co.kr/@jinha0802/35&quot;&gt;https://brunch.co.kr/@jinha0802/35&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>프로젝트/OrientalUnity</category>
      <category>Naver Cloud Platform</category>
      <category>OrientalUnity</category>
      <category>papago</category>
      <category>React</category>
      <category>spring</category>
      <category>spring boot</category>
      <category>네이버클라우드</category>
      <category>프로젝트 회고</category>
      <category>회고</category>
      <author>Jong12</author>
      <guid isPermaLink="true">https://devjong12.tistory.com/118</guid>
      <comments>https://devjong12.tistory.com/118#entry118comment</comments>
      <pubDate>Tue, 21 Nov 2023 17:25:35 +0900</pubDate>
    </item>
    <item>
      <title>[OrientalUnity][React] i18next를 활용한 다국어 처리</title>
      <link>https://devjong12.tistory.com/117</link>
      <description>&lt;div class=&quot;book-toc&quot; style=&quot;margin-top: 20px; margin-bottom: 30px;&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;목차&lt;/p&gt;
&lt;ul id=&quot;toc&quot; style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;&lt;/ul&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;1️⃣ 글을 작성하기에 앞서...&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;필자의 경우 BackEnd를 위주로 공부하다 보니 Spring, Java 코드들에 비해서는 깔끔하면서 능숙한 코드가 안나올 수도 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그 점은 양해하며, 어떻게 작업을 했는지를 중점으로 봐주면 좋을 듯 하다..  &lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 style=&quot;color: #000000;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;2️⃣ 다국어 처리를 하게 된 이유 그리고 i18next&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 프로젝트는 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;게시물을 작성 할 때 4개국어로 번역&lt;/b&gt;&lt;/span&gt;한 이후 저장이 되는&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt; 타 국가와 소통이 가능한 프로젝트&lt;/b&gt;&lt;/span&gt;이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정작 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;게시물은 4개국어로 저장&lt;/b&gt;&lt;/span&gt;이 되는데 반해, &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;페이지는 한국어로 계속해서 표현이 되면 부자연스럽다 생각&lt;/b&gt;&lt;/span&gt;하게 되었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이후 생각이 들었던 프로젝트의 방향은 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;다양한 사이트에서 봤던 기능&lt;/b&gt;&lt;/span&gt;인, &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;국가 변경을 했을 때 해당 국가의 언어에 맞게 페이지, 데이터가 변경이 되어야 겠다는 생각&lt;/b&gt;&lt;/span&gt;을 하게 되었고 다국어 처리를 할 수 있는 방법이 무엇이 있는지를 확인하다 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;i18next를 사용할 수 있다는 것&lt;/b&gt;&lt;/span&gt;을 알아 선택하게 되었다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style5&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h2 style=&quot;color: #000000;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;3️⃣ i18next란? 설치방법은?&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.i18next.com/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;공식페이지&lt;/a&gt;를 보면 JavaScript를 기반으로 한 국제화 프레임워크로, 다국어 처리를 할 수 있는 프레임워크다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사용할 수 있는 도구를 다 기록해 놓은 것 같다.. (이미지에는 없지만 스프링도 사용은 가능하다는걸 처음알았다.)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;951&quot; data-origin-height=&quot;544&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/TGNm0/btsAzaUE0II/0lfXfWyhHgL5EfHDhgavfK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/TGNm0/btsAzaUE0II/0lfXfWyhHgL5EfHDhgavfK/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/TGNm0/btsAzaUE0II/0lfXfWyhHgL5EfHDhgavfK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FTGNm0%2FbtsAzaUE0II%2F0lfXfWyhHgL5EfHDhgavfK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;951&quot; height=&quot;544&quot; data-origin-width=&quot;951&quot; data-origin-height=&quot;544&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure data-ke-type=&quot;image&quot; data-ke-style=&quot;alignCenter&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;
&lt;figcaption style=&quot;display: none;&quot;&gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;설치의 경우에는 FrontEnd 프로젝트에서 다음의 Json적용을 하면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;필자의 경우에는 두개 전부 적용을 했다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;746&quot; data-origin-height=&quot;272&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/QUlCo/btsAyLVAuzS/AXLCYFbPlL73hEpd3NKbs1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/QUlCo/btsAyLVAuzS/AXLCYFbPlL73hEpd3NKbs1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/QUlCo/btsAyLVAuzS/AXLCYFbPlL73hEpd3NKbs1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FQUlCo%2FbtsAyLVAuzS%2FAXLCYFbPlL73hEpd3NKbs1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;746&quot; height=&quot;272&quot; data-origin-width=&quot;746&quot; data-origin-height=&quot;272&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr data-ke-style=&quot;style5&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h2 style=&quot;color: #000000;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;4️⃣ i18next 설정&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;필자가 프로젝트에 적용한 설정은 다음과 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4개국어의 정보를 resources로 담고, 이후 i18n객체에 지정을 하였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한 localStoreage에 기존에 선택한 값이 없는 경우 한국어가 기본적으로 설정하게 하였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;resources의 언어값은 개발하는 본인이 직접 지정을 해도 상관없다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;746&quot; data-origin-height=&quot;681&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bxW6md/btsAy9haFyr/I4PNCv9AFcsKommZKWb040/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bxW6md/btsAy9haFyr/I4PNCv9AFcsKommZKWb040/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bxW6md/btsAy9haFyr/I4PNCv9AFcsKommZKWb040/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbxW6md%2FbtsAy9haFyr%2FI4PNCv9AFcsKommZKWb040%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;746&quot; height=&quot;681&quot; data-origin-width=&quot;746&quot; data-origin-height=&quot;681&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실제 src하위의 디렉토리 구조가 locales아래에 번역된 정보들이 존재한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2023-11-20 오후 6.03.58.png&quot; data-origin-width=&quot;524&quot; data-origin-height=&quot;964&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/s9LLF/btsACkJsP9N/LhxDcMeVjcmKAZlwGKPgsK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/s9LLF/btsACkJsP9N/LhxDcMeVjcmKAZlwGKPgsK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/s9LLF/btsACkJsP9N/LhxDcMeVjcmKAZlwGKPgsK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fs9LLF%2FbtsACkJsP9N%2FLhxDcMeVjcmKAZlwGKPgsK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;524&quot; height=&quot;964&quot; data-filename=&quot;스크린샷 2023-11-20 오후 6.03.58.png&quot; data-origin-width=&quot;524&quot; data-origin-height=&quot;964&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;번역정보를 담는 일부인 중국어와 한국어에 대한 번역 메세지 정보를 담는 파일역시 전부 json으로 구성하였다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2023-11-20 오후 6.05.12.png&quot; data-origin-width=&quot;532&quot; data-origin-height=&quot;388&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Ozlxl/btsAFv4yYvh/n05oMCm0G6lF4jpVfaHGV1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Ozlxl/btsAFv4yYvh/n05oMCm0G6lF4jpVfaHGV1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Ozlxl/btsAFv4yYvh/n05oMCm0G6lF4jpVfaHGV1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FOzlxl%2FbtsAFv4yYvh%2Fn05oMCm0G6lF4jpVfaHGV1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;532&quot; height=&quot;388&quot; data-filename=&quot;스크린샷 2023-11-20 오후 6.05.12.png&quot; data-origin-width=&quot;532&quot; data-origin-height=&quot;388&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2023-11-20 오후 6.05.28.png&quot; data-origin-width=&quot;508&quot; data-origin-height=&quot;382&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/brgkWW/btsACkCJkwq/12kk5QTugRGpzuwo4ZPt7k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/brgkWW/btsACkCJkwq/12kk5QTugRGpzuwo4ZPt7k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/brgkWW/btsACkCJkwq/12kk5QTugRGpzuwo4ZPt7k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbrgkWW%2FbtsACkCJkwq%2F12kk5QTugRGpzuwo4ZPt7k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;508&quot; height=&quot;382&quot; data-filename=&quot;스크린샷 2023-11-20 오후 6.05.28.png&quot; data-origin-width=&quot;508&quot; data-origin-height=&quot;382&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr data-ke-style=&quot;style5&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h2 style=&quot;color: #000000;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;5️⃣ 각 컴포넌트에서 해야하는 작업&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다국어 메세지를 가져와야 하는 컴포넌트에서는 아래와 같이 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;useTranslation()을 통하여 i18next의 hook을 가져와야한다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이후 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;메세지가 필요한곳에 useTranslation의 첫번째 변수를 사용해 메세지&lt;/b&gt;&lt;/span&gt;를 가져 올 수 있게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이후 필자의 경우에는 i18n을 effect를 통해 감지를 하였는데, 선택한 &lt;span style=&quot;color: #409d00;&quot;&gt;&lt;b&gt;국가의 변경이 일어날 때 페이지의 모든 언어를 선택한 국가의 언어로 변경하고자 하여 감지를 진행&lt;/b&gt;&lt;/span&gt;하였다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;746&quot; data-origin-height=&quot;1147&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/SIHmU/btsAyr3srz8/QxJ5Kyg08EdSJKgNxVdJz0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/SIHmU/btsAyr3srz8/QxJ5Kyg08EdSJKgNxVdJz0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/SIHmU/btsAyr3srz8/QxJ5Kyg08EdSJKgNxVdJz0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FSIHmU%2FbtsAyr3srz8%2FQxJ5Kyg08EdSJKgNxVdJz0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;746&quot; height=&quot;1147&quot; data-origin-width=&quot;746&quot; data-origin-height=&quot;1147&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 style=&quot;color: #000000;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;6️⃣ 헤더에서의 언어 선택과 데이터 변경&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;완성된 기능은 아래의 이미지처럼 Header에서 언어를 선택할 경우 언어가 변경되도록 진행하였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;데이터가 변경되는 기능은 각페이지마다 useEffect를 통해 변경감지로 데이터가 변경되게 하였다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;640&quot; data-origin-height=&quot;376&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dNv5jf/btsAFE8gZ91/HSltzt4kVNFSjlZdFHQvG0/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dNv5jf/btsAFE8gZ91/HSltzt4kVNFSjlZdFHQvG0/img.gif&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dNv5jf/btsAFE8gZ91/HSltzt4kVNFSjlZdFHQvG0/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/dNv5jf/btsAFE8gZ91/HSltzt4kVNFSjlZdFHQvG0/img.gif&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;640&quot; height=&quot;376&quot; data-origin-width=&quot;640&quot; data-origin-height=&quot;376&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;해당 챕터에서는 Header의 코드를 나열해보고자 한다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;우선 Header에서는 Language를 선택할 수 있는 컴포넌트를 호출합니다. (원본 소스에서는 다양한 props가 있지만 가독성을 위해 전부 제거하였습니다.)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;746&quot; data-origin-height=&quot;718&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kyesB/btsAGQVr3kh/0vNt7XQAUsW2gyYD77RmfK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kyesB/btsAGQVr3kh/0vNt7XQAUsW2gyYD77RmfK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kyesB/btsAGQVr3kh/0vNt7XQAUsW2gyYD77RmfK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FkyesB%2FbtsAGQVr3kh%2F0vNt7XQAUsW2gyYD77RmfK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;746&quot; height=&quot;718&quot; data-origin-width=&quot;746&quot; data-origin-height=&quot;718&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이후 셀렉트가 가능한 드롭박스의 코드는 아래와 같이 작성을 하였습니다.Option의 Value를 i18n.js의 resources에 선언했던 Key값으로 지정을 하였으며, onChange이벤트가 발생할 경우에는 i18n.changeLanguage의 설정 언어를 변경해 주었습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;746&quot; data-origin-height=&quot;663&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cziCw2/btsAIIv0lIO/jQERLrxCtE1CrqpeFpsVQ1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cziCw2/btsAIIv0lIO/jQERLrxCtE1CrqpeFpsVQ1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cziCw2/btsAIIv0lIO/jQERLrxCtE1CrqpeFpsVQ1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcziCw2%2FbtsAIIv0lIO%2FjQERLrxCtE1CrqpeFpsVQ1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;746&quot; height=&quot;663&quot; data-origin-width=&quot;746&quot; data-origin-height=&quot;663&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;i18n의 useTranslation자체가 Hook으로 작동이 되는 원리이다 보니, 각기 다른 컴포넌트에서 사용이 가능했으며 한곳에서 변경을 시켜도 다른곳에서 감지를 하고 그에 맞는 언어로 변경이 되는 원리여서 다음과 같이 onChange이벤트에서 언어변경만으로 구현이 가능하였습니다.&lt;/p&gt;
&lt;hr data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 style=&quot;color: #000000;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;7️⃣ 글을 마치며...&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Front.. 특히 SPA에 대해서는 매우 해박한 지식까지 가지고 있는 부분이 아니다 보니, 실제 구현을 하면서 작동원리를 깊게 이해를 하지 못하는걸 느낄 수 있었던 부분이었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러다 보니 정말 참고한 Reference도 많았던 것 같습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래도 기능의 구현과 구현된 기능을 가져다 쓰는 부분이다 보니 금방감은 잡고 사용이 가능했어서 큰 문제는 없었고.. 단지 메세지를 전부 미리 채워놔줘야 한다는 불편함을 크게 느낄 수 있었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;막상 완성되고 보니 언어감지를 해가지고 페이지가 자동으로 변경되는것을 봤을떄는 아 이래서 프론트 하는 구나 하는 생각도 들었던 작업이었습니다.&lt;/p&gt;
&lt;hr data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 style=&quot;color: #000000;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;8️⃣ 참고한 Reference&lt;/b&gt;&lt;/h2&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://react.i18next.com/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://react.i18next.com/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://babycoder05.tistory.com/entry/React%EC%97%90%EC%84%9C-react-i18next-%EC%82%AC%EC%9A%A9%ED%95%98%EB%8A%94-%EB%B0%A9%EB%B2%95&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://babycoder05.tistory.com/entry/React%EC%97%90%EC%84%9C-react-i18next-%EC%82%AC%EC%9A%A9%ED%95%98%EB%8A%94-%EB%B0%A9%EB%B2%95&lt;/a&gt;&amp;nbsp;&amp;nbsp;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://dlsgh120.tistory.com/53&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://dlsgh120.tistory.com/53&lt;/a&gt;&amp;nbsp;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://velog.io/@remon/React-%EB%8B%A4%EA%B5%AD%EC%96%B4-%EC%B2%98%EB%A6%AC-react-i18next&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://velog.io/@remon/React-%EB%8B%A4%EA%B5%AD%EC%96%B4-%EC%B2%98%EB%A6%AC-react-i18next&lt;/a&gt; &lt;a href=&quot;https://babycoder05.tistory.com/m/entry/React%EC%97%90%EC%84%9C-react-i18next-%EC%82%AC%EC%9A%A9%ED%95%98%EB%8A%94-%EB%B0%A9%EB%B2%95&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://babycoder05.tistory.com/m/entry/React%EC%97%90%EC%84%9C-react-i18next-%EC%82%AC%EC%9A%A9%ED%95%98%EB%8A%94-%EB%B0%A9%EB%B2%95&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://byul91oh.tistory.com/552&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://byul91oh.tistory.com/552&lt;/a&gt;&amp;nbsp;&amp;nbsp;&lt;/li&gt;
&lt;/ol&gt;</description>
      <category>프로젝트/OrientalUnity</category>
      <category>Frontend</category>
      <category>i18next</category>
      <category>OrientalUnity</category>
      <category>React</category>
      <category>react-i18next</category>
      <category>다국어</category>
      <author>Jong12</author>
      <guid isPermaLink="true">https://devjong12.tistory.com/117</guid>
      <comments>https://devjong12.tistory.com/117#entry117comment</comments>
      <pubDate>Tue, 21 Nov 2023 15:57:31 +0900</pubDate>
    </item>
    <item>
      <title>[OrientalUnity][React, Spring] React Quill의 바이트 코드이미지 삽입이슈와 해결법</title>
      <link>https://devjong12.tistory.com/116</link>
      <description>&lt;div class=&quot;book-toc&quot; style=&quot;margin-top: 20px; margin-bottom: 30px;&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;목차&lt;/p&gt;
&lt;ul id=&quot;toc&quot; style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;&lt;/ul&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;1️⃣ 글 작성에 앞서...&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 이슈는 우리 팀이 구현한 사용한 도구에 대한 이해가 필요하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일단 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;FrontEnd의 경우 React를 기반으로 작성&lt;/b&gt;&lt;/span&gt;을 진행하였으며, 이슈가 발생한 장소는 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;게시물을 등록하는 곳에서 발생&lt;/b&gt;&lt;/span&gt;이 되었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;게시물을 등록시 필자의 팀의 경우에는 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;에디터를 사용하여 게시물을 등록&lt;/b&gt;&lt;/span&gt;할 수 있도록 기능 구현을 하였으며, 오픈소스중 하나인 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;React Quill을 활용&lt;/b&gt;&lt;/span&gt;하였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Quill자체에는 이미지를 업로드하는 기능이 존재하였으나, 이미지를 업로드할때 발생이 되는 이슈사항에 대하여 기록을 해보고자 한다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 style=&quot;color: #000000;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;2️⃣ ReactQuill와 Quill을 선정한 이유?&lt;/b&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;i&gt;&lt;b&gt;1. ReactQuill이란?&lt;/b&gt;&lt;/i&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;공식페이지에서 소개되어있는 내용으로, 긴 텍스트를 작성할 수 있는 에디터라고 설명이 되어있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;에디터를 작성하게 되면 TextArea와는 다르게 HTML마크업을 그대로 전달받을 수 있게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://quilljs.com/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://quilljs.com/&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1700462207055&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Quill - Your powerful rich text editor&quot; data-og-description=&quot;Sailec Light Sofia Pro Slabo 27px Roboto Slab Inconsolata Ubuntu Mono Quill Rich Text Editor Quill is a free, open source WYSIWYG editor built for the modern web. With its modular architecture and expressive API, it is completely customizable to fit any ne&quot; data-og-host=&quot;quilljs.com&quot; data-og-source-url=&quot;https://quilljs.com/&quot; data-og-url=&quot;https://quilljs.com/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bpGbTn/hyUCg0aDMn/XqPQMPnhNwevccJX0b2QQk/img.png?width=300&amp;amp;height=300&amp;amp;face=0_0_300_300,https://scrap.kakaocdn.net/dn/iMfJx/hyUywjh92h/wzORS253DyGLOoToYqclZ0/img.png?width=300&amp;amp;height=300&amp;amp;face=0_0_300_300&quot;&gt;&lt;a href=&quot;https://quilljs.com/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://quilljs.com/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bpGbTn/hyUCg0aDMn/XqPQMPnhNwevccJX0b2QQk/img.png?width=300&amp;amp;height=300&amp;amp;face=0_0_300_300,https://scrap.kakaocdn.net/dn/iMfJx/hyUywjh92h/wzORS253DyGLOoToYqclZ0/img.png?width=300&amp;amp;height=300&amp;amp;face=0_0_300_300');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Quill - Your powerful rich text editor&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Sailec Light Sofia Pro Slabo 27px Roboto Slab Inconsolata Ubuntu Mono Quill Rich Text Editor Quill is a free, open source WYSIWYG editor built for the modern web. With its modular architecture and expressive API, it is completely customizable to fit any ne&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;quilljs.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2023-11-20 오후 3.36.15.png&quot; data-origin-width=&quot;3354&quot; data-origin-height=&quot;1800&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bu7vy6/btsAFZqDK54/A9mT0CkuekQ0HLQIO2WSQ1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bu7vy6/btsAFZqDK54/A9mT0CkuekQ0HLQIO2WSQ1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bu7vy6/btsAFZqDK54/A9mT0CkuekQ0HLQIO2WSQ1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbu7vy6%2FbtsAFZqDK54%2FA9mT0CkuekQ0HLQIO2WSQ1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3354&quot; height=&quot;1800&quot; data-filename=&quot;스크린샷 2023-11-20 오후 3.36.15.png&quot; data-origin-width=&quot;3354&quot; data-origin-height=&quot;1800&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;i&gt;&lt;b&gt;2. 필자가 생각하는 에디터를 사용해야 하는 이유&lt;/b&gt;&lt;/i&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;에디터를 써야하는 이유는 필자가 생각함에 있어서는 일단 정보를 전달하는 글을 작성함에 있어 강조의 표현을 다르게 꾸며논다든가 등 글의 가독성을 높일 수 있기 위해서는 HTML언어를 적용 시킬 수 있어야 하는데, TextArea로는 작성자가 의도대로 작성하는지의 확인이 힘들다는 단점이 가장 큰 문제이지 않나 싶다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;그 외에도 호환문제라든가 여러가지 사유가 존재하고, 각자가 다 다를 수 있으니 해당사항은 직접 생각해보면 좋을 듯 하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;i&gt;&lt;b&gt;3. 왜 Quill이었는가?&lt;/b&gt;&lt;/i&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;딱히 큰 이유는 없었다. 오픈소스에 무료사용이 가능한점, Editor를 검색시 가장 먼저 나온점등이 이유였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그저, &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;이미지를 넣을 수 있고, HTML로 Content를 받아올 수만 있었다면 자료가 많은것중 아무거나 가져와서 사용했을 것&lt;/b&gt;&lt;/span&gt;이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Quill이 먼저 많이 나온 자료였고, 아래의 이미지 처럼 구현이 바로바로 가능했기때문에 빠르게 채택하였다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2023-11-20 오후 3.49.49.png&quot; data-origin-width=&quot;1928&quot; data-origin-height=&quot;404&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cKiNxa/btsACmNRmfm/NJGvE2NTW3t9T6HeiatoU0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cKiNxa/btsACmNRmfm/NJGvE2NTW3t9T6HeiatoU0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cKiNxa/btsACmNRmfm/NJGvE2NTW3t9T6HeiatoU0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcKiNxa%2FbtsACmNRmfm%2FNJGvE2NTW3t9T6HeiatoU0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1928&quot; height=&quot;404&quot; data-filename=&quot;스크린샷 2023-11-20 오후 3.49.49.png&quot; data-origin-width=&quot;1928&quot; data-origin-height=&quot;404&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;그냥 에디터를 왜 써?&lt;/b&gt;&lt;/span&gt; 라고 묻는다면..한번 생각해보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우리가 블로그에서 글을 작성하건, 커뮤니티 싸이트에서 글을 작성하건.. 사진을 못올리고, &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;게시물의 내용을 볼드나 이태릭처리를 못하는 그런 커뮤니티나 블로그를 본적이 있는가?&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이게 내가 생각했을때 커뮤니티 프로젝트를 하게 된 순간부터 에디터를 고려 할 수밖에 없단 사항이다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style5&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h2 style=&quot;color: #000000;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;3️⃣ 이슈내용&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이미지를 업로드할 떄 문제가 된다고 처음에 말을 하였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이미지는 굉장히 긴 바이트코드로 이루어져있다. FrontEnd Application레벨에서는 이미지를 어떻게 처리하는지를 나도 몰랐다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ReactQuill에서는 그&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt; 긴 바이트코드를 HTML태그로 img태그에 집어넣고 있었다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;오른쪽의 코드가 IMG태그의 src속성에 직접 바이트코드로 넣고 있는것을 볼 수 있으며, 저 문자열을 그대로 Spring에서 받게 된다는 것이다. 그렇게 넘어오는 것 자체를 필자는 이슈라고 정의하였다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2023-11-20 오후 4.05.54.png&quot; data-origin-width=&quot;2676&quot; data-origin-height=&quot;1750&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/KENOp/btsAzCKrBhr/sronfMbZPgSQ5ZF07kqPf0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/KENOp/btsAzCKrBhr/sronfMbZPgSQ5ZF07kqPf0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/KENOp/btsAzCKrBhr/sronfMbZPgSQ5ZF07kqPf0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FKENOp%2FbtsAzCKrBhr%2FsronfMbZPgSQ5ZF07kqPf0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2676&quot; height=&quot;1750&quot; data-filename=&quot;스크린샷 2023-11-20 오후 4.05.54.png&quot; data-origin-width=&quot;2676&quot; data-origin-height=&quot;1750&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr data-ke-style=&quot;style5&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h2 style=&quot;color: #000000;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;4️⃣ 해결 방안?&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해결의 최종점은 바이트코드를 대신해서 서버에 업로드된 이미지의 Path를 기록하게 하는 것이었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그를 위해 어떻게 작업을 해야할까? 고민을 했고, Image를 업로드할 때 사용되는 Handler를 제작해서 적용하기로 마음먹었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;로직을 이해하기 쉽게 이미지로만 끝내면 다음과 같이 표현이 가능해진다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;i&gt;&lt;b&gt;1. 기존에 React Quill을 사용시의 로직&lt;/b&gt;&lt;/i&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;mermaid-diagram-2023-11-20-161538.png&quot; data-origin-width=&quot;972&quot; data-origin-height=&quot;772&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/vVBwG/btsAD1vK2JK/Rzeuauem9Oj5J1JXvtpnK1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/vVBwG/btsAD1vK2JK/Rzeuauem9Oj5J1JXvtpnK1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/vVBwG/btsAD1vK2JK/Rzeuauem9Oj5J1JXvtpnK1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FvVBwG%2FbtsAD1vK2JK%2FRzeuauem9Oj5J1JXvtpnK1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;972&quot; height=&quot;772&quot; data-filename=&quot;mermaid-diagram-2023-11-20-161538.png&quot; data-origin-width=&quot;972&quot; data-origin-height=&quot;772&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;i&gt;&lt;b&gt;2. Server의 Path를 가져오는 로직&lt;/b&gt;&lt;/i&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;mermaid-diagram-2023-11-20-162051.png&quot; data-origin-width=&quot;972&quot; data-origin-height=&quot;772&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bpu6BL/btsACm8eP4W/9KVOnJucj6gHOdtVm7kv10/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bpu6BL/btsACm8eP4W/9KVOnJucj6gHOdtVm7kv10/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bpu6BL/btsACm8eP4W/9KVOnJucj6gHOdtVm7kv10/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbpu6BL%2FbtsACm8eP4W%2F9KVOnJucj6gHOdtVm7kv10%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;972&quot; height=&quot;772&quot; data-filename=&quot;mermaid-diagram-2023-11-20-162051.png&quot; data-origin-width=&quot;972&quot; data-origin-height=&quot;772&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr data-ke-style=&quot;style5&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h2 style=&quot;color: #000000;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;5️⃣ BackEnd (Spring)의 작업내역&lt;/b&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;i&gt;&lt;b&gt;1. Controller&lt;/b&gt;&lt;/i&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;i&gt;&lt;/i&gt;&lt;span style=&quot;color: #000000;&quot;&gt;이미지를 업로드할 API를 제작한다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;해당 요청은 MultiPart를 받아야 하기때문에 POST메소드를 사용해야 한다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;650&quot; data-origin-height=&quot;707&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bKVbj6/btsAzCjstFY/QSNHGEWneBUebQokrd1MN0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bKVbj6/btsAzCjstFY/QSNHGEWneBUebQokrd1MN0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bKVbj6/btsAzCjstFY/QSNHGEWneBUebQokrd1MN0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbKVbj6%2FbtsAzCjstFY%2FQSNHGEWneBUebQokrd1MN0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;650&quot; height=&quot;707&quot; data-origin-width=&quot;650&quot; data-origin-height=&quot;707&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;i&gt;&lt;b&gt;2. DTO&lt;/b&gt;&lt;/i&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Request를 담당할 DTO와 Response를 담당할 DTO를 생성한다. &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;필자의 경우 사용처를 Path에 집어넣고 있어서, 어느 기능에서 올린것인지 구분하기 위한 Enum이 존재한다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;650&quot; data-origin-height=&quot;521&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b2RPNb/btsAyrI4HKY/Lw9DCgdvEar1JtYazDd51K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b2RPNb/btsAyrI4HKY/Lw9DCgdvEar1JtYazDd51K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b2RPNb/btsAyrI4HKY/Lw9DCgdvEar1JtYazDd51K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb2RPNb%2FbtsAyrI4HKY%2FLw9DCgdvEar1JtYazDd51K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;650&quot; height=&quot;521&quot; data-origin-width=&quot;650&quot; data-origin-height=&quot;521&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;650&quot; data-origin-height=&quot;689&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/xzcpm/btsAx1xtWrD/HQok18mVKzprkKzsbvBQDK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/xzcpm/btsAx1xtWrD/HQok18mVKzprkKzsbvBQDK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/xzcpm/btsAx1xtWrD/HQok18mVKzprkKzsbvBQDK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fxzcpm%2FbtsAx1xtWrD%2FHQok18mVKzprkKzsbvBQDK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;650&quot; height=&quot;689&quot; data-origin-width=&quot;650&quot; data-origin-height=&quot;689&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;i&gt;&lt;b&gt;3. Service&lt;/b&gt;&lt;/i&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Service에서는 우선적으로 로그인한 사용자인지를 구분하며, 이후 테이블에 요청한 사용자의 정보를 바탕으로 올린 파일정보를 기록해두며, Response객체로 감싸서 Return을 한다.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cToZn9/btsACm8f0Jz/T3v332tm65AmuPSnhWPoZk/img.png&quot; data-origin-width=&quot;906&quot; data-origin-height=&quot;532&quot; data-is-animation=&quot;false&quot; /&gt;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;i&gt;&lt;b&gt;4. FileUpload Util&lt;/b&gt;&lt;/i&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 코드에서 실질적인 파일 업로드가 이뤄진다. 정말로 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;파일 업로드&lt;/b&gt;&lt;/span&gt;와 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;변경된 파일 명을 반환&lt;/b&gt;&lt;/span&gt;만한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 기억할 사항은 필자의 경우 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;spring.profiles.active의 Value&lt;/b&gt;&lt;/span&gt;에 따라 &lt;span style=&quot;color: #409d00;&quot;&gt;&lt;b&gt;/dev~ 로 시작할지, /local~ 로 시작할 지를 구분&lt;/b&gt;&lt;/span&gt;하였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한 파일의 경우 &lt;span style=&quot;color: #409d00;&quot;&gt;&lt;b&gt;실행위치 + 사용처 + 시간 + 파일명으로 저장&lt;/b&gt;&lt;/span&gt;이 되게 된다&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;906&quot; data-origin-height=&quot;2357&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cI7X7V/btsAxZNbnZd/31wk1tXaNTo1gEuBpTYQK0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cI7X7V/btsAxZNbnZd/31wk1tXaNTo1gEuBpTYQK0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cI7X7V/btsAxZNbnZd/31wk1tXaNTo1gEuBpTYQK0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcI7X7V%2FbtsAxZNbnZd%2F31wk1tXaNTo1gEuBpTYQK0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;906&quot; height=&quot;2357&quot; data-origin-width=&quot;906&quot; data-origin-height=&quot;2357&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;i&gt;&lt;b&gt;5. Amazon S3 Bean&lt;/b&gt;&lt;/i&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 코드에서는 FileUpload를 진행하는 Util에서 사용하는 S3의 Bean을 설정하는 코드만 존재한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;StorageProperties까지는 나열하지 않을 예정이므로, &lt;a href=&quot;https://github.com/hook-killer/back-end&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Git Repository를 참고&lt;/a&gt;해주기 바란다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;746&quot; data-origin-height=&quot;1016&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/vChOd/btsAyV4ExGn/Zi9aRIBt7sOtdKDK3KM6oK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/vChOd/btsAyV4ExGn/Zi9aRIBt7sOtdKDK3KM6oK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/vChOd/btsAyV4ExGn/Zi9aRIBt7sOtdKDK3KM6oK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FvChOd%2FbtsAyV4ExGn%2FZi9aRIBt7sOtdKDK3KM6oK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;746&quot; height=&quot;1016&quot; data-origin-width=&quot;746&quot; data-origin-height=&quot;1016&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 style=&quot;color: #000000;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;6️⃣ FrontEnd (React)에서의 작업사항&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;FrontEnd에서는 굉장히 간단한 작업이 된다. &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;useMemo를 통해 사용할 Module을 선정한다. 이후 handlers에서 Image를 업로드하는 태그인 image의 함수를 제작해주면 작업이 완료된다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;FormData로 Dto형식에 맞게 생성한 이후 받아온 Path를 InsertEmbed메소드를 통해 기록하면 된다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;또한 useMemo를 통해 생성한 module를 ReactQuill에서는 당연히 참조를 해야한다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;746&quot; data-origin-height=&quot;998&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ER0nV/btsAxWCvFv0/W26GgGhgcb9ZR1MR44BCc0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ER0nV/btsAxWCvFv0/W26GgGhgcb9ZR1MR44BCc0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ER0nV/btsAxWCvFv0/W26GgGhgcb9ZR1MR44BCc0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FER0nV%2FbtsAxWCvFv0%2FW26GgGhgcb9ZR1MR44BCc0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;746&quot; height=&quot;998&quot; data-origin-width=&quot;746&quot; data-origin-height=&quot;998&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 style=&quot;color: #000000;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;7️⃣ 결과물&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;왼쪽의 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;이미지가 참조가 되지 않는 이유&lt;/b&gt;&lt;/span&gt;는 현재는 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;해당 Object Storage를 없앴기 떄문에 실제 업로드 기능을 BE에서 비활성화&lt;/b&gt; &lt;/span&gt;해놓은 상황이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실제 해당 경로에 올라가지 않았기 때문에 이미지를 못 불러 오는건 어쩔 수 없으며, &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;오른쪽의 경로&lt;/b&gt;&lt;/span&gt;를 자세히 봐주면 좋을 듯 하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #409d00;&quot;&gt;&lt;b&gt;local~로 시작하면서 업로드한 Path 정보의 확인이 가능&lt;/b&gt;&lt;/span&gt;하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #409d00;&quot;&gt;&lt;b&gt;위의 경우에는 작업이 완료된 이후의 src 속성의 값&lt;/b&gt;&lt;/span&gt;이며, &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;아래는 작업 전의 src 속성값&lt;/b&gt;&lt;/span&gt;이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;어떤것이 좋을 지는 게시물을 읽고있는 독자가 판단하면 좋을 듯 하다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2023-11-20 오후 4.55.25.png&quot; data-origin-width=&quot;2616&quot; data-origin-height=&quot;628&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ehIqxp/btsAyVXPoTs/ITlV2dKXOr9QLSMxXz1mZk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ehIqxp/btsAyVXPoTs/ITlV2dKXOr9QLSMxXz1mZk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ehIqxp/btsAyVXPoTs/ITlV2dKXOr9QLSMxXz1mZk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FehIqxp%2FbtsAyVXPoTs%2FITlV2dKXOr9QLSMxXz1mZk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2616&quot; height=&quot;628&quot; data-filename=&quot;스크린샷 2023-11-20 오후 4.55.25.png&quot; data-origin-width=&quot;2616&quot; data-origin-height=&quot;628&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2023-11-20 오후 4.05.54.png&quot; data-origin-width=&quot;2676&quot; data-origin-height=&quot;1750&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/KENOp/btsAzCKrBhr/sronfMbZPgSQ5ZF07kqPf0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/KENOp/btsAzCKrBhr/sronfMbZPgSQ5ZF07kqPf0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/KENOp/btsAzCKrBhr/sronfMbZPgSQ5ZF07kqPf0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FKENOp%2FbtsAzCKrBhr%2FsronfMbZPgSQ5ZF07kqPf0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2676&quot; height=&quot;1750&quot; data-filename=&quot;스크린샷 2023-11-20 오후 4.05.54.png&quot; data-origin-width=&quot;2676&quot; data-origin-height=&quot;1750&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 style=&quot;color: #000000;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;8️⃣ 왜 이런 작업을 생각하게 되었나?&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;필자의 프로젝트 컨셉에 들어가는 기능은 게시물의 자동번역이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러다 보니 저 바이트코드가 전부 번역기능(Papago)에 요청을 보낼 경우 문자열 한개로 인식을 하고 있었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;바이트코드의 길이가 수백자 수천자가 될 수 있는 상황&lt;/b&gt;&lt;/span&gt;인데, 이걸 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;전부 요청을 보내면 천문학적인 비용이 청부 될 수도 있겠다 생각&lt;/b&gt;&lt;/span&gt;하였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한 필자가 하던 생각이 맞다 보니 더 심각하게 해당 이슈를 바라 볼 수밖에 없었다.&lt;/p&gt;
&lt;hr data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 style=&quot;color: #000000;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;9️⃣ 글을 마치며&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;파일 업로드를 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;Spring으로 제작한 선례의 자료가 찾기 힘들었다&lt;/b&gt;&lt;/span&gt;. (그냥 없었다 수준인듯..?)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Image Handler를 컨트롤하는 방법만 알면 어렵진 않겠다 생각이 들었고, Next등으로 만든걸 올려준 사람이 많다보니 쉽게 할 수 있었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;항상 하는 생각이지만, 제작하면서 더 깊이 들은 생각은 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;&quot;언어는 그냥 도구일 뿐이고, 어떤 언어든 실행로직을 이해하면 다른 언어로도 어느 정도는 구현할 줄 알아야 한다&quot; &lt;/b&gt;&lt;/span&gt;였다. (진짜로 불가능하거나 너무 효율이 안좋은 경우도 있겠지만 말이다.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실제 Reference에 기록을 해뒀지만, Quill의 ImageHandler를 어떻게 컨트롤 할 수 있는지 참조만하고 작업을 하였으니 말이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;※ 진짜 작성하기 가장 무서웠던 글의 작성을 드디어 끝냈다... 내용이 많아서 언제하지 하면서 겁을 내고있었다.&lt;/p&gt;
&lt;hr data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 style=&quot;color: #000000;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;  참고한 Reference&lt;/b&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Quill의 Image Handler의 사용법 참고&lt;br /&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://12ahn22.tistory.com/entry/Quill-%EC%97%90%EB%94%94%ED%84%B0-%EC%9D%B4%EB%AF%B8%EC%A7%80-%EC%B2%98%EB%A6%AC%ED%95%98%EA%B8%B0&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://12ahn22.tistory.com/entry/Quill-%EC%97%90%EB%94%94%ED%84%B0-%EC%9D%B4%EB%AF%B8%EC%A7%80-%EC%B2%98%EB%A6%AC%ED%95%98%EA%B8%B0&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;figure id=&quot;og_1700467980575&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;Quill 에디터 - 이미지 처리하기&quot; data-og-description=&quot;깃허브에 작성한 ReadMe를 블로그로 옮겨왔다.(형식은 조금 수정..) 요새 너무 바빠서 글을 못올려서..^^ 팀 프로젝트에서 Quill 에디터를 사용했는 데, 이미지 업로드에 고생을 좀 해서 정리해봤다. &quot; data-og-host=&quot;12ahn22.tistory.com&quot; data-og-source-url=&quot;https://12ahn22.tistory.com/entry/Quill-%EC%97%90%EB%94%94%ED%84%B0-%EC%9D%B4%EB%AF%B8%EC%A7%80-%EC%B2%98%EB%A6%AC%ED%95%98%EA%B8%B0&quot; data-og-url=&quot;https://12ahn22.tistory.com/entry/Quill-%EC%97%90%EB%94%94%ED%84%B0-%EC%9D%B4%EB%AF%B8%EC%A7%80-%EC%B2%98%EB%A6%AC%ED%95%98%EA%B8%B0&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/zo4Wz/hyUCbLltsR/Y3aCF0TKnRl0mQiyMwZLjk/img.png?width=586&amp;amp;height=509&amp;amp;face=120_190_512_284,https://scrap.kakaocdn.net/dn/f8z97/hyUB64ljzU/FtNAK7XThz9JNFssBGshj0/img.png?width=586&amp;amp;height=509&amp;amp;face=120_190_512_284,https://scrap.kakaocdn.net/dn/fcHw7/hyUB2HDmRp/at7K47ympTyM44jHuiJ8E0/img.png?width=1012&amp;amp;height=590&amp;amp;face=0_0_1012_590&quot;&gt;&lt;a href=&quot;https://12ahn22.tistory.com/entry/Quill-%EC%97%90%EB%94%94%ED%84%B0-%EC%9D%B4%EB%AF%B8%EC%A7%80-%EC%B2%98%EB%A6%AC%ED%95%98%EA%B8%B0&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://12ahn22.tistory.com/entry/Quill-%EC%97%90%EB%94%94%ED%84%B0-%EC%9D%B4%EB%AF%B8%EC%A7%80-%EC%B2%98%EB%A6%AC%ED%95%98%EA%B8%B0&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/zo4Wz/hyUCbLltsR/Y3aCF0TKnRl0mQiyMwZLjk/img.png?width=586&amp;amp;height=509&amp;amp;face=120_190_512_284,https://scrap.kakaocdn.net/dn/f8z97/hyUB64ljzU/FtNAK7XThz9JNFssBGshj0/img.png?width=586&amp;amp;height=509&amp;amp;face=120_190_512_284,https://scrap.kakaocdn.net/dn/fcHw7/hyUB2HDmRp/at7K47ympTyM44jHuiJ8E0/img.png?width=1012&amp;amp;height=590&amp;amp;face=0_0_1012_590');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Quill 에디터 - 이미지 처리하기&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;깃허브에 작성한 ReadMe를 블로그로 옮겨왔다.(형식은 조금 수정..) 요새 너무 바빠서 글을 못올려서..^^ 팀 프로젝트에서 Quill 에디터를 사용했는 데, 이미지 업로드에 고생을 좀 해서 정리해봤다.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;12ahn22.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>프로젝트/OrientalUnity</category>
      <category>editor</category>
      <category>Java</category>
      <category>NCP</category>
      <category>object storage</category>
      <category>OrientalUnity</category>
      <category>Quill</category>
      <category>React</category>
      <category>ReactQuill</category>
      <category>s3</category>
      <category>spring</category>
      <author>Jong12</author>
      <guid isPermaLink="true">https://devjong12.tistory.com/116</guid>
      <comments>https://devjong12.tistory.com/116#entry116comment</comments>
      <pubDate>Mon, 20 Nov 2023 17:19:06 +0900</pubDate>
    </item>
  </channel>
</rss>