<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>삶 가운데 남긴 기록 AACII.TISTORY.COM</title>
    <link>https://aacii.tistory.com/</link>
    <description>Anti-symmetric Asynchronous Comet Internet Interface
命中日記</description>
    <language>ko</language>
    <pubDate>Tue, 14 Apr 2026 02:27:10 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>ALEPH.GEM</managingEditor>
    <image>
      <title>삶 가운데 남긴 기록 AACII.TISTORY.COM</title>
      <url>https://tistory1.daumcdn.net/tistory/3900768/attach/d643d88721f24572a2dfa94b4d500967</url>
      <link>https://aacii.tistory.com</link>
    </image>
    <item>
      <title>대항해시대 온라인 - Caravan 공략</title>
      <link>https://aacii.tistory.com/459</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;트레저 헌트 테마&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 테마: 보물의 장 - 번영했던 도시(Rank10)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 월드 클락이 17세기이거나 호칭(장비)이 17세기인 경우에만 시작할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. 입수한 렉릭피스를 주점 주인에게서 합성하다 보면 예지의 서 &amp;gt; 보물의 장 &amp;gt; &quot;번영했던 도시로 가는 길&quot; 퀘스트를 받아서 진행할 수 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;2025-12-05 12 10 40.png&quot; data-origin-width=&quot;739&quot; data-origin-height=&quot;395&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bCLbpE/dJMcacIm4Tv/ACVx34y2uhqYfkBIxkrhCK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bCLbpE/dJMcacIm4Tv/ACVx34y2uhqYfkBIxkrhCK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bCLbpE/dJMcacIm4Tv/ACVx34y2uhqYfkBIxkrhCK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbCLbpE%2FdJMcacIm4Tv%2FACVx34y2uhqYfkBIxkrhCK%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;739&quot; height=&quot;395&quot; data-filename=&quot;2025-12-05 12 10 40.png&quot; data-origin-width=&quot;739&quot; data-origin-height=&quot;395&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;h3 data-ke-size=&quot;size23&quot;&gt;번영했던 도시로 가는 길&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;준비물:&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;탐색 13랭크, 고고학 15 랭크, 중국어 1 랭크&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.ssjoy.org/dho/quest/3950012&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.ssjoy.org/dho/quest/3950012&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1764904326046&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;봇 검증 중...&quot; data-og-description=&quot;안전한 접속을 위해 확인이 필요합니다 잠시만 기다려 주세요. 아래 보안 인증을 완료하면 자동으로 페이지가 갱신됩니다. 자동 제출이 되지 않는다면 직접 확인 버튼을 눌러 주세요.&quot; data-og-host=&quot;www.ssjoy.org&quot; data-og-source-url=&quot;https://www.ssjoy.org/dho/quest/3950012&quot; data-og-url=&quot;https://www.ssjoy.org/dho/quest/3950012&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://www.ssjoy.org/dho/quest/3950012&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.ssjoy.org/dho/quest/3950012&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&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;봇 검증 중...&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;안전한 접속을 위해 확인이 필요합니다 잠시만 기다려 주세요. 아래 보안 인증을 완료하면 자동으로 페이지가 갱신됩니다. 자동 제출이 되지 않는다면 직접 확인 버튼을 눌러 주세요.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.ssjoy.org&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 황하 하류에 상륙합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 황토 고원(2차 필드)에 진입합니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;2025-12-05 12 13 18.png&quot; data-origin-width=&quot;401&quot; data-origin-height=&quot;279&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/pJa1b/dJMcah3Yl5E/NDBRacWC6A3NKfIRrKhoyk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/pJa1b/dJMcah3Yl5E/NDBRacWC6A3NKfIRrKhoyk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/pJa1b/dJMcah3Yl5E/NDBRacWC6A3NKfIRrKhoyk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FpJa1b%2FdJMcah3Yl5E%2FNDBRacWC6A3NKfIRrKhoyk%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;401&quot; height=&quot;279&quot; data-filename=&quot;2025-12-05 12 13 18.png&quot; data-origin-width=&quot;401&quot; data-origin-height=&quot;279&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. 기울어진 바위를 클릭합니다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;중국어 혹은 세계언어해설서 필요&lt;br /&gt;고고학, 탐색 랭크 공유 가능&lt;br /&gt;17세기 호칭 필요&lt;/blockquote&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;2025-12-05 12 17 24.png&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;279&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/boTU9N/dJMcagcV9Lx/ZHfwkQtbc5Ew4FASehl7P0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/boTU9N/dJMcagcV9Lx/ZHfwkQtbc5Ew4FASehl7P0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/boTU9N/dJMcagcV9Lx/ZHfwkQtbc5Ew4FASehl7P0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FboTU9N%2FdJMcagcV9Lx%2FZHfwkQtbc5Ew4FASehl7P0%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;400&quot; height=&quot;279&quot; data-filename=&quot;2025-12-05 12 17 24.png&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;279&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. 퀘스트 완료 후 &quot;옛 도시의 지리지&quot; 아이템을 얻을 수 있습니다.&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;h3 data-ke-size=&quot;size23&quot;&gt;운대산&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. &quot;옛 도시의 지리지&quot; 아이템을 소지한 채로 운대산 항구에 입항합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 운대산 항구 서쪽 끝에 마부가 있는데, 이 마부와 대화를 하면 옛 교역 도시와 연결된 길을 찾을 수 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;2025-12-05 12 20 52.png&quot; data-origin-width=&quot;856&quot; data-origin-height=&quot;256&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bBbUyv/dJMcadNZcN7/37yl858MPFp5RGQ9rqpn8k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bBbUyv/dJMcadNZcN7/37yl858MPFp5RGQ9rqpn8k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bBbUyv/dJMcadNZcN7/37yl858MPFp5RGQ9rqpn8k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbBbUyv%2FdJMcadNZcN7%2F37yl858MPFp5RGQ9rqpn8k%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;856&quot; height=&quot;256&quot; data-filename=&quot;2025-12-05 12 20 52.png&quot; data-origin-width=&quot;856&quot; data-origin-height=&quot;256&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;h3 data-ke-size=&quot;size23&quot;&gt;서안&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 서안에 가면 아레타와 만날 수 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;2025-12-05 12 27 03.png&quot; data-origin-width=&quot;649&quot; data-origin-height=&quot;258&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/YOIx4/dJMcagjGZxP/dzNYHioSlkOgKICn5PXXpK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/YOIx4/dJMcagjGZxP/dzNYHioSlkOgKICn5PXXpK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/YOIx4/dJMcagjGZxP/dzNYHioSlkOgKICn5PXXpK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FYOIx4%2FdJMcagjGZxP%2FdzNYHioSlkOgKICn5PXXpK%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;649&quot; height=&quot;258&quot; data-filename=&quot;2025-12-05 12 27 03.png&quot; data-origin-width=&quot;649&quot; data-origin-height=&quot;258&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 이벤트를 진행하다 보면 1억 두캇이 필요합니다. 1억 두캇을 준비해서 이벤트를 진행합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. 캐러밴 중개인은 서안 광장에 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. 캐러밴 중개인을 통해 캐러밴의 강화방침과 대장을 선택하고 중개비를 지불하면 캐러밴을 편성할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;5. 강화방침을 변경할 경우에는 고용한 대장을 해고해야 하며 대장을 해고하면 새로운 대장을 고용할 때까지 캐러밴은 성장하지 않습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;6. 캐러밴 정보는 배/함대 메뉴에서 확인할 수 있습니다. 캐러밴과의 친밀도가 올라가면 캐러밴의 능력과 낙타에 대해 보다 자세히 알 수 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;2025-12-05 12 41 58.png&quot; data-origin-width=&quot;502&quot; data-origin-height=&quot;284&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/DS2ED/dJMcagRwGXV/tbHg1EYz9OEkRhf2VouKj1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/DS2ED/dJMcagRwGXV/tbHg1EYz9OEkRhf2VouKj1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/DS2ED/dJMcagRwGXV/tbHg1EYz9OEkRhf2VouKj1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FDS2ED%2FdJMcagRwGXV%2FtbHg1EYz9OEkRhf2VouKj1%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;502&quot; height=&quot;284&quot; data-filename=&quot;2025-12-05 12 41 58.png&quot; data-origin-width=&quot;502&quot; data-origin-height=&quot;284&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;h3 data-ke-size=&quot;size23&quot;&gt;캐러밴 정보&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 캐러밴의 종합 능력&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;지구력: 대열에서 낙오하는 낙타의 수가 감소합니다.&lt;br /&gt;각력: 육로 이동 후, 다시 이동할 수 있게 되는 회복시간이 감소합니다.&lt;br /&gt;요령: 운반할 수 있는 교역품의 종류가 증가합니다.&lt;br /&gt;저력: 캐러밴의 각 능력이 빨리 성장합니다.&lt;br /&gt;친애: 낙타를 마련할 때 평소보다 많은 낙타를 입수할 수&amp;nbsp; 있습니다.&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;2. 낙타의 등급&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;캐러밴 편성후 일정한 항해일 수(120일)가 경화할 때마다 낙타를 입수하는 경우가 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;캐러밴의 랭크에 맞는 상한 수까지 낙타를 소지할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;낙타가 늘어남에 따라 캐러밴의 종합적인 능력도 올라가며 종합 능력에 따라 입수한 낙타들은 1~6단계의 등급을 가집니다.&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;3. 캐러밴과의 친밀도&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;항해일 수 10일이 넘으면 친밀도가 올라갑니다. 항해일 수가 10일이 넘지 않은 상태에서 입항하면 친밀도 상승에 계산되지 않습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다만, 육로 이동 시 낙타를 잃게 되면 친밀도는 내려갑니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;친밀도가 일정 이상(20 이상)이 되면 캐러밴의 종합능력 확인이 가능해집니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;2025-12-05 12 55 23.png&quot; data-origin-width=&quot;588&quot; data-origin-height=&quot;291&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/WTaZN/dJMcah3YmIC/4BTzKsF4yYfDk9btmSDQek/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/WTaZN/dJMcah3YmIC/4BTzKsF4yYfDk9btmSDQek/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/WTaZN/dJMcah3YmIC/4BTzKsF4yYfDk9btmSDQek/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FWTaZN%2FdJMcah3YmIC%2F4BTzKsF4yYfDk9btmSDQek%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;588&quot; height=&quot;291&quot; data-filename=&quot;2025-12-05 12 55 23.png&quot; data-origin-width=&quot;588&quot; data-origin-height=&quot;291&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;4. 캐러밴의 상세 능력&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;캐러밴 랭크: 초기 랭크는 1이며 강화를 통해 10까지 랭크업 가능합니다.&lt;/li&gt;
&lt;li&gt;친밀도: 항해일 수 10일이 될 때마다 1씩 상승합니다. 낙타를 잃으면 잃은 수에 따라 감소합니다.&lt;/li&gt;
&lt;li&gt;대장: 대장의 강화방침에 따라 캐러밴이 강화됩니다. 대장이 없으면 친밀도가 상승하지 않고 소지 낙타도 증가하지 않습니다. 또한 육로 이동도 불가능합니다.&lt;/li&gt;
&lt;li&gt;종합능력: 낙타가 증가하면 높아집니다.&lt;/li&gt;
&lt;li&gt;소지 교역품: 위가 교역품 수 / 이동 가능한 교역품 상한 이고, 아래가 교역품 종류 / 이동 가능한 교역품 종류 상한 입니다. 교역품 수의 상한은 캐러밴의 랭크가 상승할수록 증가합니다. 교역품 종류의 상한은 요령 능력치가 높을수록 증가합니다.&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;5. 캐러밴의 강화&lt;/p&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;하루에 강화할 수 있는 제한: 5회&lt;/li&gt;
&lt;li&gt;각지의 은행원을 통해서 강화 가능&lt;/li&gt;
&lt;li&gt;랭크는 해산하지 않는 한 내려 가지 않음.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;2025-12-05 13 06 35.png&quot; data-origin-width=&quot;585&quot; data-origin-height=&quot;348&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cdLtyy/dJMcaiBLwKE/yd59PEwpN2wZKnPZQfdoE1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cdLtyy/dJMcaiBLwKE/yd59PEwpN2wZKnPZQfdoE1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cdLtyy/dJMcaiBLwKE/yd59PEwpN2wZKnPZQfdoE1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcdLtyy%2FdJMcaiBLwKE%2Fyd59PEwpN2wZKnPZQfdoE1%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;585&quot; height=&quot;348&quot; data-filename=&quot;2025-12-05 13 06 35.png&quot; data-origin-width=&quot;585&quot; data-origin-height=&quot;348&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;6. 육로 이동&lt;/p&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;육로 이동은 캐러밴 중개인을 통해 할 수 있습니다.&amp;nbsp;&lt;/li&gt;
&lt;li&gt;일정량의 두캇(약12만)과 회항 허가증이 필요합니다.&lt;/li&gt;
&lt;li&gt;한 번 이동한 후 일정 시간이 지나아 다시 육로 이동이 가능합니다.(각력)&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;&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;&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;&amp;nbsp;&lt;/p&gt;</description>
      <category>GAME/대항해시대</category>
      <category>Caravan</category>
      <category>낙타</category>
      <category>대항해시대</category>
      <category>동서교역편</category>
      <category>서안</category>
      <category>온라인</category>
      <category>캐러밴</category>
      <author>ALEPH.GEM</author>
      <guid isPermaLink="true">https://aacii.tistory.com/459</guid>
      <comments>https://aacii.tistory.com/459#entry459comment</comments>
      <pubDate>Fri, 5 Dec 2025 13:13:13 +0900</pubDate>
    </item>
    <item>
      <title>윈도우11 python 3.x 개발 환경 설정</title>
      <link>https://aacii.tistory.com/458</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;윈도우11 에서 파이썬 애플리케이션을 개발하기 위한 설정입니다.&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;1. 파이썬 다운로드 및 설치&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.python.org/downloads/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.python.org/downloads/&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1764498095154&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;Download Python&quot; data-og-description=&quot;The official home of the Python Programming Language&quot; data-og-host=&quot;www.python.org&quot; data-og-source-url=&quot;https://www.python.org/downloads/&quot; data-og-url=&quot;https://www.python.org/downloads/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/yc3Wv/hyZOOYRzVs/YJQJ6zXQI40EzNhSJ9MlgK/img.png?width=200&amp;amp;height=200&amp;amp;face=0_0_200_200&quot;&gt;&lt;a href=&quot;https://www.python.org/downloads/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.python.org/downloads/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/yc3Wv/hyZOOYRzVs/YJQJ6zXQI40EzNhSJ9MlgK/img.png?width=200&amp;amp;height=200&amp;amp;face=0_0_200_200');&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;Download Python&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;The official home of the Python Programming Language&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.python.org&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 윈도우용 installer를 다운로드하고 설치하면 됩니다.&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;span style=&quot;color: #f89009;&quot;&gt;&lt;b&gt;Add python.exe to PATH를&lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; 체크해야 합니다. 그래야 cmd에서 파이썬을 자동 실행 할 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;이후 Install Now를 클릭해서 설치를 완료합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;설치 완료 후 cmd를 열고 아래 명령어로 파이썬 버전을 확인했을 때, 버전이 출력되면 정상 설치 된 것입니다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1764498285515&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;python --version&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;h3 data-ke-size=&quot;size23&quot;&gt;2. VS Code 설치 및 설정&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://code.visualstudio.com/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://code.visualstudio.com/&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1764499272169&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;Visual Studio Code - The open source AI code editor&quot; data-og-description=&quot;Visual Studio Code redefines AI-powered coding with GitHub Copilot for building and debugging modern web and cloud applications. Visual Studio Code is free and available on your favorite platform - Linux, macOS, and Windows.&quot; data-og-host=&quot;code.visualstudio.com&quot; data-og-source-url=&quot;https://code.visualstudio.com/&quot; data-og-url=&quot;https://code.visualstudio.com/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/PHt1d/hyZOvmatvt/Rsy8s4KFLDUoM7nT2Mt9b1/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/ctkGsu/hyZOUSa4hh/Ho8EgbiLsgIl7ghdWUM4fK/img.png?width=256&amp;amp;height=256&amp;amp;face=0_0_256_256&quot;&gt;&lt;a href=&quot;https://code.visualstudio.com/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://code.visualstudio.com/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/PHt1d/hyZOvmatvt/Rsy8s4KFLDUoM7nT2Mt9b1/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/ctkGsu/hyZOUSa4hh/Ho8EgbiLsgIl7ghdWUM4fK/img.png?width=256&amp;amp;height=256&amp;amp;face=0_0_256_256');&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;Visual Studio Code - The open source AI code editor&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Visual Studio Code redefines AI-powered coding with GitHub Copilot for building and debugging modern web and cloud applications. Visual Studio Code is free and available on your favorite platform - Linux, macOS, and Windows.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;code.visualstudio.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Download for Windows를 클릭해서 설치합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기본 설정 대로 설치 완료 후 VSCode를 실행합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;2-1. 파이썬 확장팩 설치&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. VS Code 왼쪽 메뉴바에서 Extentions를 클릭합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 검색 창에 Python을 입력합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. Microsoft가 만든 Python 확장팩의 install 버튼을 눌러 설치합니다.&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;h3 data-ke-size=&quot;size23&quot;&gt;3. 테스트 프로젝트 만들기&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 윈도우 탐색기에 원하는 위치에 파이썬 프로젝트용 폴더를 생성합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. VS Code를 실행합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. 상단 메뉴에서 File &amp;gt; Open Folder를 선택하고 방금 생성한 폴더를 선택합니다.&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;h3 data-ke-size=&quot;size23&quot;&gt;4. 가상 환경 만들기&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. VS Code의 상단 메뉴에서 Terminal &amp;gt; New Terminal를 클릭합니다. 그러면 아래 부분에 터미널 명령을 입력할 수 있게 창이 열립니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 터미널에 아래 명령어를 입력해서 가상 환경을 생성합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1764499641208&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;python -m venv venv&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;3. PowerShell 실행 정책 변경해서 파이썬 스크립트를 실행할 수 있는 권한을 부여해 줍니다.&lt;/p&gt;
&lt;pre id=&quot;code_1764499694637&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;Set-ExecutionPolicy RemoteSigned -Scope CurrentUser&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;4. 터미널에 아래 명령을 입력해서 가상 환경 활성화를 합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1764499771676&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;.\venv\Scripts\activate&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;4-1. GUI 애플리케이션 개발용 라이브러리 설치&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;터미널에서 venv가 떠있는 상태에서 아래 명령어를 입력합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1764500955528&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;pip install pynput pyinstaller tk&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;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;5. 테스트 파이썬 파일 생성 및 실행&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. VS Code의 File &amp;gt; New File 후 test.py을 입력합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 소스 편집 화면에서 아래 내용을 입력하고 저장합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1764499916167&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;print(&quot;Hello World&quot;)&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;3. 오른쪽 상단 Run 버튼을 누르거나 터미널에서 아래 명령어를 입력합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1764499971843&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;python test.py&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;이제 터미널 화면에 Hello World가 출력되면 정상입니다.&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;h3 data-ke-size=&quot;size23&quot;&gt;6. GUI용 애플리케이션 빌드&lt;/h3&gt;
&lt;pre id=&quot;code_1764501131509&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;pyinstaller --onefile --noconsole --name=&quot;MyTestGUI&quot; test_gui.py&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;--onefile 옵션은 exe 파일 1개로 패키징해서 빌드 하라는 의미입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;--noconsole 옵션은 GUI 애플리케이션을 실행할 때 콘솔창(터미널)을 띄우지 말라는 의미입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;--name 옵션은 빌드후 실행할 exe 파일의 이름을 지정해줍니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;마지막 test_gui.py는 실제 코딩한 GUI용 애플리케이션 소스 코드 파일을 의미합니다.&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>DEV&amp;amp;OPS/Python</category>
      <category>Python</category>
      <category>개발 환경</category>
      <category>설정</category>
      <category>윈도우</category>
      <category>파이썬</category>
      <author>ALEPH.GEM</author>
      <guid isPermaLink="true">https://aacii.tistory.com/458</guid>
      <comments>https://aacii.tistory.com/458#entry458comment</comments>
      <pubDate>Sun, 30 Nov 2025 19:54:22 +0900</pubDate>
    </item>
    <item>
      <title>spring mvc / jsp  페이징 처리</title>
      <link>https://aacii.tistory.com/335</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;여기서는 limit 기능이 존재하는 DBMS를 대상으로 페이징 처리를 다룹니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Spring MVC 패턴으로 lombok과 mybatis를 이용한다고 가정합니다.&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;LIMIT&lt;/h3&gt;
&lt;pre id=&quot;code_1762417803338&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT * FROM 테이블이름 ORDER BY tno DESC LIMIT 0, 10; -- 0개 건너 뛰고 10개 표시: 즉 1 page 보기
SELECT * FROM 테이블이름 ORDER BY tno DESC LIMIT 10, 10; -- 10개 건너 뛰고 10개 표시:즉 2 page 보기
SELECT * FROM 테이블이름 ORDER BY tno DESC LIMIT 20, 10; -- 20개 건너 뛰고 10개 표시:즉 3 page 보기&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;limit 건너뛰어야할게시물수, 가져와야할게시물수.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 해당 페이지를 가져오도록 되어있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;건너뛰어야할 게시물 수에는 수식을 넣을 수 없고 숫자만 넣어야 해서 프로그래밍 언어에서 숫자를 잘 조작해서 SQL을 실행할 때 숫자로 넣어줘야 합니다.&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;h3 data-ke-size=&quot;size23&quot;&gt;PageRequestDTO&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;페이징 처리용 DTO 객체를 만들어 둡니다.&lt;/p&gt;
&lt;pre id=&quot;code_1762419347242&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

@Builder
@Data
@AllArgsConstructor
@NoArgsConstructor
public class PageRequestDTO {
    @Builder.Default
    private int page = 1;   //페이지 번호

    @Builder.Default
    private int size = 10;  //한 페이당 보여주는 게시물 개수
    
    private String link;

	//건너뛰는 게시물 수
    public int getSkip(){
        return (page - 1) * 10;
    }
    
    public String getLink(){
        if(link == null){
            StringBuffer sb = new StringBuffer();
            sb.append(&quot;page=&quot;).append(this.page);
            sb.append(&quot;&amp;amp;size=&quot;).append(this.size);
            link = sb.toString();
        }
        return link;
    }
}&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;h3 data-ke-size=&quot;size23&quot;&gt;Mapper interface&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Mybatis와 연결할 매퍼 인터페이스를 만듭니다.&lt;/p&gt;
&lt;pre id=&quot;code_1762419661071&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public interface SampleMapper {
    //SQL들은 .xml 파일에 정의하고 mapper 인터페이스를 xml 파일의 네임스페이스로 연결 필요.
    List&amp;lt;sampleVO&amp;gt; selectList(PageRequestDTO pageRequestDTO);	//DB에서 가져온 데이터는 sampleVO에 담는다고 가정
    int getCount(PageRequestDTO pageRequestDTO); //게시물 총 개수
}&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;h3 data-ke-size=&quot;size23&quot;&gt;PageMapper.xml&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사용할 SQL문들을 xml 파일에 등록합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1762419789977&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;    &amp;lt;select id=&quot;selectList&quot; resultType=&quot;net.aacii.spring.domain.TodoVO&quot;&amp;gt;
        SELECT * FROM 테이블이름 ORDER BY tno DESC LIMIT #{skip}, #{size}
    &amp;lt;/select&amp;gt;
    &amp;lt;select id=&quot;getCount&quot; resultType=&quot;int&quot;&amp;gt;
        SELECT count(tno) FROM 테이블이름
    &amp;lt;/select&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;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;PageResponseDTO&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;sampleDTO 의 목록, 전체 데이터의 수, 페이지 처리를 위한 데이터들(시작 페이지 번호, 끝 페이지 번호)로 구성된 DTO를 만듭니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;현재 페이지 번호(page)와 페이지당 데이터의 수(size)를 이용해서 화면상의 페이지 번호를 구해야 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 PageResponseDTO는 생성자를 통해 필요한 page나 size 등을 전달 받아야 합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1762422750210&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;@Getter
@ToString
public class PageResponseDTO&amp;lt;E&amp;gt; {
    private int page;
    private int size;
    private int total;
    private int start; //시작 페이지 번호
    private int end; //끝 페이지 번호
    private boolean prev; //이전 페이지의 존재 여부
    private boolean next; //다음 페이지의 존재 여부
    private List&amp;lt;E&amp;gt; dtoList; //데이터 리스트

    //생성자
    @Builder(builderMethodName = &quot;withAll&quot;)
    public PageResponseDTO(PageRequestDTO pageRequestDTO, int total, List&amp;lt;E&amp;gt; dtoList){
        this.page = pageRequestDTO.getPage();
        this.size = pageRequestDTO.getSize();
        this.total = total;
        this.dtoList = dtoList;
        this.end = (int)(Math.ceil(this.page / 10.0)) * 10;
        this.start = this.end - 9;
        int last = (int)(Math.ceil((total / (double)size)));
        this.end = Math.min(end, last);
        this.prev = this.page &amp;gt; 1;
        this.next = total &amp;gt; this.end * this.size;
    }
}&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;마지막 페이지(end)를 먼저 구해야 시작 페이지(start)를 구하기 쉬워집니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;마지막 페이지 계산&lt;/p&gt;
&lt;pre id=&quot;code_1762423018227&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;this.end = (int)(Math.ceil(this.page / 10.0)) * 10;&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;시작 페이지 계산&lt;/p&gt;
&lt;pre id=&quot;code_1762423052268&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;this.start = this.end -9;&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;마지막 페이지의 경우 전체 개수(total)를 고려해야합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약 10개씩 보여주는 경우 전체 개수가 72라면 마지막 페이지는 8 이어야 하기 때문입니다.&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1762423265874&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;int last = (int)(Math.ceil((total/(doble)size)));&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;마지막 페이지(end)는 last 값 보다 작은경우 last 값이 end가 되어야 합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1762423345759&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;this.end = end &amp;gt; last ? last : end;&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;이전 페이지와 다음페이지 계산&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1페이지를 제외하고 무조건 이전 페이지는 true 이어야 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;마지막 페이지(end)와 페이지당 개수(size)를 곱한 값보다 전체 개수(total)가 많은지 검사해봐야 합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1762423558880&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;this.prev = this.start &amp;gt; 1;
this.next = total &amp;gt; this.end * this.size;&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;h3 data-ke-size=&quot;size23&quot;&gt;Service 인터페이스&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;PageRequestDTO를 매개변수로 받아서 DB에서 가져온 데이터를 SampleDTO(게시물DTO)로 되어진 리스트를 만들어서 PageResponseDTO 데이터 타입으로 리턴해주는 인터페이스를 작성합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1762429039793&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public interface SampleService {
    PageResponseDTO&amp;lt;SampleDTO&amp;gt; getList(PageRequestDTO pageRequestDTO);

}&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;Service 인터페이스 구현체&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SampleDTO와 SampleVO는 테이블 구조에 따라 달라지니 생략합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1762429239578&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;@Service
@Log4j2
@RequiredArgsConstructor
public class SampleServiceImpl implements SampleService{
    private final SampleMapper sampleMapper;       
    private final ModelMapper modelMapper;   //모델매퍼 설정은 따로 언급

    @Override
    public PageResponseDTO&amp;lt;SampleDTO&amp;gt; getList(PageRequestDTO pageRequestDTO) {
        //request로 받은 DTO를 이용해서 DB에서 가져온 VO들을 list에 담음
        List&amp;lt;SampleVO&amp;gt; voList = todoMapper.selectList(pageRequestDTO);
        //VO 리스트의 스트림을 얻어서 모델 매퍼로 DTO로 변환한 뒤 이 DTO들을 다시 리스트에 담음
        List&amp;lt;SampleDTO&amp;gt; dtoList = voList.stream()
                .map(vo-&amp;gt;modelMapper.map(vo, SampleDTO.class))
                .collect(Collectors.toList());

        //총 개시물 개수 구하기
        int total = todoMapper.getCount(pageRequestDTO);

        //페이징된 결과를 response에 맞는 데이터로 가공하기 위해서 
        //PageResponseDTO의 생성자를 통해 데이터를 설정해야하는데,
        //그 과정에서 필요한 데이터들은 위에서 구한 값로 세팅해서 빌드한뒤 리턴
        PageResponseDTO&amp;lt;TodoDTO&amp;gt; pageResponseDTO = PageResponseDTO.&amp;lt;SampleDTO&amp;gt;withAll()
                .dtoList(dtoList)
                .total(total)
                .pageRequestDTO(pageRequestDTO)
                .build();
        return pageResponseDTO;
    }&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;모델 매퍼 설정&lt;/p&gt;
&lt;pre id=&quot;code_1762429363788&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import org.modelmapper.ModelMapper;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class ModelMapperConfig {
    @Bean
    public ModelMapper getMapper() {
        ModelMapper mapper = new ModelMapper();
        mapper.getConfiguration()
                .setFieldMatchingEnabled(true)
                .setFieldAccessLevel(org.modelmapper.config.Configuration.AccessLevel.PRIVATE)
                .setMatchingStrategy(org.modelmapper.convention.MatchingStrategies.STRICT);
        return mapper;
    }
}&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;root-context.xml에도 위 모델 매퍼 설정을 bean 객체로 스캔하기 위해 패키지 경로를 등록 해줘야 합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1762429525621&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;	&amp;lt;!-- 모델 매퍼 설정 스프링 bean 스캔 경로 지정 --&amp;gt;
    &amp;lt;context:component-scan base-package=&quot;ModelMapperConfig클래스의패키지경로&quot;/&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;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;JSP 화면&lt;/h3&gt;
&lt;pre id=&quot;code_1762473604677&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;%@ page contentType=&quot;text/html;charset=UTF-8&quot; language=&quot;java&quot; %&amp;gt;
&amp;lt;%@ taglib prefix=&quot;c&quot; uri=&quot;http://java.sun.com/jsp/jstl/core&quot; %&amp;gt;
&amp;lt;!-- 생략... BootStrap 5를 사용한다고 가정--&amp;gt;

                    &amp;lt;div class=&quot;float-end&quot;&amp;gt;
                        &amp;lt;ul class=&quot;pagination flex-wrap&quot;&amp;gt;
                            &amp;lt;c:if test=&quot;${responseDTO.prev}&quot;&amp;gt;
                                &amp;lt;li class=&quot;page-item&quot;&amp;gt;
                                    &amp;lt;a class=&quot;page-link&quot; data-num=&quot;${responseDTO.start -1}&quot;&amp;gt;Prev&amp;lt;/a&amp;gt;
                                &amp;lt;/li&amp;gt;
                            &amp;lt;/c:if&amp;gt;
                            &amp;lt;c:forEach begin=&quot;${responseDTO.start}&quot; end=&quot;${responseDTO.end}&quot; var=&quot;num&quot;&amp;gt;
                                &amp;lt;li class=&quot;page-item ${responseDTO.page == num ? &quot;active&quot; : &quot;&quot;} &quot;&amp;gt;
                                    &amp;lt;a class=&quot;page-link&quot; data-num=&quot;${num}&quot;&amp;gt;${num}&amp;lt;/a&amp;gt;
                                &amp;lt;/li&amp;gt;
                            &amp;lt;/c:forEach&amp;gt;
                            &amp;lt;c:if test=&quot;${responseDTO.next}&quot;&amp;gt;
                                &amp;lt;li class=&quot;page-item&quot;&amp;gt;
                                    &amp;lt;a class=&quot;page-link&quot; data-num=&quot;${responseDTO.end + 1}&quot;&amp;gt;Next&amp;lt;/a&amp;gt;
                                &amp;lt;/li&amp;gt;
                            &amp;lt;/c:if&amp;gt;
                        &amp;lt;/ul&amp;gt;
                        &amp;lt;script&amp;gt;
                            document.querySelector(&quot;.pagination&quot;).addEventListener(&quot;click&quot;, function(e){
                                e.preventDefault();
                                e.stopPropagation();
                                const target = e.target
                                if(target.tagName !== 'A'){
                                    return;
                                }
                                const num = target.getAttribute(&quot;data-num&quot;)
                                self.location = `/todo/list?page=\${num}` //backtic(`): 작은 따옴표 아님 주의
                            }, false);
                        &amp;lt;/script&amp;gt;
                    &amp;lt;/div&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;&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;&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;&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>DEV&amp;amp;OPS/Java</category>
      <category>Java</category>
      <category>jsp</category>
      <category>MVC</category>
      <category>PAGING</category>
      <category>SERVLET</category>
      <category>spring</category>
      <category>공식</category>
      <category>페이지</category>
      <category>페이징</category>
      <author>ALEPH.GEM</author>
      <guid isPermaLink="true">https://aacii.tistory.com/335</guid>
      <comments>https://aacii.tistory.com/335#entry335comment</comments>
      <pubDate>Fri, 7 Nov 2025 09:19:10 +0900</pubDate>
    </item>
    <item>
      <title>은하영웅전설4 EX(도스판) 에디터 코드 표</title>
      <link>https://aacii.tistory.com/457</link>
      <description>&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot; data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;인물번호&amp;quot;}&quot;&gt;&lt;b&gt;인물번호&lt;/b&gt;&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;인물이름&amp;quot;}&quot;&gt;&lt;b&gt;인물이름&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;0&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;아이제나흐     &amp;quot;}&quot;&gt;아이제나흐&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;1&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;아이헨돌프     &amp;quot;}&quot;&gt;아이헨돌프&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;2&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;암츠돌프       &amp;quot;}&quot;&gt;암츠돌프&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;3&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;알트링겐       &amp;quot;}&quot;&gt;알트링겐&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;4&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;안스바흐&amp;quot;}&quot;&gt;안스바흐&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;5&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;버겐자일        &amp;quot;}&quot;&gt;버겐자일&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;6&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;베라              &amp;quot;}&quot;&gt;베라&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;7&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;에렌베르크     &amp;quot;}&quot;&gt;에렌베르크&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;8&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;에르라흐       &amp;quot;}&quot;&gt;에르라흐&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;9&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;오이겐&amp;quot;}&quot;&gt;오이겐&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;10&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;오벨슈타인     &amp;quot;}&quot;&gt;오벨슈타인&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;11&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;오프레서       &amp;quot;}&quot;&gt;오프레서&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;12&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;올라우           &amp;quot;}&quot;&gt;올라우&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;13&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;칼나프          &amp;quot;}&quot;&gt;칼나프&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;14&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;키슬링&amp;quot;}&quot;&gt;키슬링&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;15&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;키르히아이스   &amp;quot;}&quot;&gt;키르히아이스&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;16&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;크냅슈타인  &amp;quot;}&quot;&gt;크냅슈타인&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;17&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;구텐존           &amp;quot;}&quot;&gt;구텐존&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;18&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;크라젠          &amp;quot;}&quot;&gt;크라젠&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;19&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;크라프&amp;quot;}&quot;&gt;크라프&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;20&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;그리스           &amp;quot;}&quot;&gt;그리스&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;21&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;크리히           &amp;quot;}&quot;&gt;크리히&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;22&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;그뤼네만       &amp;quot;}&quot;&gt;그뤼네만&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;23&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;그릴팔처       &amp;quot;}&quot;&gt;그릴팔처&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;24&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;크루젠슈테른&amp;quot;}&quot;&gt;크루젠슈테른&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;25&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;그래저           &amp;quot;}&quot;&gt;그래저&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;26&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;그뢰브너        &amp;quot;}&quot;&gt;그뢰브너&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;27&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;그로테볼       &amp;quot;}&quot;&gt;그로테볼&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;28&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;케슬러         &amp;quot;}&quot;&gt;케슬러&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;29&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;켐프&amp;quot;}&quot;&gt;켐프&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;30&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;자우켄           &amp;quot;}&quot;&gt;자우켄&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;31&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;잔데르즈        &amp;quot;}&quot;&gt;잔데르즈&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;32&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;샤우덴          &amp;quot;}&quot;&gt;샤우덴&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;33&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;샤프트          &amp;quot;}&quot;&gt;샤프트&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;34&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;슈타인호프&amp;quot;}&quot;&gt;슈타인호프&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;35&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;슈타인메츠 &amp;quot;}&quot;&gt;슈타인메츠&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;36&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;슈타덴           &amp;quot;}&quot;&gt;슈타덴&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;37&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;슈토크하우젠   &amp;quot;}&quot;&gt;슈토크하우젠&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;38&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;슈트라이트     &amp;quot;}&quot;&gt;슈트라이트&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;39&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;슈나이더&amp;quot;}&quot;&gt;슈나이더&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;40&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;슈마허 &amp;quot;}&quot;&gt;슈마허&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;41&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;슈무데          &amp;quot;}&quot;&gt;슈무데&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;42&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;쉬러              &amp;quot;}&quot;&gt;쉬러&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;43&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;진쳐             &amp;quot;}&quot;&gt;진쳐&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;44&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;제크트&amp;quot;}&quot;&gt;제크트&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;45&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;세르벨           &amp;quot;}&quot;&gt;세르벨&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;46&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;존넨페르스    &amp;quot;}&quot;&gt;존넨페르스&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;47&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;좀바르트       &amp;quot;}&quot;&gt;좀바르트&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;48&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;딕켈             &amp;quot;}&quot;&gt;딕켈&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;49&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;디터스돌프&amp;quot;}&quot;&gt;디터스돌프&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;50&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;디르센           &amp;quot;}&quot;&gt;디르센&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;51&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;투르나이젠     &amp;quot;}&quot;&gt;투르나이젠&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;52&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;드레벤츠       &amp;quot;}&quot;&gt;드레벤츠&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;53&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;드로이젠       &amp;quot;}&quot;&gt;드로이젠&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;54&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;나이세바흐&amp;quot;}&quot;&gt;나이세바흐&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;55&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;노르드하임     &amp;quot;}&quot;&gt;노르드하임&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;56&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;바이엘라인     &amp;quot;}&quot;&gt;바이엘라인&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;57&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;하우흐         &amp;quot;}&quot;&gt;하우흐&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;58&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;하우프트만     &amp;quot;}&quot;&gt;하우프트만&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;59&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;파트리켄&amp;quot;}&quot;&gt;파트리켄&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;60&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;바르트하우저  &amp;quot;}&quot;&gt;바르트하우저&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;61&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;하르바슈타트   &amp;quot;}&quot;&gt;하르바슈타트&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;62&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;비텐펠트       &amp;quot;}&quot;&gt;비텐펠트&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;63&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;뷔로           &amp;quot;}&quot;&gt;뷔로&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;64&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;힐데스하임&amp;quot;}&quot;&gt;힐데스하임&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;65&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;파렌하이트     &amp;quot;}&quot;&gt;파렌하이트&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;66&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;페르너            &amp;quot;}&quot;&gt;페르너&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;67&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;포겔            &amp;quot;}&quot;&gt;포겔&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;68&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;북스테휘트     &amp;quot;}&quot;&gt;북스테휘트&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;69&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;푸세네거&amp;quot;}&quot;&gt;푸세네거&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;70&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;브라우히츠     &amp;quot;}&quot;&gt;브라우히츠&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;71&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;브라운슈바이크 &amp;quot;}&quot;&gt;브라운슈바이크&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;72&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;브르다흐       &amp;quot;}&quot;&gt;브르다흐&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;73&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;프레겔         &amp;quot;}&quot;&gt;프레겔&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;74&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;브렌타노&amp;quot;}&quot;&gt;브렌타노&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;75&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;베르겐그륀     &amp;quot;}&quot;&gt;베르겐그륀&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;76&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;호프마이스터   &amp;quot;}&quot;&gt;호프마이스터&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;77&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;홀츠바우어     &amp;quot;}&quot;&gt;홀츠바우어&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;78&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;마이포흐       &amp;quot;}&quot;&gt;마이포흐&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;79&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;마린돌프&amp;quot;}&quot;&gt;마린돌프&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;80&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;미터마이어     &amp;quot;}&quot;&gt;미터마이어&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;81&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;라인하르트      &amp;quot;}&quot;&gt;라인하르트&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;82&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;뮤켄베르가     &amp;quot;}&quot;&gt;뮤켄베르가&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;83&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;뮐러           &amp;quot;}&quot;&gt;뮐러&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;84&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;메크링거&amp;quot;}&quot;&gt;메크링거&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;85&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;메르카츠        &amp;quot;}&quot;&gt;메르카츠&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;86&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;모르트             &amp;quot;}&quot;&gt;모르트&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;87&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;라이블           &amp;quot;}&quot;&gt;라이블&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;88&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;란즈베르크     &amp;quot;}&quot;&gt;란즈베르크&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;89&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;리텐하임&amp;quot;}&quot;&gt;리텐하임&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;90&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;리히텐라데     &amp;quot;}&quot;&gt;리히텐라데&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;91&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;뤼케               &amp;quot;}&quot;&gt;뤼케&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;92&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;루츠              &amp;quot;}&quot;&gt;루츠&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;93&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;루비치           &amp;quot;}&quot;&gt;루비치&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;94&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;레켄돌프&amp;quot;}&quot;&gt;레켄돌프&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;95&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;레폴트           &amp;quot;}&quot;&gt;레폴트&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;96&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;레믈러            &amp;quot;}&quot;&gt;레믈러&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;97&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;렌넨칸프       &amp;quot;}&quot;&gt;렌넨칸프&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;98&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;로이엔탈         &amp;quot;}&quot;&gt;로이엔탈&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;99&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;봐렌&amp;quot;}&quot;&gt;봐렌&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;100&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;아텐보로       &amp;quot;}&quot;&gt;아텐보로&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;101&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;애플턴            &amp;quot;}&quot;&gt;애플턴&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;102&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;아랄콘         &amp;quot;}&quot;&gt;아랄콘&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;103&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;알.살렘           &amp;quot;}&quot;&gt;알.살렘&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;104&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;발리먼트&amp;quot;}&quot;&gt;발리먼트&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;105&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;비올라          &amp;quot;}&quot;&gt;비올라&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;106&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;우란프            &amp;quot;}&quot;&gt;우란프&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;107&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;에벤즈         &amp;quot;}&quot;&gt;에벤즈&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;108&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;에다             &amp;quot;}&quot;&gt;에다&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;109&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;에만슨&amp;quot;}&quot;&gt;에만슨&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;110&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;칼센              &amp;quot;}&quot;&gt;칼센&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;111&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;카젤느           &amp;quot;}&quot;&gt;카젤느&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;112&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;구엔             &amp;quot;}&quot;&gt;구엔&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;113&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;쿠브리슬리       &amp;quot;}&quot;&gt;쿠브리슬리&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;114&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;D.그린힐&amp;quot;}&quot;&gt;D.그린힐&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;115&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;크리스티안     &amp;quot;}&quot;&gt;크리스티안&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;116&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;코크랜           &amp;quot;}&quot;&gt;코크랜&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;117&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;코날리         &amp;quot;}&quot;&gt;코날리&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;118&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;코네프         &amp;quot;}&quot;&gt;코네프&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;119&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;이반.코네프&amp;quot;}&quot;&gt;이반.코네프&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;120&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;콜드웰           &amp;quot;}&quot;&gt;콜드웰&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;121&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;자니얼           &amp;quot;}&quot;&gt;자니얼&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;122&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;쉔코프         &amp;quot;}&quot;&gt;쉔코프&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;123&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;시틀레           &amp;quot;}&quot;&gt;시틀레&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;124&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;샤르티안&amp;quot;}&quot;&gt;샤르티안&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;125&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;술즈콰리터     &amp;quot;}&quot;&gt;술즈콰리터&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;126&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;스토크스          &amp;quot;}&quot;&gt;스토크스&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;127&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;첸             &amp;quot;}&quot;&gt;첸&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;128&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;춘               &amp;quot;}&quot;&gt;춘&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;129&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;도손&amp;quot;}&quot;&gt;도손&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;130&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;토다              &amp;quot;}&quot;&gt;토다&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;131&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;닐슨              &amp;quot;}&quot;&gt;닐슨&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;132&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;파에타         &amp;quot;}&quot;&gt;파에타&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;133&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;바그다쉬         &amp;quot;}&quot;&gt;바그다쉬&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;134&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;파스톨&amp;quot;}&quot;&gt;파스톨&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;135&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;파트리체프     &amp;quot;}&quot;&gt;파트리체프&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;136&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;뷰코크           &amp;quot;}&quot;&gt;뷰코크&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;137&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;비로라이넨     &amp;quot;}&quot;&gt;비로라이넨&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;138&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;파이펠         &amp;quot;}&quot;&gt;파이펠&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;139&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;피셔&amp;quot;}&quot;&gt;피셔&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;140&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;필즈              &amp;quot;}&quot;&gt;필즈&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;141&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;포크              &amp;quot;}&quot;&gt;포크&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;142&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;브러드죠       &amp;quot;}&quot;&gt;브러드죠&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;143&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;브룸하르트     &amp;quot;}&quot;&gt;브룸하르트&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;144&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;F.그린힐&amp;quot;}&quot;&gt;F.그린힐&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;145&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;브론즈           &amp;quot;}&quot;&gt;브론즈&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;146&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;베이               &amp;quot;}&quot;&gt;베이&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;147&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;호우드         &amp;quot;}&quot;&gt;호우드&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;148&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;포플런         &amp;quot;}&quot;&gt;포플런&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;149&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;보로딘&amp;quot;}&quot;&gt;보로딘&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;150&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;마쉰고           &amp;quot;}&quot;&gt;마쉰고&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;151&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;마리네티        &amp;quot;}&quot;&gt;마리네티&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;152&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;마리노         &amp;quot;}&quot;&gt;마리노&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;153&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;무어            &amp;quot;}&quot;&gt;무어&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;154&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;무라이&amp;quot;}&quot;&gt;무라이&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;155&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;모톤               &amp;quot;}&quot;&gt;모톤&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;156&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;얀.웬리           &amp;quot;}&quot;&gt;얀.웬리&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;157&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;민츠            &amp;quot;}&quot;&gt;민츠&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;158&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;라오           &amp;quot;}&quot;&gt;라오&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;159&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;로벨.러프&amp;quot;}&quot;&gt;로벨.러프&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;160&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;린츠&amp;quot;}&quot;&gt;린츠&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;161&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;루그랑쥐       &amp;quot;}&quot;&gt;루그랑쥐&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;162&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;루페브르        &amp;quot;}&quot;&gt;루페브르&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;163&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;로크웰         &amp;quot;}&quot;&gt;로크웰&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;164&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;로보스&amp;quot;}&quot;&gt;로보스&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;165&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;트류니히트     &amp;quot;}&quot;&gt;트류니히트&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;166&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;윗티           &amp;quot;}&quot;&gt;윗티&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;167&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;슈트라우스       &amp;quot;}&quot;&gt;슈트라우스&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;168&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;자므            &amp;quot;}&quot;&gt;자므&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;169&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;캄브버&amp;quot;}&quot;&gt;캄브버&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;170&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;슈라이어         &amp;quot;}&quot;&gt;슈라이어&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;171&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;뷰젠휘터       &amp;quot;}&quot;&gt;뷰젠휘터&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;172&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;크라이버       &amp;quot;}&quot;&gt;크라이버&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;173&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;라첼            &amp;quot;}&quot;&gt;라첼&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;174&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;린저&amp;quot;}&quot;&gt;린저&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;175&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;바운스고르   &amp;quot;}&quot;&gt;바운스고르&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;176&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;마스커니       &amp;quot;}&quot;&gt;마스커니&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;177&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;테슈            &amp;quot;}&quot;&gt;테슈&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;178&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;자와프           &amp;quot;}&quot;&gt;자와프&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;179&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;애슈르&amp;quot;}&quot;&gt;애슈르&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;180&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;크로이첼&amp;quot;}&quot;&gt;크로이첼&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어 얀 웬리는 156 입니다.&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 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;도스박스로 실행할 때 전투 시 속도가 느리다면? &lt;span style=&quot;background-color: #ffffff;&quot;&gt;ctrl + 12 &lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;으로 &lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;만정도로 CPU 사이클을 올려주면 빨라집니다.&amp;nbsp;&lt;/span&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 alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;2025-11-06 16 49 03.png&quot; data-origin-width=&quot;1026&quot; data-origin-height=&quot;820&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/PUQoC/dJMcacuEyOA/L7sKR4NtIJKeOD2ZTOKCY1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/PUQoC/dJMcacuEyOA/L7sKR4NtIJKeOD2ZTOKCY1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/PUQoC/dJMcacuEyOA/L7sKR4NtIJKeOD2ZTOKCY1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FPUQoC%2FdJMcacuEyOA%2FL7sKR4NtIJKeOD2ZTOKCY1%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;1026&quot; height=&quot;820&quot; data-filename=&quot;2025-11-06 16 49 03.png&quot; data-origin-width=&quot;1026&quot; data-origin-height=&quot;820&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;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot; data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;혹성번호&amp;quot;}&quot;&gt;&lt;b&gt;혹성번호&lt;/b&gt;&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;혹성이름&amp;quot;}&quot;&gt;&lt;b&gt;혹성이름&lt;/b&gt;&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;존재성계&amp;quot;}&quot;&gt;&lt;b&gt;존재성계&lt;/b&gt;&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;소속&amp;quot;}&quot;&gt;&lt;b&gt;소속&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;0&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;오딘&amp;quot;}&quot;&gt;오딘&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;발하라&amp;quot;}&quot;&gt;발하라&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;제국&amp;quot;}&quot;&gt;제국&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;1&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;아스가르즈&amp;quot;}&quot;&gt;아스가르즈&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;발하라&amp;quot;}&quot;&gt;발하라&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;제국&amp;quot;}&quot;&gt;제국&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;2&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;유그드라실&amp;quot;}&quot;&gt;유그드라실&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;발하라&amp;quot;}&quot;&gt;발하라&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;제국&amp;quot;}&quot;&gt;제국&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;3&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;다룸슈타트&amp;quot;}&quot;&gt;다룸슈타트&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;아이젠후트&amp;quot;}&quot;&gt;아이젠후트&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;제국&amp;quot;}&quot;&gt;제국&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;4&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;베스트파리아&amp;quot;}&quot;&gt;베스트파리아&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;아이젠헤르츠&amp;quot;}&quot;&gt;아이젠헤르츠&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;제국&amp;quot;}&quot;&gt;제국&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;5&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;디사우&amp;quot;}&quot;&gt;디사우&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;아이젠헤르츠&amp;quot;}&quot;&gt;아이젠헤르츠&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;제국&amp;quot;}&quot;&gt;제국&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;6&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;클라잉켈트&amp;quot;}&quot;&gt;클라잉켈트&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;암리처&amp;quot;}&quot;&gt;암리처&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;제국&amp;quot;}&quot;&gt;제국&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;7&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;모르겐&amp;quot;}&quot;&gt;모르겐&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;암리처&amp;quot;}&quot;&gt;암리처&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;제국&amp;quot;}&quot;&gt;제국&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;8&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;니플헤임&amp;quot;}&quot;&gt;니플헤임&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;프레이아&amp;quot;}&quot;&gt;프레이아&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;제국&amp;quot;}&quot;&gt;제국&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;9&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;렌텐베르크&amp;quot;}&quot;&gt;렌텐베르크&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;프레이아&amp;quot;}&quot;&gt;프레이아&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;제국&amp;quot;}&quot;&gt;제국&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;10&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;바텐도라흐&amp;quot;}&quot;&gt;바텐도라흐&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;알멘트푸벨&amp;quot;}&quot;&gt;알멘트푸벨&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;제국&amp;quot;}&quot;&gt;제국&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;11&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;이젤론&amp;quot;}&quot;&gt;이젤론&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;이젤론&amp;quot;}&quot;&gt;이젤론&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;제국&amp;quot;}&quot;&gt;제국&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;12&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;브렌하임&amp;quot;}&quot;&gt;브렌하임&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;바르텐베르크&amp;quot;}&quot;&gt;바르텐베르크&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;제국&amp;quot;}&quot;&gt;제국&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;13&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;카르슈타트&amp;quot;}&quot;&gt;카르슈타트&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;바르텐베르크&amp;quot;}&quot;&gt;바르텐베르크&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;제국&amp;quot;}&quot;&gt;제국&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;14&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;레오폴트슈타트&amp;quot;}&quot;&gt;레오폴트슈타트&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;빌렌슈타인&amp;quot;}&quot;&gt;빌렌슈타인&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;제국&amp;quot;}&quot;&gt;제국&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;15&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;그라츠&amp;quot;}&quot;&gt;그라츠&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;빌렌슈타인&amp;quot;}&quot;&gt;빌렌슈타인&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;제국&amp;quot;}&quot;&gt;제국&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;16&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;자크스코프르크&amp;quot;}&quot;&gt;자크스코프르크&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;에크하르트&amp;quot;}&quot;&gt;에크하르트&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;제국&amp;quot;}&quot;&gt;제국&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;17&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;케니히그라흐&amp;quot;}&quot;&gt;케니히그라흐&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;카스트로프&amp;quot;}&quot;&gt;카스트로프&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;제국&amp;quot;}&quot;&gt;제국&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;18&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;스루즈헤임&amp;quot;}&quot;&gt;스루즈헤임&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;키포이저&amp;quot;}&quot;&gt;키포이저&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;제국&amp;quot;}&quot;&gt;제국&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;19&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;갸라호른&amp;quot;}&quot;&gt;갸라호른&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;키포이저&amp;quot;}&quot;&gt;키포이저&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;제국&amp;quot;}&quot;&gt;제국&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;20&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;가르미슈&amp;quot;}&quot;&gt;가르미슈&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;키포이저&amp;quot;}&quot;&gt;키포이저&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;제국&amp;quot;}&quot;&gt;제국&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;21&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;폰트노이&amp;quot;}&quot;&gt;폰트노이&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;샨타우&amp;quot;}&quot;&gt;샨타우&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;제국&amp;quot;}&quot;&gt;제국&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;22&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;크네스도르프&amp;quot;}&quot;&gt;크네스도르프&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;샨타우&amp;quot;}&quot;&gt;샨타우&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;제국&amp;quot;}&quot;&gt;제국&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;23&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;에스링그&amp;quot;}&quot;&gt;에스링그&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;샨타우&amp;quot;}&quot;&gt;샨타우&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;제국&amp;quot;}&quot;&gt;제국&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;24&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;슈바르츠브르크&amp;quot;}&quot;&gt;슈바르츠브르크&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;샤헨&amp;quot;}&quot;&gt;샤헨&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;제국&amp;quot;}&quot;&gt;제국&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;25&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;호포키르히&amp;quot;}&quot;&gt;호포키르히&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;트라바흐&amp;quot;}&quot;&gt;트라바흐&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;제국&amp;quot;}&quot;&gt;제국&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;26&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;비텐베르크&amp;quot;}&quot;&gt;비텐베르크&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;트라바흐&amp;quot;}&quot;&gt;트라바흐&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;제국&amp;quot;}&quot;&gt;제국&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;27&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;자르펜트&amp;quot;}&quot;&gt;자르펜트&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;하안&amp;quot;}&quot;&gt;하안&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;제국&amp;quot;}&quot;&gt;제국&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;28&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;뤼겐&amp;quot;}&quot;&gt;뤼겐&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;포르겐&amp;quot;}&quot;&gt;포르겐&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;제국&amp;quot;}&quot;&gt;제국&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;29&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;비르로스트&amp;quot;}&quot;&gt;비르로스트&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;보덴&amp;quot;}&quot;&gt;보덴&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;제국&amp;quot;}&quot;&gt;제국&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;30&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;야반하르&amp;quot;}&quot;&gt;야반하르&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;포르겐&amp;quot;}&quot;&gt;포르겐&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;제국&amp;quot;}&quot;&gt;제국&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;31&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;톤도르프&amp;quot;}&quot;&gt;톤도르프&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;브라운슈베크&amp;quot;}&quot;&gt;브라운슈베크&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;제국&amp;quot;}&quot;&gt;제국&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;32&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;베스타란트&amp;quot;}&quot;&gt;베스타란트&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;브라운슈베크&amp;quot;}&quot;&gt;브라운슈베크&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;제국&amp;quot;}&quot;&gt;제국&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;33&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;가이에스브르크&amp;quot;}&quot;&gt;가이에스브르크&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;알테너&amp;quot;}&quot;&gt;알테너&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;제국&amp;quot;}&quot;&gt;제국&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;34&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;헷세카셀&amp;quot;}&quot;&gt;헷세카셀&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;알테너&amp;quot;}&quot;&gt;알테너&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;제국&amp;quot;}&quot;&gt;제국&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;35&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;아르비스&amp;quot;}&quot;&gt;아르비스&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;보덴&amp;quot;}&quot;&gt;보덴&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;제국&amp;quot;}&quot;&gt;제국&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;36&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;반스테이드&amp;quot;}&quot;&gt;반스테이드&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;포르겐&amp;quot;}&quot;&gt;포르겐&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;제국&amp;quot;}&quot;&gt;제국&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;37&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;보르소른&amp;quot;}&quot;&gt;보르소른&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;보덴&amp;quot;}&quot;&gt;보덴&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;제국&amp;quot;}&quot;&gt;제국&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;38&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;테레젠슈타트&amp;quot;}&quot;&gt;테레젠슈타트&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;마린도르프&amp;quot;}&quot;&gt;마린도르프&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;제국&amp;quot;}&quot;&gt;제국&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;39&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;민덴&amp;quot;}&quot;&gt;민덴&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;마르바흐&amp;quot;}&quot;&gt;마르바흐&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;제국&amp;quot;}&quot;&gt;제국&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;40&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;로스바흐&amp;quot;}&quot;&gt;로스바흐&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;요툰하임&amp;quot;}&quot;&gt;요툰하임&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;제국&amp;quot;}&quot;&gt;제국&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;41&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;퀴스트린&amp;quot;}&quot;&gt;퀴스트린&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;리텐하임&amp;quot;}&quot;&gt;리텐하임&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;제국&amp;quot;}&quot;&gt;제국&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;42&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;에크뮐&amp;quot;}&quot;&gt;에크뮐&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;리텐하임&amp;quot;}&quot;&gt;리텐하임&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;제국&amp;quot;}&quot;&gt;제국&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;43&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;에르힌겐&amp;quot;}&quot;&gt;에르힌겐&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;리히텐라데&amp;quot;}&quot;&gt;리히텐라데&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;제국&amp;quot;}&quot;&gt;제국&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;44&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;페잔&amp;quot;}&quot;&gt;페잔&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;페잔&amp;quot;}&quot;&gt;페잔&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;중립&amp;quot;}&quot;&gt;중립&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;45&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;아트라하시스&amp;quot;}&quot;&gt;아트라하시스&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;아스타테&amp;quot;}&quot;&gt;아스타테&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;동맹&amp;quot;}&quot;&gt;동맹&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;46&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;아스페륀&amp;quot;}&quot;&gt;아스페륀&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;아스타테&amp;quot;}&quot;&gt;아스타테&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;동맹&amp;quot;}&quot;&gt;동맹&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;47&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;우가리트&amp;quot;}&quot;&gt;우가리트&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;아스타테&amp;quot;}&quot;&gt;아스타테&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;동맹&amp;quot;}&quot;&gt;동맹&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;48&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;탄므즈&amp;quot;}&quot;&gt;탄므즈&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;아레스하임&amp;quot;}&quot;&gt;아레스하임&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;동맹&amp;quot;}&quot;&gt;동맹&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;49&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;카토르브러&amp;quot;}&quot;&gt;카토르브러&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;밴플리트&amp;quot;}&quot;&gt;밴플리트&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;동맹&amp;quot;}&quot;&gt;동맹&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;50&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;알에리스&amp;quot;}&quot;&gt;알에리스&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;샨다르아&amp;quot;}&quot;&gt;샨다르아&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;동맹&amp;quot;}&quot;&gt;동맹&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;51&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;에레키슈갈&amp;quot;}&quot;&gt;에레키슈갈&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;슈파라&amp;quot;}&quot;&gt;슈파라&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;동맹&amp;quot;}&quot;&gt;동맹&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;52&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;카프튜랑카&amp;quot;}&quot;&gt;카프튜랑카&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;다곤&amp;quot;}&quot;&gt;다곤&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;동맹&amp;quot;}&quot;&gt;동맹&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;53&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;라므&amp;quot;}&quot;&gt;라므&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;티아매트&amp;quot;}&quot;&gt;티아매트&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;동맹&amp;quot;}&quot;&gt;동맹&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;54&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;안샤르&amp;quot;}&quot;&gt;안샤르&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;티아매트&amp;quot;}&quot;&gt;티아매트&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;동맹&amp;quot;}&quot;&gt;동맹&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;55&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;프르샤스쿠타&amp;quot;}&quot;&gt;프르샤스쿠타&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;바라투르프&amp;quot;}&quot;&gt;바라투르프&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;동맹&amp;quot;}&quot;&gt;동맹&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;56&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;케르코포르타&amp;quot;}&quot;&gt;케르코포르타&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;팔란티아&amp;quot;}&quot;&gt;팔란티아&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;동맹&amp;quot;}&quot;&gt;동맹&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;57&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;우가리트&amp;quot;}&quot;&gt;우가리트&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;파이어저드&amp;quot;}&quot;&gt;파이어저드&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;동맹&amp;quot;}&quot;&gt;동맹&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;58&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;라트포트&amp;quot;}&quot;&gt;라트포트&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;파이어저드&amp;quot;}&quot;&gt;파이어저드&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;동맹&amp;quot;}&quot;&gt;동맹&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;59&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;네페르카프타흐&amp;quot;}&quot;&gt;네페르카프타흐&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;폴세티&amp;quot;}&quot;&gt;폴세티&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;동맹&amp;quot;}&quot;&gt;동맹&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;60&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;루지아나&amp;quot;}&quot;&gt;루지아나&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;포레비트&amp;quot;}&quot;&gt;포레비트&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;동맹&amp;quot;}&quot;&gt;동맹&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;61&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;파프라비&amp;quot;}&quot;&gt;파프라비&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;말아뎃타&amp;quot;}&quot;&gt;말아뎃타&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;동맹&amp;quot;}&quot;&gt;동맹&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;62&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;라티고스트&amp;quot;}&quot;&gt;라티고스트&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;란테마리오&amp;quot;}&quot;&gt;란테마리오&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;동맹&amp;quot;}&quot;&gt;동맹&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;63&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;스벤트비트&amp;quot;}&quot;&gt;스벤트비트&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;란테마리오&amp;quot;}&quot;&gt;란테마리오&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;동맹&amp;quot;}&quot;&gt;동맹&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;64&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;야로비트&amp;quot;}&quot;&gt;야로비트&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;란테마리오&amp;quot;}&quot;&gt;란테마리오&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;동맹&amp;quot;}&quot;&gt;동맹&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;65&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;카스티리오&amp;quot;}&quot;&gt;카스티리오&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;룬비니&amp;quot;}&quot;&gt;룬비니&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;동맹&amp;quot;}&quot;&gt;동맹&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;66&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;악타이온&amp;quot;}&quot;&gt;악타이온&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;에뤼세라&amp;quot;}&quot;&gt;에뤼세라&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;동맹&amp;quot;}&quot;&gt;동맹&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;67&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;샴프르&amp;quot;}&quot;&gt;샴프르&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;엘곤&amp;quot;}&quot;&gt;엘곤&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;동맹&amp;quot;}&quot;&gt;동맹&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;68&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;메헤라브&amp;quot;}&quot;&gt;메헤라브&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;엘곤&amp;quot;}&quot;&gt;엘곤&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;동맹&amp;quot;}&quot;&gt;동맹&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;69&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;보프마나프&amp;quot;}&quot;&gt;보프마나프&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;엘곤&amp;quot;}&quot;&gt;엘곤&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;동맹&amp;quot;}&quot;&gt;동맹&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;70&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;엘파실&amp;quot;}&quot;&gt;엘파실&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;엘파실&amp;quot;}&quot;&gt;엘파실&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;동맹&amp;quot;}&quot;&gt;동맹&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;71&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;에스트레마도라&amp;quot;}&quot;&gt;에스트레마도라&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;엘파실&amp;quot;}&quot;&gt;엘파실&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;동맹&amp;quot;}&quot;&gt;동맹&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;72&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;우르바시&amp;quot;}&quot;&gt;우르바시&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;간달바&amp;quot;}&quot;&gt;간달바&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;동맹&amp;quot;}&quot;&gt;동맹&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;73&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;프르라바스&amp;quot;}&quot;&gt;프르라바스&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;간달바&amp;quot;}&quot;&gt;간달바&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;동맹&amp;quot;}&quot;&gt;동맹&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;74&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;네프티스&amp;quot;}&quot;&gt;네프티스&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;케림&amp;quot;}&quot;&gt;케림&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;동맹&amp;quot;}&quot;&gt;동맹&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;75&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;이제크온&amp;quot;}&quot;&gt;이제크온&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;케림&amp;quot;}&quot;&gt;케림&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;동맹&amp;quot;}&quot;&gt;동맹&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;76&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;지비에&amp;quot;}&quot;&gt;지비에&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;시바&amp;quot;}&quot;&gt;시바&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;동맹&amp;quot;}&quot;&gt;동맹&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;77&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;미트라&amp;quot;}&quot;&gt;미트라&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;시바&amp;quot;}&quot;&gt;시바&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;동맹&amp;quot;}&quot;&gt;동맹&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;78&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;다프테잠시드&amp;quot;}&quot;&gt;다프테잠시드&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;잠시드&amp;quot;}&quot;&gt;잠시드&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;동맹&amp;quot;}&quot;&gt;동맹&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;79&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;카퍼&amp;quot;}&quot;&gt;카퍼&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;잠시드&amp;quot;}&quot;&gt;잠시드&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;동맹&amp;quot;}&quot;&gt;동맹&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;80&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;파라스&amp;quot;}&quot;&gt;파라스&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;타시리&amp;quot;}&quot;&gt;타시리&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;동맹&amp;quot;}&quot;&gt;동맹&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;81&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;에코니아&amp;quot;}&quot;&gt;에코니아&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;타나투스&amp;quot;}&quot;&gt;타나투스&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;동맹&amp;quot;}&quot;&gt;동맹&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;82&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;마스지트&amp;quot;}&quot;&gt;마스지트&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;타나투스&amp;quot;}&quot;&gt;타나투스&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;동맹&amp;quot;}&quot;&gt;동맹&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;83&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;팔머랜드&amp;quot;}&quot;&gt;팔머랜드&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;트리플라&amp;quot;}&quot;&gt;트리플라&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;동맹&amp;quot;}&quot;&gt;동맹&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;84&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;보이오디아&amp;quot;}&quot;&gt;보이오디아&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;도리아&amp;quot;}&quot;&gt;도리아&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;동맹&amp;quot;}&quot;&gt;동맹&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;85&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;델모퓌라이&amp;quot;}&quot;&gt;델모퓌라이&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;도리아&amp;quot;}&quot;&gt;도리아&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;동맹&amp;quot;}&quot;&gt;동맹&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;86&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;몽마리유&amp;quot;}&quot;&gt;몽마리유&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;버밀리언&amp;quot;}&quot;&gt;버밀리언&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;동맹&amp;quot;}&quot;&gt;동맹&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;87&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;하이네센&amp;quot;}&quot;&gt;하이네센&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;바라트&amp;quot;}&quot;&gt;바라트&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;동맹&amp;quot;}&quot;&gt;동맹&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;88&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;테르누젠&amp;quot;}&quot;&gt;테르누젠&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;바라트&amp;quot;}&quot;&gt;바라트&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;동맹&amp;quot;}&quot;&gt;동맹&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;89&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;시뤼나갈&amp;quot;}&quot;&gt;시뤼나갈&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;바라트&amp;quot;}&quot;&gt;바라트&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;동맹&amp;quot;}&quot;&gt;동맹&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;90&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;비트리아&amp;quot;}&quot;&gt;비트리아&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;뤼카스&amp;quot;}&quot;&gt;뤼카스&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;동맹&amp;quot;}&quot;&gt;동맹&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;91&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;마그토레드&amp;quot;}&quot;&gt;마그토레드&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;라이갈&amp;quot;}&quot;&gt;라이갈&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;동맹&amp;quot;}&quot;&gt;동맹&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;92&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;카시나&amp;quot;}&quot;&gt;카시나&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;리오베르데&amp;quot;}&quot;&gt;리오베르데&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;동맹&amp;quot;}&quot;&gt;동맹&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;93&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;아로요드모리노&amp;quot;}&quot;&gt;아로요드모리노&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;리오베르데&amp;quot;}&quot;&gt;리오베르데&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;동맹&amp;quot;}&quot;&gt;동맹&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;94&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;키베론&amp;quot;}&quot;&gt;키베론&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;로포덴&amp;quot;}&quot;&gt;로포덴&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;동맹&amp;quot;}&quot;&gt;동맹&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;95&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;루드밀라&amp;quot;}&quot;&gt;루드밀라&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;로포덴&amp;quot;}&quot;&gt;로포덴&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;동맹&amp;quot;}&quot;&gt;동맹&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;96&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;드벨그&amp;quot;}&quot;&gt;드벨그&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;암리처&amp;quot;}&quot;&gt;암리처&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;제국&amp;quot;}&quot;&gt;제국&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&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;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot; data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;성계번호&amp;quot;}&quot;&gt;&lt;b&gt;성계번호&lt;/b&gt;&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;성계이름&amp;quot;}&quot;&gt;&lt;b&gt;성계이름&lt;/b&gt;&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;소속&amp;quot;}&quot;&gt;&lt;b&gt;소속&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;0&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;발하라&amp;quot;}&quot;&gt;발하라&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;제국&amp;quot;}&quot;&gt;제국&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;1&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;바라트&amp;quot;}&quot;&gt;바라트&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;동맹&amp;quot;}&quot;&gt;동맹&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;2&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;아이젠후트&amp;quot;}&quot;&gt;아이젠후트&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;제국&amp;quot;}&quot;&gt;제국&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;3&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;아이젠헤르츠&amp;quot;}&quot;&gt;아이젠헤르츠&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;제국&amp;quot;}&quot;&gt;제국&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;4&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;아스타테&amp;quot;}&quot;&gt;아스타테&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;동맹&amp;quot;}&quot;&gt;동맹&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;5&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;암리처&amp;quot;}&quot;&gt;암리처&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;제국&amp;quot;}&quot;&gt;제국&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;6&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;프레이아&amp;quot;}&quot;&gt;프레이아&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;제국&amp;quot;}&quot;&gt;제국&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;7&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;알멘트푸벨&amp;quot;}&quot;&gt;알멘트푸벨&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;제국&amp;quot;}&quot;&gt;제국&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;8&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;아레스하임&amp;quot;}&quot;&gt;아레스하임&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;제국&amp;quot;}&quot;&gt;제국&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;9&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;이젤론&amp;quot;}&quot;&gt;이젤론&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;제국&amp;quot;}&quot;&gt;제국&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;10&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;에크하르트&amp;quot;}&quot;&gt;에크하르트&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;제국&amp;quot;}&quot;&gt;제국&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;11&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;에뤼세라&amp;quot;}&quot;&gt;에뤼세라&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;동맹&amp;quot;}&quot;&gt;동맹&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;12&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;엘파실&amp;quot;}&quot;&gt;엘파실&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;동맹&amp;quot;}&quot;&gt;동맹&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;13&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;엘곤&amp;quot;}&quot;&gt;엘곤&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;동맹&amp;quot;}&quot;&gt;동맹&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;14&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;카스트로프&amp;quot;}&quot;&gt;카스트로프&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;동맹&amp;quot;}&quot;&gt;동맹&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;15&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;간달바&amp;quot;}&quot;&gt;간달바&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;동맹&amp;quot;}&quot;&gt;동맹&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;16&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;키포이저&amp;quot;}&quot;&gt;키포이저&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;제국&amp;quot;}&quot;&gt;제국&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;17&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;케림&amp;quot;}&quot;&gt;케림&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;동맹&amp;quot;}&quot;&gt;동맹&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;18&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;시바&amp;quot;}&quot;&gt;시바&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;동맹&amp;quot;}&quot;&gt;동맹&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;19&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;샤헨&amp;quot;}&quot;&gt;샤헨&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;제국&amp;quot;}&quot;&gt;제국&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;20&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;잠시드&amp;quot;}&quot;&gt;잠시드&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;동맹&amp;quot;}&quot;&gt;동맹&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;21&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;샨타우&amp;quot;}&quot;&gt;샨타우&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;제국&amp;quot;}&quot;&gt;제국&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;22&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;샨다르아&amp;quot;}&quot;&gt;샨다르아&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;동맹&amp;quot;}&quot;&gt;동맹&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;23&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;슈파라&amp;quot;}&quot;&gt;슈파라&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;동맹&amp;quot;}&quot;&gt;동맹&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;24&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;다곤&amp;quot;}&quot;&gt;다곤&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;동맹&amp;quot;}&quot;&gt;동맹&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;25&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;타시리&amp;quot;}&quot;&gt;타시리&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;동맹&amp;quot;}&quot;&gt;동맹&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;26&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;타나투스&amp;quot;}&quot;&gt;타나투스&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;동맹&amp;quot;}&quot;&gt;동맹&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;27&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;티아매트&amp;quot;}&quot;&gt;티아매트&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;동맹&amp;quot;}&quot;&gt;동맹&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;28&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;도리아&amp;quot;}&quot;&gt;도리아&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;동맹&amp;quot;}&quot;&gt;동맹&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;29&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;트라바흐&amp;quot;}&quot;&gt;트라바흐&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;제국&amp;quot;}&quot;&gt;제국&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;30&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;트리플라&amp;quot;}&quot;&gt;트리플라&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;동맹&amp;quot;}&quot;&gt;동맹&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;31&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;하안&amp;quot;}&quot;&gt;하안&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;제국&amp;quot;}&quot;&gt;제국&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;32&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;버밀리언&amp;quot;}&quot;&gt;버밀리언&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;동맹&amp;quot;}&quot;&gt;동맹&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;33&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;바라투르프&amp;quot;}&quot;&gt;바라투르프&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;제국&amp;quot;}&quot;&gt;제국&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;34&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;팔란티아&amp;quot;}&quot;&gt;팔란티아&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;동맹&amp;quot;}&quot;&gt;동맹&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;35&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;파이어저드&amp;quot;}&quot;&gt;파이어저드&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;동맹&amp;quot;}&quot;&gt;동맹&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;36&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;페잔&amp;quot;}&quot;&gt;페잔&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;중립&amp;quot;}&quot;&gt;중립&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;37&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;포르겐&amp;quot;}&quot;&gt;포르겐&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;제국&amp;quot;}&quot;&gt;제국&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;38&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;폴세티&amp;quot;}&quot;&gt;폴세티&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;동맹&amp;quot;}&quot;&gt;동맹&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;39&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;브라운슈베크&amp;quot;}&quot;&gt;브라운슈베크&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;제국&amp;quot;}&quot;&gt;제국&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;40&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;알테너&amp;quot;}&quot;&gt;알테너&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;제국&amp;quot;}&quot;&gt;제국&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;41&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;보덴&amp;quot;}&quot;&gt;보덴&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;제국&amp;quot;}&quot;&gt;제국&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;42&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;포레비트&amp;quot;}&quot;&gt;포레비트&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;동맹&amp;quot;}&quot;&gt;동맹&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;43&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;마린도르프&amp;quot;}&quot;&gt;마린도르프&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;제국&amp;quot;}&quot;&gt;제국&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;44&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;마르바흐&amp;quot;}&quot;&gt;마르바흐&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;제국&amp;quot;}&quot;&gt;제국&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;45&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;말아뎃타&amp;quot;}&quot;&gt;말아뎃타&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;동맹&amp;quot;}&quot;&gt;동맹&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;46&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;요툰하임&amp;quot;}&quot;&gt;요툰하임&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;제국&amp;quot;}&quot;&gt;제국&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;47&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;라이갈&amp;quot;}&quot;&gt;라이갈&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;동맹&amp;quot;}&quot;&gt;동맹&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;48&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;란테마리오&amp;quot;}&quot;&gt;란테마리오&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;동맹&amp;quot;}&quot;&gt;동맹&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;49&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;리오베르데&amp;quot;}&quot;&gt;리오베르데&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;동맹&amp;quot;}&quot;&gt;동맹&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;50&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;리텐하임&amp;quot;}&quot;&gt;리텐하임&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;제국&amp;quot;}&quot;&gt;제국&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;51&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;리히텐라데&amp;quot;}&quot;&gt;리히텐라데&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;제국&amp;quot;}&quot;&gt;제국&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;52&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;뤼카스&amp;quot;}&quot;&gt;뤼카스&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;동맹&amp;quot;}&quot;&gt;동맹&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;53&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;룬비니&amp;quot;}&quot;&gt;룬비니&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;동맹&amp;quot;}&quot;&gt;동맹&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;54&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;로포덴&amp;quot;}&quot;&gt;로포덴&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;제국&amp;quot;}&quot;&gt;제국&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;55&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;바르텐베르크&amp;quot;}&quot;&gt;바르텐베르크&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;제국&amp;quot;}&quot;&gt;제국&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;56&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;밴플리트&amp;quot;}&quot;&gt;밴플리트&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;동맹&amp;quot;}&quot;&gt;동맹&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td height=&quot;18&quot;&gt;57&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;빌렌슈탕니&amp;quot;}&quot;&gt;빌렌슈탕니&lt;/td&gt;
&lt;td data-sheets-value=&quot;{ &amp;quot;1&amp;quot;: 2, &amp;quot;2&amp;quot;: &amp;quot;제국&amp;quot;}&quot;&gt;제국&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>GAME/고전게임</category>
      <category>고전게임</category>
      <category>도스</category>
      <category>에디터</category>
      <category>은하영웅전설</category>
      <category>은하영웅전설4 EX</category>
      <category>인물</category>
      <category>코드표</category>
      <category>행성</category>
      <category>혹성</category>
      <author>ALEPH.GEM</author>
      <guid isPermaLink="true">https://aacii.tistory.com/457</guid>
      <comments>https://aacii.tistory.com/457#entry457comment</comments>
      <pubDate>Thu, 6 Nov 2025 16:47:48 +0900</pubDate>
    </item>
    <item>
      <title>Spring MVC 다국어 처리</title>
      <link>https://aacii.tistory.com/337</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;h2 data-ke-size=&quot;size26&quot;&gt;properties 파일 작성&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Spring MVC 프로젝트에서... src/main/resources 경로에 message_ko.properties 와 message_en.properties 파일을 생성합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러면 빌드와 배포를 했을 때 WEB-INF/classes 경로(classpath)에 프로퍼티 파일들이 생성됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 프로퍼티 파일들은 유니코드로 저장되며, 이클립스를 전자정부프레임워크를 사용하거나 properties editor 플러그인을 사용하면 자동으로 유니코드를 한국어로 표기해줍니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Help &amp;gt; Install New Software... &amp;gt; Add...&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Name : properties&amp;nbsp;editor&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Location :&amp;nbsp;&lt;a href=&quot;http://propedit.sourceforge.jp/eclipse/updates&quot;&gt;http://propedit.sourceforge.jp/eclipse/updates&lt;/a&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;message_ko.properties 예)&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;#################################################################### &lt;br /&gt;STAT.STAT=예약 상태 &lt;br /&gt;STAT.STAT01=예약 신청 &lt;br /&gt;STAT.STAT02=예약 취소 &lt;br /&gt;STAT.STAT03=예약 완료&lt;br /&gt;STAT.STAT04=예약 실패&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;message_en.properties 예)&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;STAT.STAT=Reservation status &lt;br /&gt;STAT.STAT01=Reservation Application &lt;br /&gt;STAT.STAT02=Cancel Reservation &lt;br /&gt;STAT.STAT03=Reservation Complete &lt;br /&gt;STAT.STAT04=Reservation Failure&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;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;스프링 설정&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서는 root-context.xml에 bean을 등록 합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1674030825473&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&amp;gt;
&amp;lt;beans xmlns=&quot;http://www.springframework.org/schema/beans&quot;
	xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
	xmlns:aop=&quot;http://www.springframework.org/schema/aop&quot;
	xmlns:context=&quot;http://www.springframework.org/schema/context&quot;
	xmlns:jdbc=&quot;http://www.springframework.org/schema/jdbc&quot;
	xmlns:mybatis-spring=&quot;http://mybatis.org/schema/mybatis-spring&quot;
	xmlns:tx=&quot;http://www.springframework.org/schema/tx&quot;
	xmlns:mvc=&quot;http://www.springframework.org/schema/mvc&quot;
	xsi:schemaLocation=&quot;http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-4.3.xsd
		http://mybatis.org/schema/mybatis-spring http://mybatis.org/schema/mybatis-spring-1.2.xsd
		http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.1.xsd
		http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
		http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
		http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd&quot;&amp;gt;
&amp;lt;!-- 생략 --&amp;gt;

	&amp;lt;!-- MessageSource Configuration : 메시지 프로퍼티 파일 bean id 변경 금지. 60초마다 프로퍼티 파일을 갱신해서 서버 재시작이 필요 없음 --&amp;gt;
	&amp;lt;bean id=&quot;messageSource&quot; class=&quot;org.springframework.context.support.ReloadableResourceBundleMessageSource&quot;&amp;gt;
		&amp;lt;property name=&quot;basenames&quot;&amp;gt;
			&amp;lt;list&amp;gt;
				&amp;lt;value&amp;gt;classpath:/message&amp;lt;/value&amp;gt;
			&amp;lt;/list&amp;gt;
		&amp;lt;/property&amp;gt;
		&amp;lt;property name=&quot;cacheSeconds&quot;&amp;gt;
			&amp;lt;value&amp;gt;60&amp;lt;/value&amp;gt;
		&amp;lt;/property&amp;gt;
		&amp;lt;property name=&quot;defaultEncoding&quot; value=&quot;UTF-8&quot;/&amp;gt;
	&amp;lt;/bean&amp;gt;
	&amp;lt;!-- LocaleResolver Registration : 세션값으로 로케일(언어)을 관리 bean id 변경 금지 --&amp;gt;
	&amp;lt;bean id=&quot;localeResolver&quot; class=&quot;org.springframework.web.servlet.i18n.SessionLocaleResolver&quot;&amp;gt;
		&amp;lt;property name=&quot;defaultLocale&quot; value=&quot;ko&quot; /&amp;gt;
	&amp;lt;/bean&amp;gt;
    
 &amp;lt;!-- 생략 --&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;주의할 점은 실제 프로퍼티 파일이 message_ko.properites, message_en.properties 이더라도&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;basename 에 classpath:/message_ko 라고 적지말고 접두사 처럼 classpaht:/message까지만 적으면 프로퍼티 &quot;파일이름_국가코드&quot;는 스프링이 알아서 처리하게 되어있다는 것입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;패키지 경로(예:package)가 있다면 classpath:/package/message 처럼 적으면 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 bean id 는 지정된 것이라 바꾸면 안됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;localeResolver는 세션을 이용하는 방법, 쿠키를 이용하는 방법, request header정보의 language값을 이용하는 방법이 있는데, 여기서는 Session을 이용하는 방법으로 구현해보겠습니다.&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;그리고 나서 인터셉터를 이용해서 locale 설정에 따라 메시지 출력(랜더링)을 제어해야 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이클립스 스프링MVC 프로젝트에서&amp;nbsp;src/main/webapp/WEB-INF/spring/servlet-context.xml 에 인터셉터를 등록합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1674031663962&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&amp;gt;
&amp;lt;beans:beans xmlns=&quot;http://www.springframework.org/schema/mvc&quot;
	xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
	xmlns:beans=&quot;http://www.springframework.org/schema/beans&quot;
	xmlns:context=&quot;http://www.springframework.org/schema/context&quot;
	xsi:schemaLocation=&quot;http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd
		http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd&quot;&amp;gt;

	&amp;lt;!-- DispatcherServlet Context: defines this servlet's request-processing infrastructure --&amp;gt;
	
	&amp;lt;!-- Enables the Spring MVC @Controller programming model --&amp;gt;
	&amp;lt;annotation-driven /&amp;gt;

	&amp;lt;!-- Handles HTTP GET requests for /resources/** by efficiently serving up static resources in the ${webappRoot}/resources directory --&amp;gt;
	&amp;lt;resources mapping=&quot;/resources/**&quot; location=&quot;/resources/&quot; /&amp;gt;

	&amp;lt;!-- Resolves views selected for rendering by @Controllers to .jsp resources in the /WEB-INF/views directory --&amp;gt;
	&amp;lt;beans:bean class=&quot;org.springframework.web.servlet.view.InternalResourceViewResolver&quot;&amp;gt;
		&amp;lt;beans:property name=&quot;prefix&quot; value=&quot;/WEB-INF/views/&quot; /&amp;gt;
		&amp;lt;beans:property name=&quot;suffix&quot; value=&quot;.jsp&quot; /&amp;gt;
	&amp;lt;/beans:bean&amp;gt;
	
	&amp;lt;!-- 생략 --&amp;gt;
	
	&amp;lt;!-- LocaleChangeInterceptor Registration : 인터셉터를 이용해 lang parameter 값으로  로케일(언어) 설정 --&amp;gt;
	&amp;lt;interceptors&amp;gt;
		&amp;lt;beans:bean id=&quot;localeChangeInterceptor&quot; class=&quot;org.springframework.web.servlet.i18n.LocaleChangeInterceptor&quot;&amp;gt;
			&amp;lt;beans:property name=&quot;paramName&quot; value=&quot;lang&quot;/&amp;gt;
		&amp;lt;/beans:bean&amp;gt;
	&amp;lt;/interceptors&amp;gt;
	
&amp;lt;/beans:beans&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;역시 bean id는 변경해서는 안되며 파라메터 이름은 lang으로 지정했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러면 request 요청시 파라메터에 ?lang=ko 혹은 ?lang=en 으로 요청하면 언어셋(Locale)을 그때 그때 변경 적용해서 유연하게 다국어 메시지 처리를 할 수 있게됩니다.&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;h3 data-ke-size=&quot;size23&quot;&gt;구현&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;서블릿에서 구현하는 방법&lt;/p&gt;
&lt;pre id=&quot;code_1674032203507&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import java.util.Locale;
import org.springframework.context.MessageSource;
import org.springframework.web.servlet.i18n.SessionLocaleResolver;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

@Controller
public class HomeController {
	private static final Logger logger = LoggerFactory.getLogger(HomeController.class);

	@Autowired
	SessionLocaleResolver localeResolver;

	@Autowired
	MessageSource messageSource;

	@RequestMapping(value = &quot;/i18n.do&quot;, method = RequestMethod.GET)
	public String i18n(Locale locale, HttpServletRequest request, Model model) {

		// RequestMapingHandler로 부터 받은 Locale 객체
		logger.info(&quot;Welcome i18n! The client locale is {}.&quot;, locale);

		// localeResolver 로부터 Locale 을 출력
		logger.info(&quot;Session locale is {}.&quot;, localeResolver.resolveLocale(request));

		// JSP 페이지에서 EL식으로 사용할 수 있도록 모델에 등록합니다.
		model.addAttribute(&quot;siteCount&quot;, messageSource.getMessage(&quot;STAT.STAT&quot;, null, &quot;default text&quot;, locale));

		return &quot;i18n&quot;;
	}
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;messageSource 는&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;messageSource.getMessage(&quot;프로퍼티파일의키값&quot;, 대체값이 있는경우 값의배열, &quot;메시지기본값&quot;, Locale);&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;jsp에서 &amp;lt;spring:message&amp;gt; 태그 라이브러리로 구현하는 방법&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;/WEB-INF/views/i18n.jsp&lt;/p&gt;
&lt;pre id=&quot;code_1674032647201&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;%@ page language=&quot;java&quot; contentType=&quot;text/html; charset=UTF-8&quot; pageEncoding=&quot;UTF-8&quot;%&amp;gt;
&amp;lt;%@ taglib uri=&quot;http://java.sun.com/jsp/jstl/core&quot; prefix=&quot;c&quot; %&amp;gt;
&amp;lt;%@ taglib uri=&quot;http://www.springframework.org/tags&quot; prefix=&quot;spring&quot; %&amp;gt;
&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html&amp;gt;
&amp;lt;head&amp;gt;
	&amp;lt;meta http-equiv=&quot;Content-Type&quot; content=&quot;text/html; charset=UTF-8&quot; /&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
	&amp;lt;p&amp;gt;
		&amp;lt;a href=&quot;&amp;lt;c:url value=&quot;/i18n.do?lang=ko&quot; /&amp;gt;&quot;&amp;gt;한국어&amp;lt;/a&amp;gt;
		&amp;lt;a href=&quot;&amp;lt;c:url value=&quot;/i18n.do?lang=en&quot; /&amp;gt;&quot;&amp;gt;English&amp;lt;/a&amp;gt;
	&amp;lt;/p&amp;gt;
	&amp;lt;p&amp;gt;&amp;lt;spring:message code=&quot;STAT.STAT&quot; text=&quot;default text&quot; /&amp;gt;&amp;lt;/p&amp;gt;
	&amp;lt;p&amp;gt;&amp;lt;spring:message code=&quot;STAT.STAT01&quot; text=&quot;default text1&quot; /&amp;gt;&amp;lt;/p&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 properties 파일에 등록한 키값에 해당하는 value 값이 출력되게 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;언어 셋을 바꾸려면 위 예제 처럼 URL?lang=en 처럼 parameter로 전달해서 바꿀 수 있습니다.&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;&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;&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;&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;&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;&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;</description>
      <category>DEV&amp;amp;OPS/Java</category>
      <category>i18</category>
      <category>jsp</category>
      <category>message</category>
      <category>Properties</category>
      <category>SERVLET</category>
      <category>spring</category>
      <category>다국어</category>
      <category>언어</category>
      <author>ALEPH.GEM</author>
      <guid isPermaLink="true">https://aacii.tistory.com/337</guid>
      <comments>https://aacii.tistory.com/337#entry337comment</comments>
      <pubDate>Wed, 5 Nov 2025 12:21:27 +0900</pubDate>
    </item>
    <item>
      <title>Spring 3 Quartz 1.8.6 스케줄링</title>
      <link>https://aacii.tistory.com/139</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;Quartz 1.8.6&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Spring3.X 프로젝트에서는 Quartz 2.X 이상을 지원하지 않아서 보통 Quartz 1.8.6을 많이 사용합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;http://www.quartz-scheduler.org/downloads/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;http://www.quartz-scheduler.org/downloads/&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1629878298560&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;Downloads&quot; data-og-description=&quot;&quot; data-og-host=&quot;www.quartz-scheduler.org&quot; data-og-source-url=&quot;http://www.quartz-scheduler.org/downloads/&quot; data-og-url=&quot;http://www.quartz-scheduler.org/downloads/&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;http://www.quartz-scheduler.org/downloads/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;http://www.quartz-scheduler.org/downloads/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&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;Downloads&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.quartz-scheduler.org&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;h3 data-ke-size=&quot;size23&quot;&gt;Maven pom.xml&lt;/h3&gt;
&lt;pre id=&quot;code_1630054956149&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;dependencies&amp;gt;
    &amp;lt;!-- Spring 3 dependencies --&amp;gt;
    &amp;lt;dependency&amp;gt;
        &amp;lt;groupId&amp;gt;org.springframework&amp;lt;/groupId&amp;gt;
        &amp;lt;artifactId&amp;gt;spring-core&amp;lt;/artifactId&amp;gt;
        &amp;lt;version&amp;gt;3.1.2.RELEASE&amp;lt;/version&amp;gt;
    &amp;lt;/dependency&amp;gt; 
    &amp;lt;!-- QuartzJobBean in spring-context-support.jar --&amp;gt;
    &amp;lt;dependency&amp;gt;
        &amp;lt;groupId&amp;gt;org.springframework&amp;lt;/groupId&amp;gt;
        &amp;lt;artifactId&amp;gt;spring-context-support&amp;lt;/artifactId&amp;gt;
        &amp;lt;version&amp;gt;3.1.2.RELEASE&amp;lt;/version&amp;gt;
    &amp;lt;/dependency&amp;gt;
    &amp;lt;!-- Spring + Quartz need transaction --&amp;gt;
    &amp;lt;dependency&amp;gt;
        &amp;lt;groupId&amp;gt;org.springframework&amp;lt;/groupId&amp;gt;
        &amp;lt;artifactId&amp;gt;spring-tx&amp;lt;/artifactId&amp;gt;
        &amp;lt;version&amp;gt;3.1.2.RELEASE&amp;lt;/version&amp;gt;
    &amp;lt;/dependency&amp;gt;
    &amp;lt;!-- Quartz framework --&amp;gt;
    &amp;lt;dependency&amp;gt;
        &amp;lt;groupId&amp;gt;org.quartz-scheduler&amp;lt;/groupId&amp;gt;
        &amp;lt;artifactId&amp;gt;quartz&amp;lt;/artifactId&amp;gt;
        &amp;lt;version&amp;gt;1.8.6&amp;lt;/version&amp;gt;
    &amp;lt;/dependency&amp;gt;
&amp;lt;/dependencies&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Spring 3.X 에서 quartz를 사용하기 위해 1.8.6 버전으로 사용합니다.&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;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Job : 비지니스 로직이 들어갈 컴포넌트. 실제 해당 시간에 수행할 작업들을 구현합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;JobDetailBean : Job의 속성 정보, 작업을 정의한 클래스를 스케줄링에 등록하는 컴포넌트.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;TriggerBean :&amp;nbsp; 시간 주기를 설정하는 컴포넌트&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SchedulerBean : Job 정보와 각종 속성들을 모아 Manager Thread를 생성하여 해당 시간에 Job을 실행하는 컴포넌트&amp;nbsp;&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;Quartz 설정 (applicationContext.xml)&lt;/h3&gt;
&lt;pre id=&quot;code_1630055685558&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&amp;gt;
&amp;lt;beans xmlns=&quot;http://www.springframework.org/schema/beans&quot;
	xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
	xmlns:context=&quot;http://www.springframework.org/schema/context&quot;
	xmlns:tx=&quot;http://www.springframework.org/schema/tx&quot;
	xmlns:aop=&quot;http://www.springframework.org/schema/aop&quot;
	xsi:schemaLocation=&quot;
		http://www.springframework.org/schema/beans
		http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
		http://www.springframework.org/schema/context
		http://www.springframework.org/schema/context/spring-context-3.1.xsd
		http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
		http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd&quot;&amp;gt;
		
		&amp;lt;!-- 실제 작업을 수행하는 클래스 등록 --&amp;gt;
		&amp;lt;bean id=&quot;processor&quot; class=&quot;com.datastreams.gw.scheduler.daily.Processor&quot; /&amp;gt;
        
		&amp;lt;!-- 작업을 정의한 클래스(setter로 주입)를 등록  --&amp;gt;
		&amp;lt;bean name=&quot;runJob&quot; class=&quot;org.springframework.scheduling.quartz.JobDetailBean&quot;&amp;gt;
			&amp;lt;!-- 작업을 정의 --&amp;gt;
			&amp;lt;property name=&quot;jobClass&quot; value=&quot;com.datastreams.gw.scheduler.daily.RunJob&quot; /&amp;gt;
			&amp;lt;!-- 실제 스케줄링될 작업 --&amp;gt;
			&amp;lt;property name=&quot;jobDataAsMap&quot;&amp;gt;
				&amp;lt;map&amp;gt;
					&amp;lt;entry key=&quot;processor&quot; value-ref=&quot;processor&quot; /&amp;gt;
				&amp;lt;/map&amp;gt;
			&amp;lt;/property&amp;gt;
		&amp;lt;/bean&amp;gt;
        
		&amp;lt;!-- trigger: 작업 주기를 등록(cronExpression을 사용) --&amp;gt;
		&amp;lt;bean id=&quot;cronTriggerDaily&quot; class=&quot;org.springframework.scheduling.quartz.CronTriggerBean&quot;&amp;gt;
			&amp;lt;property name=&quot;jobDetail&quot; ref=&quot;runJob&quot; /&amp;gt;	&amp;lt;!-- 실행할 작업 --&amp;gt;
			&amp;lt;!-- 초 분 시 일 월 요일(1-7, 일요일부터) 연도(생략가능) --&amp;gt;
			&amp;lt;property name=&quot;cronExpression&quot; value=&quot;0 10 10 ? * 2-6&quot; /&amp;gt; &amp;lt;!-- 매주 월~금요일 10시 10분 0초 마다 실행 --&amp;gt;
		&amp;lt;/bean&amp;gt;
        
		&amp;lt;!-- Scheduler : 스케줄 관리를 위해 작업과 트리거를 같이 등록--&amp;gt;
		&amp;lt;bean class=&quot;org.springframework.scheduling.quartz.SchedulerFactoryBean&quot;&amp;gt;
			&amp;lt;property name=&quot;jobDetails&quot;&amp;gt;
				&amp;lt;list&amp;gt;
					&amp;lt;ref bean=&quot;runJob&quot; /&amp;gt;
				&amp;lt;/list&amp;gt;
			&amp;lt;/property&amp;gt;
			&amp;lt;property name=&quot;triggers&quot;&amp;gt;
				&amp;lt;list&amp;gt;
					&amp;lt;ref bean=&quot;cronTriggerDaily&quot; /&amp;gt;
				&amp;lt;/list&amp;gt;
			&amp;lt;/property&amp;gt;
		&amp;lt;/bean&amp;gt;	
&amp;lt;/beans&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;trigger를 사용할 때 simple trigger를 사용할 수도 있으나 정밀한 주기 설정을 위해서 cron trigger를 사용하는 것을 권장합니다.&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;CronExpression&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자동 실행될 배치 주기를 기술하는 표현법으로 &quot;초 분 시 일 월 요일 년도&quot;&amp;nbsp; 으로 표기합니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;년도는 생략가능합니다.&lt;/li&gt;
&lt;li&gt;요일을 기술하면 일(날짜)을 ? 처리 해야하고 일(날짜)를 기술하면 요일을 ? 으로 기술해야 해서 배타적입니다. 즉, 동시에 요일과 날짜를 기술할 수 없습니다. 요일과 날짜 중에서 둘 중 하나는 물음표 표기를 해야만 합니다.&lt;/li&gt;
&lt;li&gt;* 기호는 전체 값을 기술합니다.&lt;/li&gt;
&lt;li&gt;- 기호는 값의 범위를 지정합니다.&amp;nbsp;요일은 일요일(1)부터 토요일(7)까지 숫자로 표기할 수 있고 월요일부터 금요일이라면 2-6 으로 표기합니다. 일반적으로 리눅스 등에서 사용하는 cron expression은 0-6 이지만 quartz에서 사용하는 요일은 1-7 을 사용합니다.&lt;/li&gt;
&lt;li&gt;/ 기호는&amp;nbsp; (범위/숫자) 으로 표기하며 범위에 속한 값 중에서 숫자만큼의 간격으로 실행하게 해 줍니다. 만약 (*/10 * * * *) 이라면 10초 간격으로 반복 실행합니다.&amp;nbsp;&amp;nbsp;&lt;/li&gt;
&lt;li&gt;, (콤마) 기호는 값을 개별로 추가할 때 사용합니다. 중복해서 기술할 수 있습니다.&lt;/li&gt;
&lt;li&gt;L 은 마지막을 뜻합니다.&lt;/li&gt;
&lt;li&gt;W는 주중(weekday)을 뜻합니다.&lt;/li&gt;
&lt;li&gt;#은 n번째를 의미합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예제&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;0 0 12 * * ? 매일 12시(정오) &lt;br /&gt;0 10 10 ? * * 매일 오전 10시 10분 &lt;br /&gt;0 15 10 * * ? 2021 2021년에 매일 아침 10시 15분 &lt;br /&gt;0&amp;nbsp;*&amp;nbsp;14&amp;nbsp;*&amp;nbsp;*&amp;nbsp;?&amp;nbsp;매일&amp;nbsp;오후&amp;nbsp;2시&amp;nbsp;0분&amp;nbsp;~&amp;nbsp;59분 &lt;br /&gt;0 0/5 14,18 * * ? 매일 오후 2시부터 2시 55분까지 5분마다, 6시부터 6시 55분까지 5분마다 &lt;br /&gt;0&amp;nbsp;0-5&amp;nbsp;14&amp;nbsp;*&amp;nbsp;*&amp;nbsp;?&amp;nbsp;매일&amp;nbsp;오후&amp;nbsp;2시부터&amp;nbsp;2시&amp;nbsp;5분까지&amp;nbsp;매분 &lt;br /&gt;0 15 10 ? * MON-FRI 월요일부터 금요일까지 오전 10시 15분 &lt;br /&gt;0&amp;nbsp;15&amp;nbsp;10&amp;nbsp;15&amp;nbsp;*&amp;nbsp;?&amp;nbsp;매달&amp;nbsp;15일&amp;nbsp;오전&amp;nbsp;10시&amp;nbsp;15분 &lt;br /&gt;0&amp;nbsp;15&amp;nbsp;10&amp;nbsp;L&amp;nbsp;*&amp;nbsp;?&amp;nbsp;매달&amp;nbsp;마지막&amp;nbsp;날&amp;nbsp;오전&amp;nbsp;10시&amp;nbsp;15분 &lt;br /&gt;0&amp;nbsp;15&amp;nbsp;10&amp;nbsp;?&amp;nbsp;*&amp;nbsp;6L&amp;nbsp;매달&amp;nbsp;마지막&amp;nbsp;금요일&amp;nbsp;오전&amp;nbsp;10시&amp;nbsp;15분 &lt;br /&gt;0 15 10 ? * 6L 2021-2022 2021년부터 2022년까지 매달 마지막 금요일 오전 10시 15분 &lt;br /&gt;0&amp;nbsp;15&amp;nbsp;10&amp;nbsp;?&amp;nbsp;*&amp;nbsp;6#3&amp;nbsp;매달&amp;nbsp;3번째&amp;nbsp;금요일&amp;nbsp;오전&amp;nbsp;10시&amp;nbsp;15분 &lt;br /&gt;0&amp;nbsp;0&amp;nbsp;12&amp;nbsp;1/5&amp;nbsp;*&amp;nbsp;?&amp;nbsp;매달&amp;nbsp;첫날부터&amp;nbsp;5일마다&amp;nbsp;12시(정오)&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;실제 작업을 수행할 클래스 Processor.java&lt;/h3&gt;
&lt;pre id=&quot;code_1630284929552&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public class Processor {
  //기본생성자
  public Processor() {		
  }
	
  //실제 배치 작업을 기술 한다. 실제 반복 실행할 메서드
  public void process() {
      System.out.println(&quot;배치 작업 실행!&quot;);
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;스케줄러를 정의하는 클래스 RunJob.java&lt;/h3&gt;
&lt;pre id=&quot;code_1630285529365&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.scheduling.quartz.QuartzJobBean;

//QuartzJobBean을 상속받아서 스케줄러를 구현구현
public class RunJob extends QuartzJobBean {
	//실제 실행될 태스크 인스턴스
	private Processor processor;
	
	//setter방식으로 주입
	public void setProcessor(Processor processor) {
		this.processor = processor;
	}

	@Override
	protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
	//스캐줄러에서 실행을 원하는 메서드를 호출
		processor.process();		
	}
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Main.java&lt;/h3&gt;
&lt;pre id=&quot;code_1630285667104&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Main {
    public static void main(String[] args) {        
        AbstractApplicationContext context = new ClassPathXmlApplicationContext(&quot;applicationContext.xml&quot;);    
    }
}&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;&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;&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>DEV&amp;amp;OPS/Java</category>
      <category>Java</category>
      <category>job</category>
      <category>Quartz</category>
      <category>Scheduling</category>
      <category>spring</category>
      <category>Task</category>
      <category>배치</category>
      <author>ALEPH.GEM</author>
      <guid isPermaLink="true">https://aacii.tistory.com/139</guid>
      <comments>https://aacii.tistory.com/139#entry139comment</comments>
      <pubDate>Wed, 5 Nov 2025 12:20:36 +0900</pubDate>
    </item>
    <item>
      <title>Spring Web Project 한글 설정</title>
      <link>https://aacii.tistory.com/120</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;html 파일에 한글 설정&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1604654741949&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;head&amp;gt;
	&amp;lt;!-- HTML5의 경우 --&amp;gt;
	&amp;lt;meta http-equiv=&quot;Content-Type&quot; content=&quot;text/html; charset=UTF-8&quot;&amp;gt;
	&amp;lt;!-- XHTML의 경우 --&amp;gt;
	&amp;lt;meta charset=&quot;utf-8&quot;&amp;gt;
&amp;lt;/head&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;&lt;b&gt;server.xml 한글 설정&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1604654876097&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;Connector connectionTimeout=&quot;20000&quot; port=&quot;8080&quot; protocol=&quot;HTTP/1.1&quot; redirectPort=&quot;8443&quot; URIEncoding=&quot;UTF-8&quot; /&amp;gt;
&amp;lt;Connector port=&quot;8009&quot; protocol=&quot;AJP/1.3&quot; redirectPort=&quot;8443&quot; URIEncoding=&quot;UTF-8&quot; /&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;GET방식에서는 질의 문자열들을 URI에 포함되기 때문에 URI인코딩 처리 작업을 해야 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;server.xml 파일에 URIEncoding=&quot;UTF-8&quot; 프로퍼티를 설정합니다.&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;web.xml 한글 설정&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1604654021777&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;filter&amp;gt; 
    &amp;lt;filter-name&amp;gt;encodingFilter&amp;lt;/filter-name&amp;gt; 
    &amp;lt;filter-class&amp;gt;org.springframework.web.filter.CharacterEncodingFilter&amp;lt;/filter-class&amp;gt; 
    &amp;lt;init-param&amp;gt; 
       &amp;lt;param-name&amp;gt;encoding&amp;lt;/param-name&amp;gt; 
       &amp;lt;param-value&amp;gt;UTF-8&amp;lt;/param-value&amp;gt; 
    &amp;lt;/init-param&amp;gt; 
    &amp;lt;init-param&amp;gt; 
       &amp;lt;param-name&amp;gt;forceEncoding&amp;lt;/param-name&amp;gt; 
       &amp;lt;param-value&amp;gt;true&amp;lt;/param-value&amp;gt; 
    &amp;lt;/init-param&amp;gt; 
 &amp;lt;/filter&amp;gt; 
 &amp;lt;filter-mapping&amp;gt; 
    &amp;lt;filter-name&amp;gt;encodingFilter&amp;lt;/filter-name&amp;gt; 
    &amp;lt;url-pattern&amp;gt;/*&amp;lt;/url-pattern&amp;gt; 
 &amp;lt;/filter-mapping&amp;gt; 
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;POST 전송 방식은 요청 body에 담아 전달됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CharacterEncodingFilter는 http상 주고받는 데이터의 헤더 값을 인코딩합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Servlet에서 request.setCharacterEncoding(&quot;utf-8&quot;); 처리와 동일한 처리입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Spring Security설정이 있는 경우 한글 필터 설정이 springSecurityFilterChain 앞 쪽에 위치해야 합니다.&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;servlet에서 한글 처리&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1604904772195&quot; class=&quot;java&quot; style=&quot;margin: 20px auto 0px; display: block; overflow: auto; padding: 15px; color: #383a42; background: #f6f7f8; font-size: 14px; border-radius: 3px; font-family: Menlo, Consolas, Monaco, monospace; border: 1px solid #dddddd; cursor: default; z-index: 1;&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/* 요청정보 Body에 있는 문자열들을 인자값으로 지정한 문자코드로 인코딩 */
request.setCharacterEncoding(&quot;UTF-8&quot;);

/* 응답정보 문자열들을 인자값으로 지정한 문자코드로 인코딩 */
response.setContentType(&quot;text/html;charset=UTF-8&quot;);
&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;&lt;b&gt;. jsp 파일에서 한글 처리&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1604905247164&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;%@ page contentType=&quot;text/html; charset=UTF-8&quot; pageEncoding=&quot;UTF-8&quot; language=&quot;java&quot; %&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;이 태그는 서블릿에서 response.setContentType(&quot;text/html;charset=UTF-8&quot;) 처리와 유사한 기능을 수행합니다.&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;dispatcher-servlet.xml 에서의 설정&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1604907747127&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;bean class=&quot;org.springframework.web.servlet.view.InternalResourceViewResolver&quot;&amp;gt;
	&amp;lt;property name=&quot;prefix&quot; value=&quot;/WEB-INF/views/&quot;/&amp;gt;
	&amp;lt;property name=&quot;suffix&quot; value=&quot;.jsp&quot;/&amp;gt;
  &amp;lt;property name=&quot;contentType&quot; value=&quot;text/html; charset=UTF-8&quot;/&amp;gt;
&amp;lt;/bean&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;&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;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthContent&quot; data-filename=&quot;0000.png&quot; data-origin-width=&quot;661&quot; data-origin-height=&quot;418&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/wiN8z/btqM0rcGH2k/dEhvxNKKOIvjciGksfbiV1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/wiN8z/btqM0rcGH2k/dEhvxNKKOIvjciGksfbiV1/img.png&quot; data-alt=&quot;DEV&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/wiN8z/btqM0rcGH2k/dEhvxNKKOIvjciGksfbiV1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FwiN8z%2FbtqM0rcGH2k%2FdEhvxNKKOIvjciGksfbiV1%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;661&quot; height=&quot;418&quot; data-filename=&quot;0000.png&quot; data-origin-width=&quot;661&quot; data-origin-height=&quot;418&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;DEV&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>DEV&amp;amp;OPS/Java</category>
      <category>Java</category>
      <category>MVC</category>
      <category>SERVLET</category>
      <category>spring</category>
      <category>한글</category>
      <author>ALEPH.GEM</author>
      <guid isPermaLink="true">https://aacii.tistory.com/120</guid>
      <comments>https://aacii.tistory.com/120#entry120comment</comments>
      <pubDate>Wed, 5 Nov 2025 12:20:18 +0900</pubDate>
    </item>
    <item>
      <title>Spring  AOP</title>
      <link>https://aacii.tistory.com/336</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;관점 지향(Aspect Oriented Programming)&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;로깅&lt;/li&gt;
&lt;li&gt;보안/인증&lt;/li&gt;
&lt;li&gt;트랜잭션&lt;/li&gt;
&lt;li&gt;리소스 풀링&lt;/li&gt;
&lt;li&gt;에러 검사 / 처리&lt;/li&gt;
&lt;li&gt;정책&lt;/li&gt;
&lt;li&gt;멀티 스레드 안전 관리&lt;/li&gt;
&lt;li&gt;데이터 영속처리&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 항목들은 소프트웨어 개발 시 발생하는 공통적인 문제들입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;핵심 관심(core concern)은 업무 로직을 말합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;횡단 관심(cross-cutting concern)은 위에서 언급한 로깅이나 보안등 공통 시스템 로직을 말합니다.&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;h3 data-ke-size=&quot;size23&quot;&gt;관점 지향 용어&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;advice : 관점이 언제, 무엇을 하는지를 정의&lt;/li&gt;
&lt;li&gt;joinpoint : 관점이 실행될 수 있는 위치들&lt;/li&gt;
&lt;li&gt;pointcut : joinpoint 중에서 advice 하는 위치(어디서)&lt;/li&gt;
&lt;li&gt;aspect : advice + pointcut 즉, 무엇을 언제 어디서 하는 지를 정의&lt;/li&gt;
&lt;li&gt;weaving : proxied object를 생성하여 aspect를 대상 객체에 적용&lt;/li&gt;
&lt;li&gt;introduction : 기존 클래스에 새로운 메서드나 애트리뷰트를 추가하는 것&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;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Advice&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;before : 메서드 호출 전 advice기능이 발생&lt;/li&gt;
&lt;li&gt;after : 메서드 실행 완료 후 결과와 관계없이 advice 기능이 발생&lt;/li&gt;
&lt;li&gt;after-returning : 메서드가 성공적으로 완료 후 advice 기능이 발생&lt;/li&gt;
&lt;li&gt;after-throwing : 메서드가 예외를 발생 후 advice 기능이 발생&lt;/li&gt;
&lt;li&gt;arount : 메서드가 호출되기 전과 후에 advice 기능이 발생&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;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Spring AOP&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;pom.xml에 아래 2가지 모듈을 추가합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1673871834128&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;		&amp;lt;dependency&amp;gt;
			&amp;lt;groupId&amp;gt;org.springframework&amp;lt;/groupId&amp;gt;
			&amp;lt;artifactId&amp;gt;spring-aop&amp;lt;/artifactId&amp;gt;
			&amp;lt;version&amp;gt;${spring-framework.version}&amp;lt;/version&amp;gt;
		&amp;lt;/dependency&amp;gt;
		&amp;lt;dependency&amp;gt;
			&amp;lt;groupId&amp;gt;org.springframework&amp;lt;/groupId&amp;gt;
			&amp;lt;artifactId&amp;gt;spring-aspects&amp;lt;/artifactId&amp;gt;
			&amp;lt;version&amp;gt;${spring-framework.version}&amp;lt;/version&amp;gt;
		&amp;lt;/dependency&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;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;로깅 기능 구현 예제&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;스프링 프로젝트의 기본 패키지에 aspect&amp;nbsp; 패키지를 생성 후 aspect 클래스(여기서는 LoggingAspect)를 정의합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1673872212944&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;@Component
public class LoggingAspect {
    private Logger log = LoggerFactory.getLogger(getClass());
	
    //advice 메서드
    //before advice
	public void logBefore(JoinPoint joinpoint) {
		String message = buildJoinpoint(joinpoint);
		message += &quot;메서드 실행 전&quot;;
		log.info(message);
	}
    
    //...
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;advice는 joinpoint 타입이 인수로 전달됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래 예제처럼 Joinpoint 인터페이스의 메서드들로 조인 포인트의 정보들을 구할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1673872650998&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;private String buildJoinpoint(JoinPoint joinpoint) {
    //joinpoint의 클래스 네임
    String className = joinpoint.getTarget().getClass().getName();
    
    //메서드의 시그니처 네임
    String methodName = joinpoint.getSignature().getName();
    
    String message = className + &quot; 의 &quot; + methodName + &quot;( &quot;;
    
    //joinpoint의 메서드 매개 변수 목록
    Object [] args = joinpoint.getArgs();
    
    for(int i = 0; i &amp;lt; args.length; ++i){
        Object arg  = args[i];
        message += arg.getClass().getTypeName();
        if(i != args.length - 1 )
            message += &quot;, &quot;;
    }
    
    message += &quot; ) &quot;;
    
    return message;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;around advice의 경우는 ProceddingJoinPoint 타입의 매개 변수를 받는데&amp;nbsp; 메서드 실행 전과 실행 후에 실행되기 때문에 joinpoint를 진행(proceed) 시킬 필요가 있습니다.&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1673873455140&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;	// around 어드바이스 
	public void logAround(ProceedingJoinPoint joinpoint) throws Throwable {
    	//시작
		String message = buildJoinpoint(joinpoint);
		message += &quot;메서드 실행 시작&quot;;
		log.info(message);
		
        //메서드 호출 진행
        joinpoint.proceed();		 
		
        //종료
        message = buildJoinpoint(joinpoint);
		message += &quot;메서드 실행 종료&quot;;

		log.info(message);
	}&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;h3 data-ke-size=&quot;size23&quot;&gt;aspect 설정&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위에서 구현한 LoggingAspect 클래스를 Spring bean으로 설정합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1673874280444&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&amp;gt;
&amp;lt;beans xmlns=&quot;http://www.springframework.org/schema/beans&quot;
	xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
	xmlns:context=&quot;http://www.springframework.org/schema/context&quot;
	xmlns:aop=&quot;http://www.springframework.org/schema/aop&quot;
	xsi:schemaLocation=&quot;http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd
		http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.1.xsd&quot;&amp;gt;
	&amp;lt;context:component-scan base-package=&quot;컴포넌트베이스패키지경로(예:com.aacii.aspect)&quot;/&amp;gt;
	 	&amp;lt;bean id=&quot;loggingAspect&quot; class=&quot;클래스경로(예:com.aacii.aspect.LoggingAspect)&quot;/&amp;gt;
 	&amp;lt;aop:config&amp;gt;
 		&amp;lt;aop:aspect ref=&quot;loggingAspect&quot;&amp;gt;
 			&amp;lt;aop:pointcut expression=&quot;execution(* 컴포넌트패키지경로.*.*.get*(..)) || execution(* 컴포넌트패키지경로.*.*.find*(..))&quot; id=&quot;getLogging&quot;/&amp;gt;
 			&amp;lt;aop:pointcut expression=&quot;execution(* 컴포넌트패키지경로.*.*.save*(..))&quot; id=&quot;saveLogging&quot;/&amp;gt;
 			&amp;lt;aop:before method=&quot;logBefore&quot; pointcut-ref=&quot;getLogging&quot;/&amp;gt;
 			&amp;lt;aop:around method=&quot;logAround&quot; pointcut-ref=&quot;saveLogging&quot;/&amp;gt;
 		&amp;lt;/aop:aspect&amp;gt;
 	&amp;lt;/aop:config&amp;gt;
&amp;lt;/beans&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;lt;aop:config&amp;gt; :&amp;nbsp; 최상위 AOP element&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;lt;aop:aspect&amp;gt; : 관점 설정&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;lt;aop:pointcut&amp;gt; : point 컷 설정&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;lt;aop:before&amp;gt; : before advice 설정&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;lt;aop:around&amp;gt; : around advice 설정&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;after, after-returning, after-throwing은 생략했습니다.&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;h3 data-ke-size=&quot;size23&quot;&gt;pointcut 설정&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;pointcut은 aop를 구현할 때 advice가 실행되는 위치를 지정합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;pointcut을 표현하는 expression은 아래와 같습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1673874867525&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;execution(반환타입 메서드가속한패키지.*.*.메서드이름*(인수))&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1673874951100&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;!-- 예제 --&amp;gt;
execution(* com.aacii.*.*.get*(..))&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;execution() 지명자 외에도 within(), bean(), target(), this(), args() 들이 있지만 여기서는 생략합니다.&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;예를들어 업무 로직이 exampleService.getAll() 이라면,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;aspect(관점)은 xml의 &amp;lt;aop:before pointcut-ref=&quot;getLogging&quot; method=&quot;logBefore&quot; /&amp;gt; 등으로 설정하고,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;시스템로직은 advice로 별도 클래스(LoggingAspect)를 만들어서 메서드(logBefore();)로 동작을 정의합니다.&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;h3 data-ke-size=&quot;size23&quot;&gt;@AspectJ&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;@AspectJ 어노테이션을 이용해서 XML 설정 없이 AOP를 구현할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위에서 언급한 용어대로 @Aspect, @Pointcut, @Before, @After, @Around 등을 이용해서 설정 할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;aspect 클래스를 spring bean으로 설정하기 위해 @Componet 을 추가합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1673955786598&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;@Aspect
@Component
public class LoggingAspect {
	
    // getLogging 포인트컷
	@Pointcut(&quot;execution(* com.aacii.ex.*.*.get*(..))&quot; + &quot; || execution(* com.aacii.ex.*.*.find*(..))&quot;)
	public void getLogging() {}
	
    // before 어드바이스
	@Before(&quot;getLogging()&quot;)
	public void logBefore(JoinPoint joinpoint) {
		String message = buildJoinpoint(joinpoint);
		message += &quot;실행 시작&quot;;
		log.info(message);
	}
    //생략...
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;@Around 어노테이션은 괄호안에 포인트컷 표현식을 문자열로 설정합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;XML 때와 마찬가지로 ProceedingJoinPoint를 이용해야 하고, proceed()메서드를 호출해야 메서드를 실행시킵니다.&lt;/p&gt;
&lt;pre id=&quot;code_1673956229151&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;	// around 어드바이스 
	@Around(&quot;execution(* com.aacii.ex.*.*.save*(..))&quot;)
	public void logAround(ProceedingJoinPoint joinpoint) throws Throwable {
		long start = System.currentTimeMillis();
		String message = buildJoinpoint(joinpoint);
		message += &quot;메서드 실행 시작&quot;;
		log.info(message);
        
		joinpoint.proceed();		// 메서드 호출 
        
		message = buildJoinpoint(joinpoint);
		message += &quot;메서드 실행 종료&quot;;
		long end = System.currentTimeMillis();
        
		long duration = end - start;
		log.info(&quot;실행 시간 : &quot; + duration + &quot; 밀리초&quot;);
	}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 구현된 LoggingAspect 클래스를 관점 클래스로 만들기 위해 Spring context 를 지정한&amp;nbsp; xml 파일에 프록시 bean을 설정해서 @AspectJ 어노테이션이 지정된 bean을 프록시 어드바이스로 변환해야 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래처럼&amp;nbsp;&amp;lt;aop:aspectj-autoproxy/&amp;gt; 태그를 이용합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1673956430002&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&amp;gt;
&amp;lt;beans xmlns=&quot;http://www.springframework.org/schema/beans&quot;
	xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
	xmlns:context=&quot;http://www.springframework.org/schema/context&quot;
	xmlns:aop=&quot;http://www.springframework.org/schema/aop&quot;
	xsi:schemaLocation=&quot;http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd
		http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.1.xsd&quot;&amp;gt;
	&amp;lt;context:component-scan base-package=&quot;com.ensoa.order&quot;/&amp;gt;	
	&amp;lt;aop:aspectj-autoproxy/&amp;gt;
&amp;lt;/beans&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;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Advice에 매개 변수 전달&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;업무 로직을 구현한 메서드를 호출할 때 매개변수를 advice에서 가로채기 위해 매개 변수를 전달할 필요가 있을 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래 처럼 pointcut을 지정하는 execution() 표현식에서 매개변수를 지정해주고 사용합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1673956913068&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;	// 매개변수 포인트 컷
	@Pointcut(&quot;execution(* com.aacii.ex.service.*.update*(com.aacii.ex.domain.Product))&quot; + &quot; &amp;amp;&amp;amp; args(product)&quot;)
	public void updateLogging(Product product) {}    
    
	// 매개변수가 필요한 advice
	@Before(&quot;updateLogging(customer)&quot;)
	public void logBeforeUpdate(JoinPoint joinpoint, Product product) {
		String message = buildJoinpoint(joinpoint);
		message += &quot;메서드 실행 시작&quot;;
		log.info(message);
	}&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;&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;&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;&amp;nbsp;&lt;/p&gt;</description>
      <category>DEV&amp;amp;OPS/Java</category>
      <category>advice</category>
      <category>AOP</category>
      <category>aspect</category>
      <category>AspectJ</category>
      <category>JoinPoint</category>
      <category>PointCut</category>
      <category>관점지향</category>
      <category>스프링</category>
      <category>자바</category>
      <author>ALEPH.GEM</author>
      <guid isPermaLink="true">https://aacii.tistory.com/336</guid>
      <comments>https://aacii.tistory.com/336#entry336comment</comments>
      <pubDate>Wed, 5 Nov 2025 11:31:48 +0900</pubDate>
    </item>
    <item>
      <title>Spring 주요 어노테이션</title>
      <link>https://aacii.tistory.com/325</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;Spring bean을 XML로 관리 할 수 있지만, bean객체가 많아지면 XML 설정도 많아져 불편해집니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 나온 방법이 auto wiring(bean 연결) 과 annotation wiring(bean 연결) 입니다.&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;annotation wiring&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;어노테이션 와이어링을 사용하기 위해서는 context를 관리하는 XML 설정 파일에 context 네임스페이스를 추가해야 합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1673613961925&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&amp;gt;
&amp;lt;beans xmlns=&quot;http://www.springframework.org/schema/beans&quot;
	xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
	xmlns:context=&quot;http://www.springframework.org/schema/context&quot;
	xsi:schemaLocation=&quot;http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd&quot;&amp;gt;
	&amp;lt;context:component-scan base-package=&quot;컴포넌트를 스캔할 패키지 경로(예:net.aacii.service)&quot;/&amp;gt;
&amp;lt;/beans&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;lt;context:component-scan base-package=&quot;net.aacii.service&quot; /&amp;gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 패키지 이름을 component-scan 으로 지정해주면 Spring이 자동으로 bean을 스캔해서 발견해줍니다.&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;h3 data-ke-size=&quot;size23&quot;&gt;@Autowired&amp;nbsp;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Spring의 기본 의존성 주입을 위한 어노테이션입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;필드, 생성자, setter 메서드에 사용할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;타입 와이어링을 시도 한 후 실패하면 이름 와이어링으로 후보 bean을 찾습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1673614384541&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public class CustomerSerivceImpl implements CustomerService{
    @Autowired
    private CustomerRepository repository;
    //...
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;와이어링 할 bean이 없는 경우&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;@Autowired(reqired=false)&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;를 지정하면 null 값을 허용하게됩니다.&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;아래와 같이 pom.xml에 dependency를 추가하면 @Inject 어노테이션으로 @Autowired 를 대체 할 수 있습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1673615324681&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;dependency&amp;gt;
    &amp;lt;groupId&amp;gt;javax.inject&amp;lt;/groupId&amp;gt;
    &amp;lt;artifactId&amp;gt;javax.inject&amp;lt;/artifactId&amp;gt;
    &amp;lt;version&amp;gt;1&amp;lt;/version&amp;gt;
&amp;lt;/dependency&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;또한 아래와 같이 pom.xml에 dependency를 추가하면 @Resource 어노테이션으로 @Autowired를 대체 할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이것은 JNDI 리소스 와이어링 방식입니다.&lt;/p&gt;
&lt;pre id=&quot;code_1673615707501&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;dependency&amp;gt;
    &amp;lt;groupId&amp;gt;javax.annotation&amp;lt;/groupId&amp;gt;
    &amp;lt;artifactId&amp;gt;jsr250-api&amp;lt;/artifactId&amp;gt;
    &amp;lt;version&amp;gt;1.0&amp;lt;/version&amp;gt;
&amp;lt;/dependency&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;@Component&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 클래스가 Spring bean을 명시하는 범용 어노테이션입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 때 클래스명의 첫 글자를 소문자로 한 이름이 default Spring bean의 이름입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약 이 Spring bean의 이름을 바꾸고 싶으면 아래 처럼 괄호안에 직접 지정해주면 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;@Component(&quot;바꿀이름&quot;)&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;@Repository&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 클래스가 데이터를 엑세스하는 repository 즉, DAO 클래스를 명시합니다. 예를 들어&lt;/p&gt;
&lt;pre id=&quot;code_1673616068506&quot; class=&quot;groovy&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;@Repository
public class MemberDAOImpl implements MemberDAO {
	@Inject
	private SqlSession sqlSession; 
    ...
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;@Service&lt;/h3&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;h3 data-ke-size=&quot;size23&quot;&gt;@Controller&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;클래스가 MVC 패턴에서 컨트롤러임을 명시합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;컨트롤러는 각족 Request로부터 parameter를 전달 받고 다양한 데이터 타입을 리턴 할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;주로 문자열, 객체, 기본 자료형, JSON(ResponseEntity) 들을 리턴해 뷰에 전달해줍니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;@RestController 으로 지정하면 REST방식의 처리를 위한 컨트롤러로 사용할 수있습니다.&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;@GetMapping 또는 PostMapping 또는 PutMapping ...&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Http 전송 method 방식에 따라 컨트롤러의 메소드를 다르게 지정해 줄 수 있습니다.&amp;nbsp;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1762322359705&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;    @GetMapping(&quot;/list&quot;)
    public void listGET(){
		...
    }&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;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;@RequestMapping&lt;/h3&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;컨트롤러에서 지정하는 어노테이션으로, 특정 요청 URI에 매칭되는 클래스나 메소드임을 명시합니다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;이 어노테이션은 GET/POST 둘 다 지원합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1762322407041&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;java&quot;&gt;&lt;code&gt;@Controller
@RequestMapping(&quot;/sample&quot;)
public class SampleController {
    @RequestMapping(&quot;/list&quot;)
    public void list(){
        ...
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;이렇게 지정하면 URL이 http://호스트:포트/컨텍스트루트/sample/list 으로 컨트롤러 실행이 가능합니다.&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;h3 data-ke-size=&quot;size23&quot;&gt;@RequestParam&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;request 의 파라메터 중에서 특정 parameter를 찾습니다.&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;@RequestHeader&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;request에서 HTTP헤더 정보를 추출합니다.&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;@ResponseBody&lt;/h3&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;이 어노테이션이 적용된 메서드에서는 리턴되는 데이터 타입이 HTTP response로 전송 됩니다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;예를 들어 아래처럼 JSON을 리턴하도록 사용할 수 있습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1762322501591&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;java&quot;&gt;&lt;code&gt;	@RequestMapping(&quot;/doJSON&quot;)
	public @ResponseBody ProductVO doJSON() {
		ProductVO vo = new ProductVO(&quot;샘플제품&quot;,30000);
		return vo; //JAVA 객체가 JSON으로 변환되어 리턴 됨.
	}&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;주로 REST 방식의 컨트롤러에서 사용됩니다.&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;@PathVariable&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;URI에서 경로중의 일부를 변수로 삼아 처리하기 위해 사용합니다.&amp;nbsp;&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;@CookieValue&lt;/h3&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;h3 data-ke-size=&quot;size23&quot;&gt;@ModelAttribute&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 객체를 뷰까지 전달 합니다. 예를 들어 아래처럼&lt;/p&gt;
&lt;pre id=&quot;code_1671004028305&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;	@RequestMapping(&quot;doC&quot;)
	public String doC(@ModelAttribute(&quot;msg&quot;) String msg) {
		logger.info(&quot;doC is called.&quot;);
		return &quot;doC&quot;;
	}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;라고 했을 때 request시 msg라는 이름의 parameter를 메서드 내에서 String msg로 처리하고 뷰(jsp)에 msg라는 이름의 response parameter로 전달 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;스프링MVC에서 컨트롤러, 서비스, DAO, View 사이에 데이터를 전달할 때 기본적으로 동일한 방식으로 데이터를 규격화 해서 전달할 필요가 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;서블릿 방식에는 request.setAttribute() 를 통해서 데이터를 담아서 View까지 전달했지만 스프링MVC에서는 Model이라는 특별한 객체를 이용해서 처리합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를들어 컨트롤러 클래스에서 메소드를 아래 처럼 작성했다고 합시다.&lt;/p&gt;
&lt;pre id=&quot;code_1762316045974&quot; class=&quot;aspectj&quot; style=&quot;background-color: #f8f8f8; color: #383a42;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;java&quot;&gt;&lt;code&gt;    @GetMapping(&quot;/ex&quot;)
    public void ex4(Model model){
        model.addAttribute(&quot;message&quot;, &quot;hello world!&quot;);  //Model 객체에 속성을 추가해서 뷰까지 전달
    }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;model 객체에 &quot;message&quot; 를 키로 &quot;hello world!&quot; 라는 값을 가지는 Attribute를 추가해서 view(jsp 등)에 전달하여 EL이나 JSTL 등으로 접근할 수 있습니다.&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1762316045975&quot; class=&quot;dust&quot; style=&quot;background-color: #f8f8f8; color: #383a42;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;html&quot;&gt;&lt;code&gt;&amp;lt;%@ page contentType=&quot;text/html;charset=UTF-8&quot; language=&quot;java&quot; %&amp;gt;
&amp;lt;html&amp;gt;
&amp;lt;head&amp;gt;
    &amp;lt;title&amp;gt;Hello page&amp;lt;/title&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
    &amp;lt;h2&amp;gt;${message}&amp;lt;/h2&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;컨트롤러에서 Model 클래스 대신 DTO클래스로 생성된 인스턴스 객체들을 전달해도 마찬가지로 view에서 DTO 객체를 접근할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기본적으로 클래스 이름의 첫글자를 소문자로 바꾼 이름으로 접근할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그렇지만 컨트롤러에서 파라메터 전달 시 @ModelAttribute(&quot;바꾼객체이름&quot;) 을 사용해서 DTD객체의 이름을 바꿔서 view에 전달할 수도 있습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1762316045976&quot; class=&quot;less&quot; style=&quot;background-color: #f8f8f8; color: #383a42;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;java&quot;&gt;&lt;code&gt;@GetMapping(&quot;/ex&quot;)
public void ex(@ModelAttribute(&quot;dto&quot;) SomeDTO someDTO){
    ...
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이러면 view에서 ${dto} 라는 이름의 객체로 접근이 가능합니다.&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;h3 data-ke-size=&quot;size23&quot;&gt;@SessionAttribute&lt;/h3&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;h3 data-ke-size=&quot;size23&quot;&gt;@InitBinder&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;parameter를 수집해서 객체로 만들 경우에 커스터마이징 합니다.&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;@RequestBody&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;request문자열이 그대로 파라미터로 전달됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉, URI 경로에서 원하는 데이터를 추출합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;@ModelAttribute와 유사하지만 JSON 데이터를 객체로 변환해주는 용도입니다.&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;&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;&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;&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;&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;</description>
      <category>DEV&amp;amp;OPS/Java</category>
      <category>annotation</category>
      <category>spring</category>
      <category>스프링</category>
      <category>애노테이션</category>
      <category>어노테이션</category>
      <author>ALEPH.GEM</author>
      <guid isPermaLink="true">https://aacii.tistory.com/325</guid>
      <comments>https://aacii.tistory.com/325#entry325comment</comments>
      <pubDate>Wed, 5 Nov 2025 11:31:32 +0900</pubDate>
    </item>
    <item>
      <title>Spring bean</title>
      <link>https://aacii.tistory.com/334</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;Spring bean&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;스프링 프레임워크가 관리하는 클래스들의 인스턴스 객체들을 Spring bean 이라고 합니다.&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;h3 data-ke-size=&quot;size23&quot;&gt;Spring bean 설정 방법&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;XML로 설정 할 때에는 아래 처럼 설정합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1673526821554&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&amp;gt;
&amp;lt;beans xmlns=&quot;http://www.springframework.org/schema/beans&quot;
	xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
	xsi:schemaLocation=&quot;http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd&quot;&amp;gt;
	&amp;lt;bean id=&quot;bean객체를식별하는id값&quot; class=&quot;bean객체가정의된클래스의패키지경로&quot; /&amp;gt;
&amp;lt;/beans&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;어노테이션을 이용해서 설정할 때에는 아래처럼 클래스 위에 @Configuration 어노테이션을 설정하고, 메서드 위에는 @Bean 어노테이션을 설정해 줍니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;패키지 경로는 net.aacii.app 으로 가정합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1673527165926&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import net.aacii.app.service.SampleService;
import net.aacii.app.service.SampleServiceImpl;

@Configuration
public class AppConfig {
	@Bean
	SampleService sampleService() {
		return new SampleServiceImpl();
	}
}&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;h3 data-ke-size=&quot;size23&quot;&gt;IoC 컨테이너&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Spring bean 인스턴스를 생성하기 위해 IoC 컨테이너를 먼저 생성해야 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;IoC컨테이너는 bean 인스턴스들간의 의존성을 관리합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ApplicationContext 인터페이스는 이러한 IoC 컨테이너의 인터페이스 입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ApplicationContext는 일반적으로 아래처럼 생성 할 수 있습니다. (beans.xml은 bean이 정의된 xml파일입니다.)&lt;/p&gt;
&lt;pre id=&quot;code_1673527679366&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;ApplicationContext ctx = new ClassPathXmlApplicationContext(&quot;beans.xml&quot;);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약 파일 시스템의 절대 경로를 지정한다면 아래 처럼 생성 할 수 있습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1673527790176&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;ApplicationContext ctx = new FileSystemXmlApplicationContext(&quot;src/main/java/beans.xml&quot;);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약 위의 예제 처럼 AppConfig class 파일로 IoC 컨테이너를 생성할 때는 아래처럼 할 수 있습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1673527885881&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;ApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig.class);&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;ApplicationContext에 bean 인스턴스가 생성될 때, 생성되는 Scope를 정할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;singleton은 ApplicationContext 하나 당 하나의 인스턴스를 생성합니다.(기본값)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;prototype은 getBean()메서드가 호출될 때마다 하나의 인스턴스를 생성합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;request는 HTTP request 영역 안에 인스턴스가 생성됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;session은 HTTP session 영역 안에 인스턴스가 생성됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;global-session은 전역 HTTP session 안에서 인스턴스가 생성됩니다.&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;예를 들어 xml의 경우&lt;/p&gt;
&lt;pre id=&quot;code_1673528493837&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;bean id=&quot;bean객체를식별하는id값&quot; class=&quot;bean객체가정의된클래스의패키지경로&quot; scope=&quot;prototype&quot; /&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;처럼 scope를 지정해 줄 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;클래스 파일을 사용하는 경우에는 @Scope 어노테이션으로 지정합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1673528586306&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;@Bean
@Scope(&quot;prototype&quot;)
SampleService sampleService(){
    return new SampleServiceImple();
}&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;h3 data-ke-size=&quot;size23&quot;&gt;Bean 인스턴스(객체) 의 생성 소멸&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;java에서 인스턴스가 생성 될 때 생성자가 호출되고 소멸할 때 소멸자가 호출됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;bean 인스턴스도 마찬가지 인데, 생성될 때 호출 되는 메서드와 소멸될 때 호출되는 메서드를 지정할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;xml 의 예)&lt;/p&gt;
&lt;pre id=&quot;code_1673528942199&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;bean id=&quot;bean객체를식별하는id값&quot; class=&quot;bean객체가정의된클래스의패키지경로&quot; init-method=&quot;init&quot; destroy-method=&quot;cleanUp&quot; /&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;class 의 예)&lt;/p&gt;
&lt;pre id=&quot;code_1673529057159&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public class SampleServiceImpl implements SampleService{
    public void init(){
    }
    public void cleanUp(){
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;팩토리 패턴의 예)&lt;/p&gt;
&lt;pre id=&quot;code_1673529347793&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;bean id=&quot;bean객체를식별하는id값&quot; class=&quot;bean객체가정의된클래스의패키지경로&quot; factory-mehtod=&quot;getInstance&quot; /&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1673529506704&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public class SampleServiceImpl implements SampleService{
    private SampleServiceImpl(){
    }
    private static class FactoryHolder{
        static SampleService instance = new SampleServiceImpl();
    }
    public static SampleService getInstance(){
    return FactoryHolder.instance;
    }
}&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;&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;&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>DEV&amp;amp;OPS/Java</category>
      <category>bean</category>
      <category>framework</category>
      <category>Java</category>
      <category>spring</category>
      <category>빈</category>
      <category>스프링</category>
      <category>자바</category>
      <author>ALEPH.GEM</author>
      <guid isPermaLink="true">https://aacii.tistory.com/334</guid>
      <comments>https://aacii.tistory.com/334#entry334comment</comments>
      <pubDate>Wed, 5 Nov 2025 11:31:19 +0900</pubDate>
    </item>
    <item>
      <title>Spring MVC 프로젝트 구조</title>
      <link>https://aacii.tistory.com/338</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Spring MVC.png&quot; data-origin-width=&quot;1447&quot; data-origin-height=&quot;913&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bTxwng/btrWI2g8Sqk/EqaRvjkMCo0EdLtOBQZo30/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bTxwng/btrWI2g8Sqk/EqaRvjkMCo0EdLtOBQZo30/img.png&quot; data-alt=&quot;시퀀스 다이어그램&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bTxwng/btrWI2g8Sqk/EqaRvjkMCo0EdLtOBQZo30/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbTxwng%2FbtrWI2g8Sqk%2FEqaRvjkMCo0EdLtOBQZo30%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;1447&quot; height=&quot;913&quot; data-filename=&quot;Spring MVC.png&quot; data-origin-width=&quot;1447&quot; data-origin-height=&quot;913&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;시퀀스 다이어그램&lt;/figcaption&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;h3 data-ke-size=&quot;size23&quot;&gt;Spring MVC 프로젝트 구조 설명&lt;/h3&gt;
&lt;div&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;src/main/java/ : 자바 소스 경로&lt;/li&gt;
&lt;li&gt;src/main/resources/ : 실행시 자동 참고되는 경로(주로 설정파일, log4j.xml 등등)&lt;/li&gt;
&lt;li&gt;src/test/java/ : 테스트 자바 코드 경로&lt;/li&gt;
&lt;li&gt;src/test/resources/ : 테스트 관련 설정 파일 경로&lt;/li&gt;
&lt;li&gt;src/webapp/WEB-INF/spring/appServlet/ : sevlet-context.xml 외 spring 설정 파일&lt;/li&gt;
&lt;li&gt;src/webapp/WEB-INF/spring/&amp;nbsp; : root-context.xml 외 spring 설정 파일&lt;/li&gt;
&lt;li&gt;src/webapp/WEB-INF/views/&amp;nbsp; : MVC 패턴 중 view 페이지(jsp) 들이 위치 한 경로&lt;/li&gt;
&lt;li&gt;src/webapp/WEB-INF/&amp;nbsp; : tomcat의 web.xml 파일 위치&lt;/li&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;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;DispatcherServlet (FrontController)&lt;/h3&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;기존 웹 어플리케이션 개발은 HttpServlet을 상속하는 클래스를 만들고 doGet()이나 doPost()메서드를 구현하고 HttpServletRequest에서 매개변수를 추출하고 비지니스 로직(process)를 실행하고 반환될 정보를 HttpServletResponse에 담아서 반환합니다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;이 때, 비지니스 로직을 제외하고 나머지 작업들은 반복해서 해야하는 작업이기 때문에 이 반복작업을 대신 해주는 서블릿이 DispatcherServlet입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;DispatcherServlet은 web.xml 에서 등록합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1674128330137&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;	&amp;lt;servlet&amp;gt;
		&amp;lt;servlet-name&amp;gt;appServlet&amp;lt;/servlet-name&amp;gt;
		&amp;lt;servlet-class&amp;gt;org.springframework.web.servlet.DispatcherServlet&amp;lt;/servlet-class&amp;gt;
		&amp;lt;init-param&amp;gt;
			&amp;lt;param-name&amp;gt;contextConfigLocation&amp;lt;/param-name&amp;gt;
			&amp;lt;param-value&amp;gt;/WEB-INF/spring/appServlet/servlet-context.xml&amp;lt;/param-value&amp;gt;
		&amp;lt;/init-param&amp;gt;
		&amp;lt;load-on-startup&amp;gt;1&amp;lt;/load-on-startup&amp;gt;
	&amp;lt;/servlet&amp;gt;
    
	&amp;lt;servlet-mapping&amp;gt;
		&amp;lt;servlet-name&amp;gt;appServlet&amp;lt;/servlet-name&amp;gt;
		&amp;lt;url-pattern&amp;gt;/&amp;lt;/url-pattern&amp;gt;
	&amp;lt;/servlet-mapping&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;DispatcherServlet은 WebApplicationContext를 생성합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;WebApplicationContext는 bean 관리, Controller, HandlerMapping, ViewResolver 를 포함합니다.&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;h3 data-ke-size=&quot;size23&quot;&gt;WebApplicationContext&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;어플리케이션 전체 관련 bean은 root-context.xml에서 관리합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;데이터 소스 bean, 트랜잭션 bean, 서비스 bean, VO bean 등을 등록합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;web.xml에 ContextLoaderListener는 어플리케이션 컨텍스트를 시작하고 종료시킵니다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1674131726179&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;	&amp;lt;context-param&amp;gt;
		&amp;lt;param-name&amp;gt;contextConfigLocation&amp;lt;/param-name&amp;gt;
		&amp;lt;param-value&amp;gt;/WEB-INF/spring/root-context.xml&amp;lt;/param-value&amp;gt;
	&amp;lt;/context-param&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;root-context를 등록하기 위해서는 web.xml에 이벤트 리스너를 등록해야 합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1674131754639&quot; class=&quot;xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;	&amp;lt;listener&amp;gt;
		&amp;lt;listener-class&amp;gt;org.springframework.web.context.ContextLoaderListener&amp;lt;/listener-class&amp;gt;
	&amp;lt;/listener&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;servlet-context.xml&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;서블릿 관련 bean은 servlet-context.xml 에서 관리합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;컨트롤러, 핸들러 매핑, 뷰리졸버 등을 관리하는 bean 을 등록 합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1674130048813&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&amp;gt;
&amp;lt;beans:beans xmlns=&quot;http://www.springframework.org/schema/mvc&quot;
	xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
	xmlns:beans=&quot;http://www.springframework.org/schema/beans&quot;
	xmlns:context=&quot;http://www.springframework.org/schema/context&quot;
	xsi:schemaLocation=&quot;http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
		http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd&quot;&amp;gt;

	&amp;lt;!-- DispatcherServlet Context: defines this servlet's request-processing infrastructure --&amp;gt;
	
	&amp;lt;!-- 어노테이션 와이어링 --&amp;gt;
	&amp;lt;annotation-driven /&amp;gt;

	&amp;lt;!-- URL로 오는 모든 정적인 리소스 파일들 경로  --&amp;gt;
	&amp;lt;resources mapping=&quot;/resources/**&quot; location=&quot;/resources/&quot; /&amp;gt;

	&amp;lt;!-- 뷰 리졸버 --&amp;gt;
	&amp;lt;beans:bean class=&quot;org.springframework.web.servlet.view.InternalResourceViewResolver&quot;&amp;gt;
		&amp;lt;beans:property name=&quot;prefix&quot; value=&quot;/WEB-INF/views/&quot; /&amp;gt;
		&amp;lt;beans:property name=&quot;suffix&quot; value=&quot;.jsp&quot; /&amp;gt;
	&amp;lt;/beans:bean&amp;gt;
	
	&amp;lt;!-- 컨트롤러 컴포넌트 스캔 패키지 --&amp;gt;
	&amp;lt;context:component-scan base-package=&quot;com.aacii.order&quot; /&amp;gt;
	
	
	
&amp;lt;/beans:beans&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&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;/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;</description>
      <category>DEV&amp;amp;OPS/Java</category>
      <category>MVC</category>
      <category>spring</category>
      <category>구조</category>
      <category>스프링</category>
      <category>자바</category>
      <category>프레임워크</category>
      <author>ALEPH.GEM</author>
      <guid isPermaLink="true">https://aacii.tistory.com/338</guid>
      <comments>https://aacii.tistory.com/338#entry338comment</comments>
      <pubDate>Wed, 5 Nov 2025 11:30:08 +0900</pubDate>
    </item>
    <item>
      <title>Spring 의존성 주입과 제어의 역전</title>
      <link>https://aacii.tistory.com/302</link>
      <description>&lt;h3 style=&quot;color: #000000;&quot; data-ke-size=&quot;size23&quot;&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;그런 상황에 대응하기 위해 스프링에서는 인터페이스를 이용해 클래스간 느슨한 결합을 하도록해서 의존&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;h3 data-ke-size=&quot;size23&quot;&gt;의존성 주입(Dependency Injection)&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;의존성 주입은 디자인 패턴으로 제어의 역전(Inversion of Control)을 구현하기 위한 방법중의 하나입니다.&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;이처럼 클래스들은 서로 연결되어 있어서 의존성(dependency)이 강합니다.&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;IoC 컨테이너는 시스템의 모든 인스턴스 객체를 관리하고 인스턴스 객체들 사이의 의존성이 있으면 주입하는 일을 담당합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Spring에서는 XML 설정이나 자바 클래스내 Config 설정등 다향한 방법을 이용해 필요한 객체들을 찾아서 사용할 수 있도록 이를 구현하고 있습니다.&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;h3 data-ke-size=&quot;size23&quot;&gt;일반적인 자바 객체의 생성과 초기화&lt;/h3&gt;
&lt;pre id=&quot;code_1661320397180&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public class Service{
    private final Persistence persistence;
    
    public Service(){
    	this.persistence = new Persistence();
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1661322326834&quot; class=&quot;routeros&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public static void main(String[] args){
    Service service = new Service();
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;외부 클래스의 생성자를 호출하여 객체를 생성하여 초기화하는 일반적인 방법입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 경우 Persistence 클래스에 의존(dependent)하고 있어서 Persistence 클래스가 없다면 제 기능을 하지 못합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Service클래스는 Persistence클래스에 의존하고 있으며, Service클래스가 Persistence 객체를 생성하고 관리합니다.&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;h3 data-ke-size=&quot;size23&quot;&gt;Setter를 이용한 의존성 주입 예제&lt;/h3&gt;
&lt;pre id=&quot;code_1661322642660&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public class Service{
    private final IPersistence persistence;
    
    public void setIPersistence(IPersistence persistence){
        this.persistence = persistence;
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1661322757777&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public static void main(String[] args){
    IPersistence persistence = new Persistence();
    Service service = new Service();
    service.setIPersistence(persistence);
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일반 적인 방법과 의존성 주입의 차이점은 인터페이스를 이용한다는 점과 객체를 외부에서 생성해서 setter(혹은 생성자)로 객체를 전달(주입)한다는 점입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이러한 의존성 주입을 관리해주는 컨테이너 중 하나가 바로 스프링(Spring) 프레임워크입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;생성자 주입 방식&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;Spring3 이후 부터는 생성자 주입 방식으로 의존성 주입을 더 많이 활용합니다.&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;1. 주입받아야 하는 객체의 변수는 final로 작성합니다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;2. 생성자를 이용해서 해당 병수를 생성자의 파라미터로 지정합니다.&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;이 생성자 주입 방식은 객체를 생성할 때 문제가 발생하는지 미리 확인할 수 있기 때문에 Setter를 이용한 주입 방식 보다 선호됩니다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;Lombok 라이브러리를 사용하면 @RequiredArgsConstructor 라는 어노테이션을 이용해서 생성자를 자동으로 작성 할수 있게 해주기 때문에 편리합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1762254637110&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import lombok.RequiredArgsConstructor;
import lombok.ToString;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
@ToString
@RequiredArgsConstructor	//생성자 주입 방식 
public class SampleService {
    @Autowired
    private final SampleDAO sampleDAO;  //주입 받아야 하는 변수를 final으로
}&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;h3 data-ke-size=&quot;size23&quot;&gt;스프링 프레임워크(Spring framework)&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로젝트의 규모가 커질수록 관리해야 하는 객체들이 많아질 수록 의존성 주입 컨테이너를 통해 객체의 생성과 관리하는 방법이 효율적이게 됩니다.&lt;/p&gt;
&lt;pre id=&quot;code_1661324473237&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public class MyService{
    Service service;
    ShareService shareService;
    NotiService notiService;
    ScheduledService scheduledService;
}

public class ShereService{
    UserService userService;
    EventService eventService;
    SharePersistence persistence;
}

public class NotiService{
    EventService eventService;
    UserService userService;
    NotiPersistence persistence;
}

public class SharePersistence{
    JDBCConnection connection;
    ...
}&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1661326087302&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;JDBCConnection connection = new JDBCConnection();
Service service = new Service();
UserService userService = new UserService();
EventService eventService = new EventService();
NotiPersistence notiPersistence = new NotiPersistence(connection);
SharePersistence sharePersistence = new SharePersistence(connection);
ShareService shareService = new ShareService(userService, eventService, sharePersistence);
NotiServie notiService = new NotiService(userService, eventSerivce, sharePersistence);
MyService myService = new MyService(Service, shareService, notiService, new ScheduledService());&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 의존하는 객체들이 많아질 수록 객체 관리가 어려워지게 되는데 Spring의 어노테이션, xml, class 를 이용해서 bean객체간의 의존성을 명시할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;어플리케이션(WAS) 시작시 spring Ioc컨테이너가 객체를 생성해주고 관리도 해주게 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 예제를 Spring 어노테이션을 이용해서 아래 예제처럼 의존성을 명시할 수 있습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1661328052766&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;@Service
public class MyService{
    @Autowired Service service;
    @Autowired ShareService shareService;
    @Autowired NotiService notiService;
    @Autowired ScheduledService scheduledService;
}

@Service
public class ShareService{
    @Autowired UserService userService;
    @Autowired EventService eventService;
    @Autowired SharePersistence persistence;
}

@Service
public clasee NotiService{
    @Autowired EventService eventService;
    @Autowired UserService userService;
    @Autowired NotiPersistence persistence;
}

@Service
public class SharePersistence{
    @Autowired JDBCConnection connection;
    ...
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 예제 처럼 의존관계를 명시해주면 일일이 new 해서 객체를 생성하는 작업을 하지 않아도 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이러한 작업을 ApplicationContext 객체가 대신 해주게 됩니다.&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;&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;&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;&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>DEV&amp;amp;OPS/Java</category>
      <category>Di</category>
      <category>IOC</category>
      <category>Java</category>
      <category>spring</category>
      <category>디자인 패턴</category>
      <category>스프링</category>
      <category>스프링 부트</category>
      <category>의존성 주입</category>
      <category>제어의 역전</category>
      <author>ALEPH.GEM</author>
      <guid isPermaLink="true">https://aacii.tistory.com/302</guid>
      <comments>https://aacii.tistory.com/302#entry302comment</comments>
      <pubDate>Tue, 4 Nov 2025 21:02:59 +0900</pubDate>
    </item>
    <item>
      <title>WSL 2 네트워크</title>
      <link>https://aacii.tistory.com/448</link>
      <description>&lt;h2 style=&quot;color: #000000;&quot; data-ke-size=&quot;size26&quot;&gt;WSL2 네트워크&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;WSL 에서는 윈도우의 물리적 네트워크 인터페이스를 사용하는데 반해 WSL 2는 경량 VM에서 리눅스 커널이 실행됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가상화된 네트워크 어댑터가 있어서 자체 IP 주소가 할당되어 네트워크를 이용할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;윈도우에서 PowerShell을 실행시키고 다음 명령어를 입력하면 네트워크 어댑터 정보를 확인할 수 있습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1760878145599&quot; class=&quot;mathematica&quot; style=&quot;background-color: #f8f8f8; color: #383a42;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;Get-NetAdapter *WSL* | Format-List&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;IP 주소를 확인하려면 PowerShell에서 다음과 같이 입력합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1760878145599&quot; class=&quot;mathematica&quot; style=&quot;background-color: #f8f8f8; color: #383a42;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;Get-NetAdapter *WSL* | Get-NetIPAddress | Format-List IPAddress&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;h3 data-ke-size=&quot;size23&quot;&gt;우분투 배포판의 IP&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;WSL의 우분투 배포판의 IP는 NAT 가상 네트워크에 속해 있으므로 터미널을 열고 ifconfig으로 알아냅니다.&lt;/p&gt;
&lt;pre id=&quot;code_1761477917523&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;ifconfig&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;우분투 터미널 내에서 윈도우 호스트의 IP를 알아내려면 우분투 터미널에서 /etc/resolv.conf 파일을 확인합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1761477984900&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;cat /etc/resolv.conf&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러면 출력되는 내용 중에서 nameserver로 되어있는 IP가 윈도우의 호스트 IP입니다.&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;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;윈도우에서 WSL 우분투 배포판으로 포트 포워딩 하는 방법&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;윈도우에서 WSL 우분투 배포판의 애플리케이션에 접속할 때 포트 포워딩을 이용할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;포트 번호는 애플리케이션마다 다르지만 여기서는 postgresql의 기본 포트인 5432 포트를 기준으로 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;윈도우 파워셸에서 다음을 실행해 주세요.&lt;/p&gt;
&lt;pre id=&quot;code_1761134780047&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# WSL의 내부 IP 주소를 172.19.120.200 이라 가정합니다.

# 윈도우즈 파워쉘의 네트워크 관리 기능인 netsh 명령어를 이용하여 5432 포트를 포워딩 설정합니다.
netsh interface portproxy add v4tov4 listenport=5432 listenaddress=0.0.0.0 connectport=5432 connectaddress=172.19.120.200

# 다시 netsh 명령어로 방화벽 규칙을 추가합니다.
netsh advfirewall firewall add rule name=&quot;WSL PostgreSQL Port Forwarding&quot; dir=in action=allow protocol=TCP localport=5432&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div id=&quot;main-content&quot; style=&quot;background-color: #ffffff; color: #172b4d; text-align: start;&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&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;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;name=&quot;WSL PostgreSQL Port Forwarding&quot;&lt;/b&gt;: 규칙의 이름을 지정합니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;dir=in&lt;/b&gt;: 규칙의 방향을 지정하여, direction=inbound 즉, 들어오는 트래픽에 적용합니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;action=allow&lt;/b&gt;: 트래픽을 허용합니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;protocol=TCP&lt;/b&gt;: 규칙이 TCP 프로토콜에 적용됩니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;localport=5432&lt;/b&gt;: 로컬 포트 5432로 향하는 트래픽에 적용됩니다.&lt;/span&gt;&lt;/li&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;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;Localhost 포트 포워딩&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;호스트(윈도우)의 웹 브라우저에서 WSL 우분투의 톰캣 서버에 접속하려면 localhost 포트 포워딩을 이용 할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;최신 WSL2은 기본적으로 localhost 포트 포워딩을 제공합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를들어 WSL 우분투의 톰캣 서버를 8080 포트로 실행했다면 윈도우(호스트)의 브라우저 주소창에 http://localhost:8080 을 입력하면 우분투의 톰캣 서버로 자동 연결됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;네트워크가 NAT인경우 윈도우(호스트)와 WSL 배포판 우분투의 IP가 다르지만 locahost로 접근하는 경우 자동 포트 포워딩을 해주는 기능을 이용하는 것입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div id=&quot;likes-and-labels-container&quot; style=&quot;background-color: #ffffff; color: #172b4d; text-align: start;&quot;&gt;
&lt;div style=&quot;color: #3f4c66;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;Mirrored 네트워킹&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가상 네트워크(NAT)를 사용할 때 우분투 배포판을 재시작 하는 경우 IP가 변경될 수도 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그럴때마다 위에서 설정했던 포트 포워딩이랑 방화벽 설정을 해야할 수도 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 문제를 해결하는 방법이 NAT를 사용하지 않고 Mirrored 모드 네트워킹을 사용하는 것입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 모드는 WSL이 호스트(윈도우)의 네트워크 인터페이스를 그대로 복제(미러링)해서 사용하는 방식입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 모드는 윈도우즈11 의 22H2 이후 버전에서만 지원합니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Mirrored 네트워킹의 장점은 다음과 같습니다..&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;WSL이 윈도우와 동일한 네트워크 대역의 IP를 갖게되어서 IP를 고정 할 수 있습니다.&amp;nbsp;&lt;/li&gt;
&lt;li&gt;포트 포워딩 설정을 할 필요가 없어집니다.&amp;nbsp;&lt;/li&gt;
&lt;li&gt;윈도우 방화벽의 규칙이 WSL에도 동일하게 적용됩니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;Mirrored 네트워킹 설정 방법&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 윈도우 탐색기 주소창에 %USERPROFILE% 을 입력하면 사용자 홈 디렉토리로 이동합니다.&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. 해당 폴더에서 .wslconfig 파일을 생성한 뒤 텍스트 편집기로 엽니다.&lt;span style=&quot;color: #f3c000;&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;3. 파일에 다음 내용을 추가해주거나 입력합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1762159155717&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;[wsl2]
networkingMode=mirrored&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;4. 파일을 저장합니다.&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;5. WSL을 종료합니다. 파워셸(powershell) 또는 명령프롬프트(cmd) 에서 다음과 같이 입력합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1762159246730&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;wsl --shutdown&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;6. 다시 WSL 우분투를 시작하면 새로운 네트워킹 모드로 실행되어 윈도우와 우분투의 IP가 동일하게 설정된 것을 확인할 수 있습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1762159335603&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;ifconfig&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;&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;&amp;nbsp;&lt;/p&gt;</description>
      <category>DEV&amp;amp;OPS/Linux &amp;amp; Cloud</category>
      <category>IP</category>
      <category>mirror 모드</category>
      <category>WSL 2</category>
      <category>네트워크</category>
      <category>포트 포워딩</category>
      <author>ALEPH.GEM</author>
      <guid isPermaLink="true">https://aacii.tistory.com/448</guid>
      <comments>https://aacii.tistory.com/448#entry448comment</comments>
      <pubDate>Mon, 3 Nov 2025 17:42:38 +0900</pubDate>
    </item>
    <item>
      <title>리스너(Listener) : 옵저버(observer) 패턴</title>
      <link>https://aacii.tistory.com/456</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;특정한 구독자(subscriber)들을 보관하고 있다가 이벤트를 발행(publish)하면 구독자들이 실행하는 방식입니다.&amp;nbsp;&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;ServletContext Listener&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;서블릿 API는 여러 이벤트에 맞는 리스너들을 인터페이스로 정의해두었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이를 이용해서 애플리케이션이 시작되거나 종료될 때 특정 작업을 수행하거나, session에 특정한 작업에 대한 감시와 처리, request에 특정한 작업에 대한 감시와 처리들을 할 수 있습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1762126154171&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import lombok.extern.log4j.Log4j2;
import javax.servlet.annotation.WebListener;

@WebListener
@Log4j2
public class W2AppListener implements javax.servlet.ServletContextListener {
    @Override
    public void contextInitialized(javax.servlet.ServletContextEvent sce) {
        log.info(&quot;Servlet initialized&quot;);
    }
    @Override
    public void contextDestroyed(javax.servlet.ServletContextEvent sce) {
        log.info(&quot;Servlet destroyed&quot;);
    }
}&lt;/code&gt;&lt;/pre&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;이 contextInitialized()와 contextDestroyed()에는 파라메터로 ServletContextEvent가 전달됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ServletContext는 웹 애플리케이션의 모든 공유자원들이 있는 공간이므로 여기에 저장된 정보들은 모든 컨트롤러나 JSP/EL 등에서 접근해서 사용할 수 있습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1762126598737&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;    @Override
    public void contextInitialized(javax.servlet.ServletContextEvent sce) {
        log.info(&quot;Servlet initialized&quot;);
        ServletContext servletContext = sce.getServletContext();
        //애플리케이션 전역에서 사용할 수 있는 정보 등록
        servletContext.setAttribute(&quot;appName&quot;, &quot;example&quot;);
    }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어 위처럼 servletContext에 setAttribute() 메소드를 이용해서 값을 설정한 다음 아래 예제처럼 컨트롤러나 jsp 같은 곳에서 활용할 수 있습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1762128340382&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException{
        ServletContext servletContext = req.getServletContext();
        log.info(&quot;[doGet()]&quot;+servletContext.getAttribute(&quot;appName&quot;));
}&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1762128469289&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;html&amp;gt;
&amp;lt;body&amp;gt;
&amp;lt;h2&amp;gt;${appName}&amp;lt;/h2&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&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;Spring framework에서도 웹 프로젝트에서 미리 로딩하는 작업을 처리할 때 ServletContextListener를 이용합니다.&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;h3 data-ke-size=&quot;size23&quot;&gt;세션 관련 리스너&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;서블릿 리스너 중에서는 HttpSession 관련 작업을 감시하는 리스너를 등록할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;HttpSessionListener나 HttpSessionAttributeListener 들이 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이를 이용해서 세션이 생성되거나 setAttribute()가 실행될 때 이를 감지할 수 있습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1762129296515&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import lombok.extern.log4j.Log4j2;
import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpSessionAttributeListener;
import javax.servlet.http.HttpSessionBindingEvent;

@WebListener
@Log4j2
public class LoginListener implements HttpSessionAttributeListener {
    @Override
    public void attributeAdded(HttpSessionBindingEvent event) {
        String name = event.getName();
        Object obj = event.getValue();
        if(name.equals(&quot;loginInfo&quot;)) {
            log.info(&quot;A user logged in.&quot;);
            log.info(obj);
        }
    }
}&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;&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;&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;&amp;nbsp;&lt;/p&gt;</description>
      <category>DEV&amp;amp;OPS/Java</category>
      <category>Java</category>
      <category>Listener</category>
      <category>Observer</category>
      <category>리스너</category>
      <category>서블릿</category>
      <category>옵저버 패턴</category>
      <author>ALEPH.GEM</author>
      <guid isPermaLink="true">https://aacii.tistory.com/456</guid>
      <comments>https://aacii.tistory.com/456#entry456comment</comments>
      <pubDate>Mon, 3 Nov 2025 09:22:23 +0900</pubDate>
    </item>
    <item>
      <title>Singleton Pattern 과 DeadLock</title>
      <link>https://aacii.tistory.com/75</link>
      <description>&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;싱글톤 패턴:&amp;nbsp;&lt;/b&gt;하나의 인스턴스만 사용하기 위한 디자인 패턴으로 스레드 풀링, 커넥션 풀링 등에서 주로 사용합니다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;ol style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&amp;nbsp;인스턴스를 생성할 때 참조 변수를 private static으로 합니다.&amp;nbsp;&lt;/li&gt;
&lt;li&gt;생성자를 private로 한다. 이는 외부에서 new로 인스턴스를 생성하지 못하게 합니다.&lt;/li&gt;
&lt;li&gt;인스턴스를 리턴하는 public static getInstance() 메서드를 제공합니다. 이 메서드 내부에서 인스턴스를 생성할 때 null 체크 후 생성해서 인스턴스를 리턴 해야 합니다.&lt;/li&gt;
&lt;li&gt;멀티스레드 환경에서는 위 getInstance메서드를 synchronized 해야 안전합니다. 하지만 전반적인 성능 저하 때문에 일반적으로 아래와 같은 패턴으로 코딩합니다.&lt;/li&gt;
&lt;/ol&gt;
&lt;div&gt;싱글톤패턴1&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;pre class=&quot;highlight smali&quot; style=&quot;background-color: #f8f8f8; border-radius: 10px; border: 1px solid #cccccc; box-sizing: inherit; color: rgba(0, 0, 0, 0.87); font-family: consolas, menlo, monaco, courier, monospace; font-size: 15px; line-height: 1.3; margin-bottom: 15px; overflow-x: auto; padding: 15px 20px; tab-size: 4; width: 802px;&quot;&gt;&lt;code&gt;public class InitializationOnDemandHolderIdiom {
 
 private InitializationOnDemandHolderIdiom () {}
 private static class Singleton {
  private static final InitializationOnDemandHolderIdiom instance = new InitializationOnDemandHolderIdiom();
 }
 
 public static InitializationOnDemandHolderIdiom getInstance () {
  System.out.println(&quot;create instance&quot;);
  return Singleton.instance;
 }
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;싱글톤패턴2&lt;/div&gt;
&lt;div&gt;
&lt;pre class=&quot;highlight routeros&quot; style=&quot;background-color: #f8f8f8; border-radius: 10px; border: 1px solid #cccccc; box-sizing: inherit; color: rgba(0, 0, 0, 0.87); font-family: consolas, menlo, monaco, courier, monospace; font-size: 15px; line-height: 1.3; margin-bottom: 15px; overflow-x: auto; padding: 15px 20px; tab-size: 4; width: 802px;&quot;&gt;&lt;code&gt;public enum EnumInitialization {
 INSTANCE;
 static String test = &quot;&quot;;
 public static EnumInitialization getInstance() {
  test = &quot;test&quot;;
  return INSTANCE;
 }
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;div&gt;이처럼 enum 열거형을 반환값으로 가지면서 대문자로 INSTANCE;를 선헌해주면 JVM에서 싱글톤 인스턴스를 보장해줍니다.&lt;/div&gt;
&lt;div&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;스레드 안전성(Thread-Safety)&lt;/b&gt;: 여러 스레드에서 동시에 접근해도 인스턴스가 여러 개 생성되지 않도록 보장합니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;직렬화(Serialization) 보장&lt;/b&gt;: 직렬화/역직렬화 과정에서도 싱글톤이 깨지지 않습니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;리플렉션(Reflection) 방어&lt;/b&gt;: 리플렉션을 통한 강제적인 인스턴스 생성을 막아줍니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;enum을 sigleton으로 만들면 new로 객체를 생성할 필요 없이 INSTANCE 상수를 직접 사용하면 됩니다.&lt;/p&gt;
&lt;pre id=&quot;code_1761989927045&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public class Main {
    public static void main(String[] args) {
        // 'new'로 생성하지 않고, INSTANCE를 직접 참조합니다.
        MySingleton singletonA = MySingleton.INSTANCE;
        singletonA.doSomething(); // &quot;싱글톤 인스턴스가 동작합니다.&quot;

        // 프로그램의 다른 어디에서 접근하더라도...
        MySingleton singletonB = MySingleton.INSTANCE;
        singletonB.anotherMethod(); // &quot;항상 동일한 인스턴스가 이 메서드를 실행합니다.&quot;

        // 두 참조는 항상 동일한 객체를 가리킵니다.
        if (singletonA == singletonB) {
            System.out.println(&quot;A와 B는 정확히 같은 인스턴스입니다.&quot;); 
        }
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;고전적인 1번 패턴 방법보다 enum을 사용한 2번 패턴을 더 많이 사용합니다.&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;멀티스레드 Deadlock 방지를 위한 고려 사항들&lt;/b&gt;&lt;/h2&gt;
&lt;div&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;멀티스레드에서 내부에서 호출하는 메서드 중에서 인스턴스의 멤버 변수에 접근할 때는 synchronized 해주어야한다.&lt;/li&gt;
&lt;li&gt;멀티스레드 환경에서는 singleton 패턴으로 인스턴스를 하나만 생성해서는 병목현상이 일어나므로 되도록 singleton 패턴을 안 쓰는 것이 좋다.&lt;/li&gt;
&lt;li&gt;서블릿 프로그램에서 서블릿 클래스에 멤버 변수를 정의하지 말라. 서블릿 인스턴스는 컨테이너에서 싱글톤 처럼 동작(한 번 생성한 인스턴스를 재활용)하므로 스레드 경합시 데이터 값을 보장할 수 없기 때문이다.&lt;/li&gt;
&lt;li&gt;오픈 호출: lock을 확보하지 않은 상태로 메서드 호출 하는 기법&lt;/li&gt;
&lt;li&gt;lock의 시간제한: 암묵적인 락 synchronized 말고 락 시간을 제한할 있는 Lock 클래스의 tryLock 메소드를 사용한다.&amp;nbsp;&lt;/li&gt;
&lt;li&gt;순환대기 (circular wait) 예방 : 프로그래밍에서 적용할 수 있는 현실적인 방법이다. 여러가지 아이디어가 있을 수 있지만 핵심은 lock을 걸어주는 타이밍을 잘 조정해 주어서 순환 대기가 발생하지 않게 하는 것이다.&lt;/li&gt;
&lt;li&gt;synchronized 동기화 블록 최소화&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;참고 URL&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://blog.seotory.com/post/2016/03/java-singleton-pattern&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://blog.seotory.com/post/2016/03/java-singleton-pattern&lt;/a&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;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthContent&quot; data-filename=&quot;0000.png&quot; data-origin-width=&quot;661&quot; data-origin-height=&quot;418&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cSPAYZ/btqESW5nyD4/xnPLTF3EkPD8Mc6twokX9K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cSPAYZ/btqESW5nyD4/xnPLTF3EkPD8Mc6twokX9K/img.png&quot; data-alt=&quot;DEV&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cSPAYZ/btqESW5nyD4/xnPLTF3EkPD8Mc6twokX9K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcSPAYZ%2FbtqESW5nyD4%2FxnPLTF3EkPD8Mc6twokX9K%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;661&quot; height=&quot;418&quot; data-filename=&quot;0000.png&quot; data-origin-width=&quot;661&quot; data-origin-height=&quot;418&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;DEV&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>DEV&amp;amp;OPS/Java</category>
      <category>dead lock</category>
      <category>Java</category>
      <category>Singleton Pattern</category>
      <category>멀티스레드</category>
      <category>자바</category>
      <author>ALEPH.GEM</author>
      <guid isPermaLink="true">https://aacii.tistory.com/75</guid>
      <comments>https://aacii.tistory.com/75#entry75comment</comments>
      <pubDate>Sat, 1 Nov 2025 18:39:23 +0900</pubDate>
    </item>
    <item>
      <title>Jenkins로 AWS에 배포</title>
      <link>https://aacii.tistory.com/455</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;AWS 계정생성&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://aws.amazon.com/ko/free&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://aws.amazon.com/ko/free&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1761969737777&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;무료 클라우드 컴퓨팅 서비스 - AWS 프리 티어&quot; data-og-description=&quot;AWS 프리 티어 제품 및 서비스를 통해 AWS 플랫폼, 제품 및 서비스를 무료로 체험해 볼 수 있습니다. AWS 프리 티어 서비스의 100가지 제품 및 서비스를 찾아보세요.&quot; data-og-host=&quot;aws.amazon.com&quot; data-og-source-url=&quot;https://aws.amazon.com/ko/free&quot; data-og-url=&quot;https://aws.amazon.com/ko/free/&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://aws.amazon.com/ko/free&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://aws.amazon.com/ko/free&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&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;무료 클라우드 컴퓨팅 서비스 - AWS 프리 티어&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;AWS 프리 티어 제품 및 서비스를 통해 AWS 플랫폼, 제품 및 서비스를 무료로 체험해 볼 수 있습니다. AWS 프리 티어 서비스의 100가지 제품 및 서비스를 찾아보세요.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;aws.amazon.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AWS프리티어로 무료 계정 생성을 합니다.&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;지원 플랜 선택은 무료로 선택하고 완료합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AWS 인스턴스를 생성하기 전에 AWS 계정 보안 설정을 참고해 주세요.&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;h2 data-ke-size=&quot;size26&quot;&gt;AWS 인스턴스 생성&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. AWS 콘솔에 로그인합니다.&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. EC2(Elastic Compute Cloud)를 이용하겠습니다. 콘솔에 로그인 버튼을 클릭한 후 AWS service 페이지에서 모든 서비스를 클릭해서 컴퓨팅&amp;gt; EC2를 선택합니다.&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;3. 표시된 EC2 대시보드에서 인스턴스 시작을 클릭해서 인스턴스 작성을 시작합니다.&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. AMI(Amazon Machine Image)를 선택하는데 여기서는 CentOS7을 기준으로 합니다. AWS Marketplace를 클릭해서 CentOS를 검색해서 CentOS7을 선택합니다.&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;5. 요금 안내가 표시되는데 프리 티어 사용 가능을 확인하고 Continue 버튼을 클릭합니다.&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;6. 인스턴스 유형을 요금이 발생하지 않는 t2.micro를 선택한 후 &quot;검토 및 시작&quot;을 클릭합니다.&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;7. 범용 SSD에서 부팅 화면에서는 권장 사항을 선택 후 다음을 클릭합니다.&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;8. 인스턴스 시작 검토 페이지에서 보안 그룹의 보안 그룹편집을 클릭해서 보안 그룹을 변경합니다.&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;9. 보안 그룹 할당에서 &quot;기존 보안 그룹 선택&quot;을 선택하고 이름이 default인 보안 그룹을 체크 후 검토 및 시작 버튼을 클릭합니다.&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. 보안 그룹이 변경된 것을 확인하고 시작 버튼을 클릭합니다.&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;11. 키 페어가 등록되어 있지 않으면 적절한 SSH 키를 생성해 줍니다. 이 키는 SSH로 접속할 때나 젠킨스에서 배포할 때 사용합니다. 키페어를 다운로드하여서 로컬 PC에 저장해 둡니다.&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;12. 키 페어가 다운로드된 후 인스턴스 시작 버튼을 클릭해서 인스턴스를 시작합니다.&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;13. 대기화면이 끝나면 '시작 상태'에 대한 설명 및 사용량, 리눅스 시스템에 접속하는 버 등을 알려주는 페이지가 나옵니다. 그 페이지에 있는 '인스턴스 보기'를 클릭합니다. 인스턴스 생성에 수 분 이상 소요될 수 있습니다.&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;h2 data-ke-size=&quot;size26&quot;&gt;보안 그룹 설정&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SSH로 AWS인스턴스에 접속이 가능하도록 '보안 그룹'을 설정합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;22번 포트에 인바운드 가능하게 설정합니다.&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;1. 좌측 메뉴에서 NETWORK &amp;amp; SECURITY &amp;gt; 보안 그룹을 클릭하고 그룹 이름이 'defaul'인 보안 그룹을 선택합니다. 그룹을 추가하지 않았다면 보안 그룹이 하나만 표시됩니다.&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 data-ke-size=&quot;size16&quot;&gt;3. 인바운드 규칙 편집 화면에서 SSH 접속용으로 22번 포트와 톰캣 접속용으로 8080 포트를 설정한 다음 저장을 클릭합니다.&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. 생성한 인스턴스에 SSH로 접속해서 톰캣을 설치합니다.&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;5. SSH 클라이언트는 없다면 PuTTY를 다운로드하여서 사용하십시오.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.chiark.greenend.org.uk/~sgtatham/putty/latest.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.chiark.greenend.org.uk/~sgtatham/putty/latest.html&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1761972547081&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;Download PuTTY: latest release (0.83)&quot; data-og-description=&quot;This page contains download links for the latest released version of PuTTY. Currently this is 0.83, released on 2025-02-08. When new releases come out, this page will update to contain the latest, so this is a good page to bookmark or link to. Alternativel&quot; data-og-host=&quot;www.chiark.greenend.org.uk&quot; data-og-source-url=&quot;https://www.chiark.greenend.org.uk/~sgtatham/putty/latest.html&quot; data-og-url=&quot;https://www.chiark.greenend.org.uk/~sgtatham/putty/latest.html&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://www.chiark.greenend.org.uk/~sgtatham/putty/latest.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.chiark.greenend.org.uk/~sgtatham/putty/latest.html&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&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;Download PuTTY: latest release (0.83)&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;This page contains download links for the latest released version of PuTTY. Currently this is 0.83, released on 2025-02-08. When new releases come out, this page will update to contain the latest, so this is a good page to bookmark or link to. Alternativel&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.chiark.greenend.org.uk&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;6. puttygen.exe를 실행해서 AWS엣 다운로드한 키 (.pem) 파일을 PuTTY용 ppk 파일로 변환합니다. puttygen화면에서 Actions&amp;gt; Load를 클릭한 뒤 파일 형식을 모든 파일로 변경 후 pem 파일을 선택합니다. 그리고 Save private key 버튼을 클릭해서 개인키를 로컬 PC에 저장해 둡니다. &quot;암호 없이 저장하겠습니까?&quot; 경고문이 나오면 &quot;예&quot;를 클릭합니다.&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;7. AWS 인스턴스의 DNS 주소를 복사한 뒤 PuTTY를 실행해서 SSH로 접속합니다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;AWS 콘솔 좌측 메뉴에서 인스턴스를 클릭한 후 접속할 인스턴스를 선택합니다.&lt;/li&gt;
&lt;li&gt;하단에 퍼블릭 DNS(IPv4) 주소를 클립 보드에 복사합니다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;8. DNS 주소가 복사되었다면 putty.exe를 실행해서 복사한 퍼블릭 DNS 주소를 Host Name(or IP address)의 입력란에 붙여 넣은 뒤 Connection &amp;gt; SSH &amp;gt; Auth를 클릭합니다.&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;9. Auth 메뉴에서 Browse 버튼을 클릭해서 위에서 저장했던 private key(.ppk)파일을 선택합니다.&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. 이제 Open 버튼을 클릭해서 SSH로 접속할 수 있습니다. SSH 인증 경고문이 뜬 뒤 &quot;예&quot;를 누르면 접속됩니다.&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;11. login as: centos를 입력하고 엔터를 누르면 로그인됩니다.&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;h2 data-ke-size=&quot;size26&quot;&gt;AWS에 톰캣 설치&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. SSH로 AWS 인스턴스에 접속 후 root 사용자로 전환해 라이브러리를 업데이트합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1761973664523&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;sudo su -
yum update&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;2. 자바를 설치합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1761973698200&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;yum install java&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;3. 톰캣을 다운로드하여서 설치합니다. 예제에서는 /usr/local/src에 다운로드해서 압축을 풉니다. 톰캣 다운로드 페이지에서 tar.gz 형식으로 다운로드합니다.&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. 다운로드 페이지의 Mirrors 항목에서 Other mirrors 값을 &lt;a href=&quot;http://www-eu.apache.org/dist/&quot;&gt;http://www-eu.apache.org/dist/&lt;/a&gt; 으로 선택합니다. tar.gz 링키에서 마우스 오른쪽 클릭해서 Copy Link Location을 선택해서 링크 주소를 복사합니다.&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;5. PuTTY 화면으로 돌아가서 다운로드할 디렉터리로 이동 후에 curl 명령어로 다운로드를 진행합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1761973961570&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;curl 아까복사했던다운로드용URL링크주소&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;6. 다운로드가 완료되면 압축을 풉니다.&lt;/p&gt;
&lt;pre id=&quot;code_1761974010328&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;tar -zxvf 다운받은톰캣파일.tar.gz&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;7. 압축 해제된 파일을 mv 명령으로 이동 후 소유자를 root에서 centos로 변경합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1761974141710&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;mv apache-tomcat-버전/ /usr/local/tomcat
chown -R centos:centos /usr/local/tomcat/&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;8. centos 유저로 변경한 후 톰캣을 실행합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1761974265824&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;su centos
/usr/local/tomcat/bin/startup.sh&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;9. 톰캣이 정상적으로 작동되는지 톰캣 화면에 접속합니다. AWS의 인스턴스의 퍼블릭 DNS에 표시되어 있는 도메인의 뒤에 8080 포트를 붙여서 접속합니다. 톰캣 고양이 그림이 나오는지 확인해 주세요.&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;h2 data-ke-size=&quot;size26&quot;&gt;배포하기&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;젠킨스에서 원격 환경에도 톰캣 매니저를 이용해서 배포가 가능하지만, 일반적으로는 SSH로 배포합니다.&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;1. 젠킨스 설정에서 플러그인 설치 화면으로 가서 Publish Over SSH 플러그인을 다운로드하고 설치합니다.&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. Jenkins 관리 &amp;gt; System &amp;gt; Publish over SSH 항목으로 이동합니다.&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;3. AWS 인스턴스 작성 시 다운로드한 키파일(.pem) 파일을 텍스트 에디터로 열어서 SSH Key정보를 입력한 후 그 SSH Key로 접속가능한 서버를 추가합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Passphrase : 키에 암호화를 걸었다면 해당 암호를 입력합니다. 예제에서는 암호를 입력하지 않았으니 공란으로 둡니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Path to Key: 키 파일이 있는 절대 경로를 입력합니다. 아니면 Key 항목에 .pem 파일을 열어서 입력된 키값을 복사해서 넣습니다.&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. SSH Servers에 추가 버튼을 눌러서 대상 서버를 추가합니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;name : 적당한 이름을 넣습니다.&lt;/li&gt;
&lt;li&gt;hostname: 해당 서버의 주소를 입력합니다. 여기서는 AWS 퍼블릭 DNS주소를 복사해서 붙여 넣습니다.&lt;/li&gt;
&lt;li&gt;Username: SSH로 접속할 유저를 입력합니다. 예제에서는 centos를 입력합니다.&lt;/li&gt;
&lt;li&gt;Remote Directory : 접속할 때 홈 디렉터리를 입력합니다. 예제에서는 톰캣의 홈 디렉토리를 입력합니다.&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;5. 입력 후 Save 버튼을 클릭한 뒤 로컬 배포에서 사용하던 잡(job)을 변경해서 SSH를 이용해서 배포를 해봅니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://aacii.tistory.com/454&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://aacii.tistory.com/454&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1761977898268&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;Jenkins (젠킨스)&quot; data-og-description=&quot;젠킨스는 자바 오픈소스 소프트웨어이며 플러그인으로 다른 다양한 시스템들과 연동할 수 있습니다. 주요기능git과 연동웹 인터페이스테스트 보고서 생성빌드 및 테스트 자동화코드 품질 감시&quot; data-og-host=&quot;blog.aacii.net&quot; data-og-source-url=&quot;https://aacii.tistory.com/454&quot; data-og-url=&quot;https://blog.aacii.net/454&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/dLhkNt/hyZMSubeGd/LI95FIndFF0W97dRJhf1Hk/img.png?width=800&amp;amp;height=308&amp;amp;face=0_0_800_308,https://scrap.kakaocdn.net/dn/hP15E/hyZMSHJW1L/VRGzfn6go7kvlFrmW0KgN0/img.png?width=800&amp;amp;height=308&amp;amp;face=0_0_800_308,https://scrap.kakaocdn.net/dn/cWqDwJ/hyZMT7IjsX/bjSsN0XzWUOEiYg8qlaqKk/img.png?width=1016&amp;amp;height=392&amp;amp;face=0_0_1016_392&quot;&gt;&lt;a href=&quot;https://aacii.tistory.com/454&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://aacii.tistory.com/454&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/dLhkNt/hyZMSubeGd/LI95FIndFF0W97dRJhf1Hk/img.png?width=800&amp;amp;height=308&amp;amp;face=0_0_800_308,https://scrap.kakaocdn.net/dn/hP15E/hyZMSHJW1L/VRGzfn6go7kvlFrmW0KgN0/img.png?width=800&amp;amp;height=308&amp;amp;face=0_0_800_308,https://scrap.kakaocdn.net/dn/cWqDwJ/hyZMT7IjsX/bjSsN0XzWUOEiYg8qlaqKk/img.png?width=1016&amp;amp;height=392&amp;amp;face=0_0_1016_392');&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;Jenkins (젠킨스)&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;젠킨스는 자바 오픈소스 소프트웨어이며 플러그인으로 다른 다양한 시스템들과 연동할 수 있습니다. 주요기능git과 연동웹 인터페이스테스트 보고서 생성빌드 및 테스트 자동화코드 품질 감시&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;blog.aacii.net&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;6. DeployTomcatJob을 선택하고 구성을 클릭합니다. 위 454 게시글에서 추가했던 Deploy war/ear to a container 항목의 우측 상단 X 버튼을 눌러서 삭제합니다.&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;7. 빌드 후 조치에서 Send build artifacts over SSH를 선택하고 필요한 정보를 입력합니다. Name에는 SSH-Key를 선택하고 Transfers 부분에서 Source Files에 전송할 war 파일의 경로를 입력합니다. (예: build/libs/war파일이름.war)&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;8. Remove prefix는 Source Files에서 제외할 접두사를 지정합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Remote Directory는 파일을 전송할 디렉터리를 지정합니다. 위에서 SSH로 접속 시 홈 디렉터리로 톰캣 홈을 지정해 주었으니 여기서는 그 하위 폴더인 webapps 만을 입력합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Exec command는 파일이 전송된 후 실행할 명령어를 지정할 수 있습니다. 실제 운영에서 배포 전후에 처리할 작업을 처리하는 용도로 사용합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다 입력했다면 저장합니다. 예제에서는 하나으니 Transfers만 설정했지만 실무에서는 여러 개 설정하는 경우가 많습니다. Transfers 추가는 Add Transfer Set을 클릭하면 됩니다.&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;9. 저장된 내용으로 Build Now를 클릭합니다. 빌드가 성공적으로 끝나면 AWS에 배포가 잘 되었는지 확인합니다.&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;h2 data-ke-size=&quot;size26&quot;&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;1. 자신의 깃허브에 있는 프로젝트(저장소)의 Settings로 이동합니다.&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. 여기서는 간편한 Webhooks를 이용합니다. 좌측 메뉴에서 Webhooks를 클릭하고&amp;nbsp; 우측 상단의 Add webhook을 클릭합니다.&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;3. Payload URL에 다음과 같이 URL을 입력합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1761980368530&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;http(s)://젠킨스서버URL/github-webhook/&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;4. Which events would you like to triger this webhook 에는 푸시 이벤트가 발생했을 때 실행되도록 Just the push event를 선택합니다.&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;5. Payload URL을 다 입력했다면 Add webhook을 클릭하면 완료 화면이 표시됩니다.&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;6. 화면에서 Edit 버튼을 눌러서 하단에 표시되는 Recent Deliverires 부분에 연결이 잘 되었나 확인합니다.&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;7. 젠킨스에서 job 구성을 클릭합니다. Triggers에서 Github hook trigger for GITScm polling을 체크하고 저장합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 소스를 push 하면 젠킨스의 job이 실행되어 배포까지 가능해집니다.&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;h2 data-ke-size=&quot;size26&quot;&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;1. 매개변수를 지정하는 방법은 job의 구성 메뉴 General에서 '이 빌드는 매개변수가 있습니다'를 체크하면 됩니다.&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;2. 대상 서버에 접속하기 위한 SSH정보는 이전 정보를 그대로 사용합니다.&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;3. 등록한 내용은 jenkins 관리 &amp;gt; 시스템 설정 &amp;gt; publish over SSH에서 확인 및 변경이 가능합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이전에 만들었던 DeployTomcatJob과 같은 기능을 셸스크립트로 실행하는 공통 잡을 만들어 보겠습니다.&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;실행 중인 톰캣을 정지합니다.&lt;/li&gt;
&lt;li&gt;webapps에 배포된 애플리케이션을 삭제합니다.&lt;/li&gt;
&lt;li&gt;젠킨스 서버에서 war 파일을 복사합니다.&lt;/li&gt;
&lt;li&gt;톰캣 서버를 시작합니다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. 새로운 Item을 클릭해서 Freestyle project에 DeployTomcatWithShellJob 이라는 이름으로 새로운 잡을 하나 만들어봅니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;General에서 '이 빌드는 매개변수가 있습니다'에 체크하고 '매개변수 추가'에서 String Parameter를 선택합니다.&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;5. 첫 String Parameter에서 매개변수 명에는 CI_WAR를 입력하고, Default Value 에는 build/libs/war파일이름.war 를 입력합니다.&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;6. 다시 매개변수 추가를 클릭하고 String Parameter를 선택한 후 매개변수 명에 CI_REMOTE_PATH를, Default Value에 webapps를 입력합니다.&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;7. 같은 방법을 CI_NAME에는 적절한 이름을, BUILD_ID에 dontKillme를 추가하여 매개변수를 추가합니다. BUILD_ID는 젠킨스가 대상 서버에서 톰캣을 실행한 후 접속을 종료하더라도 톰캣 프로세스를 계속 실행하는 용도입니다.&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;8. Git에 적절한 저장소를 지정해 주고, Build에서 Invoke를 적절히(gradle or maven) 추가 후 clean install를 입력합니다.&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;9. 빌드 후 조치에서 Send build artifacts over SSH를 선택한 후 실행할 명령어 순서대로 입력합니다.&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;SSH Server &amp;gt; Name은 앞에서 설정한 것을 선택해 줍니다.&lt;/li&gt;
&lt;li&gt;Transfers &amp;gt; Exec command 에는 톰캣 중지 스크립트인 shutdown.sh 와 기존 배포된 App 삭제 명령어를 입력합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;10. Add Transfer Set을 클릭하고 나머지 명령어도 입력해 줍니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Source files는 ${CI_WAR}&lt;/li&gt;
&lt;li&gt;Remove prefix는 build/libs 혹은 target&lt;/li&gt;
&lt;li&gt;Remote directory는 ${CI_REMOTE_PATH}&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;11. 이제 톰캣을 실행하는 설정을 합니다. Add Transfer Set을 추가하고 Exec command에 톰캣실행 스크립트인&amp;nbsp; /usr/local/tomcat/bin/startup.sh를 입력합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저장하고 대시보드로 돌아가면 Build Now가 사라지고 Build with Parameters가 보입니다. 클릭해서 페이지를 이동합니다.&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;12. 앞에서 설정한 매개변수를 지정할 수 있는 화면이 대시보드에 나옵니다. 기본값은 앞에서 지정한 Default Value로 되어있습니다. 빌드하기를 눌러서 빌드를 실행하고 콘솔 출력에서 정상적으로 배포되는지 확인합니다.&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;h2 data-ke-size=&quot;size26&quot;&gt;빌드 파이프라인&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여러 개의 Jenkins의 Job들을 묶어서 실행하는 빌드 파이프라인을 만들 수 있습니다.&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;&amp;nbsp;&lt;/p&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;/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;젠킨스와 소나큐브를 연결해서 사용할 수도 있는데 자세한 내용은 여기서 다루지 않겠습니다.&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;&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;&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;&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;&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;</description>
      <category>DEV&amp;amp;OPS/Java</category>
      <category>AWS</category>
      <category>deploy</category>
      <category>Java</category>
      <category>jenkins</category>
      <category>War</category>
      <author>ALEPH.GEM</author>
      <guid isPermaLink="true">https://aacii.tistory.com/455</guid>
      <comments>https://aacii.tistory.com/455#entry455comment</comments>
      <pubDate>Sat, 1 Nov 2025 16:44:25 +0900</pubDate>
    </item>
    <item>
      <title>Jenkins (젠킨스)</title>
      <link>https://aacii.tistory.com/454</link>
      <description>&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;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;git과 연동&lt;/li&gt;
&lt;li&gt;웹 인터페이스&lt;/li&gt;
&lt;li&gt;테스트 보고서 생성&lt;/li&gt;
&lt;li&gt;빌드 및 테스트 자동화&lt;/li&gt;
&lt;li&gt;코드 품질 감시&lt;/li&gt;
&lt;li&gt;인증 권한 관리&lt;/li&gt;
&lt;li&gt;배포 관리 자동화&lt;/li&gt;
&lt;li&gt;분산 빌드&lt;/li&gt;
&lt;li&gt;그루비 스크립트를 사용한 잡 스케줄링&lt;/li&gt;
&lt;/ul&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;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;젠킨스를 사용하려면 JDK와 메이븐이 필요합니다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;여기서는 JDK11 이상을 설치했다고 가정합니다.&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;LTS 버전을 다운로드 받습니다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;여기서는 Generic Java package (.war) 을 다운받는다고 가정합니다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://jenkins.io&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://jenkins.io&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1761905858372&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;Jenkins&quot; data-og-description=&quot;Jenkins &amp;ndash; an open source automation server which enables developers around the world to reliably build, test, and deploy their software&quot; data-og-host=&quot;www.jenkins.io&quot; data-og-source-url=&quot;https://jenkins.io&quot; data-og-url=&quot;https://www.jenkins.io/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bBubhv/hyZMUytcZV/V2ZFzz53qXEQB6b9PlyHMK/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/bWIJfF/hyZMJwYRdR/C46Lu14zZ9na3xveEkqfKk/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/cFXOAt/hyZML9oa3d/pvXrngVCVde7PLSP6iUalk/img.png?width=1800&amp;amp;height=630&amp;amp;face=0_0_1800_630&quot;&gt;&lt;a href=&quot;https://jenkins.io&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://jenkins.io&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bBubhv/hyZMUytcZV/V2ZFzz53qXEQB6b9PlyHMK/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/bWIJfF/hyZMJwYRdR/C46Lu14zZ9na3xveEkqfKk/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/cFXOAt/hyZML9oa3d/pvXrngVCVde7PLSP6iUalk/img.png?width=1800&amp;amp;height=630&amp;amp;face=0_0_1800_630');&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;Jenkins&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Jenkins &amp;ndash; an open source automation server which enables developers around the world to reliably build, test, and deploy their software&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.jenkins.io&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;1. 내려 받은 war 파일을 tomcat 서버에 deploy해도 되지만 아래 처럼 jre를 이용해서 바로 실행해도 됩니다.&lt;/p&gt;
&lt;pre id=&quot;code_1761906548740&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;D:\dev\jenkins\&amp;gt;java -jar jenkins.war&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서는 D:\dev\jenkins\ 경로에 다운받은 jenkins.war 파일을 이동시켜놨다고 가정합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러면 war 파일 내부에 제티 웹 서버가 8080 포트로 실행되어 젠킨스를 사용할 수 있습니다.&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. 브라우저에서 http://localhost:8080/ 을 입력하면 관리자 패스워드 입력화면이 나옵니다.&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;3. Administrator password를 입력하고 continue를 누릅니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러면 jenkins 실행시 나오던 로그에서 Please use the following password to proceed to installaton 문장 다음에 나오는 암호화키를 복사 붙여넣고 continue를 누르시면됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아니면 C:\User\사용자이름\.jenkins\secrets\initialAdminPassword 파일을 메모장으로 열면 위에 나오는 키를 확인할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;설치시 예상치 않은 문제가 발생시 jenkins 인스턴스를 멈추고 위 jenkins 폴더를 삭제 후 다시 시도해 보십시오.&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. Install suggested plugins를 선택하면 젠킨스 추천 플러그인들이 같이 설치되고, Select plugins to install을 선택하면 필요한 플러그인을 직접 선택할 수 있습니다. 여기서는 Install suggested plugins를 선택하겠습니다.&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;5. 플러그인 설치가 끝나면 관리자 정보 입력 화면이 나옵니다. 입력하고 Save&amp;nbsp; and Finish 버튼을 클릭합니다.&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;6. URL설정이 나오고 Save and Finish 하면 설치가 종료됩니다.&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;h2 data-ke-size=&quot;size26&quot;&gt;윈도우 사용시 유니코드 적용&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;윈도우 환경에서 컴파일 시 문자 인코딩이 깨질 수 있어서 UTF-8 으로 설정합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;시스템&amp;gt;고급 시스템 설정&amp;gt;환경 변수&amp;gt;시스템 변수 항목에서 새로 만들기를 해서 다음과 같은 항목을 추가해줍니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;시스템 변수 이름: JAVA_TOOL_OPTIONS&lt;/li&gt;
&lt;li&gt;변수 값: -Dfile.encoding=UTF-8 -Dsun.jnu.encoding=UTF-8&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;잡(job) 생성&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 좌측 상단 새로운 Item 을 클릭합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 적당한 이름을 넣고 아래 템플릿 중에서 Freestyle project 를 선택하고 OK합니다.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 26.1628%;&quot;&gt;FreeStyle project&lt;/td&gt;
&lt;td style=&quot;width: 73.8372%;&quot;&gt;대부분의 젠킨스 설정을 할 수 있습니다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 26.1628%;&quot;&gt;Pipeline&lt;/td&gt;
&lt;td style=&quot;width: 73.8372%;&quot;&gt;그루비 스크립트로 파이프라인을 작성할 때 사용합니다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 26.1628%;&quot;&gt;Multi-configuration project&lt;/td&gt;
&lt;td style=&quot;width: 73.8372%;&quot;&gt;복수의 다른 환경의 서버에 각각 다른 설정을 할 때 사용합니다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 26.1628%;&quot;&gt;Folder&lt;/td&gt;
&lt;td style=&quot;width: 73.8372%;&quot;&gt;폴더를 만들어 잡들을 그룹화 합니다. 하위 폴더도 만들 수 있습니다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 26.1628%;&quot;&gt;GitHub Organization&lt;/td&gt;
&lt;td style=&quot;width: 73.8372%;&quot;&gt;깃허브의 조직 혹은 개인 단위로 자동화하는 플러그인 입니다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 26.1628%;&quot;&gt;Multibranch Pipeline&lt;/td&gt;
&lt;td style=&quot;width: 73.8372%;&quot;&gt;브랜치의 빌드를 자동으로 그룹화해서, 새 브랜치가 푸시될 때마다 자동으로 새 젠킨스 잡을 만듭니다.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3.&amp;nbsp; 그러면 설정 메뉴가 생기는데, 깃허브에 있는 소스를 가지고 와서 빌드해봅시다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. 소스코드 관리 메뉴에서 Git을 선택하고 깃허브나 깃원격저당소의 URL을 복사해서 Repository URL에 붙여넣습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;5. 다음은 자격 증명을 추가합니다. ssh key를 이용하는 방법이나 깃허브 계정을 입력하는 방법 등이 있습니다. 여기서는 깃허브 계정을 등록합니다. Credentials 항목에 Add를 클릭하고 Jenkins 를 선택합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;6. Kind는 Username with password 상태로 두고 Username에 깃허브 ID를 Password에 깃허브 패스워드를 입력하고 Add 버튼을 클릭합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;7. Credentials 항목에 방금 추가했던 깃허브 계정을 선택하고 일단 Save 버튼을 누릅니다. 정상 작성되었다면 잡의 대시보드로 이동합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;8. 지금 빌드를 클릭해서 빌드해봅시다. 그러면 좌측 아래 Build history가 보이게 됩니다. history를 클릭해보면 자세한 정보가 보이는데 Console Output을 클릭해보면 콘솔 출력을 확인할 수 있습니다.&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;h2 data-ke-size=&quot;size26&quot;&gt;로컬 환경에서 애플리케이션 배포&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;빌드한 war 파일을 로컬 컴퓨터의 톰캣 서버에 배포하는 연습을 해봅니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서는 윈도우용 톰캣 9 버전을 기준으로 합니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;tomcat 다운로드 및 설정&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://tomcat.apache.org&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://tomcat.apache.org&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1761962724417&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;Apache Tomcat&amp;reg; - Welcome!&quot; data-og-description=&quot;The Apache Tomcat&amp;reg; software is an open source implementation of the Jakarta Servlet, Jakarta Pages, Jakarta Expression Language, Jakarta WebSocket, Jakarta Annotations and Jakarta Authentication specifications. These specifications are part of the Jakarta&quot; data-og-host=&quot;tomcat.apache.org&quot; data-og-source-url=&quot;https://tomcat.apache.org&quot; data-og-url=&quot;https://tomcat.apache.org&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://tomcat.apache.org&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://tomcat.apache.org&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&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;Apache Tomcat&amp;reg; - Welcome!&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;The Apache Tomcat&amp;reg; software is an open source implementation of the Jakarta Servlet, Jakarta Pages, Jakarta Expression Language, Jakarta WebSocket, Jakarta Annotations and Jakarta Authentication specifications. These specifications are part of the Jakarta&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;tomcat.apache.org&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서는 Windows.zip 으로 다운받습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;tomcat manager 기능을 사용하기 위해 적당한 곳에 압축을 풀고 압축을 푼 경로를 TOMCAT_HOME 이라고 하면 TOMCAT_HOME/conf/tomcat-users.xml 파일을 텍스트 에디터로 열고 &amp;lt;tomcat-users&amp;gt; &amp;lt;/tomcat-users&amp;gt;태그 사이에 다음 내용을 추가해줍니다.&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1761963532029&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;  &amp;lt;role rolename=&quot;admin-gui&quot;/&amp;gt;
  &amp;lt;role rolename=&quot;manager-gui&quot;/&amp;gt;
  &amp;lt;role rolename=&quot;manager-status&quot;/&amp;gt;
  &amp;lt;role rolename=&quot;manager-script&quot;/&amp;gt;
  &amp;lt;user username=&quot;tomcat&quot; password=&quot;tomcat&quot; roles=&quot;tomcat,admin-gui,manager-gui,manager-status,manager-script&quot;/&amp;gt;
  &amp;lt;user username=&quot;jenkins&quot; password=&quot;jenkins&quot; roles=&quot;tomcat,admin-gui,manager-gui,manager-status,manager-script&quot;/&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;젠킨스 서버가 8080 포트를 사용하기 때문에 톰캣의 기본 포트를 8088번으로 변경합니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;TOMCAT_HOME/conf/server.xml 파일을 텍스트 에디터로 열어서 포트 번호를 8080에서 8088으로 변경해줍니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;시스템 환경 변수에 JAVA_HOME과 JRE_HOME을 설치된 JDK 경로로 지정해줍니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 나서 TOMCAT_HOME/bin/startup.bat 을 실행시킵니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정상 실행되면 브라우저로 http://localhost:8088 으로 접속해서 tomcat 화면이 나오면 정상입니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;2025-11-01 11 33 49.png&quot; data-origin-width=&quot;1016&quot; data-origin-height=&quot;392&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bvVgR5/dJMcafx7vVJ/Xkyd36hUUK8TG1MEYs6T10/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bvVgR5/dJMcafx7vVJ/Xkyd36hUUK8TG1MEYs6T10/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bvVgR5/dJMcafx7vVJ/Xkyd36hUUK8TG1MEYs6T10/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbvVgR5%2FdJMcafx7vVJ%2FXkyd36hUUK8TG1MEYs6T10%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;1016&quot; height=&quot;392&quot; data-filename=&quot;2025-11-01 11 33 49.png&quot; data-origin-width=&quot;1016&quot; data-origin-height=&quot;392&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 우측 상단 Manager App 버튼을 눌러서 아까 xml 파일에 추가했던 유저인 아이디 tomcat / 비번 tomcat 계정으로 로그인되는지 확인합니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;manager app은 로컬 PC에서만 접속가능합니다. 다른 PC에서 접속하려면 추가 설정이 필요한데 여기서는 다루지 않겠습니다.&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;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;젠킨스 설정에서 플러그인을 선택한 뒤 검색에서 deploy to container 플러그인을 설치해줍니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;새로운 Item을 눌러서 새로운 job을 Freestyle project 으로 생성합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 이름은 DeployTomcatJob 으로 하겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;소스 코드 관리에서 깃허브 원격 저장소 URL을 이용해 war 파일 제작용 웹 프로젝트를 연결합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예)https://github.com/사용자계정/spring-mvc-web-ex&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 Build Steps 설정에서 gradle 프로젝트이면 Invoke Gradle script를 선택하고 maven이라면 Invoke top-level Maven targets 을 선택합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 빌드 후 조치에서 Deploy war/ear to a container를 선택하고 아래와 같은 정보를 입력해줍니다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;이 내용은 예제일 뿐 프로젝트 상황에 맞게 잘 입력해야합니다.&lt;br /&gt;WAR/EAR files: **/build/libs/*war&lt;br /&gt;Context path: /spring&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Containers 에 Add Container 항목을 눌러서 tomcat 9를 선택합니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Credentials 에 Add 버튼을 눌러 톰캣 매니저의 아이디와 패스워드를 입력해줍니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Tomcat URL은 위에서 설정했던 http://localhost:8088 을 입력해줍니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;설정이 끝나면 save하고 지금 빌드를 눌러 빌드해봅니다.&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;&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;&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;&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;&amp;nbsp;&lt;/p&gt;</description>
      <category>DEV&amp;amp;OPS/Java</category>
      <category>cd</category>
      <category>CI</category>
      <category>Java</category>
      <category>jenkins</category>
      <category>젠킨스</category>
      <author>ALEPH.GEM</author>
      <guid isPermaLink="true">https://aacii.tistory.com/454</guid>
      <comments>https://aacii.tistory.com/454#entry454comment</comments>
      <pubDate>Sat, 1 Nov 2025 12:14:34 +0900</pubDate>
    </item>
    <item>
      <title>git branch 관리: tracking, cherry-pick, stash</title>
      <link>https://aacii.tistory.com/342</link>
      <description>&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;h3 data-ke-size=&quot;size23&quot;&gt;원격 브랜치 로컬로 가져오기(fetch)&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 원격 저장소(orign)의 모든 원격 브랜치를 로컬로 가져옴&lt;/p&gt;
&lt;pre id=&quot;code_1677563519125&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;git fetch origin&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;2. 체크아웃할 수 있는 브랜치 목록 확인&lt;/p&gt;
&lt;pre id=&quot;code_1677563558268&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;git branch -a&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;브랜치 목록 중에서 원격 브랜치에는 remotes/origin 접두사가 붙어 있습니다.&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;h3 data-ke-size=&quot;size23&quot;&gt;로컬 브랜치를 분리 생성 후 원격 브랜치에 적용&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 분리하려는 원본 브랜치를 checkout 합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1732708670849&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;git checkout 분리하려는브랜치이름&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;2. 로컬 저장소에 분리하려는 새로운 브랜치를 생성합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1732708805623&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;git checkout -b 분리생성할브랜치이름&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;3. 원격 저장소에 새 브랜치를 push 해 줍니다.&lt;/p&gt;
&lt;pre id=&quot;code_1732708879650&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;git push origin 로컬에분리생성된브랜치이름&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;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;원격 브랜치 업데이트&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 원격 저장소의 브랜치들을 갱신&lt;/p&gt;
&lt;pre id=&quot;code_1677564888009&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;git remote update&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;2. 원격 저장소 브랜치 목록 확인&lt;/p&gt;
&lt;pre id=&quot;code_1677564957178&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;git branch -r&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;그런데 삭제된 원격 브랜치가 목록에 나오는 경우가 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;git remote update 명령은 원격 저장소에서 삭제된 브랜치들을 로컬 저장소에서 정리하지는 않기 때문입니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모든 원격 저장소에 대해 삭제된 브랜치 정보를 정리(prune)하려면 아래와 같이 입력합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1677566253990&quot; class=&quot;brainfuck&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;git fetch --all --prune&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약 특정 원격 저장소에 대해 삭제된 브랜치 정보를 정리하려면 아래와 같이 입력합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1677566253990&quot; class=&quot;pgsql&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;git fetch 원격저장소이름 --prune&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어 원격 저장소(origin)에 브랜치를 merge 하고 나서 삭제해도 로컬에는 해당 브랜치가 존재하는 상황에서&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;로컬의 브랜치들을 잘라 없애는(prune) 작업은 위 처럼 할 수도 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 아래 명령도 같은 기능을 수행합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1677568342669&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;git remote prune origin&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;혹은&lt;/p&gt;
&lt;pre id=&quot;code_1677568519401&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;git remote update --prune&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;&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;h3 data-ke-size=&quot;size23&quot;&gt;원격 브랜치의 변경 이력을 로컬 브랜치에 가져와서 적용(tracking)&lt;/h3&gt;
&lt;pre id=&quot;code_1677565158711&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;git checkout -t 원격브랜치명&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 명령어는 원격 저장소의 브랜치를 로컬 브랜치에 영구적으로 tracking 할 때 -t 옵션으로 checkout 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 checkout 하면 원격 브랜치 명과 로컬 브랜치명이 같게 checkout 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약 원격과 로컬 브랜치명을 다르게 checkout 하고 싶으면 아래처럼 입력합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1677565525747&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;git checkout -b 로컬브랜치명 원격브랜치명&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어 origin/feature/tests 원격 브랜치를 로컬로 복사하려면 아래와 같이 입력합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1677563972675&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;git checkout -b feature/tests origin/feature/tests&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 명령어는 feature/tests 브랜치를 생성하고, 새 브랜치(feature/tests)로 체크 아웃하며, 원격 브랜치 origin/feature/tests의 변경 이력을 로컬 feature/tests 브랜치로 가져(pull) 옵니다.&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;h3 data-ke-size=&quot;size23&quot;&gt;브랜치 삭제&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;로컬 브랜치 삭제&lt;/p&gt;
&lt;pre id=&quot;code_1677568712218&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;git branch -d 브랜치명&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;-D 옵션으로 강제로 삭제할 수 있습니다.&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;원격 저장소(origin) 브랜치 삭제&lt;/p&gt;
&lt;pre id=&quot;code_1677568881606&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;git push origin --delete 브랜치명&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;참고: git 웹페이지에서 원격 브랜치를 삭제를 지원할 수도 있습니다.&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;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;브랜치 병합&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;브랜치의 head는 현재 사용중인 브랜치의 제일 최신 커밋 부분을 가리키고 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어 master 브랜치에 bugfix/MM-1234 브랜치를 가져와 합치는 상황이라고 가정합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우선 기준이 되는 마스터 브랜치 체크아웃&lt;/p&gt;
&lt;pre id=&quot;code_1761889659464&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;git checkout master
git pull&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;bugfix/MM-1234 브랜치 병합&lt;/p&gt;
&lt;pre id=&quot;code_1761889724352&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;git merge bugfix/MM-1234&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;이 때 conflict 가 없었다면 그대로 원격 저장소에 push합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1761889826129&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;git push&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;그런데 만약 conflict가 발생했다면 해당 파일을 열어봅니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&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;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;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;======= 를 기준으로 윗부분이 기준이되는 master 브랜치의 내용이고 아래 부분이 합쳐질 bugfix 브랜치의 내용입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;내용을 보고 적절히 선택 후에 필요없는 부분을 제거한 다음 저장하고 커밋&amp;amp;push하면됩니다.&lt;/p&gt;
&lt;pre id=&quot;code_1761890061880&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;git add.
git commit -m &quot;충돌해결&quot;
git push&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;그런데 만약 conflict 가 발생했을 때 위 처럼 merge 작업을 취소하고 이전 상태로 돌아가려면,&lt;/p&gt;
&lt;pre id=&quot;code_1761890189153&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;git merge --abort&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 취소하면됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 후 병합되는 bugfix 쪽 브랜치를 충돌이 나지 않게 다시 작업해서 다시 merge를 시도하면 됩니다.&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;h3 data-ke-size=&quot;size23&quot;&gt;다른 브랜치 커밋을 개별 적용&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;git cherry-pick은 다른 브랜치에 있는 커밋을 개별로 현재 브랜치에 적용시킬 때 사용합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;브랜치 전체를 병합(merge)하는 것이 아니라 특정 커밋만을 현재 브랜치로 가져옵니다.&lt;/p&gt;
&lt;pre id=&quot;code_1677759044322&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;git cherry-pick 커밋해시값&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약 merge 한 커밋에 대해 cherry-pick을 하려면 아래처럼 할 수 있습니다.&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1677759121802&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;git cherry-pick -m 1 머지커밋해시값&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;cherry-pick 중단 명령&lt;/p&gt;
&lt;pre id=&quot;code_1677759171367&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;git cherry-pick --abort&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 id=&quot;git현재브랜치상태임시저장후복원-##현재브랜치상태임시저장&quot; style=&quot;background-color: #ffffff; color: #172b4d; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;현재 브랜치 상태 임시 저장/복원&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 현재 브랜치 상태 임시 저장&lt;/p&gt;
&lt;pre id=&quot;code_1740026751908&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;git stash&lt;/code&gt;&lt;/pre&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 id=&quot;git현재브랜치상태임시저장후복원-##다른브랜치로이동하여작업&quot; style=&quot;background-color: #ffffff; color: #172b4d; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;2. 다른 브랜치로 이동하여 작업&lt;/p&gt;
&lt;pre id=&quot;code_1740026773124&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;git checkout 다른_브랜치_이름&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #172b4d; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;이제 다른 브랜치에서 필요한 작업 수행합니다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #172b4d; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p id=&quot;git현재브랜치상태임시저장후복원-##원래브랜치로돌아오기&quot; style=&quot;background-color: #ffffff; color: #172b4d; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;3. 원래 브랜치로 돌아오기&lt;/p&gt;
&lt;pre id=&quot;code_1740026799732&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;git checkout 원래_브랜치_이름&lt;/code&gt;&lt;/pre&gt;
&lt;div style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-macro-name=&quot;code&quot; data-hasbody=&quot;true&quot;&gt;
&lt;div style=&quot;background-color: #ffffff; color: #333333; text-align: left;&quot;&gt;
&lt;div&gt;임시 저장했던 원래 브랜치로 checkout 합니다.&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p id=&quot;git현재브랜치상태임시저장후복원-##임시저장된상태복원&quot; style=&quot;background-color: #ffffff; color: #172b4d; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;4. 임시 저장된 상태 복원&lt;/p&gt;
&lt;pre id=&quot;code_1740026814232&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;git stash pop&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #172b4d; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;git stash pop 명령어는 임시 저장된 상태를(스택) 삭제하면서 불러오는 명령어이고,&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #172b4d; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;git stash apply 명령어는 임시 저장된 상태를 그대로 두면서 불러오는 명령어입니다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #172b4d; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #172b4d; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;5. 임시 저장된 작업 목록을 삭제&lt;/p&gt;
&lt;pre id=&quot;code_1761898918703&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;git stash drop
git stash clear&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;background-color: #ffffff; color: #172b4d; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #172b4d; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #172b4d; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>DEV&amp;amp;OPS/Linux &amp;amp; Cloud</category>
      <category>Branch</category>
      <category>checkout</category>
      <category>cherry pick</category>
      <category>git</category>
      <category>Stash</category>
      <category>브랜치</category>
      <category>체리픽</category>
      <author>ALEPH.GEM</author>
      <guid isPermaLink="true">https://aacii.tistory.com/342</guid>
      <comments>https://aacii.tistory.com/342#entry342comment</comments>
      <pubDate>Fri, 31 Oct 2025 18:26:46 +0900</pubDate>
    </item>
    <item>
      <title>git 기본 사용 방법</title>
      <link>https://aacii.tistory.com/453</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;git 클라이언트 설치&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://git-scm.com/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://git-scm.com/&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1761891587377&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;Git&quot; data-og-description=&quot;&quot; data-og-host=&quot;git-scm.com&quot; data-og-source-url=&quot;https://git-scm.com/&quot; data-og-url=&quot;https://git-scm.com/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/DeeSB/hyZMBkZO5d/b3t31SIykKElbkjkz00yi0/img.png?width=778&amp;amp;height=502&amp;amp;face=0_0_778_502&quot;&gt;&lt;a href=&quot;https://git-scm.com/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://git-scm.com/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/DeeSB/hyZMBkZO5d/b3t31SIykKElbkjkz00yi0/img.png?width=778&amp;amp;height=502&amp;amp;face=0_0_778_502');&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;Git&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;git-scm.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&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;h2 data-ke-size=&quot;size26&quot;&gt;git&amp;nbsp; 로컬 저장소 만들기&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;윈도우의 cmd를 사용해도 되지만 linux 스타일인 위에서 설치한 git bash를 실행시켜 작업하겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;d:\ 드라이브로 이동합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1761892382910&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;cd /d&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;git이라는 디렉터리를 생성한 뒤 이동합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1761892494698&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;mkdir git
cd git&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기에 다시 gitwork 디렉토리를 생성한 뒤 이동합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1761892542399&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;mkdir gitwork
cd gitwork&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;깃 저장소를 생성해서 초기화 하는 명령어를 실행합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1761892631396&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;git init&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러면. git이라는 디렉터리가 하위에 자동생성되며 이 디렉터리가 git에서 관리하는 저장소라는 역할을 하게 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;디렉터리 경로 앞에 점(.)을 붙이는 것은 리눅스에서 숨김 폴더(파일) 처리하는 것이므로 일반 ls 명령어로는 숨겨집니다.(하지만 윈도우 탐색기에선 그냥 보입니다.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 사용자 등록을 해보겠습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1761893113457&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;git config --global user.name &quot;{사용자명}&quot;
git config --global user.email &quot;{이메일주소}&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이것으로 git 로컬 저장소가 준비되었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;원격 저장소 (github) 만들기&amp;nbsp;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://github.com/&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1761893616778&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 &amp;middot; Change is constant. GitHub keeps you ahead.&quot; data-og-description=&quot;Join the world's most widely adopted, AI-powered developer platform where millions of developers, businesses, and the largest open source community build software that advances humanity.&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/&quot; data-og-url=&quot;https://github.com/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/HyAIi/hyZMtmWWYU/DF6uzBaktMNJDgj8JzmoF0/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/NF68g/hyZMSgjqjC/KSDNZK9ySOw1U8zf7IarFk/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630&quot;&gt;&lt;a href=&quot;https://github.com/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/HyAIi/hyZMtmWWYU/DF6uzBaktMNJDgj8JzmoF0/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/NF68g/hyZMSgjqjC/KSDNZK9ySOw1U8zf7IarFk/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630');&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 &amp;middot; Change is constant. GitHub keeps you ahead.&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Join the world's most widely adopted, AI-powered developer platform where millions of developers, businesses, and the largest open source community build software that advances humanity.&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;영문의 압박감이 있지만 잘 가입해서 로그인해주시길 바랍니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;로그인하면 Create 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;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 Owner는 소유자 Repository name에는 원격저장소 이름을 입력해 주시고 아래 옵션들을 결정합니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Choose visibility는 public으로 무료 공개 저장소로 만들기 위한 옵션입니다.&lt;/li&gt;
&lt;li&gt;Add README 옵션은 readme 파일을 자동으로 생성할지 옵션입니다.&lt;/li&gt;
&lt;li&gt;Add .gitignore 옵션은 git에서 관리하지 않는 예외 파일목록이 저장된 파일이 .gitignore 파일입니다. 이 파일은 저장소가 생성될 때 같이 생성하는 게 좋습니다. 그래서 No..gitignore 옵션을 사용하는 프로그래밍 언어로 변경해 주시길 바랍니다.&lt;/li&gt;
&lt;li&gt;Add license 옵션에서는 라이선스 표시를 결정합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러고 나서 Create 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;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;원격 저장소에 push&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위에서 git config&amp;nbsp; 명령어로 등록했던 사용자 정보와 github에 가입했던 사용자 정보랑 일치하지 않으면 git config 명령으로 일치시켜 주세요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 github에서 생성한 원격 저장소 경로를 git bash에서 추가해 줍니다.&lt;/p&gt;
&lt;pre id=&quot;code_1761895071605&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;git remote add origin https://github.com/계정명/원격저장소명.git&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;이제 d:/git/gitwork/ 경로에 README.MD 파일을 하나 생성해서 내용을 아무 내용이나 적어 놓습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 나서 로컬 저장소에 commit을 합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1761895321944&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;git add -A
git commit -m &quot;first commit&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러고 나서 push 하기 전에 원격저장소와 연결을 시켜줍니다.&lt;/p&gt;
&lt;pre id=&quot;code_1761895408743&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;git push --set-upstream origin master&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 origin master은 원격저장소를 생성할 때 기본적으로 생성된 master 브랜치를 의미합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다른 branch에 push 하려면 다른 branch에 하셔도 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이때 push를 하게 되면 github 계정 인증 작업을 하게 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;적절한 인증 절차를 거치면 push가 완료되고 원격 저장소에 로컬 저장소 내용이 적용되게 됩니다.&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;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;새로운 로컬 디렉터리 d:\git\gitClone 디렉터리를 생성한 뒤(mkdir) git hub에 아까 생성했던 원격저장소 페이지에 갑니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;초록색 Code 버튼을 눌러보면 Clone을 위한 HTTPS와 SSH 등 프로토콜이 있는데 여기서는 HTTPS를 이용하겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&quot;&lt;a href=&quot;https://github.com/계정이름/저장소이름.git&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/계정이름/저장소이름.git&lt;/a&gt;&quot; 옆의 copy url to clipboad 버튼을 눌러 url을 복사합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 git bash에 위에서 만들었던 d:\git\gitClone 디렉터리로 이동(cd)해서 clone을 실행합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1761896721255&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;git clone https://github.com/계정이름/원격저장소이름.git&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;clone을 실행하면 하위에 원격저장소 디렉터리가 생성되며 원격 저장소의 내용이 로컬 저장소와 동기화됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 이 로컬 저장소에서&amp;nbsp; pull, push 등 명령어로 원격 저장소와 동기화 관리를 할 수 있습니다.&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;h2 data-ke-size=&quot;size26&quot;&gt;버전 관리 대상에서 제외하기(.gitignore)&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;로컬 저장소에 .gitignore 파일이 만들어져 있거나 만들면 버전 관리 대상에서 제외할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하위 디렉터리의 .gitignore 설정이 상위 디렉토리 설정보다 우선해서 적용됩니다.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 160px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 21px;&quot;&gt;
&lt;td style=&quot;width: 23.3332%; height: 21px;&quot;&gt;설정&lt;/td&gt;
&lt;td style=&quot;width: 11.3567%; height: 21px;&quot;&gt;예제&lt;/td&gt;
&lt;td style=&quot;width: 65.31%; height: 21px;&quot;&gt;의미&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 21px;&quot;&gt;
&lt;td style=&quot;width: 23.3332%; height: 21px;&quot;&gt;/ 가 없는 이름&lt;/td&gt;
&lt;td style=&quot;width: 11.3567%; height: 21px;&quot;&gt;web.xml&lt;/td&gt;
&lt;td style=&quot;width: 65.31%; height: 21px;&quot;&gt;.gitignore 이하의 모든 서브 디렉토리에서 설정한 파일(디렉토리)을 제외&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 21px;&quot;&gt;
&lt;td style=&quot;width: 23.3332%; height: 21px;&quot;&gt;/ 가 줄 마지막에 없는 이름&lt;/td&gt;
&lt;td style=&quot;width: 11.3567%; height: 21px;&quot;&gt;/file&lt;/td&gt;
&lt;td style=&quot;width: 65.31%; height: 21px;&quot;&gt;.gitignore 가 있는 디렉토리를 기준으로 상대 경로로 지정된 파일(디렉토리)를 제외&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 21px;&quot;&gt;
&lt;td style=&quot;width: 23.3332%; height: 21px;&quot;&gt;/ 가 줄 마지막에 있는 이름&lt;/td&gt;
&lt;td style=&quot;width: 11.3567%; height: 21px;&quot;&gt;path/&lt;/td&gt;
&lt;td style=&quot;width: 65.31%; height: 21px;&quot;&gt;.gitignore 이하의 모든 서브 디렉토리에서 지정된 디렉토리를 제외&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 42px;&quot;&gt;
&lt;td style=&quot;width: 23.3332%; height: 42px;&quot;&gt;/ 가 줄의 마지막과 다른 곳에도 있는 경우&lt;/td&gt;
&lt;td style=&quot;width: 11.3567%; height: 42px;&quot;&gt;/file/&lt;/td&gt;
&lt;td style=&quot;width: 65.31%; height: 42px;&quot;&gt;.gitignore 가 있는 디렉토리 기준으로 상대 경로로 지정된 디렉토리를 제외&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 23.3332%; height: 17px;&quot;&gt;! 으로 시작하는 경우&lt;/td&gt;
&lt;td style=&quot;width: 11.3567%; height: 17px;&quot;&gt;!/path/file&lt;/td&gt;
&lt;td style=&quot;width: 65.31%; height: 17px;&quot;&gt;! 다음의 문자열의 파일(디렉토리)를 버전 관리 제외로 하지 않음. 상위 디렉토리에서 제외시켰다고 해도 하위 디렉토리에서 이 설정을 하면 버전 관리 대상에 포함시킴&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 23.3332%; height: 17px;&quot;&gt;# 으로 시작하는 경우&lt;/td&gt;
&lt;td style=&quot;width: 11.3567%; height: 17px;&quot;&gt;#/path/file&lt;/td&gt;
&lt;td style=&quot;width: 65.31%; height: 17px;&quot;&gt;주석으로 취급&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이것 이외에 와일드카드 문자도 활용 할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어 *.bak 하면 확장자기 .bak는 제외시킬 수 있습니다.&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;h2 data-ke-size=&quot;size26&quot;&gt;브랜치의 활용&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://aacii.tistory.com/342&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://aacii.tistory.com/342&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1761897896911&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;git branch 관리: tracking, cherry-pick, stash&quot; data-og-description=&quot;원격 브랜치 로컬로 가져오기(fetch)1. 원격 저장소(orign)의 모든 원격 브랜치를 로컬로 가져옴git fetch origin 2. 체크아웃할 수 있는 브랜치 목록 확인git branch -a브랜치 목록 중에서 원격 브랜치에는 r&quot; data-og-host=&quot;blog.aacii.net&quot; data-og-source-url=&quot;https://aacii.tistory.com/342&quot; data-og-url=&quot;https://blog.aacii.net/342&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/uhClJ/hyZMX9Lvax/bqJRl7JzjjdoCg186KXE61/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/y440S/hyZMKJlOEs/blpKjVgMNdf3GrTOfblkvk/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/b0bM1v/hyZMOrquZu/zxR2paXQXBbUuQR4DkNd5k/img.png?width=400&amp;amp;height=400&amp;amp;face=0_0_400_400&quot;&gt;&lt;a href=&quot;https://aacii.tistory.com/342&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://aacii.tistory.com/342&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/uhClJ/hyZMX9Lvax/bqJRl7JzjjdoCg186KXE61/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/y440S/hyZMKJlOEs/blpKjVgMNdf3GrTOfblkvk/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/b0bM1v/hyZMOrquZu/zxR2paXQXBbUuQR4DkNd5k/img.png?width=400&amp;amp;height=400&amp;amp;face=0_0_400_400');&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;git branch 관리: tracking, cherry-pick, stash&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;원격 브랜치 로컬로 가져오기(fetch)1. 원격 저장소(orign)의 모든 원격 브랜치를 로컬로 가져옴git fetch origin 2. 체크아웃할 수 있는 브랜치 목록 확인git branch -a브랜치 목록 중에서 원격 브랜치에는 r&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;blog.aacii.net&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;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;자주 사용하는 git 명령어 정리&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;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 44.3023%;&quot;&gt;&lt;span&gt;git config --global user.name &quot;사용자이름&quot;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 55.6977%;&quot;&gt;커밋할 사용자를 지정합니다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 44.3023%;&quot;&gt;git config --global user.email &quot;메일주소&quot;&lt;/td&gt;
&lt;td style=&quot;width: 55.6977%;&quot;&gt;사용자의 메일 주소를 지정합니다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 44.3023%;&quot;&gt;git config --list&lt;/td&gt;
&lt;td style=&quot;width: 55.6977%;&quot;&gt;현재 설정값들을 보여줍니다.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&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;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 45.2325%;&quot;&gt;git init 프로젝트이름&lt;/td&gt;
&lt;td style=&quot;width: 54.7675%;&quot;&gt;새로운 로컬 저장소를 프로젝트 이름으로 생성합니다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 45.2325%;&quot; rowspan=&quot;2&quot;&gt;git clone 원격저장소주소URL&lt;/td&gt;
&lt;td style=&quot;width: 54.7675%;&quot; rowspan=&quot;2&quot;&gt;원격저장소에서 전체 소스를 현재 로컬 저장소에 복제합니다.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&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;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 45.1163%;&quot;&gt;gir rm 파일이름&lt;/td&gt;
&lt;td style=&quot;width: 54.8837%;&quot;&gt;대상 파일을 작업 디렉토리와 스테이지에서 삭제합니다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 45.1163%;&quot;&gt;git mv 파일1 파일2&lt;/td&gt;
&lt;td style=&quot;width: 54.8837%;&quot;&gt;대상 파일1을 파일2 으로 이름을 바꿉니다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 45.1163%;&quot;&gt;git config --global core.autocrlf true&lt;/td&gt;
&lt;td style=&quot;width: 54.8837%;&quot;&gt;이 값이 true 이면 윈도우로 체크아웃할 때 줄바꿈 문자(LF)를 윈도우의 줄바꿈 문자인 CRLF 으로 변환됩니다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 45.1163%;&quot;&gt;git config --global core.autocrlf input&lt;/td&gt;
&lt;td style=&quot;width: 54.8837%;&quot;&gt;리눅스 환경에서 이 값을 input으로 하는 경우 커밋할 때만 CRLF를 LF로 변환합니다.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&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;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 43.6047%;&quot;&gt;git log 파일이름&lt;/td&gt;
&lt;td style=&quot;width: 56.3953%;&quot;&gt;해당 파일의 커밋 로그를 참조합니다.&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 43.6047%;&quot;&gt;git diff 브랜치1 브랜치2&lt;/td&gt;
&lt;td style=&quot;width: 56.3953%;&quot;&gt;두 브랜치를 비교해서 차이점을 표시합니다.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&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;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 42.3256%;&quot;&gt;git commit -amend&lt;/td&gt;
&lt;td style=&quot;width: 57.6744%;&quot;&gt;이전에 커밋했던 내용에 새로운 내용을 추가합니다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 42.3256%;&quot;&gt;git revert 커밋번호&lt;/td&gt;
&lt;td style=&quot;width: 57.6744%;&quot;&gt;이전에 작성한 특정 커밋을 지울때 사용합니다.&lt;br /&gt;rebase나 reset도 가능하지만 지우고 싶지 않은 커밋이 있는 경우 사용합니다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 42.3256%;&quot;&gt;git reset 모드 헤드&lt;/td&gt;
&lt;td style=&quot;width: 57.6744%;&quot;&gt;reset은 필요없어진 커밋을 삭제합니다.&lt;br /&gt;모드에는 -soft, -mixed, -hard 가 있으며 head&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&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;&amp;nbsp;&lt;/p&gt;</description>
      <category>DEV&amp;amp;OPS/Linux &amp;amp; Cloud</category>
      <category>git</category>
      <category>git bash</category>
      <category>github</category>
      <category>기본</category>
      <category>사용법</category>
      <author>ALEPH.GEM</author>
      <guid isPermaLink="true">https://aacii.tistory.com/453</guid>
      <comments>https://aacii.tistory.com/453#entry453comment</comments>
      <pubDate>Fri, 31 Oct 2025 18:26:35 +0900</pubDate>
    </item>
    <item>
      <title>build.gradle 의 기본</title>
      <link>https://aacii.tistory.com/452</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;gradle 8.5와 인텔리제이를 기준으로 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;Task&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;gradle은 기본적으로 task를 작성하고 실행합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;task는 실행할 처리들로 이루어진 명령어들을 작성해둔 것입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 정의한 task는 gradle 명령어로 실행할 수 있습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1761804596842&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;tasks.register('enjoy') {
    doLast {
        println(&quot;================================================&quot;);
        println(&quot;enjoy gradle build system.&quot;);
        println(&quot;================================================&quot;);
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;build.gradle 파일의 끝에 위 task내용을 등록합시다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 나서 인텔리제이 터미널이나 cmd로 해당 gradle 프로젝트 경로에서 아래와 같이 gradle을 실행해보십시오.&lt;/p&gt;
&lt;pre id=&quot;code_1761804739611&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;gradle enjoy&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러면 등록했던 task의 메시지가 출력되는것을 확인할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;doLast{ }는 task의 액션 리스트 마지막에 처리를 추가하는 것입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;doFirst{ }를 task의 맨 아래에 적어도 처음에 실행되기 때문에 doFirst{ }도 task의 최초 실행할 액션 처리를 추가하는 용도로 사용합니다.&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;h2 data-ke-size=&quot;size26&quot;&gt;Task에 매개 변수 전달하기&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;task를 실행할 때 어떤 정보를 task에 전달하려면 매개 변수를 통해서 전달 할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위의 task를 아래 처럼 수정해 보십시오.&lt;/p&gt;
&lt;pre id=&quot;code_1761805748338&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;tasks.register('enjoy') {
    doLast {
        def sum = 0;
        for(def i in 1..num.toInteger()){
            sum += i;
        }
        println(&quot;SUM: &quot;+sum);
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이후 gradle을 실행할 때 아래와 같이 실행해 보십시오.&lt;/p&gt;
&lt;pre id=&quot;code_1761805826902&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;gradle enjoy -q -Pnum=100&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 때, -q 옵션은 quiet 모드로 쓸데없는 정보들을 출력하지 않게 해주는 옵션입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;-P프로퍼티=프로퍼티값 형태로 매개 변수 값을 전달 할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실행하면 아래 처럼 나옵니다.&lt;/p&gt;
&lt;pre id=&quot;code_1761805991754&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SUM: 5050&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;h2 data-ke-size=&quot;size26&quot;&gt;동적 task 생성&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;개발 환경이나 제품 배포 환경을 나누어서 빌드할 수 있도록 동적으로 task를 생성할 수 있습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1761807196160&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 1. 동적으로 생성할 기준이 되는 목록 정의
def environments = ['dev', 'staging', 'prod']

// 2. 목록을 순회하며 'tasks.register'로 태스크 등록
environments.each { env -&amp;gt;

    // 동적 태스크 이름 생성 (예: Dev, Staging)
    def taskName = &quot;${env.capitalize()}&quot;

    tasks.register(taskName) {
        group = 'Env' // 태스크 그룹 지정 (gradle tasks --group=Env 명령으로 보기 편함)
        description = &quot;Prints a greeting for the ${env} environment.&quot;

        // 'doLast' 액션으로 실제 작업 정의
        doLast {
            println &quot;=========================&quot;
            if (env == 'prod') {
                println &quot;Hello, PRODUCTION environment!&quot;
            } else {
                println &quot;Hello, ${env} environment!&quot;
            }
            println &quot;=========================&quot;
        }
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;개발환경으로 빌드할 때 아래 명령어로 실행해봅니다.&lt;/p&gt;
&lt;pre id=&quot;code_1761807856091&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;gradle dev&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;제품배포 환경으로 빌드 할 때 아래 명령어로 실행해 봅시다.&lt;/p&gt;
&lt;pre id=&quot;code_1761807911545&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;gradle prod&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;h2 data-ke-size=&quot;size26&quot;&gt;JAVA 플러그인의 task&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자바로 개발할 때의 기본적인 기능은 java 플러그인에 포함되어 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;build.gradle에서 로드해서 이용합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1761808845874&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;plugins {
    id 'java'
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;혹은&lt;/p&gt;
&lt;pre id=&quot;code_1761809839870&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;apply plugin: 'java'&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; java플러그인의 task들을 알아봅시다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;java&lt;br /&gt;자바 소스 코드를 컴파일하고 그 외 필요한 리소스들을 모아서 jar 파일을 생성합니다.&lt;br /&gt;프로그램을 배포할 때 이 태스크로 jar 파일을 만들면 유용합니다.&lt;br /&gt;단, 이 java 태스크로 생성되는 jar 파일은 Executable이 아닙니다.&lt;/blockquote&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;compileJava&amp;nbsp;&lt;br /&gt;자바 소스 코드를 모두 컴파일합니다.&lt;/blockquote&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;processResources&amp;nbsp;&lt;br /&gt;리소스 파일을 클래스 폴더 안에 복사합니다.&lt;/blockquote&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;classes&amp;nbsp;&lt;br /&gt;소스 코드 컴파일과 리소스 파일 복사를 실행합니다.&lt;/blockquote&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;test&amp;nbsp;&lt;br /&gt;프로그램 테스트를 실행합니다.&lt;/blockquote&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;jar&amp;nbsp;&lt;br /&gt;프로그램을 컴파일하고 리소스를 준비한 뒤 jar 파일로 패키징합니다. 이 jar 파일 또한 Executable jar가 아닙니다.&lt;/blockquote&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;clean&amp;nbsp;&lt;br /&gt;빌드로 생성된 파일을 모두 삭제합니다.&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;이 task들은 gradle 태스크이름 형태로 실행할 수 있습니다.&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;h2 data-ke-size=&quot;size26&quot;&gt;클래스 실행&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;src\main\java\패키지경로 밑에 실행할 수 있는 main 메소드가 있는 .java 파일을 생성 후 편집합니다.(인텔리제이에서 자동 샘플 생성을 체크했다면 Main.java 파일이 생성되어 있습니다.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 Main.java 파일을 작성해줍니다.&lt;/p&gt;
&lt;pre id=&quot;code_1761822485133&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;java&quot;&gt;&lt;code&gt;//패키지명 생략

public class Main {
    private String name;
    public static void main(String[] args) {
        System.out.println(&quot;Hello, World!&quot;);
    }
    public boolean showMessage(String name){
        this.name = name;
        System.out.println(&quot;Who are you? \n&quot;+this.name);
        return true;
    };
    public String getMessage(String name) {
        this.name = name;
        return this.name;
    }
}&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;java 플러그인에는 빌드는 할 수 있지만 실행하는 task가 없었습니다. application 플러그인을 사용해서 앱을 실행하게 됩니다.&lt;/p&gt;
&lt;pre id=&quot;code_1761813001492&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;plugins {
    // 'application' 플러그인을 적용합니다.
    // 'java' 플러그인은 'application'에 의해 자동으로 포함됩니다.
    // id 'java'
    id 'application'
}&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1761813083583&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 메인 클래스 지정
application {
    // 예를들어 'com.example.Main' 를 실행할 클래스로 지정
    mainClass = 'com.example.Main'
}&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;이처럼 buid.gradle을 수정한 후 run 태스크를 실행합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1761813158331&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;gradle run&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;application 플러그인에는 run task가 포함되어 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실행하는 동안 클래스가 컴파일되며 MyMain클래스를 실행해줍니다.&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;h2 data-ke-size=&quot;size26&quot;&gt;실행가능한 jar 만들기&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위에서 작업한 Main.java 클래스를 실행하능한 jar 으로 패키징하려면 다음과 같이 build.gradle에 추가해줍니다.&lt;/p&gt;
&lt;pre id=&quot;code_1761814072870&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 실행 가능한 Fat JAR (Uber JAR)를 만들기 위한 설정
jar {
    // application 플러그인에서 설정한 mainClass(Main.java)를 MANIFEST.MF 파일에 추가합니다.
    manifest {
        attributes 'Main-Class': application.mainClass
    }

    // 모든 의존성(라이브러리)을 JAR 파일 내에 포함시킵니다.
    from {
        configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) }
    }

    // 의존성 포함 시 중복 파일이 발생할 경우 처리 전략 (선택 사항이지만 권장)
    duplicatesStrategy = DuplicatesStrategy.EXCLUDE
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 나서 인텔리제이의 gradle 탭에서 task &amp;gt; build를 실행하거나&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;터미널에서 ./gradlew build 를 실행합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러면 build/libs 경로에 jar 파일이 생성되어있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를들어 이렇게 생성된 jar 파일이 demo-1.0-SNAPSHOT.jar 라고 가정하면&lt;/p&gt;
&lt;pre id=&quot;code_1761814293329&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;java -jar .\build\libs\demo-1.0-SNAPSHOT.jar&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;처럼 jar 파일을 실행할 수 있습니다.&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;h2 data-ke-size=&quot;size26&quot;&gt;유닛 테스트&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;java 플러그인에는 JUnit으로 유닛 테스트를 할 수 있는 태스크가 포함되어 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실행을 위한 Main.java 클래스는 위에서 작성했던 Main.java의 내용을 그대로 쓰겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;유닛 테스트를 위한 테스트 클래스(.java)는 다음과 같습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1761821750938&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import demo.exeample.Main;  //Main.java의 패키지 경로
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;

public class AppTest {
    @Test
    public void testApp(){
        String name = &quot;I am tester.&quot;;
        Main app = new Main();
        assertNotNull(app);
        assertTrue(app.showMessage(name));
        try{
            assertTrue(app.getMessage(name).contains(name));	//아래꺼랑 바꿔가면서 테스트
            //assertTrue(app.getMessage(name).contains(&quot;operator&quot;));
        }catch(Exception e){
            e.printStackTrace();
        }
    }
}&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;build.gradle 에 테스트 관련 설정을 해줍니다.&lt;/p&gt;
&lt;pre id=&quot;code_1761822238058&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;repositories {
    //jcenter()
    mavenCentral()
}

dependencies {
    testImplementation platform('org.junit:junit-bom:5.10.0')
    testImplementation 'org.junit.jupiter:junit-jupiter'
}

test {
    useJUnitPlatform()
}&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;이제 명령행에서 gradle test를 실행하시거나 인텔리제이에서 gradle 탭을 이용 test 태스크를 실행하십시오.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;테스트에 대한 보고서가 build/reports/ 경로에 생성됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;html 문서로 되어있으니 브라우저에서 확인 가능합니다.&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;&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;</description>
      <category>DEV&amp;amp;OPS/Java</category>
      <category>build</category>
      <category>gradle</category>
      <category>Groovy</category>
      <category>Java</category>
      <category>도구</category>
      <category>빌드</category>
      <author>ALEPH.GEM</author>
      <guid isPermaLink="true">https://aacii.tistory.com/452</guid>
      <comments>https://aacii.tistory.com/452#entry452comment</comments>
      <pubDate>Thu, 30 Oct 2025 20:50:37 +0900</pubDate>
    </item>
    <item>
      <title>gradle and groovy</title>
      <link>https://aacii.tistory.com/108</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #409d00;&quot;&gt;groovy&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;groovy는 jvm용 스크립트언어이며 gradle은 groovy를 사용한 빌드 도구입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;gradle 소프트웨어 내부에 groovy가 포함되어 있으므로 따로 설치 하지 않아도 됩니다만,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서는 groovy언어 연습용으로 설치해보도록 합시다.&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://groovy.apache.org/download.html&quot;&gt;https://groovy.apache.org/download.html&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1593437082571&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-og-type=&quot;website&quot; data-og-title=&quot;The Apache Groovy programming language - Download&quot; data-og-description=&quot;* Modules:2.4.X: &amp;quot;ant&amp;quot;, &amp;quot;bsf&amp;quot;, &amp;quot;console&amp;quot;, &amp;quot;docgenerator&amp;quot;, &amp;quot;groovydoc&amp;quot;, &amp;quot;groovysh&amp;quot;, &amp;quot;jmx&amp;quot;, &amp;quot;json&amp;quot;, &amp;quot;jsr223&amp;quot;, &amp;quot;nio&amp;quot;, &amp;quot;servlet&amp;quot;, &amp;quot;sql&amp;quot;, &amp;quot;swing&amp;quot;, &amp;quot;test&amp;quot;, &amp;quot;templates&amp;quot;, &amp;quot;testng&amp;quot; and &amp;quot;xml&amp;quot;2.5.0: as above but excluding optional module &amp;quot;bsf&amp;quot; plus &amp;quot;cli-picocli&amp;quot;, &amp;quot;da&quot; data-og-host=&quot;groovy.apache.org&quot; data-og-source-url=&quot;https://groovy.apache.org/download.html&quot; data-og-url=&quot;https://groovy.apache.org/download.html&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://groovy.apache.org/download.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://groovy.apache.org/download.html&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&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;The Apache Groovy programming language - Download&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;* Modules:2.4.X: &quot;ant&quot;, &quot;bsf&quot;, &quot;console&quot;, &quot;docgenerator&quot;, &quot;groovydoc&quot;, &quot;groovysh&quot;, &quot;jmx&quot;, &quot;json&quot;, &quot;jsr223&quot;, &quot;nio&quot;, &quot;servlet&quot;, &quot;sql&quot;, &quot;swing&quot;, &quot;test&quot;, &quot;templates&quot;, &quot;testng&quot; and &quot;xml&quot;2.5.0: as above but excluding optional module &quot;bsf&quot; plus &quot;cli-picocli&quot;, &quot;da&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;groovy.apache.org&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서는 윈도우10, JVM은 JDK 11,&amp;nbsp; Groovy-4.X 을 기준으로 합니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;윈도우용 설치 파일 .msi 를 다운로드 받습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;지원되는 JVM 버전을 확인하신 뒤 각자 JVM 버전에 맞는 Groovy를 다운 받습니다.&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;설치 확인: cmd 명령창에서 아래와 같이 입력해봅니다.&lt;/p&gt;
&lt;pre id=&quot;code_1702206307348&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;groovy -v&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;gradle&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://gradle.org/install&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://gradle.org/install&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1702205231822&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;Gradle | Installation&quot; data-og-description=&quot;Install the Gradle build tool on Linux, macOS or Windows, either manually or using a package manager like SDKMAN! or Homebrew.&quot; data-og-host=&quot;gradle.org&quot; data-og-source-url=&quot;https://gradle.org/install&quot; data-og-url=&quot;https://gradle.org/install/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/dqgvGj/hyUIyuAb4R/kE7umTLpAYaXRVe8xpd8hk/img.png?width=400&amp;amp;height=400&amp;amp;face=0_0_400_400,https://scrap.kakaocdn.net/dn/bboo4h/hyUL1olp5D/OXZ3gHhYQQRsemnT2thmn1/img.png?width=400&amp;amp;height=400&amp;amp;face=0_0_400_400&quot;&gt;&lt;a href=&quot;https://gradle.org/install&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://gradle.org/install&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/dqgvGj/hyUIyuAb4R/kE7umTLpAYaXRVe8xpd8hk/img.png?width=400&amp;amp;height=400&amp;amp;face=0_0_400_400,https://scrap.kakaocdn.net/dn/bboo4h/hyUL1olp5D/OXZ3gHhYQQRsemnT2thmn1/img.png?width=400&amp;amp;height=400&amp;amp;face=0_0_400_400');&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;Gradle | Installation&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Install the Gradle build tool on Linux, macOS or Windows, either manually or using a package manager like SDKMAN! or Homebrew.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;gradle.org&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 intall manually 링크를 클릭합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 binary-only를 클릭하여 다운로드 합니다.&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;시스템 변수 이름 : GRADLE_HOME&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;시스템 변수 값 : 압축 푼 경로 예) C:\gradle-8.5&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 Path값에도 아래와 같이 맨 앞에&amp;nbsp;추가합니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Path 설정 값 : %GRADLE_HOME%\bin;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;설치확인: cmd 입력창에서 아래와 같이 입력해봅니다.&lt;/p&gt;
&lt;pre id=&quot;code_1702206379306&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;gradle -v&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;h3 data-ke-size=&quot;size23&quot;&gt;예제 프로젝트 생성&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로젝트용 폴더를 하나 생성 후 cmd 창에서 그 경로로 이동합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예) d:\gradle\gradle-app&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래와 같이 gradle 명령어로 java프로젝트를 생성합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1702208477954&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;gradle init --type java-library&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;gradle은 태스크를 통해 처리를 실행합니다.&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;h3 data-ke-size=&quot;size23&quot;&gt;생성된 프로젝트의 파일 및 폴더 설명&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;.gradle 폴더 :&amp;nbsp; 태스크로 생성된 파일 등을 보관합니다.&lt;/li&gt;
&lt;li&gt;gradle 폴더: 그레이들 환경을 모아놓은 랩퍼 파일들이 있습니다.&lt;/li&gt;
&lt;li&gt;src 폴더: 프로그램 소스&lt;/li&gt;
&lt;li&gt;build.gradle : 프로젝트의 빌드 내용을 기술합니다. groovy를 통해 실행할 처리들을 작성합니다. plugin과 repositories저장소, dependencies 의존성들을 설정할 수 있습니다. repository의 값으로 &lt;a href=&quot;https://jcenter.bintray.com&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;jcenter()&lt;/a&gt;나 &lt;a href=&quot;https://mvnrepository.com/repos/central&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;mavenCentral()&lt;/a&gt; 같은 것들이 설정되어 있는데 여기에 그레이들에서 사용하는 라이브러리들이 있습니다.&lt;/li&gt;
&lt;li&gt;gradlew, gradlew.bat : 그레이들 명렁어 파일&lt;/li&gt;
&lt;li&gt;settings.gradle 빌드 설정 정보를 기술한 파일입니다.&amp;nbsp; 빌드를 실행하기 전에 읽기 때문에 라이브러리 등을 기술 할 수 있습니다. 루트프로젝트 이름을 지정 할 수 있습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;기존 그레이들 프로젝트를 이클립스에 import&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우선 이클립스에 gradle 플러그인이 market place를 통해 설치되어 있어야 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;build.gradle 파일을 열고 plugin 항목에 'eclipse' 항목을 추가한 뒤 그레이들 명령어로 아래와 같이 실행합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1702210754122&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;gradle eclipse&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러면 이클립스 관련 파일들이 생성되고 이클립스에서 해당 프로젝트를 import 할 수 있게 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;import된 프로젝트를 우클릭한 뒤 configure 항목에서 Add Gradle Nature를 선택하면 그레이들 프로젝트로서 필요한 것들이 추가됩니다.&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;h3 data-ke-size=&quot;size23&quot;&gt;JCENTER 저장소&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;메이븐 저장소도 gradle에서 사용할 수 있지만 gradle도 중앙 저장소 jcenter가 있습니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a title=&quot;jcenter&quot; href=&quot;https://jcenter.bintray.com&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://jcenter.bintray.com&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1704111073581&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;Index of virtualjcenter/&quot; data-og-description=&quot;&quot; data-og-host=&quot;jcenter.bintray.com&quot; data-og-source-url=&quot;https://jcenter.bintray.com&quot; data-og-url=&quot;https://jcenter.bintray.com&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://jcenter.bintray.com&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://jcenter.bintray.com&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&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;Index of virtualjcenter/&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;jcenter.bintray.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&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;&lt;a href=&quot;https://jfrog.com/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://jfrog.com/&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1704111304081&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;Software Supply Chain Platform for DevOps &amp;amp; Security | JFrog&quot; data-og-description=&quot;The JFrog Platform gives you an end-to-end pipeline to control the flow of your binaries from build to production. Power your software updates to the edge&quot; data-og-host=&quot;jfrog.com&quot; data-og-source-url=&quot;https://jfrog.com/&quot; data-og-url=&quot;https://jfrog.com/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/blx95s/hyUTwRhXVY/yPKZknJ87KsZ5c39wsZCj1/img.png?width=1200&amp;amp;height=628&amp;amp;face=0_0_1200_628&quot;&gt;&lt;a href=&quot;https://jfrog.com/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://jfrog.com/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/blx95s/hyUTwRhXVY/yPKZknJ87KsZ5c39wsZCj1/img.png?width=1200&amp;amp;height=628&amp;amp;face=0_0_1200_628');&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;Software Supply Chain Platform for DevOps &amp;amp; Security | JFrog&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;The JFrog Platform gives you an end-to-end pipeline to control the flow of your binaries from build to production. Power your software updates to the edge&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;jfrog.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;&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>DEV&amp;amp;OPS/Java</category>
      <category>gradle</category>
      <category>Groovy</category>
      <category>Java</category>
      <category>그래이들</category>
      <category>그루비</category>
      <category>빌드</category>
      <category>빌드도구</category>
      <category>자바</category>
      <author>ALEPH.GEM</author>
      <guid isPermaLink="true">https://aacii.tistory.com/108</guid>
      <comments>https://aacii.tistory.com/108#entry108comment</comments>
      <pubDate>Thu, 30 Oct 2025 14:58:22 +0900</pubDate>
    </item>
    <item>
      <title>WSL 우분투 배포판에서 Node.js 설치</title>
      <link>https://aacii.tistory.com/450</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;WSL ubuntu 24 기준입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;NVM(Node Version Manager) 설치&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;터미널을 열고 NVM을 설치하기 위한 스크립트를 다운로드하고 실행합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1761480932930&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash&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;curl 명령어로 스크립트를 다운로드하고 | bash 옵션으로 스크립트를 즉시 실행해서 설치를 진행하는 것입니다.&lt;/p&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;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;설치 스크립트에서 ~/.bashrc 파일에 NVM을 로드하는 설정을 추가하기 때문에, 현재 터미널 세션에 변경사항을 적용하려면 셸을 다시 로드하거나 터미널을 재시작해야 합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1761481137338&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;source ~/.bashrc&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;제대로 적용되었는지 확인하기 위해 버전 확인을 해봅니다.&lt;/p&gt;
&lt;pre id=&quot;code_1761481191184&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;nvm --version&lt;/code&gt;&lt;/pre&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;h2 data-ke-size=&quot;size26&quot;&gt;Node.js 설치&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;LTS(Long Term Support) 버전을 설치하는 것을 권장합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1761481358306&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;nvm install --lts&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;설치 후 해당 설치된 버전을 기본값으로 사용하도록 설정합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1761481401040&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;nvm alias default 'lts/*'&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;이 명령은 새 터미널을 열 때마다 LTS 버전이 자동 사용되도록 설정합니다.&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;설치 확인을 위해 Node.js 버전을 확인합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1761481470585&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;node -v&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;보통 Node.js 설치할 때 npm(Node Package Manager)도 같이 설치됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;잘 설치되었는지 확인하려면 npm 버전을 확인해 봅니다.&lt;/p&gt;
&lt;pre id=&quot;code_1761481610565&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;npm -v&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;&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;&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>DEV&amp;amp;OPS/Linux &amp;amp; Cloud</category>
      <category>Linux</category>
      <category>node.js</category>
      <category>ubuntu</category>
      <category>WSL</category>
      <author>ALEPH.GEM</author>
      <guid isPermaLink="true">https://aacii.tistory.com/450</guid>
      <comments>https://aacii.tistory.com/450#entry450comment</comments>
      <pubDate>Sun, 26 Oct 2025 21:27:26 +0900</pubDate>
    </item>
    <item>
      <title>WSL에서 리눅스 개발 환경 설정</title>
      <link>https://aacii.tistory.com/449</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ubuntu 24 배포판 기준입니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;git 설치&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;대부분의 WSL 배포판에는 git이 설치되어 있지만, git 이 설치되어 있지 않은 배포판도 많은 관계로 명시적으로 git을 설치하는 방법을 살펴보겠습니다.&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;1. 우분투 소프트웨어 repository에서 git을 설치합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1761458861196&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;sudo apt-get install git&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;2. 다 설치되었다면 설치된 버전을 확인해 봅니다.&lt;/p&gt;
&lt;pre id=&quot;code_1761458898778&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;git --version&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;3. git 설정으로 사용자 이름과 메일 주소를 설정합니다. 여러 개발자가 협업하는 환경이라면 코드 변경자를 식별할 수 있게 해 줍니다.&lt;/p&gt;
&lt;pre id=&quot;code_1761459039600&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;git config --global user.name &quot;사용자이름&quot;
git config --global user.email &quot;이메일주소&quot;&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;h2 data-ke-size=&quot;size26&quot;&gt;개행 문자 차이 문제&amp;nbsp;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;윈도우와 리눅스는 개행문자(캐리지 리턴: \r, 라인피드: \n) 처리가 다르기 때문에 이른 혼합 해서 사용하는 환경에서 이 개행문자들이 수정된 것으로 git에서 인식할 수도 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;윈도우는 캐리지 리턴과 라인피드(CRLF)를 합쳐서 줄의 끝 문자로 사용하는 반면 유닉스(리눅스) 계열에서는 LF만을 줄의 끝 문자로 취급합니다. 그래서 리눅스에서는 캐리지리턴 문자(^M) 이 추가되었는지 확인해야 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 문제를 해결하려면 윈도우에서 체크아웃할 때는 윈도우의 개행문자를 따르게하고, 커밋할 때는 리눅스의 개행문자로 변환하도록 하는 방법이 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러려면 git 설정을 아래처럼 설정하면 됩니다.&lt;/p&gt;
&lt;pre id=&quot;code_1761459500434&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;git config --global core.autocrlf true&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;이 전역 설정을 적용하면 윈도우의 캐리지 리턴이 리눅스에서는 보이지 않습니다만 사실 해당 파일에는 캐리지리턴 문자가 포함되어 있습니다. 볼 때 다만 캐리지 리턴을 무시해 주는 거죠.&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;h2 data-ke-size=&quot;size26&quot;&gt;윈도우와 WSL에서 git 자격 증명 공유&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;윈도우에 저장된 모든 자격 증명은 WSL에서 사용할 수 있어야 하고, 그 반대의 경우도 마찬가지입니다.&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;1. 윈도우 자격 증명 도우미 구성(윈도우 파워셸)&lt;/p&gt;
&lt;pre id=&quot;code_1761461179267&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;git config --global credential.helper wincred&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;2. WSL에서 윈도우의 자격 증명 도우미와 같은 프로그램을 사용하도록 합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1761462876092&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;git config --global credential.helper &quot;/mnt/c/Program\ Files/Git/mingw64/libexec/git-core/git-redential-wincred.exe&quot;&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;&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;&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;&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;&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;&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;&amp;nbsp;&lt;/p&gt;</description>
      <category>DEV&amp;amp;OPS/Linux &amp;amp; Cloud</category>
      <category>git</category>
      <category>WSL</category>
      <category>개발 환경</category>
      <category>리눅스</category>
      <category>배포판</category>
      <author>ALEPH.GEM</author>
      <guid isPermaLink="true">https://aacii.tistory.com/449</guid>
      <comments>https://aacii.tistory.com/449#entry449comment</comments>
      <pubDate>Wed, 22 Oct 2025 21:50:24 +0900</pubDate>
    </item>
    <item>
      <title>Windows 11 설치(Upgrade) 및 로컬 계정 생성 방법</title>
      <link>https://aacii.tistory.com/447</link>
      <description>&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;h2 data-ke-size=&quot;size26&quot;&gt;Windows 11 새로 설치 시 로컬(Local) 계정 생성 방법&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;네트워크가 연결되지 않은 환경이거나 기존 윈도우 처럼 로컬 계정으로 운영체제에 로그인 하려면 윈도우 설치시 로컬 계정을 생성해야 합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;Windows 11은 사용자(User)의 로그인을 Microsoft 계정이 기본 값으로 되어있습니다.&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;이 때 Shfit + F10 키를 눌러서 CMD 창을 실행하고 다음 명령어를 입력해줍니다.&lt;/p&gt;
&lt;pre id=&quot;code_1760786468309&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;oobe\bypassnro&lt;/code&gt;&lt;/pre&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;그리고 나서 &quot;제한된 설치로 계속&quot; 을 선택하면 기존 윈도우10 처럼 로컬 계정을 생성하고 로그인 할 수 있게 됩니다.&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;h2 style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;Windows 11 지원 안되는 Winodws 10 PC에서 Upgrade 설치(우회)&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;windows 11은 TPM 등 설치 조건이 까다로운 관계로 구형 PC의 경우 windows 10을 사용하는 경우가 많습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이런 상황에서 windows 10의 지원 종료되기 때문에 windows 11으로 upgrade를 하고 싶어도 할 수 없는 경우를 위한 우회 설치 방법을 소개합니다.&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://www.microsoft.com/ko-kr/software-download/windows11&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;MS Windows 11 다운로드 링크&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1760787072471&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;Windows 11 다운로드&quot; data-og-description=&quot;이 옵션은 부팅 가능한 설치 미디어(USB 플래시 드라이브, DVD)를 만들거나 가상 컴퓨터(.ISO 파일)을 만들어 Windows 11을 설치하려는 사용자를 위한 옵션입니다. 이 다운로드는 제품 키를 통해 올바&quot; data-og-host=&quot;www.microsoft.com&quot; data-og-source-url=&quot;https://www.microsoft.com/ko-kr/software-download/windows11&quot; data-og-url=&quot;https://www.microsoft.com/ko-kr/software-download/windows11&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bkBYVU/hyZMatW3v4/UZkzsmy2A2AyyS8AOrUUX1/img.jpg?width=431&amp;amp;height=270&amp;amp;face=0_0_431_270&quot;&gt;&lt;a href=&quot;https://www.microsoft.com/ko-kr/software-download/windows11&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.microsoft.com/ko-kr/software-download/windows11&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bkBYVU/hyZMatW3v4/UZkzsmy2A2AyyS8AOrUUX1/img.jpg?width=431&amp;amp;height=270&amp;amp;face=0_0_431_270');&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;Windows 11 다운로드&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;이 옵션은 부팅 가능한 설치 미디어(USB 플래시 드라이브, DVD)를 만들거나 가상 컴퓨터(.ISO 파일)을 만들어 Windows 11을 설치하려는 사용자를 위한 옵션입니다. 이 다운로드는 제품 키를 통해 올바&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.microsoft.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기에서 Winodws 11 디스크 이미지 (ISO) 다운로드를 선택해서 한국어를 선택 후 64-bit 다운로드 합니다.&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;다운로드가 완료되면 해당 iso 파일을 탐색기에서 더블 클릭(탑재)하면 iso 이미지가 드라이브 탑재됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CMD를 입력해서 명령 프롬프트를 실행한뒤 탑재된 드라이브로 이동합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(예를 들어 iso 이미지가 탑재된 드라이브가 만약 G 드러이브 인경우 아래 처럼 입력해서 드라이브를 변경할 수 있습니다.)&lt;/p&gt;
&lt;pre id=&quot;code_1760788362523&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;G:&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;그리고 아래 명령어를 입력합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1760787382762&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;setup /product server&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;그러면 Windows Server 설치 화면이 나오면서 Windows 11을 우회 설치 할 수 있습니다.&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;1. 설치프로그램 창이 뜨면 &quot;설치 프로그램에서 업데이트를 다운로드하는 방법 변경&quot; 을 누릅니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 업데이트, 드라이버 및 옵션 기능 가져오기 창에서 &quot;나중에&quot; 를 선택하고 다음을 누릅니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. 관련 통지 및 사용 조건 창에서는 동의를 누릅니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. 유지할 항목 선택 화면이 나오면 &quot;파일, 설정 및 앱 유지하기&quot;를 선택합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;5. 설치 준비 완료 화면이 나오면 설치 버튼을 누릅니다.&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;이후 설치가 진행되고 windows 11이 정상 설치됩니다.&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;&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;&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>DEV&amp;amp;OPS/Snippets</category>
      <category>TPM</category>
      <category>Upgrade</category>
      <category>windows 10</category>
      <category>Windows 11</category>
      <category>계정</category>
      <category>로컬 계정</category>
      <category>생성</category>
      <category>설치</category>
      <author>ALEPH.GEM</author>
      <guid isPermaLink="true">https://aacii.tistory.com/447</guid>
      <comments>https://aacii.tistory.com/447#entry447comment</comments>
      <pubDate>Sat, 18 Oct 2025 20:24:54 +0900</pubDate>
    </item>
    <item>
      <title>https 테스트 용 SSL 사설 인증서 Tomcat 적용</title>
      <link>https://aacii.tistory.com/446</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h1 id=&quot;SSL사설인증서Tomcat9적용-HTTPS테스트용SSL사설인증서Tomcat9적용방법&quot; style=&quot;color: #172b4d;&quot;&gt;HTTPS 테스트용 SSL 사설 인증서 Tomcat 9 적용 방법&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 HTTPS 포트는 8443 을 사용할 것입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CentOS7, JDK11, Tomcat9 기준으로 작성되었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 id=&quot;SSL사설인증서Tomcat9적용-HTTPS통신Handshake과정&quot; style=&quot;color: #172b4d;&quot; data-ke-size=&quot;size26&quot;&gt;HTTPS 통신 Handshake 과정&lt;/h2&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;서버측: 서버 정보가 담긴 인증서와 공개키-개인키 쌍을 생성한 뒤 공개키를 인증기관(CA)에 등록합니다. (개인키는 서버측에서 관리하고 공개키는 인증기관에 등록되며 브라우저에 내장 됨)&lt;/li&gt;
&lt;li&gt;클라이언트 측: 실제 데이터를 암호화할 때 필요한 대칭키 자체를 이 인증기관에 등록된 공개키로 암호화해서 이 암호문을 서버측에 전송합니다.&lt;/li&gt;
&lt;li&gt;서버측: 클라이언트에서 전송된 암호문을 개인키(1에서 생성했던)를 써서 복호화하여 실제 클라이언트와 통신할 데이터를 암호화할 대칭키(암호키와 복호키가 같아서 대칭키)를 획득합니다.&lt;/li&gt;
&lt;li&gt;클라이언트 측과 서버측은 이제 대칭키를 안전하게 나눠 가졌으므로 이제 데이터를 이 대칭키로 암호화-복호화하여 통신합니다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 id=&quot;SSL사설인증서Tomcat9적용-SSL(SecureSocketLayer)사설인증서&quot; style=&quot;color: #172b4d;&quot; data-ke-size=&quot;size26&quot;&gt;SSL(Secure Socket Layer) 사설 인증서&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;HTTPS 통신을 위한 SSL 인증서는 보통 symantec, comodo 등 공인 인증기관에 비용을 지불하고 인증서를 받아서 웹서버나 WAS에 적용합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러나 HTTPS 테스트용으로 직접 인증서를 생성해서 사용하는 것을 사설 인증서라고 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 id=&quot;SSL사설인증서Tomcat9적용-Tomcat의SSL인증서&quot; style=&quot;color: #172b4d;&quot; data-ke-size=&quot;size26&quot;&gt;Tomcat의 SSL 인증서&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Tomcat에서 지원하는 keystore의 타입은 JKS, PKCS11, PKCS12 입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;JKS: JAVA 표준 키스토어 형식&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;PKCS12: 인터넷 표준 형식&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;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 id=&quot;SSL사설인증서Tomcat9적용-JDK를이용한사설인증서생성과keystore파일생성&quot; style=&quot;color: #172b4d;&quot; data-ke-size=&quot;size26&quot;&gt;JDK를 이용한 사설 인증서 생성과 keystore 파일 생성&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;JDK의 keytool 명령어를 이용해 인증서와 keystore파일을 생성할 수 있습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1761006754769&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;keytool -genkeypair \
 -alias tomcat \
 -keyalg RSA \
 -keysize 2048 \
 -validity 365 \
 -keystore keystore.p12 \
 -storetype PKCS12&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;-alias tomcat : 인증서 별칭&lt;/li&gt;
&lt;li&gt;-keyalg RSA : 키 생성 알고리즘을 RSA로 설정&lt;/li&gt;
&lt;li&gt;-keysize 2048 : 키 길이&lt;/li&gt;
&lt;li&gt;-validity 365: 유효기간 1년&lt;/li&gt;
&lt;li&gt;-keystore keystore.p12: 키스토어 파일명 지정&lt;/li&gt;
&lt;li&gt;-storetype PKCS12: 키스토어 유형 (JDK9이상)&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;tomcat 설정에 키스토어파일을 지정해주면 마찬가지로 HTTPS 통신을 사용할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 id=&quot;SSL사설인증서Tomcat9적용-Tomcat설정&quot; style=&quot;color: #172b4d;&quot; data-ke-size=&quot;size26&quot;&gt;Tomcat 설정&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;톰캣 디렉토리 내에 conf/server.xml 파일을 수정합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;https 관련 &amp;lt;Connector&amp;gt; 설정을 해줍니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;tomcat의 server.xml에 기본적으로 주석 처리 되어있는 &amp;lt;Connector&amp;gt;설정은 두가지가 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하나는 JSSE방식으로&amp;nbsp;org.apache.coyote.http11.Http11NioProtocol 프로토콜을 사용합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다른 하나는 APR 방식으로 org.apache.coyote.http11.Http11AprProtocol 프로토콜을 사용합니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서는 간단한 JSSE방식으로 설정하겠습니다.&amp;nbsp;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1761006775216&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;Connector port=&quot;8443&quot;
            protocol=&quot;org.apache.coyote.http11.Http11NioProtocol&quot; 
            SSLEnabled=&quot;true&quot;
            maxThreads=&quot;150&quot;
            scheme=&quot;https&quot;
            secure=&quot;true&quot;
            keystoreFile=&quot;키스토어 파일의 절대경로&quot;
            keystorePass=&quot;키스토어 생성시 입력한 패스워드&quot;
            keystoreType=&quot;PKCS12&quot;
            clientAuth=&quot;false&quot;
            sslProtocol=&quot;TLS&quot; /&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;&amp;nbsp;&lt;/p&gt;
&lt;h2 id=&quot;SSL사설인증서Tomcat9적용-방화벽에서8443포트를열어줍니다.&quot; style=&quot;color: #172b4d;&quot; data-ke-size=&quot;size26&quot;&gt;방화벽에서 8443 포트를 열어줍니다.&amp;nbsp;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 8443 포트가 사용중인지 확인&lt;/p&gt;
&lt;pre id=&quot;code_1761006816608&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;sudo firewall-cmd --list-ports | grep 8443&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;2. 8443 tcp 포트 열기&lt;/p&gt;
&lt;pre id=&quot;code_1761006841639&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;sudo firewall-cmd --permanent --add-port=8443/tcp&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;&amp;nbsp;3. 방화벽 갱신&lt;/p&gt;
&lt;pre id=&quot;code_1761006857991&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;sudo firewall-cmd --reload&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;그리고 tomcat을 재시작하면 https 통신이 가능합니다.&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;h2 id=&quot;SSL사설인증서Tomcat9적용-테스트&quot; style=&quot;color: #172b4d;&quot; data-ke-size=&quot;size26&quot;&gt;테스트&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;브라우저에서&amp;nbsp;&lt;a style=&quot;color: #0052cc;&quot; href=&quot;https://localhost:8443/&quot;&gt;https://localhost:8443&lt;/a&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;h2 id=&quot;SSL사설인증서Tomcat9적용-HTTP를HTTPS으로리디렉션설정&quot; style=&quot;color: #172b4d;&quot; data-ke-size=&quot;size26&quot;&gt;HTTP 를 HTTPS 으로 리디렉션 설정&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;server.xml 에서 http 커넥터인 8080 포트 설정에 redirectPort 설정을 해줍니다.&lt;/p&gt;
&lt;pre id=&quot;code_1761006886813&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;Connector port=&quot;8080&quot;
           protocol=&quot;HTTP/1.1&quot;
           connectionTimeout=&quot;20000&quot;
           redirectPort=&quot;8443&quot; /&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;이 설정은 tomcat이 8080 요청을 https 포트인 8443 포트로 리디렉션 해줍니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 id=&quot;SSL사설인증서Tomcat9적용-모든요청에대해HTTPS으로만허용설정(선택적설정)&quot; style=&quot;color: #172b4d;&quot; data-ke-size=&quot;size26&quot;&gt;모든 요청에 대해 HTTPS으로만 허용 설정(선택적 설정)&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$CATALINA_HOME/webapps/앱컨텍스트루트/WEB-INF/web.xml 에 다음 항목을 추가해줍니다.&lt;/p&gt;
&lt;pre id=&quot;code_1761006937860&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;security-constraint&amp;gt;
    &amp;lt;web-resource-collection&amp;gt;
        &amp;lt;web-resource-name&amp;gt;HTTPS Redirect&amp;lt;/web-resource-name&amp;gt;
        &amp;lt;url-pattern&amp;gt;/*&amp;lt;/url-pattern&amp;gt;
    &amp;lt;/web-resource-collection&amp;gt;
    &amp;lt;user-data-constraint&amp;gt;
        &amp;lt;transport-guarantee&amp;gt;CONFIDENTIAL&amp;lt;/transport-guarantee&amp;gt;
    &amp;lt;/user-data-constraint&amp;gt;
&amp;lt;/security-constraint&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;이 설정은 모든 요청(/*) 에 대해서 https 으로만 허용하게 합니다.&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;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 id=&quot;SSL사설인증서Tomcat9적용-URL에포트번호없이접속하는설정&quot; style=&quot;color: #172b4d;&quot; data-ke-size=&quot;size26&quot;&gt;URL에 포트 번호 없이 접속하는 설정&amp;nbsp;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Tomcat이 직접 443 포트를 사용하도록 설정&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;sever.xml 에서 https 커넥터의 포트를 8443이 아닌 443으로 설정&lt;/p&gt;
&lt;pre id=&quot;code_1761006961220&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;Connector port=&quot;443&quot;
           protocol=&quot;org.apache.coyote.http11.Http11NioProtocol&quot;
           SSLEnabled=&quot;true&quot;
           maxThreads=&quot;150&quot;
           scheme=&quot;https&quot;
           secure=&quot;true&quot;
           keystoreFile=&quot;/절대경로/keystore.p12&quot;
           keystorePass=&quot;비밀번호&quot;
           keystoreType=&quot;PKCS12&quot;
           sslProtocol=&quot;TLS&quot; /&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;그러나 1024 이하의 포트는 root 만이 열수 있기 때문에 root으로 tomcat을 실행하는 것보다 setcap으로 443포트를 열게 해줍니다.&lt;/p&gt;
&lt;pre id=&quot;code_1761006980291&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;sudo setcap 'cap_net_bind_service=+ep' $CATALINA_HOME/bin/java&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;참고로 운영 환경에서는 보통 웹서버(Nginx)로 443 포트를 리스닝하고 Tomcat으로 전달하는 방식을 사용합니다.&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;hr data-ke-style=&quot;style1&quot; /&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;h1 id=&quot;SSL사설인증서Tomcat9적용-OpenSSL을이용해사설인증서를발급하는방법(참고)&quot; style=&quot;color: #172b4d;&quot;&gt;OpenSSL을 이용해 사설 인증서를 발급하는 방법(참고)&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 id=&quot;SSL사설인증서Tomcat9적용-OpenSSL다운로드및설치&quot; style=&quot;color: #172b4d;&quot; data-ke-size=&quot;size26&quot;&gt;OpenSSL 다운로드 및 설치&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사설 인증서를 발급하기 위해 openssl 이라는 프로그램이 필요합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a style=&quot;color: #0052cc;&quot; href=&quot;https://sourceforge.net/projects/openssl/files/latest/download?source=typ_redirect&quot;&gt;open ssl download&lt;/a&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1761007008298&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;yum install -y openssl&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;open ssl을 실행시켜서 open ssl 프롬프트 상태에서 실행해도 되지만 여기서는 bash 프롬프트에서 실행합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 id=&quot;SSL사설인증서Tomcat9적용-CA(CertificateAuthority:인증기관)개인키생성&quot; style=&quot;color: #172b4d;&quot; data-ke-size=&quot;size26&quot;&gt;CA(Certificate Authority: 인증기관) 개인키 생성&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;RSA 알고리즘으로 2048 bit 길이의 CA 개인키를 생성&lt;/p&gt;
&lt;pre id=&quot;code_1761007028602&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;openssl genrsa -out rootCA.key 2048&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;h2 id=&quot;SSL사설인증서Tomcat9적용-CACSR(CertificateSigningRequest:인증서명요청)생성&quot; style=&quot;color: #172b4d;&quot; data-ke-size=&quot;size26&quot;&gt;CA CSR(Certificate Signing Request: 인증 서명 요청) 생성&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CSR은 인증서를 발급하는데 필요한 인증 요청서입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위에서 생성한 CA 개인키를 이용해서 CSR을 생성합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1761007044769&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;openssl req -new -key rootCA.key -out rootCA.csr&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;실행하면 서버 정보를 입력해야 합니다.&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;&lt;span&gt;Country Name : KR&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;State or Province Name : Seoul&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Locality Name : SeoCho&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Organization Name : Googol&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Organizational Unit Name: YouDube&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Common Name: 192.168.0.111&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Email Address :&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;a style=&quot;color: #0052cc;&quot; href=&quot;mailto:mymail@gmail.co.kr&quot;&gt;mymail@gmail.co.kr&lt;/a&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;h2 id=&quot;SSL사설인증서Tomcat9적용-서버측개인키생성&quot; style=&quot;color: #172b4d;&quot; data-ke-size=&quot;size26&quot;&gt;서버측 개인키 생성&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위와 동일한 명령어로 서버측 개인키를 생성합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1761007059365&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;openssl genrsa -out server.key 2048&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;h2 id=&quot;SSL사설인증서Tomcat9적용-서버측CSR생성&quot; style=&quot;color: #172b4d;&quot; data-ke-size=&quot;size26&quot;&gt;서버측 CSR 생성&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;마찬가지로 CSR도 생성합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1761007072614&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;openssl req -new -key server.key -out server.csr&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;h2 id=&quot;SSL사설인증서Tomcat9적용-서버CRT(인증서)생성&quot; style=&quot;color: #172b4d;&quot; data-ke-size=&quot;size26&quot;&gt;서버 CRT(인증서) 생성&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위에서 CA 인증서를 만들었으니 이 CA로부터 인증 받은 서버의 인증서를 생성해야 합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1761007094585&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;openssl x509 -req -in server.csr -CA rootCA.crt -CAKey rootCA.key -CAcreateserial -out server.crt&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;위 일련의 작업들이 모두 성공했다면 다음과 같은 파일들이 생성됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;rootCA.crt,&amp;nbsp;rootCA.csr, rootCA.key, rootCA.srl, server.crt, server.csr, server.key&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 중에서 server.crt가 우리가 tomcat 서버에 적용해야 할 서버 인증서 입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 id=&quot;SSL사설인증서Tomcat9적용-Tomcat에서사용할수있는keystore파일생성&quot; style=&quot;color: #172b4d;&quot; data-ke-size=&quot;size26&quot;&gt;Tomcat에서 사용할 수 있는 keystore 파일 생성&lt;/h2&gt;
&lt;pre id=&quot;code_1761007115772&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;openssl pkcs12 -export -in server.crt -inkey server.key -out keystore.p12 -name tomcat&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;여기서는 pkcs12 포멧으로 생성했습니다.&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;hr data-ke-style=&quot;style1&quot; /&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;&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>DEV&amp;amp;OPS/Linux &amp;amp; Cloud</category>
      <category>https</category>
      <category>Self</category>
      <category>SSL</category>
      <category>리눅스</category>
      <category>사설</category>
      <category>인증서</category>
      <author>ALEPH.GEM</author>
      <guid isPermaLink="true">https://aacii.tistory.com/446</guid>
      <comments>https://aacii.tistory.com/446#entry446comment</comments>
      <pubDate>Mon, 21 Apr 2025 17:34:13 +0900</pubDate>
    </item>
    <item>
      <title>JAVA Thread</title>
      <link>https://aacii.tistory.com/206</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;자바 어플리케이션은 main()스레드 외에 병렬로 처리하는 스레드를 같이 실행할 수 있습니다.&amp;nbsp;보통은 단순하고 긴 작업이나 I/O작업들을 멀티 스레드로 병렬로 작업하는 것이 효율적입니다. 그러나, 너무 많은 스레드를 실행하면 각 스레드간 context switching 에 시간을 더 소비하게 되어 오히려 효율이 떨어지게 됩니다.&amp;nbsp;java.lang.Thread 클래스로부터 extends 하거나 Runnable 인터페이스로부터 implements 해서 스레드를 생성할 수 있습니다.&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;Runnable 구현 방법&lt;/p&gt;
&lt;pre id=&quot;code_1649914641165&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import java.awt.Toolkit;

public class BeepTask implements Runnable {

	@Override
	public void run() {
		Toolkit toolkit = Toolkit.getDefaultToolkit();
		for(int i=0; i&amp;lt;5;i++) {
			toolkit.beep();
			System.out.println(&quot;beep&quot;);
			try {
				Thread.sleep(1000);
			}catch(Exception e) {
				e.printStackTrace();
			}
		}
	}
	
	public static void main(String[] args) {
		Runnable beepTask = new BeepTask();
		Thread thread = new Thread(beepTask);
		thread.start();
	}
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Thread클래스로부터 상속받아 실행하는 방법(main 스레드 동시 실행)&lt;/p&gt;
&lt;pre id=&quot;code_1649915137505&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import java.awt.Toolkit;

public class BeepThread extends Thread{
	@Override
	public void run() {
		Toolkit toolkit = Toolkit.getDefaultToolkit();
		for(int i=0; i&amp;lt;5;i++) {
			toolkit.beep();
			System.out.println(&quot;beep&quot;);
			try {
				Thread.sleep(1000);
			}catch(Exception e) {
				e.printStackTrace();
			}
		}
	}
	
	public static void main(String[] args) {
		Thread thread = new BeepThread();
		thread.start();
		//메인스레드 0.5초간격 동시 진행
		for(int i=0;i&amp;lt;5;i++) {
			System.out.println(&quot;빞&quot;);
			try {
				Thread.sleep(500);
			}catch(Exception e){
				e.printStackTrace();
			}
		}
	}
}&lt;/code&gt;&lt;/pre&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;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;스레드의 이름은 크게 의미는 없지만 디버깅할 때 스레드를 구분하는 용도로 가끔 사용합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1649917267533&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public class ThreadNameEx {

	public static void main(String[] args) {
		Thread mainThread = Thread.currentThread();
		System.out.println(&quot;시작 스레드: &quot;+mainThread.getName());
		
		ThreadA threadA = new ThreadA();
		System.out.println(&quot;작업 스레드: &quot;+threadA.getName());
		threadA.start();
		
		ThreadB threadB = new ThreadB();
		System.out.println(&quot;작업 스레드: &quot;+threadB.getName());
		threadB.start();
	}

}

class ThreadA extends Thread{
	public ThreadA() {
		setName(&quot;ThreadA&quot;);	//스레드 이름 설정
	}
	
	public void run() {
		for(int i=0;i&amp;lt;2;i++) {
			System.out.println(getName() + &quot;가 실행&quot;);
		}
	}
}

class ThreadB extends Thread{
	public ThreadB() {
		setName(&quot;ThreadB&quot;);	//스레드 이름 설정
	}
	
	public void run() {
		for(int i=0;i&amp;lt;2;i++) {
			System.out.println(getName() + &quot;가 실행&quot;);
		}
	}
}&lt;/code&gt;&lt;/pre&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;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;스레드를 병렬로 실행하다보면 우선순위를 지정해줘야 할 필요가 생깁니다.&amp;nbsp;우선 순위는 1부터 10까지 부여되는데 숫자가 클수록 우선순위가 높습니다.&amp;nbsp;우선 순위의 기본값은 5입니다.&amp;nbsp;주의할 점은 우선 순위가 높다고 반드시 작업이 먼저 끝나는 것은 아닙니다.&amp;nbsp;스레드의 개수가 많을 수록 우선 순위대로 작업을 완료할 확률이 높아집니다.&lt;/p&gt;
&lt;pre id=&quot;code_1649918947613&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public class PriorityEX {

	public static void main(String[] args) {
		for(int i=1; i&amp;lt;=10; i++) {
			Thread thread = new CalcThread(&quot;thread&quot;+i);
			if(i != 10) {
				thread.setPriority(Thread.MIN_PRIORITY); 	//가장 낮은 우선순위: 1
			}else {
				thread.setPriority(Thread.MAX_PRIORITY);	//가장 높은 우선순위: 10
			}
			thread.start();
		}
	}

}

class CalcThread extends Thread{
	public CalcThread(String name) {
		setName(name);
	}
	public void run() {
		long sum = 0;
		for(int i=0;i&amp;lt;10000000;i++) {
			sum += i;
		}
		System.out.println(getName() +&quot;:&quot;+sum);
	}
}&lt;/code&gt;&lt;/pre&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;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;시스템 자원(메모리)를 여러 스레드가 공유해서 진행하다보면 결과 값이 엉터리가 될 수도 있기 때문에 각 스레드들을 동기화가 필요할 수도 있습니다.&amp;nbsp;스레드가 사용중인 자원을 작업이 끝날때까지 잠금을 걸어서 다른 스레드가 사용할 수 없도록 해야 합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1649997064821&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public class MainThreadEx {

	public static void main(String[] args) {
		Calculator calculator = new Calculator();
		
		User1 user1 = new User1();
		user1.setCalculator(calculator);
		user1.start();
		
		User2 user2 = new User2();
		user2.setCalculator(calculator);
		user2.start();
	}

}

class Calculator{
	private int memory;
	public int getMemory() {
		return memory;
	}
	public void setMemory(int memory) {
		this.memory = memory;
		try {
			Thread.sleep(2000);	//스레드를 2초 정지
		}catch(InterruptedException e) {
			e.printStackTrace();
		}
		System.out.println(Thread.currentThread().getName()+&quot;: &quot;+this.memory);
		
	}
}

class User1 extends Thread{
	private Calculator calculator;
	public void setCalculator(Calculator calculator) {
		this.setName(&quot;User1&quot;);
		this.calculator = calculator;
	}
	public void run() {
		calculator.setMemory(100); 	//공유객체 메모리에 100을 저장
	}
}

class User2 extends Thread{
	private Calculator calculator;
	public void setCalculator(Calculator calculator) {
		this.setName(&quot;User2&quot;);
		this.calculator = calculator;
	}
	public void run() {
		calculator.setMemory(40); 	//공유객체 메모리에 40을 저장
	}
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;User1스레드가 Calculator객체의 memory 필드에 100을 저장하고 2초간 일시정지 되며, 그동안 User2 스레드가 memory필드 값을 40으로 변경합니다.&amp;nbsp;2초가 지나 정지상태에 있던 User1 스레드가 memory필드값을 출력하면 40이 나오게 됩니다.&amp;nbsp;의도대로 였다면 User1은 100을 출력하고 User2는 40을 출력했어야하지만 결과는 User1, Use2둘다 40을 출력하게 됩니다.&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;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;스레드가 객체 내부 동기화 블록에 들어가면 객체에 잠금을 걸어 다른 스레드가 실행하지 못하도록 해야하는데, synchronized 키워드를 이용하면 됩니다.&amp;nbsp;위 예제에서 setMemory()메서드를 동기화 하려면 아래와 같이 하면됩니다.&lt;/p&gt;
&lt;pre id=&quot;code_1649997738226&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public class MainThreadEx {

	public static void main(String[] args) {
		Calculator calculator = new Calculator();
		
		User1 user1 = new User1();
		user1.setCalculator(calculator);
		user1.start();
		
		User2 user2 = new User2();
		user2.setCalculator(calculator);
		user2.start();
	}

}

class Calculator{
	private int memory;
	public int getMemory() {
		return memory;
	}
	public synchronized void setMemory(int memory) {
		this.memory = memory;
		try {
			Thread.sleep(2000);	//스레드를 2초 정지
		}catch(InterruptedException e) {
			e.printStackTrace();
		}
		System.out.println(Thread.currentThread().getName()+&quot;: &quot;+this.memory);
		
	}
}

class User1 extends Thread{
	private Calculator calculator;
	public void setCalculator(Calculator calculator) {
		this.setName(&quot;User1&quot;);
		this.calculator = calculator;
	}
	public void run() {
		calculator.setMemory(100); 	//공유객체 메모리에 100을 저장
	}
}

class User2 extends Thread{
	private Calculator calculator;
	public void setCalculator(Calculator calculator) {
		this.setName(&quot;User2&quot;);
		this.calculator = calculator;
	}
	public void run() {
		calculator.setMemory(40); 	//공유객체 메모리에 40을 저장
	}
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;setMemory()에 synchronized를 걸어주면 User1스레드가 setMemory() 실행을 마칠 때까지 User2스레드는 기다려야 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 예제처럼 메소드에 직접 잠금을 하는 방법 말고도 아래처럼 synchronized블록으로 잠금 대상인 Calulator 인스턴스 객체를 잠글 수 있습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1649998037759&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public synchronized void setMemory(int memory) {
	synchronized(this){
		this.memory = memory;
		try {
			Thread.sleep(2000);	//스레드를 2초 정지
		}catch(InterruptedException e) {
			e.printStackTrace();
		}
		System.out.println(Thread.currentThread().getName()+&quot;: &quot;+this.memory);
	}
}&lt;/code&gt;&lt;/pre&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;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;스레드를 start()하면 바로 스레드가 시작되는 것처럼 보이지만 사실은 실행 대기(RUNNABLE) 상태가 됩니다.&amp;nbsp;이러한 실행 대기 상태의 스레드들 중에서 우선순위 스케줄링으로 선택된 스레드가 실행됩니다.&amp;nbsp;실행중인 스레드가 할당된 시간을 다 사용하면 작업이 마무리되지 않아도 다시 대기 상태로 돌아가고 스케줄링에 의해&amp;nbsp; 다른 스레드가 선택되어 실행상태가 됩니다.&amp;nbsp;&amp;nbsp;이렇게 스레드들이 번갈아가면서 실행되다가 작업을 모두 완료하면 스레드가 종료(Terminated) 상태가 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;경우에 따라 스레드가 일시 정지(WAITING:다른스레드응답대기, TIMED_WAITING(일정시간대기), BLOCKED(락이 플릴때까지대기)) 상태가 되기도 합니다.&amp;nbsp;일시 정지된 스레드들이 다시 실행 상태가 되기 위해선 먼저 실행 대기 상태로 돌아가야 합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1650257593808&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public class TargetThreadEx {

	public static void main(String[] args) {
		StatePrintThread statePrintThread = new StatePrintThread(new TargetThread());
		statePrintThread.start();
	}

}

class StatePrintThread extends Thread{
	private Thread targetThread;
	public StatePrintThread(Thread targetThread) {
		this.targetThread = targetThread;
	}
	public void run() {
		while(true) {
			Thread.State state = targetThread.getState();
			System.out.println(&quot;타겟 스레드 상태: &quot;+state);
			if(state == Thread.State.NEW) {
				targetThread.start();
			}
			if(state == Thread.State.TERMINATED) {
				break;
			}
			try {
				Thread.sleep(300);
			}catch(Exception e) {
				e.printStackTrace();
			}
		}
	}
}

class TargetThread extends Thread{
	public void run() {
		for(long i = 0; i&amp;lt;1000000000; i++) {
		}
		
		try {
			Thread.sleep(1500);
		}catch(Exception e) {
			e.printStackTrace();
		}
		
		for(long i = 0; i&amp;lt;1000000000; i++) {
		}
	}
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;다른 스레드에게 실행 양보 yield&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;동시에 여러 스레드가 실행중일 때, 무의미한 대기 시간을 줄이기 위해 다른 스레드에게 실행을 양보할 수 있습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1650258880527&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public class YieldEx {

	public static void main(String[] args) {
		ThreadA1 threadA1 = new ThreadA1();
		ThreadB1 threadB1 = new ThreadB1();
		threadA1.start();
		threadB1.start();
		
		try {
			Thread.sleep(3000);
		}catch(Exception e) {
			e.printStackTrace();
		}
		threadA1.work = false;
		
		try {
			Thread.sleep(3000);
		}catch(Exception e) {
			e.printStackTrace();
		}
		threadA1.work =true;
		
		try {
			Thread.sleep(3000);
		}catch(Exception e) {
			e.printStackTrace();
		}
		threadA1.stop = true;
		threadB1.stop = true;
	}

}

class ThreadA1 extends Thread{
	public boolean stop = false;
	public boolean work = true;
	public void run() {
		while(!stop) {
			if(work) {
				System.out.println(&quot;ThreadA1 작업 내용&quot;);
			}else {
				Thread.yield(); //work가 false면 양보
			}
		}
		System.out.println(&quot;ThreadA1 종료&quot;);
	}
}

class ThreadB1 extends Thread{
	public boolean stop = false;
	public boolean work = true;
	
	public void run() {
		while(!stop) {
			if(work) {
				System.out.println(&quot;ThreadB1 작업 내용&quot;);
			}else {
				Thread.yield();
			}
		}
		System.out.println(&quot;ThreadB1 종료&quot;);
	}
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;다른 스레드의 종료를 기다림 join&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;어느 한 스레드가 어떠한 다른 작업을 요청 한 뒤 스레드를 일시 정지 했다가 요청한 결과값을 받으면 다시 실행해야 하는 경우가 있습니다.&amp;nbsp;예를 들어, ThreadA가 ThreadB의 join()메서드를 호출하면 ThreadA는 ThreadB가 종료될 때 까지 일시정지가 되고 ThreadB가 종료되어야 ThreadA가 비로소 일시정지에서 풀려 이후의 코드가 실행하게 되는 것입니다.&lt;/p&gt;
&lt;pre id=&quot;code_1650261768932&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public class JoinEX {

	public static void main(String[] args) {
		SumThread sumThread = new SumThread();
		sumThread.start();
		try {
			sumThread.join();
		}catch(Exception e) {
			e.printStackTrace();
		}
		System.out.println(&quot;합:&quot;+sumThread.getSum());
	}

}

class SumThread extends Thread{
	private long sum;
	public long getSum() {
		return sum;
	}
	public void setSum(long sum) {
		this.sum = sum;
	}
	public void run() {
		for(int i = 1; i &amp;lt;= 100; i++) {
			sum += i;
		}
	}
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;스레드 간 협업: wait, notify, notifyAll&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;경우에 따라, 두개의 스레드가 교대로 번갈아가면서 실행해야 하는 경우도 있습니다.&amp;nbsp;아래 예제는 두 스레드의 작업을 WorkObject의 methodA()아 methodB()에 정의 하고, 두 스레드 ThreadA2와 ThreadB2가 번갈아가면서 methodA()와 methodB()를 호출합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1650264164296&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public class WaitNotifyEx {

	public static void main(String[] args) {
		WorkObject sharedObject = new WorkObject();	//공유객체 생성
		ThreadA2 threadA2 = new ThreadA2(sharedObject);
		ThreadB2 threadB2 = new ThreadB2(sharedObject);
		threadA2.start();
		threadB2.start();
	}
}

class WorkObject{
	public synchronized void methodA() {
		System.out.println(&quot;ThreadA2의 methodA() 실행&quot;);
		notify();	//일시 정지한 ThreadB2를 실행 대기 상태로 만듦
		try {
			wait();
		}catch(Exception e) {
			e.printStackTrace();
		}
	}
	
	public synchronized void methodB() {
		System.out.println(&quot;ThreadB2의 methodB() 실행&quot;);
		notify(); 	//일시 정지한 ThreadA2를 실행 대기 상태로 만듦
		try {
			wait();
		}catch(Exception e) {
			e.printStackTrace();
		}
	}
}

class ThreadA2 extends Thread{
	private WorkObject workObject;
	public ThreadA2(WorkObject workObject) {
		this.workObject = workObject;
	}
	public void run() {
		for(int i=0;i&amp;lt;10;i++) {
			workObject.methodA();
		}
	}
}

class ThreadB2 extends Thread{
	private WorkObject workObject;
	public ThreadB2(WorkObject workObject) {
		this.workObject = workObject;
	}
	public void run() {
		for(int i=0;i&amp;lt;10;i++) {
			workObject.methodB();
		}
	}
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;생산자 스레드가 생성한 데이터를 소비자 스레드가 읽는 작업을 교대로 실행하는 예제&lt;/p&gt;
&lt;pre id=&quot;code_1650269017715&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public class WaitNotify {

	public static void main(String[] args) {
		DataBox dataBox = new DataBox();
		
		ProducerThread producerThread = new ProducerThread(dataBox);
		ConsumerThread consumerThread = new ConsumerThread(dataBox);
		producerThread.start();
		consumerThread.start();
	}

}

class DataBox{
	private String data;
	public synchronized String getData() {
		if(this.data == null) {
			try {
				wait(); 	//소비자 스레드를 일시 정지 상태로 
			}catch(InterruptedException e) {
				e.printStackTrace();
			}
		}
		String returnValue = data;
		System.out.println(&quot;소비자 스레드가 읽은 데이터:&quot;+returnValue);
		data = null;	//data필드를 null로
		notify();		//생산자 스레드를 실행 대기 상태로
		return returnValue;
	}
	public synchronized void setData(String data) {
		if(this.data != null) {
			try {
				wait(); 	//생산자 스레드를 일시 정지 상태로 
			}catch(InterruptedException e) {
				e.printStackTrace();
			}
		}
		this.data = data;	//data 필드를 세팅
		System.out.println(&quot;생산자 스레드가 생성한 데이터:&quot;+data);
		notify();	//소비자 스레드를 실행 대기 상태로
	}
}

//생산자(저장) 스레드
class ProducerThread extends Thread{
	private DataBox dataBox;
	public ProducerThread(DataBox dataBox) {
		this.dataBox = dataBox;
	}
	public void run() {
		for(int i = 1; i &amp;lt;= 3; i++) {
			String data = &quot;Data-&quot; + i;
			dataBox.setData(data);
		}
	}
}

//소비자(읽는) 스레드
class ConsumerThread extends Thread{
	private DataBox dataBox;
	public ConsumerThread(DataBox dataBox) {
		this.dataBox = dataBox;
	}
	public void run() {
		for(int i=0;i&amp;lt;=3;i++) {
			String data = dataBox.getData();
		}
	}
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;스레드의 안전한 종료 stop, interrupt&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;stop() 메소드는 deprecated되었는데 사용중이던 자원들이 종료되지 않고 남겨지기 때문입니다.&amp;nbsp;그래서 stop 플래그를 통해서 run() 메소드의 종료를 유도합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1650270513406&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public class StopFlagEx {

	public static void main(String[] args) {
		PrintThread1 printThread = new PrintThread1();
		printThread.start();
		try {
			Thread.sleep(1000);
		}catch(Exception e) {
			e.printStackTrace();
		}
		printThread.setStop(true);
	}

}

class PrintThread1 extends Thread{
	private boolean stop;
	public void setStop(boolean stop) {
		this.stop = stop;
	}
	public void run() {
		while(!stop) {
			System.out.println(&quot;실행 중&quot;);
		}
		System.out.println(&quot;자원 정리&quot;);
		System.out.println(&quot;실행 종료&quot;);
	}
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;interrupt() 메소드는 스레드가 일시 정지 상태에 있을 때 InterrruptedException을 발생시켜 스레드를 종료시킬 수 있습니다.&amp;nbsp;주의할 점은 일시 정지 상태에 있을 때만 예외를 발생시킨다는 점입니다.&lt;/p&gt;
&lt;pre id=&quot;code_1650345390715&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public class InterruptEx {

	public static void main(String[] args) {
		Thread thread = new PrintThread2();
		thread.start();
		try {
			Thread.sleep(1000);
		}catch(Exception e) {
			e.printStackTrace();
		}
		thread.interrupt(); //interruptedException 발생
	}

}

class PrintThread2 extends Thread{
	public void run() {
		while(true) {
			System.out.println(&quot;실행 중&quot;);
			if(Thread.interrupted()) {
				break;
			}
		}
		
		System.out.println(&quot;자원 정리&quot;);
		System.out.println(&quot;실행 종료&quot;);
	}
}&lt;/code&gt;&lt;/pre&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;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;데몬 스레드는 주 스레드의 보조적인 역할을 수행하는 스레드를 말합니다.&amp;nbsp;주 스레드가 종료되면 데몬 스레드도 강제적으로 종료됩니다.&amp;nbsp;이 점을 제외하면 일반 스레드와 다르지 않습니다.&amp;nbsp;스레드를 데몬으로 만들기 위해서는 주 스레드가 데몬이 될 스레드에 setDaemon(true)를 호출하면 됩니다.&amp;nbsp;주의할 점은 start() 호출되고 나서 setDaemon(true)를 호출하면 IllegalThreadStateException이 발생하기 때문에 start()하기 전에 setDaemon(true)를 호출해야 합니다.&amp;nbsp;아래 예제는 자동 저장하는 데몬 스레드 예제 입니다.&lt;/p&gt;
&lt;pre id=&quot;code_1650346362737&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public class DaemonEx {

	public static void main(String[] args) {
		AutoSaveThread autoSaveThread = new AutoSaveThread();
		autoSaveThread.setDaemon(true);
		autoSaveThread.start();
		try {
			Thread.sleep(3000);
		}catch(Exception e) {
			e.printStackTrace();
		}
		System.out.println(&quot;메인 스레드 종료&quot;);
	}

}

class AutoSaveThread extends Thread{
	public void save() {
		System.out.println(&quot;작업 내용 저장.&quot;);
	}
	
	public void run() {
		while(true) {
			try {
				Thread.sleep(1000);
			}catch(Exception e) {
				break;
			}
			save();
		}
	}
}&lt;/code&gt;&lt;/pre&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;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;스레드 그룹은 관련된 스레드끼리 묶어서 관리할 목적으로 이용합니다.&amp;nbsp;JVM이 실행되면 system스레드 그룹을 만들고 하위 스레드 그룹으로 main을 만들고 메인 스레드를 mian 그룹에 포함시킵니다.&amp;nbsp;스레드는 명시적으로 그룹을 지정하지 않으면 자신을 생성한 스레드와 같은 그룹에 속하게 됩니다.&amp;nbsp;아래 예제의 AutoSaveThread는 위의 예제의 AutoSaveThread 입니다.&lt;/p&gt;
&lt;pre id=&quot;code_1650357409121&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import java.util.Map;
import java.util.Set;

public class ThreadInfoEx {

	public static void main(String[] args) {
		AutoSaveThread autoSaveThread = new AutoSaveThread();
		autoSaveThread.setName(&quot;AutoSaveThread&quot;);
		autoSaveThread.setDaemon(true);
		autoSaveThread.start();
		
		Map&amp;lt;Thread, StackTraceElement[]&amp;gt; map = Thread.getAllStackTraces();
		Set&amp;lt;Thread&amp;gt; threads = map.keySet();
		for(Thread thread : threads) {
			System.out.println(&quot;Name: &quot;+thread.getName() + ((thread.isDaemon()) ? &quot;(데몬)&quot; : &quot;(주)&quot;));
			System.out.println(&quot;\t&quot; + &quot;소속그룹: &quot;+ thread.getThreadGroup().getName());
			System.out.println();
		}
	}

}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;스레드를 그룹으로 지정하면 interrupt()를 이용해서 일괄 종료 시킬 수 있습니다.&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;h3 data-ke-size=&quot;size23&quot;&gt;스레드 풀&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://aacii.tistory.com/209&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://aacii.tistory.com/209&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1743066716026&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;Thread Pool&quot; data-og-description=&quot;스레드 풀 스레드 풀은 작업 스레드를 제한된 개수(총 개수)만큼 정해놓고 작업 큐에 들어오는 작업들을 하나씩 스레드가 맡아서 처리합니다. 작업 처리가 끝난 스레드는 다시 작업 큐에서 새로&quot; data-og-host=&quot;blog.aacii.net&quot; data-og-source-url=&quot;https://aacii.tistory.com/209&quot; data-og-url=&quot;https://blog.aacii.net/209&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/c5TZQ2/hyYyVSakRk/A1KYW7WKqvtOl7sIBLEOT0/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/bNrRB3/hyYxEpOdOn/XiTIes9aECCUO3OkQBEWn1/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/tabIG/hyYuc9zXWE/jNolzMUzbmAdEiAt6fyVQ1/img.png?width=400&amp;amp;height=400&amp;amp;face=0_0_400_400&quot;&gt;&lt;a href=&quot;https://aacii.tistory.com/209&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://aacii.tistory.com/209&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/c5TZQ2/hyYyVSakRk/A1KYW7WKqvtOl7sIBLEOT0/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/bNrRB3/hyYxEpOdOn/XiTIes9aECCUO3OkQBEWn1/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/tabIG/hyYuc9zXWE/jNolzMUzbmAdEiAt6fyVQ1/img.png?width=400&amp;amp;height=400&amp;amp;face=0_0_400_400');&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;Thread Pool&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;스레드 풀 스레드 풀은 작업 스레드를 제한된 개수(총 개수)만큼 정해놓고 작업 큐에 들어오는 작업들을 하나씩 스레드가 맡아서 처리합니다. 작업 처리가 끝난 스레드는 다시 작업 큐에서 새로&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;blog.aacii.net&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;background-color: #ffffff; color: #172b4d; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;멀티 스레드 개발 가이드 라인&amp;nbsp;&lt;/h3&gt;
&lt;p style=&quot;background-color: #ffffff; color: #172b4d; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal; background-color: #ffffff; color: #172b4d; text-align: start;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;스레드 풀 사용: Executors.newFixedThreadPoll(스레드개수) 을 사용하여 스레드 풀을 생성하고 작업을 Runnable(Callable) 으로 작성해서 작업을 분배합니다.&lt;/li&gt;
&lt;li&gt;DB 연결: 각 스레드별로 DB 연결을 독립적으로 관리하거나 커넥션 풀(HikariCP, DBCDP)을 사용하여 안전하게 커넥션을 관리합니다.&lt;/li&gt;
&lt;li&gt;트랜잭션 관리: insert나 update가 있으면 트랜잭션 처리를 하여 데이터의 일관성을 유지합니다.&lt;/li&gt;
&lt;li&gt;파일 처리: 각 스레드가 서로 다른 파일을 처리하도록 작업을 분배하여 입출력 충돌을 최소화합니다.&lt;/li&gt;
&lt;li&gt;공유 자원 동기화: 공유 자원(파일, 컬렉션)은 동기화 블록(synchronized)를 사용하고 java.util.concurrent의 스레드에 안전한 컬렉션을 사용합니다.&lt;/li&gt;
&lt;li&gt;예외 처리:&amp;nbsp; 예외 발생시 각 스레드 내부에서 예외/로깅/재시도 처리를 해줍니다.&lt;/li&gt;
&lt;li&gt;작업 결과 통합: 각 스레드가 반환하는 결과를 Future 객체(CompletableFuture)로 받아서, 전체 작업이 끝난 후 결과를 모으거나 후속 작업을 진행합니다.&lt;/li&gt;
&lt;li&gt;작업 완료 후 ExecutorService.shutdown() 또는 shutdownNow()를 호출해서 스레드 풀을 종료시켜 작업들을 안전하게 처리합니다.&lt;/li&gt;
&lt;li&gt;메모리 누수 방지: DB커넥션과 파일 스트림 등 자원은 반드시 close()하고 try-with-resources 구분으로 예외 발생시에도 자원이 정상 해제 되도록 합니다.&lt;/li&gt;
&lt;li&gt;테스트 시 모니터링 도구를 이용해 실시간 스레드 동작 상태를 점검합니다.&lt;/li&gt;
&lt;/ol&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;</description>
      <category>DEV&amp;amp;OPS/Java</category>
      <category>Callable</category>
      <category>runnable</category>
      <category>thread</category>
      <category>가이드</category>
      <category>멀티 스레드</category>
      <category>스레드</category>
      <category>자바</category>
      <author>ALEPH.GEM</author>
      <guid isPermaLink="true">https://aacii.tistory.com/206</guid>
      <comments>https://aacii.tistory.com/206#entry206comment</comments>
      <pubDate>Thu, 27 Mar 2025 18:13:27 +0900</pubDate>
    </item>
    <item>
      <title>WSL 2 파일 시스템</title>
      <link>https://aacii.tistory.com/445</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;WSL은 두 운영체제를 분리하여 네트워크로만 접근할 수 있게 하지 않고 직접 파일을 주고 받을 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;윈도우에서 리눅스 파일 시스템을 실행할 수 있게 WSL은 리눅스 파일 시스템에서 수행되는 모든 작업을 NT 커널 작업으로 변환합니다.&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;h2 data-ke-size=&quot;size26&quot;&gt;가상 하드웨어 디스크(VHD)&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;WSL 2는 모든 리눅스 파일을 ext4 파일 시스템을 사용하는 가상 하드웨어 디스크(VHD)에 저장합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;VHD 파일은 처음 만들어질 때 최대 256GB 까지 늘어날 수 있도록 만들어지고 사용량에 따라 최대 제한에 도달할 때까지 자동으로 크기가 조절됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;한계에 도달하면 디스크 공간 부족 오류가 발생합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;디스크 공간 부족을 해결하려면 다음 단계를 진행하여 VHD 크기를 확장합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;1. 실행중인 wsl의 인스턴스들을 종료&lt;/h4&gt;
&lt;pre id=&quot;code_1742217095074&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;wsl --shutdown&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;2. 파워셸으로 리눅스(ubuntu) 배포판의 설치 패키지 이름 PackageFamilyName과 ext4.vhdx 파일의 전체 경로를 찾습니다.&lt;/h4&gt;
&lt;pre id=&quot;code_1742217445131&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$pkgFamilyName = (Get-AppxPackage -Name &quot;*ubuntu*&quot;).PackageFamilyName
$Path = &quot;$env:LOCALAPPDATA\Packages\$pkgFamilyName\LocalState\*.vhdx&quot;
$vhd = Get-ChildItem $Path
Resize-VHD -Path $VHD.FullName -SizeBytes 500GB&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;Resize-VHD 명령어를 이용하여 VHD 파일 크기를 원하는 크기(500GB)으로 확장해줍니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;3. WSL2 리눅스 배포판을 다시 시작합니다.&lt;/h4&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;4. 리눅스 내부에 변경된 사항을 적용해야 합니다.&amp;nbsp;&amp;nbsp;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음 명령어로 파일 시스템이 탑재되었는지 확인&lt;/p&gt;
&lt;pre id=&quot;code_1742217778484&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;sudo mount -t devtmpfs none /dev&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ext4 유형의 파일 시스템을 필터링해서 사용중인 루트 파일 시스템을 찾아야 합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1742217858362&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;mount | grep ext4&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;5. /dev/sdb 처럼 해당 마운트되는 디바이스(dev) 항목의 이름을 복사하고 다음 명령어를 실행합니다.&lt;/h4&gt;
&lt;pre id=&quot;code_1742217947061&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;sudo resize2fs /dev/sdb&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를들어 sda, sdb, sdc 처럼 sd 다음 문자가 달라집니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;resize2fs는 리눅스 배포판에 없다면 별도로 설치해야 합니다.&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;h2 data-ke-size=&quot;size26&quot;&gt;volfs&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;volfs는 모든 리눅스 시스템 파일과 홈 디렉터리를 저장하는 데 사용되는 WSL의 기본 파일 시스템입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모든 파일은 윈도우 파일 시스템 안에 있고 이 파일 시스템의 목적은 윈도우와 상호운용성이 아니라 /home 이나 /root같은 리눅스 환경을 제공하는 것입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 윈도우에서 새 파일이 추가되더라도 volfs에서 무시되고 사용할 수 없습니다.&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;h2 data-ke-size=&quot;size26&quot;&gt;drvfs&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 파일 시스템은 리눅스 배포판에 자동으로 마운트 되어 윈도우의 파일과 리눅스의 파일 사이의 상호 운용 가능하게 해줍니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;윈도우에서 사용하는 C드라이브가 리눅스에 /mnt/c 로 마운트 되어 사용할 수 있게 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;drvfs 파일 시스템 안의 파일을 윈도우에서 열면 파일의 퍼미션이 접근 제어 목록을 통해 적용됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;WSL 환경에서 root 권한으로도 NTFS 파일 시스템의 특정 파일(예: /mnt/c/Windows)에 접근하지 못하는 경우가 있습니다.&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;h2 data-ke-size=&quot;size26&quot;&gt;tmpfs&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;tmpfs는 메모리와 디스크 기반 스왑 공간을 조합하여 파일 시스템을 만들어 데이터를 읽고 쓰는 속도가 매우 빠릅니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;tmpfs를 마운트 해제하면 그 안의 모든 데이터가 손실됩니다.&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;h2 data-ke-size=&quot;size26&quot;&gt;procfs, sysfs&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;procfs, sysfs는 장치 구성 같은 시스템 정보가 있는 특수한 파일 시스템입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;profs는 /proc 디렉터리에서 찾을 수 있는 시스템 관련 정보들을 제공합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;/sys는 sysfs 인데 전원 설정이나 이더넷 물리 주소 같은 정보를 얻는데 사용할 수 있습니다.&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;h2 data-ke-size=&quot;size26&quot;&gt;리눅스 배포판 내에서 윈도우 파일 접근하기&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;drvfs 파일 시스템을 이용해서 언급했듯 NTFS의 C:\ 드라이브는 WSL에서 /mnt/c/ 으로 마운트 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이를 이용해서 WSL에서 윈도우 파일들을 접근할 수 있어서 리눅스 명령어나 앱으로 윈도우의 파일을 사용할 수 있습니다.&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;h2 data-ke-size=&quot;size26&quot;&gt;윈도우에서 리눅스 배포판 내의 파일 접근하기&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;윈도우에서 WSL의 리눅스의 파일에 접근하려면 윈도우 탐색기의 경로 입력창에 UNC 경로인&amp;nbsp;&amp;nbsp; \\wsl$\&amp;nbsp; &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;&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;&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;&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;</description>
      <category>DEV&amp;amp;OPS/Linux &amp;amp; Cloud</category>
      <category>vhd</category>
      <category>WSL</category>
      <category>WSL 2</category>
      <category>디스크</category>
      <category>파일 시스템</category>
      <author>ALEPH.GEM</author>
      <guid isPermaLink="true">https://aacii.tistory.com/445</guid>
      <comments>https://aacii.tistory.com/445#entry445comment</comments>
      <pubDate>Thu, 13 Mar 2025 22:40:30 +0900</pubDate>
    </item>
    <item>
      <title>WSL 배포판 관리</title>
      <link>https://aacii.tistory.com/443</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;배포판 목록 조회&lt;/h2&gt;
&lt;pre id=&quot;code_1741696023038&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;wsl -l
wsl --list&lt;/code&gt;&lt;/pre&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;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위에서 조회한 배포판의 목록을 이용해서 --setdefault 또는 -s 매개변수로 WSL 기본 배포판을 지정할 수 있습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1741696894307&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;wsl --set-default 배포판이름&lt;/code&gt;&lt;/pre&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;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;WSL의 배포판 패키지는 tar 파일로 내보내면 쉽게 백업할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;관리자 권한으로 명령 프롬프트에서 다음과 같이 export 할 수 있습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1741697810910&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;wsl --export 배포판이름 저장될윈도우경로\백업될파일이름.tar&lt;/code&gt;&lt;/pre&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;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;백업 파일이 c:\temp\ 경로에 복사되었다고 가정하면 다음과 같이 복원할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 c:\temp\ 경로는 배포판의 루트 파일 시스템이 설치됩니다.&lt;/p&gt;
&lt;pre id=&quot;code_1741698018639&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;wsl --import 배포판새이름 c:\temp\ c:\temp\백업된파일이름.tar&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러면 배포판 목록에서 import한 배포판을 확인할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가져온 배포판의 모든 파일, 루트 파일 시스템이 담긴 rootfs 폴더를 확인할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;WSL 배포판 등록 취소와 제거&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음과 같이 배포판 등록을 취소 할 수 있습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1741698635019&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;wsl --unregister 배포판이름&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;배포판을 제가할 때는 시작 메뉴에서 배포판 이름을 검색한 뒤 제거 버튼을 눌러주면 됩니다.&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;&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;</description>
      <category>DEV&amp;amp;OPS/Linux &amp;amp; Cloud</category>
      <category>WSL</category>
      <category>관리</category>
      <category>배포판</category>
      <author>ALEPH.GEM</author>
      <guid isPermaLink="true">https://aacii.tistory.com/443</guid>
      <comments>https://aacii.tistory.com/443#entry443comment</comments>
      <pubDate>Tue, 11 Mar 2025 22:14:33 +0900</pubDate>
    </item>
    <item>
      <title>WSL(Windows Subsystem for Linux) 설치와 설정</title>
      <link>https://aacii.tistory.com/440</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;WSL2&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;WSL은 리눅스 가상 머신(VM)을 실행하지 않고도 기본적인 리눅스 바이너리를 그대로 윈도우에서 실행할 수 있드록 해줍니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;단순히 리눅스 bash 쉘만 제공하는 것을 넘어서 실제 리눅스와 똑같이 보이도록 동작하게 해줍니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;단, 윈도우10 버전 1903 빌드 18362 이상에서 설치 가능합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;WSL2 기능 활성화&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1.윈도우의 PowerShell을 관리자 권한으로 실행합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;시작 버튼 &amp;gt; powershell 입력 &amp;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. 아래 명령어를 입력해서 wsl을 활성화 합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1739971953941&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1739971963942&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart&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;3. 윈도우를 재부팅합니다.&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;pre id=&quot;code_1741871224553&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;optionalfeatures&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러면 Windows 기능 켜기/끄기 가 실행되는데&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Windows Subsystem for Linux 와 Virtual Machine Platform을 체크해서 설치합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;단, 비슷한 가상 기술인 Hyper-V와 Windows Hypervisor Platform은 설치하지 않아도 됩니다.&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;h2 data-ke-size=&quot;size26&quot;&gt;WSL2 리눅스 커널 업데이트&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;X64 리눅스 커널 업데이트 패키지 다운로드&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;fileblock&quot; data-ke-align=&quot;alignLeft&quot;&gt;&lt;a href=&quot;https://blog.kakaocdn.net/dn/ta6b0/btsMoH0VMdk/slEYZoqbAdDYmwl4XKGWXk/wsl_update_x64.msi?attach=1&amp;amp;knm=tfile.msi&quot; class=&quot;&quot;&gt;
    &lt;div class=&quot;image&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;desc&quot;&gt;&lt;div class=&quot;filename&quot;&gt;&lt;span class=&quot;name&quot;&gt;wsl_update_x64.msi&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;size&quot;&gt;16.31MB&lt;/div&gt;
&lt;/div&gt;
  &lt;/a&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;arm54 리눅스 커널 업데이트 패키지 다운로드&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;fileblock&quot; data-ke-align=&quot;alignLeft&quot;&gt;&lt;a href=&quot;https://blog.kakaocdn.net/dn/dgslQi/btsMnRcd0ay/TUIagzW29YiB2FrPXgzZkk/wsl_update_arm64.msi?attach=1&amp;amp;knm=tfile.msi&quot; class=&quot;&quot;&gt;
    &lt;div class=&quot;image&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;desc&quot;&gt;&lt;div class=&quot;filename&quot;&gt;&lt;span class=&quot;name&quot;&gt;wsl_update_arm64.msi&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;size&quot;&gt;8.65MB&lt;/div&gt;
&lt;/div&gt;
  &lt;/a&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;background-color: #121212; color: #ececec; text-align: start;&quot;&gt;WslRegisterDistribution failed with error:&lt;/span&gt;이 발생합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;설치가 완료되면 윈도우 PowerShell 에서 다음과 같이 입력합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1739972257895&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;wsl --set-default-version 2&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;h2 data-ke-size=&quot;size26&quot;&gt;Microsoft Store에서 리눅스 배포판 다운로드 및 설치&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;마이크로소프트 스토어에서 리눅스 배포판을 다운로드 받을 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 시작 메뉴 &amp;gt; Microsoft Store 검색 후 실행&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. Linux or ubuntu 검색 후 다운로드&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서는 우분투24를 다운로드받고 설치하겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약 실행 시 &lt;span style=&quot;background-color: #121212; color: #ececec; text-align: start;&quot;&gt;WslRegisterDistribution failed with error: &lt;/span&gt;이 발생한다면 아래 방법으로 해결해봅니다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;1. 시작 &amp;gt; 실행 &amp;gt; %localappdata%\Packages 입력합니다.&lt;br /&gt;2..CanonicalGroupLimited.Ubuntu_ 로 검색해서 나오는 폴더를 찾아서 오른쪽 클릭을 합니다.&lt;br /&gt;3..속성 &amp;gt; 일반 &amp;gt; 고급 &amp;gt; &quot;내용을 압축하여 디스크 공간 절약&quot; 의 체크 박스의 체크를 해제합니다.&lt;br /&gt;4..Ubuntu App을 재실행 합니다..&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;정상적으로 실행되면 username과 password를 등록합니다. (윈도우 사용자 계정과 일치할 필요는 없습니다.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 사용자는 배포판의 기본 사용자이고 sudo 그룹에 추가됩니다.&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;h2 data-ke-size=&quot;size26&quot;&gt;WSL 으로 설치된 리눅스 배포판 실행&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;설치된 배포판 확인 방법(powershell 이나 cmd 에서)&lt;/p&gt;
&lt;pre id=&quot;code_1741089443036&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;wsl.exe -list
혹은
wsl.exe -l&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;위 명렁어에 나오는 리눅스 배포판 이름을 이용해서 wsl 실행 시 특정 배포판으로 실행 할 수 있습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1741089501586&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;wsl.exe -d 설치된배포판이름&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;C:\Users\사용자계정\AppData\Local\Microsoft\WindowsApps 경로에는 설치된 배포판 이름의 exe 파일이 존재하는데 이 exe 파일으로도 리눅스 배포판을 실행할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;간편하게 시작 메뉴에서 설치한 배포판을 검색해서 app으로도 실행 할 수 있습니다.&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;h2 data-ke-size=&quot;size26&quot;&gt;WSL 사용자 계정 구성 및 관리&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;특정 리눅스 배포판에 대한 암호를 잊어버렸다면 파워셸을 열고 리눅스 배포판의 루트 사용자로 실행합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1741179914158&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;wsl -u root -d 리눅스배포판이름&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;그런 다음 아래처럼 passwd 명령어로 사용자의 암호를 재 설정합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1741180036149&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;passwd 사용자계정&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;h2 data-ke-size=&quot;size26&quot;&gt;우분투 배포판 업데이트와 업그레이드&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;업데이트와 업그레이드의 차이점은 업데이트는 현재 제품을 수정하는 것이고 업그레이드는 현제 재품을 새 버전으로 교체하는 것입니다.&lt;/p&gt;
&lt;pre id=&quot;code_1741180796152&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;sudo apt update &amp;amp;&amp;amp; sudo apt upgrade&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;Advanced Package Tool(apt)는 우분투 배포판 패키지 처리를 도와주는 도구입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;apt update는 /etc/apt/sources.list 파일에 있는 배포판 소프트웨어 저장소에서 사용 가능한 패키지 목록 데이터베이스를 갱신하는 작업입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;반면 apt upgrade는 실제 소프트웨어를 업그레이드 하는 것입니다.&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;h2 data-ke-size=&quot;size26&quot;&gt;메모리, CPU 제한 값 설정&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;딥러닝 학습을 시키려면 많은 자원이 필요한데 기본 설정으로는 부족할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;%USERPROFILE%\.wslconfig 파일을 만들고 적절히 편집합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1741871676142&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# Settings apply across all Linux distros running on WSL 2
[wsl2]

# Limits VM memory to use no more than 4 GB, this can be set as whole numbers using GB or MB
memory=32GB 

# Sets the VM to use two virtual processors
processors=8

# Specify a custom Linux kernel to use with your installed distros. The default kernel used can be found at https://github.com/microsoft/WSL2-Linux-Kernel
kernel=C:\\temp\\myCustomKernel

# Sets additional kernel parameters, in this case enabling older Linux base images such as Centos 6
kernelCommandLine = vsyscall=emulate

# Sets amount of swap storage space to 8GB, default is 25% of available RAM
swap=16GB

# Sets swapfile path location, default is %USERPROFILE%\AppData\Local\Temp\swap.vhdx
swapfile=C:\\temp\\wsl-swap.vhdx

# Disable page reporting so WSL retains all allocated memory claimed from Windows and releases none back when free
pageReporting=false

# Turn on default connection to bind WSL 2 localhost to Windows localhost. Setting is ignored when networkingMode=mirrored
localhostforwarding=true

# Disables nested virtualization
nestedVirtualization=false

# Turns on output console showing contents of dmesg when opening a WSL 2 distro for debugging
debugConsole=true

# Enable experimental features
[experimental]
sparseVhd=true&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;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;WSL 에서 배포판 리눅스의 포트로 연결하는 방법&lt;/h2&gt;
&lt;pre id=&quot;code_1741917814840&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# WSL의 IP 주소를 172.19.120.200 이라 가정합니다.

# 윈도우즈 파워쉘의 네트워크 관리 기능인 netsh 명령어를 이용하여 5432 포트를 포워딩 설정합니다.
netsh interface portproxy add v4tov4 listenport=5432 listenaddress=0.0.0.0 connectport=5432 connectaddress=172.19.120.200

# 다시 netsh 명령어로 방화벽 규칙을 추가합니다.
netsh advfirewall firewall add rule name=&quot;WSL PostgreSQL Port Forwarding&quot; dir=in action=allow protocol=TCP localport=5432&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;background-color: #ffffff; color: #172b4d; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #172b4d; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;방화벽 규칙에서 사용한 옵션 설명&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #172b4d; text-align: start;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;name=&quot;WSL PostgreSQL Port Forwarding&quot;&lt;/b&gt;: 규칙의 이름을 지정합니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;dir=in&lt;/b&gt;: 규칙의 방향을 지정하여, direction=inbound 즉, 들어오는 트래픽에 적용합니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;action=allow&lt;/b&gt;: 트래픽을 허용합니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;protocol=TCP&lt;/b&gt;: 규칙이 TCP 프로토콜에 적용됩니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;localport=5432&lt;/b&gt;: 로컬 포트 5432로 향하는 트래픽에 적용됩니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000;&quot; data-ke-size=&quot;size26&quot;&gt;wsl.conf&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;/etc/wsl.conf 에 있는 파일을 사용해서 모든 배포판의 시작 구성을 설정할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 파일은 생성되지 않았다면 직접 생성해줘야 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;key=value 형식으로 속성을 지정해주면 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;변경사항을 적용하려면 wsl을 다시 시작해야 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;color: #000000;&quot; data-ke-size=&quot;size20&quot;&gt;[automount]&amp;nbsp;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 항목은 wsl 시작시 리눅스에서 파일시스템을 자동으로 마운트 해줍니다.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 13.0232%;&quot;&gt;속성&lt;/td&gt;
&lt;td style=&quot;width: 11.628%;&quot;&gt;형식&lt;/td&gt;
&lt;td style=&quot;width: 12.2093%;&quot;&gt;기본값&lt;/td&gt;
&lt;td style=&quot;width: 63.1395%;&quot;&gt;설명&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 13.0232%;&quot;&gt;enabled&lt;/td&gt;
&lt;td style=&quot;width: 11.628%;&quot;&gt;true/false&lt;/td&gt;
&lt;td style=&quot;width: 12.2093%;&quot;&gt;true&lt;/td&gt;
&lt;td style=&quot;width: 63.1395%;&quot;&gt;true를 설정하면 리눅스의 /mnt 경로 아래에 윈도우 운영체제의 C:\ , D:\ 등 고정 드라이브들이 자동으로 마운트 됩니다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 13.0232%;&quot;&gt;mountFsTab&lt;/td&gt;
&lt;td style=&quot;width: 11.628%;&quot;&gt;true/false&lt;/td&gt;
&lt;td style=&quot;width: 12.2093%;&quot;&gt;true&lt;/td&gt;
&lt;td style=&quot;width: 63.1395%;&quot;&gt;true를 설정하면 고정 드라이브 외에 /etc/fstab 파일에 서술된 항목들이 자동으로 마운트 됩니다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 13.0232%;&quot;&gt;root&lt;/td&gt;
&lt;td style=&quot;width: 11.628%;&quot;&gt;문자열&lt;/td&gt;
&lt;td style=&quot;width: 12.2093%;&quot;&gt;/mnt/&lt;/td&gt;
&lt;td style=&quot;width: 63.1395%;&quot;&gt;고정 드라이브들을 마운트할 기본 경로를 설정합니다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 13.0232%;&quot;&gt;options&lt;/td&gt;
&lt;td style=&quot;width: 11.628%;&quot;&gt;쉼표로 구분된 문자열&lt;/td&gt;
&lt;td style=&quot;width: 12.2093%;&quot;&gt;빈 문자열&lt;/td&gt;
&lt;td style=&quot;width: 63.1395%;&quot;&gt;drvfs 마운트시 세부 옵션을 추가로 지정할 수 있습니다.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;options 항목에서 사용하는 drvfs 마운트 옵션은 다음과 같습니다.&lt;/p&gt;
&lt;blockquote style=&quot;color: #666666; text-align: left;&quot; data-ke-style=&quot;style2&quot;&gt;uid: 모든 파일의 소유자가 사용하는 사용자 ID&lt;br /&gt;gid: 모든 파일의 소유자가 사용하는 그룹 ID&lt;br /&gt;umask: 모든 파일(디렉터리)를 제외하기 위한 8진수 권한 마스크&lt;br /&gt;fmask: 모든 일반 파일을 제외하기 위한 8진수 권한 마스크&lt;br /&gt;dmask: 모든 디렉터리를 제외하기 위한 8진수 권한 마스&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;color: #000000;&quot; data-ke-size=&quot;size20&quot;&gt;[network]&lt;/h4&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 20.3488%;&quot;&gt;속성&lt;/td&gt;
&lt;td style=&quot;width: 13.0233%;&quot;&gt;형식&lt;/td&gt;
&lt;td style=&quot;width: 12.2093%;&quot;&gt;기본값&lt;/td&gt;
&lt;td style=&quot;width: 54.4186%;&quot;&gt;설명&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 20.3488%;&quot;&gt;generateHosts&lt;/td&gt;
&lt;td style=&quot;width: 13.0233%;&quot;&gt;true/false&lt;/td&gt;
&lt;td style=&quot;width: 12.2093%;&quot;&gt;true&lt;/td&gt;
&lt;td style=&quot;width: 54.4186%;&quot;&gt;true로 설정하면 /etc/hosts 파일에 윈도우의 \system32\drivers\etc\hosts의 내용을 반영해줍니다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 20.3488%;&quot;&gt;generateResolvConf&lt;/td&gt;
&lt;td style=&quot;width: 13.0233%;&quot;&gt;true/false&lt;/td&gt;
&lt;td style=&quot;width: 12.2093%;&quot;&gt;true&lt;/td&gt;
&lt;td style=&quot;width: 54.4186%;&quot;&gt;true로 설정하면 /etc/resolv.conf 파일에 WSL에서 사용할 DNS 서버 주소 목록을 생성합니다.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;color: #000000;&quot; data-ke-size=&quot;size20&quot;&gt;[interop]&lt;/h4&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 19.5349%;&quot;&gt;속성&lt;/td&gt;
&lt;td style=&quot;width: 11.2791%;&quot;&gt;형식&lt;/td&gt;
&lt;td style=&quot;width: 11.5116%;&quot;&gt;기본값&lt;/td&gt;
&lt;td style=&quot;width: 57.6744%;&quot;&gt;설명&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 19.5349%;&quot;&gt;Enabled&lt;/td&gt;
&lt;td style=&quot;width: 11.2791%;&quot;&gt;true/false&lt;/td&gt;
&lt;td style=&quot;width: 11.5116%;&quot;&gt;true&lt;/td&gt;
&lt;td style=&quot;width: 57.6744%;&quot;&gt;true로 설정하면 WSL이 notepad.exe 처럼 윈도우 프로세스를 실행할 수 있습니다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 19.5349%;&quot;&gt;appendWindowsPath&lt;/td&gt;
&lt;td style=&quot;width: 11.2791%;&quot;&gt;true/false&lt;/td&gt;
&lt;td style=&quot;width: 11.5116%;&quot;&gt;true&lt;/td&gt;
&lt;td style=&quot;width: 57.6744%;&quot;&gt;true로 설정하면 환경 변수인 $PATH에 윈도우의 PATH 환경 변수의 내용을 자동으로 덧붙입니다.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&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;h2 style=&quot;color: #000000;&quot; data-ke-size=&quot;size26&quot;&gt;WSLENV&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;WSLENV는 윈도우와 WSL 환경 사이 공유되는 설정입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;WSLENV 변수에 대한 변경 사항은 WSL 세션이 종료되면 자동으로 제거됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 계속해서 값들을 유지하려면 .profile 이나 .bash_rc 값으로 설정해야 합니다.&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;blockquote style=&quot;color: #666666; text-align: left;&quot; data-ke-style=&quot;style2&quot;&gt;/p : WSL에서 윈도우 사이에 경로를 변환해야함을 의미합니다.&lt;br /&gt;/l : 환경 변수가 경로 목록임을 나타냅니다.&lt;br /&gt;/u : 이 플래그가 붙은 환경 변수는 윈도우에서 WSL 애플리케이션을 실행할 때만 사용합니다.&lt;br /&gt;/w : 이 플래그가 붙은 환경 변수는 반대로 WSL에서 윈도우 애플리케이션을 실행할 때에만 사용합니다.&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;사용 예제&lt;/p&gt;
&lt;pre id=&quot;code_1741850107412&quot; class=&quot;routeros&quot; style=&quot;background-color: #f8f8f8; color: #383a42;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;$ export FORWSL=/mnt/c
$ export FORWIN=/mnt/c/Data
$ export MYPATHLIST=/mnt/c/Users:/mnt/c/Data
$ export TEMPDIR=/mnt/c/temp
$ export WSLENV=FORWSL/u:FORWIN/w:MYPATHLIST/l:TEMPDIR/p
$ cmd.exe #WSL에서 윈도우 명령 프롬프트를 실행
C:\WINDOWS\system32&amp;gt; echo %TEMPDIR%&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>DEV&amp;amp;OPS/Linux &amp;amp; Cloud</category>
      <category>WSL</category>
      <category>wsl2</category>
      <category>가상</category>
      <category>리눅스</category>
      <category>설정</category>
      <category>설치</category>
      <author>ALEPH.GEM</author>
      <guid isPermaLink="true">https://aacii.tistory.com/440</guid>
      <comments>https://aacii.tistory.com/440#entry440comment</comments>
      <pubDate>Wed, 5 Mar 2025 22:24:29 +0900</pubDate>
    </item>
    <item>
      <title>SimCity 4 러시아워 &amp;amp; 디럭스 에디션</title>
      <link>https://aacii.tistory.com/422</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;구버진 심시티4 실행 종료 문제&lt;/h2&gt;
&lt;p style=&quot;background-color: #ffffff;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;구버전 심시티4는 &lt;span style=&quot;background-color: #ffffff;&quot;&gt;한창 플레이중에 강제로 실행 종료되는 현상이 자주 일어납니다. &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;이것은 듀얼 코어 이상 &lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;CPU&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;에서 주로 발생하는 문제로 &lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;&amp;nbsp;해결 방법은 다음과 같이 하시면 됩니다&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;심시티4 실행&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;작업관리자 실행&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;프로세스 관리에서 &lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;simcity4.exe &lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;를 우클릭&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;선호도 설정 클릭&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&amp;nbsp;cpu0 &lt;span style=&quot;background-color: #ffffff;&quot;&gt;만 체크하고 나머지 전부 체크 해제 합니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p style=&quot;background-color: #ffffff;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;그러나 실행시 마다 매번 병경하기 귀찮기 때문에 다음과 같이 바로가기에 등록해 두면 됩니다. .&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;심시티4 바로가기를 우클릭하여 속성 클릭&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;바로가기 탭의 대상&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;(T) &lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;의 명령라인 끝에 &lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;-CPUcount:1 &lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;을 추가&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p style=&quot;background-color: #ffffff;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;예&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;) &quot;C:\Program Files (x86)\Maxis\SimCity 4\Apps\SimCity 4.exe&quot; -CPUcount:1&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;background-color: #ffffff;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;구버전 심시티4 창 모드&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;/&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;전체화면 모드 실행&lt;/span&gt;&lt;/h2&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;심시티4 바로가기를 우클릭하여 속성 클릭&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;바로가기 탭의 대상&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;(T) &lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;의 명령라인 끝에 &lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;&amp;ndash;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;w &lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;혹은 &lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;&amp;ndash;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;f &lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;를 추가합니다.&amp;nbsp; -&amp;gt; &lt;/span&gt;창모드&lt;span style=&quot;background-color: #ffffff;&quot;&gt;(-w), &lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;전체화면모드&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;(-f)&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p style=&quot;background-color: #ffffff;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;예&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;) &quot;C:\Program Files (x86)\Maxis\SimCity 4\Apps\SimCity 4.exe&quot; -CPUcount:1 -w&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;지원해상도:&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;1280x800, 1440x900, 1680x1050, 1920x1200, 1360x768, 1024x600, 1600x900, 1920x1080&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;background-color: #ffffff;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;심시티4 러시아워 치트키&lt;/span&gt;&lt;/h2&gt;
&lt;p style=&quot;background-color: #ffffff;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;치트를 사용하려면 도구툴이 선택되지 않은 상태에서 &lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;[Ctrl]+[X]&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;를 누르시면 됩니다&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;. &lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;만약 커서가 다른 것으로 바뀌어있을 때는 &lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;ESC&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;를 누른 뒤 &lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;[Ctrl]+[X] &lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;를 누르시면 됩니다&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;stopwatch - 24&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;시간 주기를 일시 정지&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;/&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;시작 &lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;whattimeizit - &lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;원하는 시간을 설정 &lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;whererufrom - &lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;원하는 도시 이름 &lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;hellomynameis - &lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;원하는 시장 이름 &lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;you don't deserve it - &lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;모든 보상 건물 &lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;sizeof - &lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;화면을 확대&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;(1-100) &lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;weaknesspays - &lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;기금에 &lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;1000 &lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;추가 &lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;fightthepower - &lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;모든 건물의 전력 요구 조건을 제거 &lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;zoneria - &lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;비어있는 구역의 색깔을 숨김&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;tastyzots - zots&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;를 제거&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;(zots: &lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;도로&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;전력&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;수도&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;일자리가 없을 때&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;) &lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;howdryiam - &lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;모든 건물의 수도 요구 조건을 제거&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;background-color: #ffffff;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;심시티4 단축키&lt;/span&gt;&lt;/h2&gt;
&lt;p style=&quot;background-color: #ffffff;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;ctrl+` &lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;일시정지&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;ctrl+1 &lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;거북이속도&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;ctrl+2 &lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;코뿔소속도&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;ctrl+3 &lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;치타속도&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;ctrl+f &lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;소방차파견&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;ctrl+p &lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;경찰차파견&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;ctrl+s &lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;도시저장&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;+ &lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;줌인&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;- &lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;줌아웃&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;page up &lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;반시계방향회전&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;page down &lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;시계방향회전&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;home &lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;건물 시계방향회전&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;end &lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;건물 반시계방향회전&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;spacebar &lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;커서에 화면맞추기&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;esc &lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;창도구 켜거나 끄기&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;q &lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;낮은 밀도 주거&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;w &lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;중간 밀도 주거&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;e &lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;높은 밀도 주거&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;a &lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;낮은 밀도 상업&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;s &lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;중간 밀도 상업&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;d &lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;높은 밀도 상업&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;z &lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;농업&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;x &lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;중간 밀도 공업&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;c &lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;높은 밀도 공업&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;v &lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;구역취소&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;b &lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;철거&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;r &lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;도로도구&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;t &lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;철도도구&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;shift+t &lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;지하철도구&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;I &lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;전력선&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;i &lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;수도관&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;background-color: #ffffff;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;심시티4 팁&lt;/span&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;b&gt;건설도중 신의 모드 사용 방법&lt;/b&gt;: 도시를 만들기 전에 일단 &quot;신의 모드&quot;를 통해서 지형을 만드는데 일단 도시를 짓기 시작하면 &quot;신의 모드&quot;에 있는 &quot;지형 만들기&quot;나 &quot;지형 효과 만들기&quot; 도구를 사용할 수 없습니다. 도시를 짓고나서 위의 도구를 사용하려면 &lt;span style=&quot;background-color: #ffffff;&quot;&gt;[Ctrl]+[Alt]+[Shift]&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;을 누른 상태에서 &lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;신의 모드&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;&quot; &lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;아이콘에 클릭하시면 됩니다&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;. &lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;&lt;b&gt;탈것 조종 모드&lt;/b&gt;: 도시의 신호등을 제어하거나&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;철길 건널목의 막대를 내리거나&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;달려가는 차량에 카메라를 고정할 때는 조회도구가 선택된 상태에서 &lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;[Shift]&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;를 누르고 대상을 클릭하시면 됩니다&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;시프트 키 활용&lt;/b&gt;: &lt;span style=&quot;background-color: #ffffff;&quot;&gt;주거나 상업구역을 만들때 쉬프트를 누르고 드래그하면 거리가 생기지 않습니다&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;컨트롤 키 활용: 컨트롤 키를 누른 상태에서 구역을 만들면 최대 크기 건물을 들어서게 하는 구역을 설정할 수 있습니다. &lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;경찰을 출동시키면 도시 통계에서 체포 횟수가 늘어납니다.&amp;nbsp;&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p style=&quot;background-color: #ffffff;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;background-color: #ffffff;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;심시티4 고급 팁&lt;/span&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;b&gt;공해 산업&lt;/b&gt;은 하류층 심의 유입과 도시 발전의 기초라 기본적으로 어느 정도 육성해야 합니다. 그러나 오염이 많이 발생하므로 이웃 도시에 구역을 따로 만드는 것도 한 방법입니다. 주거 지역의 교육점수 40미만이어야 공해 산업 수요가 생깁니다. .&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;&lt;b&gt;하이테크 산업&lt;/b&gt;은 교육 점수 &lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;100 &lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;이상이면 육성할 수 있습니다. &lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;그러나 일자리 제공 역할 밖에 없으므로 무리한 육성을 하지 않아도 됩니다. &lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;고층 상업 건물&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;(CO &lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;상&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;)이 썩는 문제: &lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;부지의 적합성을 맞춰주어도 건물이 썩게되는데 수요가 부족한 것입니다. CO상 건물의 수요는 &lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;높은 교육 점수인 심즈(인구)가 있어야합니다.&amp;nbsp; &lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;즉&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;, 더 &lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;많은 인구와 교육 점수를 올려줘야 수요가 생깁니다. &lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;하류층&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;중류층&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;, &lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;&lt;b&gt;상류층&lt;/b&gt;은 교육수준에 따라 나누어 질 뿐 특별한 이유가 있지 않는한 따로 관리 할 필요 없습니다.&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;상업지역도 마찬가지로 강제로 철거해서 쫓아낼 필요 없이 수요에 따라 높은 수준으로 자동으로 교체가 됩니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;&lt;b&gt;공항&lt;/b&gt;은 &lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;오피스 &lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;상업 건물만 이용하므로 상업이 활성화되면 상업 지구와 도로와 연결합니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;&lt;b&gt;항구&lt;/b&gt;는 공업지역과&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt; 도로로 연결합니다.&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt; &lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;&lt;b&gt;도시 흑자&lt;/b&gt;를 위해서는 &lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;CS&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;상이 가장 중요 합니다. &lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;&lt;b&gt;교통&lt;/b&gt;은 아파트 단지 인구를 버스 정류장으로 모아서 대중 교통으로 일자리지역으로 이동하는 경로를 최단경로로 설계합니다. &lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;심들은 최단 거리 교통 수단을 이용 합니다. 그래서 도로가 바로 일자리로 가도록 설계하지 말고 대중 교통보다 돌아서 가도록 설계를 하는 것이 좋습니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;도로 건너편은 이동 거리가 &lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;이지만 도로가 한 칸 옆으로 이동하면 이동거리가 한 칸이므로 버스 정류장은 건물 옆이 아니라 도로 건너편에 건설 해야 합니다. &lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;대중 교통과 연결할 때도 역 도로 건너편에 버스 정류장을 배치해서 버스와 환승이 쉽도록 설계해야 합니다. &lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;&lt;b&gt;오페라하우스&lt;/b&gt;는 일정 인구 이상에서 교육 수준을 낮추는 버그가 있으므로 짓지 않습니다&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;관료청&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;보건&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;/&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;의료 기금이 기준선 초과&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;최대치&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;기금을 일시적으로 수요보다 기금을 높게 올려두면 지을 수 있습니다. 짓고 나서 기금을 다시 내리면 됩니다. &lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;우주 공항은&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;철도&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;화물역&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;(30&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;타일 이상&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;)2&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;개 열차 미션으로 해금합니다&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;대형철도역은&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;보통 해금이 어려우므로 화물 열차 미션으로 해금합니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p style=&quot;background-color: #ffffff;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;background-color: #ffffff;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;공원: 주거 수요 제한 해제 방법&lt;/span&gt;&lt;/h2&gt;
&lt;p style=&quot;background-color: #ffffff;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;도시 건설 하다보면 어느 순간 인구가 더 이상 유입되지 않습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;이것은 버그가 아니라 주거 수요 제한을 늘리기 위해 공원을 건설해야 합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;주거 수요는 아래의 공원을 사용하는 것이 효율적입니다.&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&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;커다란 광장: 상업 80, 범위 15, 주거수요상승한계치 9000&lt;/li&gt;
&lt;li&gt;커다란 화초가든&lt;span style=&quot;background-color: #ffffff;&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;오염 &lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;-15 &lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;범위 &lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;6 &lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;주거 &lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;85 &lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;범위 &lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;45, &lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;주거수요상승한계치 &lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;7000&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;테니스코트&lt;span style=&quot;background-color: #ffffff;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;스케이트보드공원&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;주거수요상승한계치 &lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;4000&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;녹지가 있는 공원은 대기 오염도 줄여줍니다&lt;span style=&quot;background-color: #ffffff;&quot;&gt;.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p style=&quot;background-color: #ffffff;&quot; data-ke-size=&quot;size16&quot;&gt;공원을 건설하다보면 보상 건물로 축구장이나 야구장을 건설 할 수 있는데 이 것들도 인구 유입 제한을 해제합니다.&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;background-color: #ffffff;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;전체 맵 크기 편집&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;background-color: #ffffff;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;C:\Users\&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;사용자&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;\Documents\SimCity 4\Regions\&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;위 Regions &lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;폴더에 원하는 맵 이름의 폴더가 있습니다. &lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;거기서&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;&amp;nbsp;config.bmp &lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;파일을 그림판으로 열어줍니다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;확대&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;(ctrl+&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;휠&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;후 스포이드 툴로 색깔 추출 후 연필 도구로 편집합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;빨강&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;: 전체 맵에서 &lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;소형 도시 구획으로 변경됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;연두&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;: 전체 맵에서 &lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;중형 도시 구획으로 변경됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;파란&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;: 전체 맵에서 &lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;대형 도시 구획으로 변경됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;background-color: #ffffff;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;심시티 디럭스 에디션&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;스팀&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;)&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;background-color: #ffffff;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;기본 설치 경로: C:\Program Files (x86)\Steam\steamapps\common\SimCity 4 Deluxe&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff;&quot; data-ke-size=&quot;size16&quot;&gt;스팀에서 구입 할 수 있는 디럭스 에디션은 한글 패치가 되어 있지 않습니다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff;&quot; data-ke-size=&quot;size16&quot;&gt;그래서 수동으로 따로 한글 패치를 해줘야 합니다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;1. &lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;한글 패치&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;심시티 설치 경로에 &lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;Korean &lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;폴더를 만든 뒤 거기에 패치 파일&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;(simcityLocale.dat)&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;을 복사합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;fileblock&quot; data-ke-align=&quot;alignLeft&quot;&gt;&lt;a href=&quot;https://blog.kakaocdn.net/dn/bzXN1O/btsH1nSzop4/IPKm13Ky8HPso6TkwikYcK/SimCityLocale.zip?attach=1&amp;amp;knm=tfile.zip&quot; class=&quot;&quot;&gt;
    &lt;div class=&quot;image&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;desc&quot;&gt;&lt;div class=&quot;filename&quot;&gt;&lt;span class=&quot;name&quot;&gt;SimCityLocale.zip&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;size&quot;&gt;0.38MB&lt;/div&gt;
&lt;/div&gt;
  &lt;/a&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;2. &lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;스팀 설정에서 시작 옵션 변경 방법&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;해상도 조정&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;: -CustomResolution:enabled -r1920x1080x32&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;인트로 끄기(EA Sports it's in the game&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;: -intro:off&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;창모드 변경&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;: -w&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;3. &lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;자문위원 한국 버전으로 바꾸기&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;심시티 설치 경로에 &lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;Sku_Data &lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;폴더에 &lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;Sku3_Thai_Kor_Tch &lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;폴더를 복사합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;fileblock&quot; data-ke-align=&quot;alignLeft&quot;&gt;&lt;a href=&quot;https://blog.kakaocdn.net/dn/GFqsQ/btsH00Dpebt/KorK5690E4RXrYJArHEnB1/Sku3_Thai_Kor_Tch.zip?attach=1&amp;amp;knm=tfile.zip&quot; class=&quot;&quot;&gt;
    &lt;div class=&quot;image&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;desc&quot;&gt;&lt;div class=&quot;filename&quot;&gt;&lt;span class=&quot;name&quot;&gt;Sku3_Thai_Kor_Tch.zip&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;size&quot;&gt;6.54MB&lt;/div&gt;
&lt;/div&gt;
  &lt;/a&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff;&quot; data-ke-size=&quot;size16&quot;&gt;4. 호환성 설정&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff;&quot; data-ke-size=&quot;size16&quot;&gt;윈도우10이나 윈도우11에서 실행이 되지 않는 경우 호환성 설정을 하셔야 합니다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff;&quot; data-ke-size=&quot;size16&quot;&gt;C:\Program&amp;nbsp;Files&amp;nbsp;(x86)\Steam\steamapps\common\SimCity&amp;nbsp;4&amp;nbsp;Deluxe\Apps&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff;&quot; data-ke-size=&quot;size16&quot;&gt;에 SimCity 4.exe 를 우클릭 &amp;gt; 속성 &amp;gt; 호환성 탭에서&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff;&quot; data-ke-size=&quot;size16&quot;&gt;Windows 7 이나 그 이전 버전으로 설정해보시고 실행하시면 됩니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;2024-12-31 19 06 02.png&quot; data-origin-width=&quot;461&quot; data-origin-height=&quot;576&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/BEekL/btsLCLoITCr/2w35GjxAvAhn6pWmmnqjkK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/BEekL/btsLCLoITCr/2w35GjxAvAhn6pWmmnqjkK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/BEekL/btsLCLoITCr/2w35GjxAvAhn6pWmmnqjkK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FBEekL%2FbtsLCLoITCr%2F2w35GjxAvAhn6pWmmnqjkK%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;461&quot; height=&quot;576&quot; data-filename=&quot;2024-12-31 19 06 02.png&quot; data-origin-width=&quot;461&quot; data-origin-height=&quot;576&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff;&quot; data-ke-size=&quot;size16&quot;&gt;5. 맵 복사 경로&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff;&quot; data-ke-size=&quot;size16&quot;&gt;C:\Users\사용자이름\Documents\SimCity 4\Regions&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff;&quot; data-ke-size=&quot;size16&quot;&gt;에 심시티 맵을 복사하시면 됩니다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;ed.jpg&quot; data-origin-width=&quot;150&quot; data-origin-height=&quot;113&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ckY2KT/btsH0YT0OxV/TINKfbX6FKU02jppKBhlKK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ckY2KT/btsH0YT0OxV/TINKfbX6FKU02jppKBhlKK/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ckY2KT/btsH0YT0OxV/TINKfbX6FKU02jppKBhlKK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FckY2KT%2FbtsH0YT0OxV%2FTINKfbX6FKU02jppKBhlKK%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;150&quot; height=&quot;113&quot; data-filename=&quot;ed.jpg&quot; data-origin-width=&quot;150&quot; data-origin-height=&quot;113&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>GAME/고전게임</category>
      <category>Rush Hour</category>
      <category>simcity4</category>
      <category>고전게임</category>
      <category>구버전</category>
      <category>디럭스</category>
      <category>러시아워</category>
      <category>스팀</category>
      <category>심시티4</category>
      <author>ALEPH.GEM</author>
      <guid isPermaLink="true">https://aacii.tistory.com/422</guid>
      <comments>https://aacii.tistory.com/422#entry422comment</comments>
      <pubDate>Tue, 31 Dec 2024 20:35:17 +0900</pubDate>
    </item>
    <item>
      <title>ORA-01704: JAVA ORACLE JDBC로 4000자 이상 CLOB 데이터 INSERT, UPDATE 예제</title>
      <link>https://aacii.tistory.com/364</link>
      <description>&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;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;ORA-01704&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;JAVA로 ORACLE DBMS에 JDBC로 프로그램을 작성할 때,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;문자열이 4000자가 넘어가면 일반 String statement로 insert/update시 &amp;nbsp;ORA-01704를 발생시키며 안됩니다.&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.sql.Clob 클래스를 사용해서 preparedStatement.setClob()를 써서 구현하면 CLOB 데이터를 insert/update 할 수 있습니다.&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;pre id=&quot;code_1703678066761&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.Clob;

public class ClobExample {

    private static final String JDBC_URL = &quot;jdbc:oracle:thin:@localhost:1521:yourdb&quot;;
    private static final String USERNAME = &quot;yourUsername&quot;;
    private static final String PASSWORD = &quot;yourPassword&quot;;

    public static void main(String[] args) {
        Connection connection = null;

        try {
            // 1. 데이터베이스 연결
            connection = DriverManager.getConnection(JDBC_URL, USERNAME, PASSWORD);

            // 2. CLOB 삽입 예제
            String clobData = generateLargeClobData(); // 큰 CLOB 데이터 생성
            insertClobData(connection, clobData);

            // 3. CLOB 업데이트 예제
            String updatedClobData = generateUpdatedClobData(); // 업데이트할 CLOB 데이터 생성
            updateClobData(connection, updatedClobData);

        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            // 4. 연결 종료
            if (connection != null) {
                try {
                    connection.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    private static void insertClobData(Connection connection, String clobData) throws SQLException {
        String insertQuery = &quot;INSERT INTO your_table (clob_column) VALUES (?)&quot;;
        try (PreparedStatement preparedStatement = connection.prepareStatement(insertQuery)) {
            // CLOB 데이터를 PreparedStatement에 설정
            Clob clob = connection.createClob();
            clob.setString(1, clobData);
            preparedStatement.setClob(1, clob);
            // 쿼리 실행
            preparedStatement.executeUpdate();
        }
    }

    private static void updateClobData(Connection connection, String updatedClobData) throws SQLException {
        String updateQuery = &quot;UPDATE your_table SET clob_column = ? WHERE your_condition&quot;;
        try (PreparedStatement preparedStatement = connection.prepareStatement(updateQuery)) {
            // CLOB 데이터를 PreparedStatement에 설정
            Clob clob = connection.createClob();
            clob.setString(1, updatedClobData);
            preparedStatement.setClob(1, clob);
            // 쿼리 실행
            preparedStatement.executeUpdate();
        }
    }

    private static String generateLargeClobData() {
        // 큰 CLOB 데이터를 생성하는 코드 작성
        return &quot;엄청나게 긴 4000자 이상 CLOB Data...&quot;;
    }

    private static String generateUpdatedClobData() {
        // 업데이트할 CLOB 데이터를 생성하는 코드 작성
        return &quot;엄청나게 긴 4000자 이상 Updated CLOB Data...&quot;;
    }
}&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;또는 아주 긴 문자열을 등분하여 insert/update 해도 됩니다.&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;String을 10등분 하는 예제&lt;/p&gt;
&lt;pre id=&quot;code_1703678933593&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public class LongStringDivider {
    public static void main(String[] args) {
        // 아주 긴 문자열 생성 
        String longString = &quot;이것은 굉장히 길어서 10등분 해서 나누어질 String 입니다...&quot;;

        // 문자열의 길이 계산
        int length = longString.length();

        // 등분할 개수 여기서는 10등분
        int parts = 10;

        // 등분한 문자열 출력
        for (int i = 0; i &amp;lt; parts; i++) {
            int startIndex = i * length / parts;
            int endIndex = (i + 1) * length / parts;
            String part = longString.substring(startIndex, endIndex);
            System.out.println(&quot;Part &quot; + (i + 1) + &quot;: &quot; + part);
        }
    }
}&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;그러고 나서 아래처럼 쿼리를 TO_CLOB() 함수를 써서 문자열 연결 연산자 || 로 연결해서 쿼리를 작성하면 됩니다.&lt;/p&gt;
&lt;pre id=&quot;code_1703678766143&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;UPDATE your_table SET clob_column = TO_CLOB('아주 긴 String') || TO_CLOB('엄청나게 긴 String') WHERE your_condition&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;또 다른 방법으로는 2000 글자씩 나누는 방법도 있습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1735279061402&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import java.util.ArrayList;
import java.util.List;

public class StringSplitter {

    private static final int CHUNK_SIZE = 2000;

    public static List&amp;lt;String&amp;gt; splitString(String input) {
        List&amp;lt;String&amp;gt; result = new ArrayList&amp;lt;&amp;gt;();
        int length = input.length();
        for (int i = 0; i &amp;lt; length; i += CHUNK_SIZE) {
            result.add(input.substring(i, Math.min(length, i + CHUNK_SIZE)));
        }
        return result;
    }

    public static void main(String[] args) {
        String longString = &quot;This is a very long string...&quot;; 
        List&amp;lt;String&amp;gt; parts = splitString(longString);
        
        for (int i = 0; i &amp;lt; parts.size(); i++) {
            System.out.println(&quot;Part &quot; + (i + 1) + &quot;: &quot; + parts.get(i));
        }
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 String을 나눈 뒤 위처럼 TO_CLOB('2000자') || TO_CLOB('2000자') 처럼 연결하는 방법도 있습니다.&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;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;두 개의 CLOB데이터를 insert 하는 예제&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;한번에 두 개 이상의 CLOB데이터를 setCharacterStream() 을 이용해서 insert 할 수 있습니다.&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1735553821310&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 1. 데이터베이스 연결
connection = DriverManager.getConnection(jdbcUrl, username, password);

// 2. 두 개의 CLOB 열이 있는 테이블의 INSERT SQL 준비
String sql = &quot;INSERT INTO clob_table (id, clob_column1, clob_column2) VALUES (?, ?, ?)&quot;;
pstmt = connection.prepareStatement(sql);

// 3. CLOB 데이터 준비
int id = 1;
String largeText1 = &quot;이것은 첫 번째 CLOB 데이터입니다.&quot;;
String largeText2 = &quot;이것은 두 번째 CLOB 데이터입니다.&quot;;

// 4. PreparedStatement에 값 설정
pstmt.setInt(1, id);
pstmt.setCharacterStream(2, new java.io.StringReader(largeText1), largeText1.length());
pstmt.setCharacterStream(3, new java.io.StringReader(largeText2), largeText2.length());

// 5. 쿼리 실행
int rowsInserted = pstmt.executeUpdate();&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;&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;&amp;nbsp;&lt;/p&gt;</description>
      <category>DEV&amp;amp;OPS/Java</category>
      <category>clob</category>
      <category>insert</category>
      <category>Java</category>
      <category>JDBC</category>
      <category>ORA-01704</category>
      <category>Oracle</category>
      <category>Update</category>
      <author>ALEPH.GEM</author>
      <guid isPermaLink="true">https://aacii.tistory.com/364</guid>
      <comments>https://aacii.tistory.com/364#entry364comment</comments>
      <pubDate>Mon, 30 Dec 2024 19:23:08 +0900</pubDate>
    </item>
    <item>
      <title>자산 분배</title>
      <link>https://aacii.tistory.com/441</link>
      <description>&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;자산 분배를 주기적으로 원화자산: 해외자산 비율을 50:50 으로 균형을 맞춰주는 것을 추천합니다.&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;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;국내 배당주&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;TIGER MKF배당귀족ETF : 국내 배당 성장주&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;PLUS 고배당주: 국내 고배당&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;RISE 200위클리커버드콜&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;PLUS 고배당주위클리커버드콜&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;KODEX금융고배당TOP10타겟위클리커버드콜&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;b&gt;국내상장미국주식&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ACE 미국WideMoat동일가중: 넓은 경제적 해자(산업내 독점적 경쟁력 높은 종목) 전략&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;TIGER미국배당다우존스타겟커버드콜2호: SCHD 60% +S&amp;amp;P 40% 먼슬리 타겟 커버드콜&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;KODEX미국배당커버드콜액티브&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;KODEX미국배당다우존스타겟커버드콜&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ACE미국500데일리타겟커버드콜(합성): S&amp;amp;P500+데일리 옵션1%&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;TIGER미국나스닥100타겟데일리커버드콜: 나스닥90%+데일리옵션 10%&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;b&gt;채권, 채권혼합&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SOL미국배당미국채혼합50: SCHD와미국채를 반반 혼합하여 연금추천&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;TIGER글로벌멀티에셋TIF액티브(채권혼합): 자산분배형 안정적인 수익 연금추천&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;KODEX iShares미국투자등급회사채액티브: 미국 우량 회사채&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;ACE미국S&amp;amp;P500채권혼합액티브: 단기채권베이스에 S&amp;amp;P 30%&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;RISE 미국30년국채커버드콜(합성): 미국장기채70%+옵션100%&lt;/p&gt;
&lt;h3 style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;br /&gt;&lt;b&gt;리츠, 인프라&lt;/b&gt;&lt;/h3&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;RISE글로벌리얼티인컴: 미국 상업용 리츠 + 국내 맥쿼리인프라 조합&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;TIGER리츠부동산인프라: 맥쿼리인프라외 국내 우수 인프라 업체들&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;KODEX한국부동산인프라: 맥쿼리인프라외 국내 우수 인프라 업체들&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;b&gt;미국&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SCHD: 배당성장, 안정적인 성장&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;JEPI: S&amp;amp;P500 기반 커버드콜 프리미엄&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SPLG: 저렴한 수수료, 저렴한 가격의 S&amp;amp;P500 지수추종&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;RSP: 동일비중 S&amp;amp;P500 지수 추종, 경기 방어주도 골고루&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SPYG: S&amp;amp;P500중에 상위 기업에 더욱 가중치를 줘서 성장중&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;MOAT: 경제적 해자( 산업내 독점적 경쟁력 )개념 ETF&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SGOV: 미국 초단기 채권 매월1일이 배당락이라 월초가 가장싸고 매월0.4%, 파킹형 달러예금효과&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;&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;</description>
      <category>STUDY/Capitalism</category>
      <category>ETF</category>
      <category>배당</category>
      <category>분배</category>
      <category>자산</category>
      <category>주식</category>
      <category>포트폴리오</category>
      <author>ALEPH.GEM</author>
      <guid isPermaLink="true">https://aacii.tistory.com/441</guid>
      <comments>https://aacii.tistory.com/441#entry441comment</comments>
      <pubDate>Sat, 21 Dec 2024 15:28:56 +0900</pubDate>
    </item>
    <item>
      <title>org.apache.poi 자바용 오피스 라이브러리 임시 파일 제거</title>
      <link>https://aacii.tistory.com/439</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;POI 라이브러리 임시 파일 저장 경로 지정&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자바로 오피스(엑셀) 파일을 다룰 때 흔히 사용하는 org.ahache.poi 라이브러리를 사용할 때, 엑셀 파일 작성을 위한 데이터와 스타일 정보들이 정의된 xml 형식의 임시 파일들이 생성되게 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 임시 파일들이 생성되는 경로는 기본적으로 시스템의 임시 디렉터리 경로를 사용합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그런데 리눅스에서는 기본 임시 파티션인 /tmp 을 사용하게 되는데, 이 /tmp 파티션이 용량이 부족한 경우가 발생할 수 있습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1732713357098&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public class TempDirCheck {
    public static void main(String[] args) {
        String tempDir = System.getProperty(&quot;java.io.tmpdir&quot;);
        System.out.println(&quot;Temporary Directory: &quot; + tempDir);
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;System.getProperty(&quot;java.io.tmpdir&quot;)을 이용하면 자바 application에서 시스템의 임시 디렉터리 경로를 알아낼 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자바 application이 실행되는 JVM 환경 변수를 지정해서 이 임시 파일들이 저장되는 경로를 변경해줄 수 있습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1732713515915&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;-Djava.io.tmpdir=/your/custom/tmpdir&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;톰캣(WAS)이나 자바를 실행할 때 위 처럼 tmpdir을 특정 경로로 지정해 주면 poi 라이브러리에서 사용하는 임시 파일(xml)들이 저장되는 경로를 지정해 줄 수 있습니다.&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;h3 data-ke-size=&quot;size23&quot;&gt;poi 라이브러리 임시 파일 자동 삭제&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Apache POI 라이브러리를 사용해서 대용량 데이터를 처리할 때 SXSSFWorkbook을 이용하면 성능을 최적화할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이때 dispose() 메서드를 작업 끝난 후 사용하면 생성되었던 임시 파일(xml)들을 자동으로 삭제할 수 있습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1732713804824&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import java.io.FileOutputStream;
import java.io.IOException;

public class POIDisposeExample {
    public static void main(String[] args) {
        // SXSSFWorkbook 생성
        SXSSFWorkbook workbook = new SXSSFWorkbook();
        Sheet sheet = workbook.createSheet(&quot;ExampleSheet&quot;);

        // 데이터를 시트에 작성
        for (int rownum = 0; rownum &amp;lt; 1000; rownum++) {
            Row row = sheet.createRow(rownum);
            for (int cellnum = 0; cellnum &amp;lt; 10; cellnum++) {
                Cell cell = row.createCell(cellnum);
                cell.setCellValue(&quot;Data &quot; + rownum + &quot;,&quot; + cellnum);
            }
        }

        try (FileOutputStream out = new FileOutputStream(&quot;example.xlsx&quot;)) {
            workbook.write(out);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // 작업이 완료된 후 dispose() 메소드를 호출하여 임시 파일 삭제
            workbook.dispose();
        }
    }
}&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;&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;&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;&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;</description>
      <category>DEV&amp;amp;OPS/Java</category>
      <category>Java</category>
      <category>org.apache.poi</category>
      <category>poi</category>
      <category>Temp</category>
      <category>라이브러리</category>
      <category>엑셀</category>
      <category>오피스</category>
      <author>ALEPH.GEM</author>
      <guid isPermaLink="true">https://aacii.tistory.com/439</guid>
      <comments>https://aacii.tistory.com/439#entry439comment</comments>
      <pubDate>Wed, 27 Nov 2024 22:23:57 +0900</pubDate>
    </item>
    <item>
      <title>[SWT/JFace] FileDialog 파일 열기 대화 상자</title>
      <link>https://aacii.tistory.com/438</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;자바 SWT/JFace 를 이용한 GUI 애플리케이션에서&amp;nbsp;실행중인 PC의 파일(텍스트)을 읽을 수 있는 파일 열기 대화 상자의 간단한 사용법에 대해 알아보겠습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1732712173054&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.*;
import org.eclipse.jface.window.ApplicationWindow;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

public class TextFileReaderApp extends ApplicationWindow {

    public TextFileReaderApp() {
        super(null);
    }

    @Override
    protected Control createContents(Composite parent) {
        parent.getShell().setText(&quot;Text File Reader&quot;);
        parent.setLayout(new FillLayout());

        Text textArea = new Text(parent, SWT.MULTI | SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL);

        Menu menuBar = new Menu(parent.getShell(), SWT.BAR);
        parent.getShell().setMenuBar(menuBar);

        MenuItem fileMenuHeader = new MenuItem(menuBar, SWT.CASCADE);
        fileMenuHeader.setText(&quot;File&quot;);

        Menu fileMenu = new Menu(parent.getShell(), SWT.DROP_DOWN);
        fileMenuHeader.setMenu(fileMenu);

        MenuItem openItem = new MenuItem(fileMenu, SWT.PUSH);
        openItem.setText(&quot;Open&quot;);

        openItem.addListener(SWT.Selection, e -&amp;gt; {
            FileDialog fileDialog = new FileDialog(parent.getShell(), SWT.OPEN);
            // 확장자를 txt으로 제한하려면 아래처럼 필터를 설정해줍니다. 
            fileDialog.setFilterExtensions(new String[] {&quot;*.txt&quot;}); 
            fileDialog.setFilterNames(new String[] {&quot;Text Files (*.txt)&quot;}); // 파일 유형 이름 설정
            String selectedFile = fileDialog.open();
            if (selectedFile != null) {
                try (BufferedReader br = new BufferedReader(new FileReader(selectedFile))) {
                    StringBuilder sb = new StringBuilder();
                    String line;
                    while ((line = br.readLine()) != null) {
                        sb.append(line).append(&quot;\n&quot;);
                    }
                    textArea.setText(sb.toString());
                } catch (IOException ex) {
                    ex.printStackTrace();
                }
            }
        });
        
        return parent;
    }

    public static void main(String[] args) {
        TextFileReaderApp app = new TextFileReaderApp();
        app.setBlockOnOpen(true);
        app.open();
        Display.getCurrent().dispose();
    }
}&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;&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;</description>
      <category>DEV&amp;amp;OPS/Java</category>
      <category>Java</category>
      <category>JFace</category>
      <category>RCP</category>
      <category>SWT</category>
      <category>오블완</category>
      <category>읽기</category>
      <category>자바</category>
      <category>티스토리챌린지</category>
      <category>파일</category>
      <author>ALEPH.GEM</author>
      <guid isPermaLink="true">https://aacii.tistory.com/438</guid>
      <comments>https://aacii.tistory.com/438#entry438comment</comments>
      <pubDate>Wed, 27 Nov 2024 22:00:07 +0900</pubDate>
    </item>
    <item>
      <title>[SWT/JFace] 주요 위젯</title>
      <link>https://aacii.tistory.com/396</link>
      <description>&lt;h3 style=&quot;color: #000000;&quot; data-ke-size=&quot;size23&quot;&gt;SWT Text 위젯&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;org.eclipse.swt.widgets.Text 위젯은 간단한 텍스트를 입력받을 때 사용하는 위젯입니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;addModifyListener() : 텍스트를 수정했음을 알리기 위한 리스너를 추가&lt;/li&gt;
&lt;li&gt;addSelectionListener() : 컨트롤이 선택되었음을 알리기 위한 리스너를 추가&lt;/li&gt;
&lt;li&gt;addVerifyListener() : 텍스트에 변화가 일어났는지 검증하기 위한 리스너를 추가&lt;/li&gt;
&lt;li&gt;append() : 현 텍스트에 주어진 문자열을 추가&lt;/li&gt;
&lt;li&gt;insert() : 현 텍스트를 주어진 문자열로 대체&lt;/li&gt;
&lt;li&gt;copy(), cut(), paste() : 선택된 문자들을 클립보드로 옮기거나 클립보드의 내용으로 대체&lt;/li&gt;
&lt;li&gt;setSelection(), selectAll() : 코드 상에서 직접 선택 영역을 설정&lt;/li&gt;
&lt;li&gt;setEchoCharacter() : 사용자가 타이핑하는 문자 대신 보여줄 다른 문자를 지정(비밀번호)&lt;/li&gt;
&lt;li&gt;setEditable() : 편집을 가능하게 하거나 불가능하게 한다.&lt;/li&gt;
&lt;li&gt;setFont() : 전체 폰트 설정. 부분적으로 폰트를 설정할 수는 없다.&amp;nbsp;&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;아래 예제는 Text위젯에 소문자를 입력하면 대문자로 바꾸는 예제입니다.&lt;/p&gt;
&lt;pre id=&quot;code_1715168251342&quot; class=&quot;java&quot; style=&quot;background-color: #f8f8f8; color: #383a42;&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import org.eclipse.swt.SWT;
import org.eclipse.swt.events.VerifyEvent;
import org.eclipse.swt.events.VerifyListener;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Text;

public class Capital extends Composite {
	public Capital(Composite parent) {
		super(parent, SWT.NONE);
		buildControls();
	}
	
	public void buildControls() {
		this.setLayout(new FillLayout());
		Text text = new Text(this, SWT.MULTI | SWT.V_SCROLL);
		text.addVerifyListener(new VerifyListener() {

			@Override
			public void verifyText(VerifyEvent e) {
				//대문자로 변경
				e.text = e.text.toUpperCase();
			}
			
		});
	}
}&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;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000;&quot; data-ke-size=&quot;size23&quot;&gt;SWT StyledText 위젯&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;org.eclipse.swt.custom.StyledText 은 텍스트 위젯에서 제공하는 메서드에 좀 더 다양한 스타일을 수정할 수 있는 기능이 추가되어 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;setKeyBinding() 메소드는 Shift 키, Ctrl 키 같은 기능키를 사용할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 기능키들은 SWT 상수로 정의되어 있어서 단축키 기능을 구현할 때 유용하게 사용할 수 있습니다.&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;StyleRange 클래스는 텍스트 범위에 대한 스타일 정보를 보유하고 있는데 모든 필드가 public 이므로 자유롭게 수정할 수 있습니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;수정한 스타일은 setStyleRange()를 호출해야 적용이 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;StyleRange는 텍스트의 영역을 관리하기 위해 시작(오프셋) 지점과 길이를 통해 관리합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1715168251344&quot; class=&quot;arduino&quot; style=&quot;background-color: #f8f8f8; color: #383a42;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;java&quot;&gt;&lt;code&gt;import java.util.LinkedList;
import java.util.List;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.ExtendedModifyEvent;
import org.eclipse.swt.custom.ExtendedModifyListener;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.events.KeyAdapter;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Composite;

public class UndoRedo extends Composite {
	public static final int MAX_STACK_SIZE = 100;	//변경 사항을 저장하는 스택의 크기
	public List undoStack;	
	public List redoStack;
	public StyledText styledText;

	/** 
	* @date        : 2024-01-26  
	* @description : 생성자에서 초기화 작업을 수행합니다.
	**/
	UndoRedo(Composite parent) {
		super(parent, SWT.NONE);
		undoStack = new LinkedList();
		redoStack = new LinkedList();
		buildControls();
	}

	public void buildControls() {
		this.setLayout(new FillLayout());
		styledText = new StyledText(this, SWT.MULTI | SWT.V_SCROLL);
		
		//텍스트가 편집될 때마다 이벤트를 처리
		styledText.addExtendedModifyListener(new ExtendedModifyListener() {

			@Override
			public void modifyText(ExtendedModifyEvent event) {
				String currText = styledText.getText();
				//편집을 되돌리기 위해 저장합니다.
				String newText = currText.substring(event.start, event.start + event.length);
				//undo 스택 처리
				if(newText != null &amp;amp;&amp;amp; newText.length() &amp;gt; 0) {
					if(undoStack.size() == MAX_STACK_SIZE) {
						undoStack.remove(undoStack.size() - 1);
					}
					undoStack.add(0, newText);
				}
			}
		});
		
		//F1 펑션키를 누르면 undo동작을 하고 F2 펑션키를 누르면 redo 동작을 수행합니다.
		styledText.addKeyListener(new KeyAdapter() {
			public void keyPressed(KeyEvent ke) {
				switch(ke.keyCode) {
				case SWT.F1:
					undo();
					break;
				case SWT.F2:
					redo();
					break;
				default:		
				}
			}
		});		
	}
	
	/** 
	* @date        : 2024-01-26  
	* @description : 커서를 끝으로 이동 시킴
	**/
	public void moveCursorToEnd() {
		styledText.setCaretOffset(styledText.getText().length());
	}
	
	/** 
	* @date        : 2024-01-26  
	* @description : 다시 실행 동작 정의
	**/
	public void redo() {
		if(redoStack.size() &amp;gt; 0) {
			//스택에서 꺼낸 뒤 append 합니다.
			String text = (String)redoStack.remove(0);
			moveCursorToEnd();
			styledText.append(text);
			moveCursorToEnd();
		}
	}
	
	/** 
	* @date        : 2024-01-26  
	* @description : 되돌리기 동작 정의 
	**/
	public void undo() {
		if(undoStack.size() &amp;gt; 0) {
			//실행 취소를 위해 스택에서 하나 꺼냅니다. 
			String lastEdit = (String)undoStack.remove(0);
			int editLength = lastEdit.length();
			String currText = styledText.getText();
			int startReplaceIndex = currText.length() - editLength;
			//버퍼에서 사라져야 할 문자열을 삭제합니다.
			styledText.replaceTextRange(startReplaceIndex, editLength, &quot;&quot;);
			redoStack.add(0, lastEdit);
		}
	}
	
}&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1715168251350&quot; class=&quot;java&quot; style=&quot;background-color: #f8f8f8; color: #383a42;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;java&quot;&gt;&lt;code&gt;import org.eclipse.jface.window.ApplicationWindow;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;

public class WidgetWindow extends ApplicationWindow {

	public WidgetWindow() {
		super(null);
	}
	
	public Control createContents(Composite parent) {
		UndoRedo undoRedo = new UndoRedo(parent);
		parent.setSize(800, 600);	
		getShell().setText(&quot;Undo Redo&quot;);
		return parent;
	}

	public static void main(String[] args) {
		WidgetWindow wwin = new WidgetWindow();
		wwin.setBlockOnOpen(true);
		wwin.open();
		Display.getCurrent().dispose();
	}

}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;화면 캡처 2024-02-21 214111.png&quot; data-origin-width=&quot;786&quot; data-origin-height=&quot;593&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/9iRup/btsHhqXFthg/W6KIKbDfKkqRr7R767FZQ1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/9iRup/btsHhqXFthg/W6KIKbDfKkqRr7R767FZQ1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/9iRup/btsHhqXFthg/W6KIKbDfKkqRr7R767FZQ1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F9iRup%2FbtsHhqXFthg%2FW6KIKbDfKkqRr7R767FZQ1%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;786&quot; height=&quot;593&quot; data-filename=&quot;화면 캡처 2024-02-21 214111.png&quot; data-origin-width=&quot;786&quot; data-origin-height=&quot;593&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;h3 style=&quot;color: #000000;&quot; data-ke-size=&quot;size23&quot;&gt;JFace 텍스트 패키지&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;JFace 텍스트 패키지는 text.jar와 jfacetext.jar 파일입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이클립스 경로/plugins/org.eclipse.text~~~ 패지지에 text.jar 파일이 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이클립스 경로/plugins/org.eclipse.jface.text~~~ 패키지에 jfacetext.jar 파일이 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote style=&quot;color: #666666; text-align: left;&quot; data-ke-style=&quot;style2&quot;&gt;IDocument 인터페이스&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AbstractDocument는 일부만 구현되어 있고 Document 클래스가 IDocument 인터페이스의 구현체입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;IDocument는 아래 처럼 고급 텍스트 기능을 지원합니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Position : 텍스트 영역에 Position을 저장해 두는 기능입니다. 북마크 기능이나 TODO 주석 찾아가기 기능 등을 구현할 수 있습니다.&amp;nbsp;&lt;/li&gt;
&lt;li&gt;Content 타입을 구분: 일반 text외에 HTML 등 Content 타입을 구분합니다.&amp;nbsp;&lt;/li&gt;
&lt;li&gt;search() :&amp;nbsp; 정규표현식이나 패턴 검색은 지원하지 않지만, 시작 위치 검색, 방향, 대소문자 구분, 단어 검색을 할 수 있습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote style=&quot;color: #666666; text-align: left;&quot; data-ke-style=&quot;style2&quot;&gt;ITextViewer 인터페이스&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;TextViewer 클래스가 구현체이며 StyledText를 이용해서 데이터를 보여줍니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;텍스트 수정 이벤트와 스타일 이벤트 양쪽에 대한 리스너를 지원합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;원할 때 StyledText에 접근하는 것을 허용하지만, 대신 TextPresentation을 권장합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;IUndoManager 인터페이스를 통해 undo 기능을 구현할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote style=&quot;color: #666666; text-align: left;&quot; data-ke-style=&quot;style2&quot;&gt;org.eclipse.jface.text 하위 패키지&lt;/blockquote&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;contentassist : 자동 완성 기능을 지원합니다.&lt;/li&gt;
&lt;li&gt;formatter : 텍스트의 서식을 설정하는 기능을 제공합니다.&amp;nbsp;&lt;/li&gt;
&lt;li&gt;presentation : 문서의 시각적인 효과를 업데이트 할 때 사용하는 패키지입니다.&amp;nbsp;&lt;/li&gt;
&lt;li&gt;reconciler : 문서를 텍스트의 외부 저장소와 동기화 하는데 사용합니다.&amp;nbsp;&lt;/li&gt;
&lt;li&gt;rules : 텍스트를 스캔하고 매치하기 위한 클래스를 지원합니다.&amp;nbsp;&lt;/li&gt;
&lt;li&gt;source : 텍스트에 시각적인 표시를 추가해줍니다. 예를 들어 이클립스에서 빨간색 X로 컴파일 에러를 표시하는 기능이 그 예입니다.&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000;&quot; data-ke-size=&quot;size23&quot;&gt;Combo 위젯&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;콤보 박스의 스타일은 Simple, Drop-down, Read-only 세 가지 스타일이 있습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1715168251352&quot; class=&quot;scala&quot; style=&quot;background-color: #f8f8f8; color: #383a42;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;java&quot;&gt;&lt;code&gt;import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.RowLayout;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;

public class ComboComposite extends Composite {

	public ComboComposite(Composite parent) {
		super(parent, SWT.NONE);
		buildControls();
	}
	
	public void buildControls() {
		setLayout(new RowLayout());
		int[] comboStyles = {SWT.SIMPLE, SWT.DROP_DOWN, SWT.READ_ONLY};
		for(int idx = 0; idx &amp;lt; comboStyles.length; ++idx) {
			Combo combo = new Combo(this, comboStyles[idx]);
			combo.add(&quot;Option 1&quot;);
			combo.add(&quot;Option 2&quot;);
			combo.add(&quot;Option 3&quot;);
		}
	}
}&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1715168251353&quot; class=&quot;java&quot; style=&quot;background-color: #f8f8f8; color: #383a42;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;java&quot;&gt;&lt;code&gt;import org.eclipse.jface.window.ApplicationWindow;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.TabFolder;
import org.eclipse.swt.widgets.TabItem;

public class WidgetWindow extends ApplicationWindow {

	public WidgetWindow() {
		super(null);
	}
	
	public Control createContents(Composite parent) {
		TabFolder tf = new TabFolder(parent, SWT.NONE);
		TabItem combos = new TabItem(tf, SWT.NONE);
		combos.setText(&quot;Combos&quot;);
		combos.setControl(new ComboComposite(tf));
		getShell().setText(&quot;위젯 윈도우&quot;);
		return parent;
	}

	public static void main(String[] args) {
		WidgetWindow wwin = new WidgetWindow();
		wwin.setBlockOnOpen(true);
		wwin.open();
		Display.getCurrent().dispose();
	}

}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;WidgetWindow.java 실행결과:&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;화면 캡처 2024-02-21 210523.png&quot; data-origin-width=&quot;252&quot; data-origin-height=&quot;161&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/7TFKC/btsHiqbOgIk/Pk8s672ofA8hwzMFQHbsZ1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/7TFKC/btsHiqbOgIk/Pk8s672ofA8hwzMFQHbsZ1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/7TFKC/btsHiqbOgIk/Pk8s672ofA8hwzMFQHbsZ1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F7TFKC%2FbtsHiqbOgIk%2FPk8s672ofA8hwzMFQHbsZ1%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;252&quot; height=&quot;161&quot; data-filename=&quot;화면 캡처 2024-02-21 210523.png&quot; data-origin-width=&quot;252&quot; data-origin-height=&quot;161&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;&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;&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;&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>DEV&amp;amp;OPS/Java</category>
      <category>Eclipse</category>
      <category>GUI</category>
      <category>Java</category>
      <category>JFace</category>
      <category>SWT</category>
      <category>widget</category>
      <category>위젯</category>
      <author>ALEPH.GEM</author>
      <guid isPermaLink="true">https://aacii.tistory.com/396</guid>
      <comments>https://aacii.tistory.com/396#entry396comment</comments>
      <pubDate>Wed, 27 Nov 2024 21:48:20 +0900</pubDate>
    </item>
    <item>
      <title>[SWT/JFace] 이벤트 처리</title>
      <link>https://aacii.tistory.com/392</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;이벤트 처리는 이벤트를 전달하는 이벤트 클래스와 이벤트를 처리하는 리스너가 담당합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;JFace는 이런 이벤트 처리를 간단하게 해줍니다.&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;SWT 에서 이벤트 처리&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SWT는 운영체제의 이벤트 큐를 사용합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Application의 Display클래스는 해당 큐의 내용을 정렬하는데 readAndDispatch()와 msg 필드를 사용합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;msg필드는 운영체제의 메시지 큐에 대한 핸들로 동작합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 이벤트를 최상위 Shell 객체로 보내고 Shell객체는 어떤 위젯이 해당 이벤트를 받을지 결정합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Shell은 해당 위젯으로 이벤트를 보내고 해당 위젯은 이 정보를 리스너 라는 인터페이스로 전달합니다.&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;h3 data-ke-size=&quot;size23&quot;&gt;Adapter 클래스&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Adapter는 추상클래스로 Listener 인터페이스를 구현하고 필요한 각 메소드의 기본적인 구현을 제공합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위젯을 리스너가 아닌 어댑터와 연결하면 이벤트를 처리할 메소드 코드만 작성하면 되기 때문에 편리합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다만 Adapter는 리스너가 하나 이상의 멤버 메소드를 가질 때만 유용합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1705820702952&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import org.eclipse.swt.SWT;
import org.eclipse.swt.events.KeyAdapter;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;

public class MouseKey extends Composite{
	Label output;
	public MouseKey(Composite parent){
		super(parent, SWT.NULL);
		
		Button typed = new Button(this, SWT.PUSH);
		typed.setText(&quot;Typed&quot;);
		typed.setLocation(2,10);
		typed.pack();
		//Adapter를 익명 리스너로 사용. 
		typed.addKeyListener(new KeyAdapter() {
			public void keyPressed(KeyEvent e) {
				keyHandler();
			}
		});
		
		Button untyped = new Button(this, SWT.PUSH);
		untyped.setText(&quot;Untyped&quot;);
		untyped.setLocation(80, 10);
		untyped.pack();
		//UntypedListener 인터페이스를 구현해서 이벤트 처리
		untyped.addListener(SWT.MouseEnter, UntypedListener);
		untyped.addListener(SWT.MouseExit, UntypedListener);
		
		output = new Label(this, SWT.SHADOW_OUT);
		output.setBounds(40, 70, 90, 40);
		output.setText(&quot;No Event&quot;);
		pack();
	}
	
	//key 이벤트를 처리
	void keyHandler() {
		output.setText(&quot;Key Event&quot;);
	}
	
	//마우스 이벤트를 처리
	Listener UntypedListener = new Listener() {
		@Override
		public void handleEvent(Event event) {
			switch (event.type) {
			case SWT.MouseEnter:
				output.setText(&quot;Mouse Enter&quot;);
				break;
			case SWT.MouseExit:
				output.setText(&quot;Mouse Exit&quot;);
				break;
			}
		}
	};
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 클래스를 CompViewer 클래스와 연결 시키면 실행 결과를 볼수 있습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1705820722433&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import org.eclipse.jface.window.ApplicationWindow;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;

public class CompViewer extends ApplicationWindow{

	public CompViewer() {
		super(null);
	}
	
	protected Control createContents(Composite parent) {
		MouseKey mk = new MouseKey(parent);
		return parent;
	}

	public static void main(String[] args) {
		CompViewer cv = new CompViewer();
		cv.setBlockOnOpen(true);
		cv.open();
		Display.getCurrent().dispose();
	}

}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실행결과:&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;화면 캡처 2024-01-21 160619.png&quot; data-origin-width=&quot;139&quot; data-origin-height=&quot;148&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/QAPzE/btsDLLQAPNs/szcXxErmRUUeFCt0nu6x21/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/QAPzE/btsDLLQAPNs/szcXxErmRUUeFCt0nu6x21/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/QAPzE/btsDLLQAPNs/szcXxErmRUUeFCt0nu6x21/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FQAPzE%2FbtsDLLQAPNs%2FszcXxErmRUUeFCt0nu6x21%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;139&quot; height=&quot;148&quot; data-filename=&quot;화면 캡처 2024-01-21 160619.png&quot; data-origin-width=&quot;139&quot; data-origin-height=&quot;148&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;키보드를 아무거나 누르면 이벤트를 처리하는 것을 볼 수 있고, Untyped 버튼에 마우스를 가져가면 마우스 이벤트도 정상 처리 됨을 볼 수 있습니다.&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;JFace의 이벤트 처리&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;JFace 개발자는 리스너, 어댑터, 위젯이 필요 없다고 여기고, 대신 이벤트 처리를 액션과 컨트리뷰터로 처리합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;액션은 사용자가 GUI와 상호작용할 때 발생하는 것이며, 컨트리뷰터는 여러 종류의 액션을 받으면서도 단일한 액션을 발생시키는 것을 말합니다.&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;JFace는 Action과 ActionContributionItem 클래스를 분리해서 제공합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;ActionContributionItem&lt;span&gt; 이 위젯의 기능과 리스너 클래스를 결합합니다.&lt;/span&gt;&lt;/span&gt;&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;사용자가 상호작용을 할 때마다 연관된 Action 클래스를 발생시켜 이벤트를 처리합니다.&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;SWT 이벤트 모델 처럼 인터페이스 처리는 Display 클래스로 시작해서 운영체제의 이벤트 큐를 모니터링합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 Display 클래스가 Display의 Shell 객체를 포함하는 ApplicationWindow 정보를 전달합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ApplicationWindow는 Action 클래스를 생성하여 원래 이벤트를 생성한 Contribution에 전달합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Contribution은 단일 이벤트 핸들러이며 Action클래스의 run() 메소드를 호출합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;Action 클래스&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;이 예제는 ApplcationWindow의 상태 표시줄에 출력하는 기능을 수행합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;툴바 안에 이 클래스를 구현할 것이라 연결 시킬 이미지가 필요한데,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이클립스경로/plugins/org.eclipse.platform_~~~ 디렉토리에서 eclipse64.png 파일을 현재 프로젝트 폴더(패키지)로 복사하면 됩니다.&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1705822556951&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.StatusLineManager;
import org.eclipse.jface.resource.ImageDescriptor;

public class StatusAction extends Action{
	StatusLineManager statman;
	short triggercount = 0;
	
	public StatusAction(StatusLineManager sm) {
		//&amp;amp;은 이 문자가 단축키가 될것을 의미
		super(&quot;&amp;amp;Trigger@Ctrl+T&quot;, AS_PUSH_BUTTON);
		statman = sm;
		setToolTipText(&quot;액션 트리거&quot;);
		setImageDescriptor(ImageDescriptor.createFromFile(this.getClass(),&quot;eclipse64.png&quot;));
	}
	
	public void run() {
		triggercount++;
		statman.setMessage(&quot;상태 액션이 발생했습니다. count: &quot;+triggercount);
	}
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 예제에서 StatusAction 클래스는 어떤 컴포넌트가 액션을 발생시키는지 모릅니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 어떤 Control이 액션을 발생시키든 추가 메서드 작성 없이 StatusAction()을 사용할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;run() 메서드가 유일한 이벤트 처리 루틴이라는 점이 SWT의 이벤트와 결합되는 핸들러가 여러개라는 점이 다른 점입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;run() 메서드가 이벤트 처리를 하지만 주요 작업은 생성자인 StatusAction()이 수행합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약 이 StatusAction 을 메뉴와 결합시키면 메뉴는 이벤트를 발생시킬 수 있게 되는 것입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;StatusAction을 발생시킬 때마다, run()이 실행됩니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그 때마다 triggercount가 누적되고 메시지가 StatusLineManager 객체로 보내지게 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;ApplicationWindow에서 Contribution 구현&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;아래 예제는 ApplcationWindow에서 Contribution과 ContributionManager를 추가하는 방법에 대한 예제 입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ActionContributionItem, MenuManager, ToolBarManager는 모두 StatusAction을 발생시키며, 이 Action은 메시지를 상태표시줄로 보냅니다.&lt;/p&gt;
&lt;pre id=&quot;code_1705826035185&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;package event;

import org.eclipse.jface.action.ActionContributionItem;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.action.StatusLineManager;
import org.eclipse.jface.action.ToolBarManager;
import org.eclipse.jface.window.ApplicationWindow;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;

public class Contributions extends ApplicationWindow{

	StatusLineManager slm = new StatusLineManager();
	//status_action 인스턴스 생성
	StatusAction status_action = new StatusAction(slm);
	//status_action 컨트리뷰션을 ActionContributionItem에 할당
	ActionContributionItem aci = new ActionContributionItem(status_action);	
	
	//생성자에서 Application Window에 자원을 추가
	public Contributions() {
		super(null);
		//상태표시줄 추가
		addStatusLine();
		//메뉴 추가
		addMenuBar();
		//툴바 추가
		addToolBar(SWT.FLAT | SWT.WRAP);
	}
	
	protected Control createContents(Composite parent) {
		//윈도우 타이틀 설정
		getShell().setText(&quot;Action/Contribution Example&quot;);
		//윈도우 크기 설정
		parent.setSize(800, 600);
		//ActionContributionItem을 호출해서 윈도우 안에 버튼을 생성
		aci.fill(parent);	//aci객체를 GUI에 넣어 눌릴때마다 statusEvent를 발생시킴	
		return parent;
	}
	
	//메뉴를 상단에 생성
	protected MenuManager createMenuManager() {
		MenuManager main_menu = new MenuManager(null);
		MenuManager action_menu = new MenuManager(&quot;Menu&quot;);
		main_menu.add(action_menu);
		//status_action 컨트리뷰션을 할당
		action_menu.add(status_action);
		return main_menu;	
	}
	
	//툴바 생성
	protected ToolBarManager createToolBarManager(int style) {
		ToolBarManager tool_bar_manager = new ToolBarManager(style);
		//status_action 컨트리뷰션을 할당
		tool_bar_manager.add(status_action);
		return tool_bar_manager;
	}
	
	protected StatusLineManager createStatusLineManager() {
		return slm;
	}

	public static void main(String[] args) {
		//윈도우 생성
		Contributions swin = new Contributions();
		//윈도우 열기
		swin.setBlockOnOpen(true);
		swin.open();
		//GUI 자원 처분
		Display.getCurrent().dispose();
	}

}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;화면 캡처 2024-01-21 181714.png&quot; data-origin-width=&quot;786&quot; data-origin-height=&quot;593&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bK8ZXM/btsDHnwX7wG/xggkxXbfscf39Zn7ERhBuk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bK8ZXM/btsDHnwX7wG/xggkxXbfscf39Zn7ERhBuk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bK8ZXM/btsDHnwX7wG/xggkxXbfscf39Zn7ERhBuk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbK8ZXM%2FbtsDHnwX7wG%2FxggkxXbfscf39Zn7ERhBuk%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;786&quot; height=&quot;593&quot; data-filename=&quot;화면 캡처 2024-01-21 181714.png&quot; data-origin-width=&quot;786&quot; data-origin-height=&quot;593&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;Contribution 연결 방법&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 예제에서 처럼&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. ContributionManager의 add() 사용. add()는 인자로 Action과 ActionContributionItem을 받는데 ContributionItem과 ContributionManager를 Action과 묵시적으로 연동할 수 있고, ActionContributionItem과 명시적으로 연동할 수 있음. 그러나 명시적 연동은 한 번만 수행되지만 묵시적 연동은 한 Action객체에 반복적으로 수행할 수 있음.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2.&amp;nbsp; ActionContributionItem의 fill() 사용. 인자로 SWT 위젯을 전달. 인자가 Composite 타입이면 해당 액션의 STYLE을 따름. 만약 인자가 SWT Menu 객체면 메뉴형태로, SWT ToolBar객체면 툴바 형태로 나타남.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;Ev_Composite.java 만들기&lt;/blockquote&gt;
&lt;pre id=&quot;code_1705831082771&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import org.eclipse.swt.SWT;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;

public class Ev_Composite extends MouseKey {
	public Ev_Composite(Composite parent) {
		super(parent);
		Button launch = new Button(this, SWT.PUSH);
		launch.setText(&quot;실행&quot;);
		launch.setLocation(40, 120);
		launch.pack();
				
		launch.addMouseListener(new MouseAdapter() {
			public void mouseDown(MouseEvent e) {
				Contributions sw = new Contributions();
				sw.open();
			}
		});
	}
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;WidgetWindow.java 수정&lt;/blockquote&gt;
&lt;pre id=&quot;code_1705831130021&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import org.eclipse.jface.window.ApplicationWindow;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.TabFolder;
import org.eclipse.swt.widgets.TabItem;

public class WidgetWindow extends ApplicationWindow {

	public WidgetWindow() {
		super(null);
	}
	
	protected Control createContents(Composite parent) {
		//탭폴더 생성
		TabFolder tf = new TabFolder(parent, SWT.NONE);
		
		TabItem ti = new TabItem(tf, SWT.NONE);
		ti.setText(&quot;탭1&quot;);
		ti.setControl(new Ev_Composite(tf));
				
		getShell().setText(&quot;위젯 윈도우&quot;);
		return parent;
	}

	public static void main(String[] args) {
		WidgetWindow wwin = new WidgetWindow();
		wwin.setBlockOnOpen(true);
		wwin.open();
		Display.getCurrent().dispose();
	}

}&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;blockquote data-ke-style=&quot;style2&quot;&gt;요약&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. JFace가 메뉴, 툴바, 버튼에 대한 빠른 코딩이 가능한 반면 SWT는 키보드 작동 및 Shell과 테이블 같은 위젯과 관련한 이벤트에 필요합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. JFace가 오른쪽 클릭과 왼쪽 클릭을 구분해야 할 때는 쓸모가 없습니다.&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;&amp;nbsp;&lt;/p&gt;</description>
      <category>DEV&amp;amp;OPS/Java</category>
      <category>EVENT</category>
      <category>Java</category>
      <category>JFace</category>
      <category>Listener</category>
      <category>SWT</category>
      <category>이벤트</category>
      <category>자바</category>
      <author>ALEPH.GEM</author>
      <guid isPermaLink="true">https://aacii.tistory.com/392</guid>
      <comments>https://aacii.tistory.com/392#entry392comment</comments>
      <pubDate>Wed, 27 Nov 2024 21:47:58 +0900</pubDate>
    </item>
    <item>
      <title>[SWT/JFace] Composite 클래스</title>
      <link>https://aacii.tistory.com/390</link>
      <description>&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;h3 data-ke-size=&quot;size23&quot;&gt;Composite 클래스&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;컨테이너 위젯은 GUI의 배경 구조를 구성하고 모듈식 코드를 제공합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여러 composite 객체가 다른 composte 객체에 결합될 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;Composite 클래스의 메소드&lt;/blockquote&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;getChildren() : Control 객체의 배열을 반환&lt;/li&gt;
&lt;li&gt;getLayout() : composite에 연결한 레이아웃을 반환&lt;/li&gt;
&lt;li&gt;setLayout(Layout) : composite에 연결할 레이아웃을 설정&lt;/li&gt;
&lt;li&gt;getTabList() : 탭 순서에 따른 Control 객체의 배열을 반환&lt;/li&gt;
&lt;li&gt;setTabList(Control[]) : Composite의 위젯들의 탭 순서를 설정&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;Composite 클래스는 Scrollable 클래스의 하위 클래스 입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 모든 Composite 클래스는 스크롤바를 가질 수 있습니다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;Scrollabe 클래스의 메소드&lt;/blockquote&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;getClientArea() : Scrollable 객체에서 가능한 화면 표시 면적을 반환&lt;/li&gt;
&lt;li&gt;computeTrim(int, int, int, int) : 클라이언트 영역을 위한 Composite의 필요 면적을 반환&lt;/li&gt;
&lt;li&gt;getHorizontalBar() : 수평 스크롤바 객체를 반환&lt;/li&gt;
&lt;li&gt;getVerticalBar() : 수직 스크롤바 객체를 반환&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;getSize()가 Control의 면적 크기를 알려주지만 타이틀바, 상태바 등등이 얼만큼의 영역을 차지하는지 알 수 없습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 trim은 Composite 에서 편집 불가능한 영역을 말합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Composite에서 편집 가능한 영역을 클라이언트 영역이라고 부릅니다.&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;h3 data-ke-size=&quot;size23&quot;&gt;SashForm&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SashForm은 컨트롤들의 크기를 동적으로 조정할 수 있도록 위젯들의 그룹을 지정해서 관리할 수 있는 기능입니다.&lt;/p&gt;
&lt;pre id=&quot;code_1705812353631&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Composite;

public class SashForm extends Composite{
	public SashForm(Composite parent) {
		super(parent, SWT.NONE);
	}
}&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1705812379579&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import org.eclipse.jface.window.ApplicationWindow;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;

public class CompViewer extends ApplicationWindow{

	public CompViewer() {
		super(null);
	}
	
	protected Control createContents(Composite parent) {
		SashForm sf = new SashForm(parent);
		sf.setSize(120, 80);;
		Button button1 = new Button(sf, SWT.ARROW | SWT.UP);
		button1.setSize(120, 40);
		Button button2 = new Button(sf, SWT.ARROW | SWT.DOWN);
		button2.setBounds(0, 40, 120, 40);
		return parent;
	}

	public static void main(String[] args) {
		CompViewer cv = new CompViewer();
		cv.setBlockOnOpen(true);
		cv.open();
		Display.getCurrent().dispose();
	}

}&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;h3 data-ke-size=&quot;size23&quot;&gt;TabFolder&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여러개의 Composite 객체를 하나의 컨테이너에 담습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;탭 인덱스를 통해서 각각에 접근 할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;메인 인스턴스를 생성한 후에 tab이라고 부르는 TabItem 객체를 생성합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 setText()를 호출하여 탭 레이블에 문자열을 설정합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;setControl()으로 탭을 선택할 때 관련된 Control을 보이도록 탭과 Control을 연결합니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;getItemCount() : TabFolder의 TabItem 수를 반환&lt;/li&gt;
&lt;li&gt;getItems() : TabItem 객체의 배열을 반환&lt;/li&gt;
&lt;li&gt;getSelection() : 사용자가 어떤 TabItem을 선택했는지 알려줌.&lt;/li&gt;
&lt;li&gt;setSelection() : 선택될 탭을 설정&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1705815920580&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Composite;

public class Ex_Composite extends Composite {
	public Ex_Composite(Composite parent) {
		super(parent, SWT.NONE);

		parent.getShell().setText(&quot;Composite 예제&quot;);
				
		SashForm cc1 = new SashForm(this);
		cc1.setLocation(0,0);
		cc1.pack();
		
		SashForm cc2 = new SashForm(this);
		cc2.setLocation(125, 25);
		cc2.pack();
		
		pack();
	}
}&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1705815944274&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import org.eclipse.jface.window.ApplicationWindow;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.TabFolder;
import org.eclipse.swt.widgets.TabItem;

public class WidgetWindow extends ApplicationWindow {

	public WidgetWindow() {
		super(null);
	}
	
	protected Control createContents(Composite parent) {
		//탭폴더 생성
		TabFolder tf = new TabFolder(parent, SWT.NONE);
		TabItem ti = new TabItem(tf, SWT.NONE);
		ti.setText(&quot;탭폴더 예제&quot;);
		ti.setControl(new Ex_Composite(tf));
		getShell().setText(&quot;위젯 윈도우&quot;);
		return parent;
	}

	public static void main(String[] args) {
		WidgetWindow wwin = new WidgetWindow();
		wwin.setBlockOnOpen(true);
		wwin.open();
		Display.getCurrent().dispose();
	}

}&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;&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;&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;&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;&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;&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;&amp;nbsp;&lt;/p&gt;</description>
      <category>DEV&amp;amp;OPS/Java</category>
      <category>composite</category>
      <category>GUI</category>
      <category>Java</category>
      <category>JFace</category>
      <category>SWT</category>
      <category>이클립스</category>
      <category>자바</category>
      <category>플러그인</category>
      <author>ALEPH.GEM</author>
      <guid isPermaLink="true">https://aacii.tistory.com/390</guid>
      <comments>https://aacii.tistory.com/390#entry390comment</comments>
      <pubDate>Wed, 27 Nov 2024 21:47:43 +0900</pubDate>
    </item>
    <item>
      <title>[SWT/JFace] Widget, Control, Label, Button</title>
      <link>https://aacii.tistory.com/388</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Widget 클래스&lt;/h3&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;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;setData(String Object) : 위젯에 객체를 붙임. 문자열로 접근 가능.&lt;/li&gt;
&lt;li&gt;getData(String) : 위젯에서 문자열에 대응하는 데이터와 관련된 객체를 반환&lt;/li&gt;
&lt;li&gt;getStyle() : 위젯의 스타일에 해당하는 정수를 반환&lt;/li&gt;
&lt;li&gt;getDisplay() : 위젯과 관련된 Display 객체를 반환&lt;/li&gt;
&lt;li&gt;toString() : 위젯 클래스를 표현하는 문자열 반환&lt;/li&gt;
&lt;li&gt;dispose() : 위젯과 위젯 자원에 대한 할당을 해제.&lt;/li&gt;
&lt;li&gt;isDisposed() : 위젯의 할당을 해제했는지에대한 boolean 값 반환&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Control 클래스&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Control클래스의 객체들은 운영체제와 짝을 이루는 부분이 있어서 클래스의 hnadle 필드를 통해서 직접 운영체제 API에 접근 할 수 있습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;getSize() : 위젯 크기를 표현하는 Point 객체를 반환.&lt;/li&gt;
&lt;li&gt;setSize(int, int) : 너비와 길이 값을 바탕으로 위젯 크기를 설정&lt;/li&gt;
&lt;li&gt;setSize(Point) : Point 객체에 따라 위젯 크기를 설정&lt;/li&gt;
&lt;li&gt;computeSize(int, int) : 위젯 내용을 모두 보여줄 수 있는 면적을 반환&lt;/li&gt;
&lt;li&gt;computeSize(int, int, boolean) : 위젯 내용을 모두 보여줄 수 있는 면적을 반환하고, 위젯 특성이 바뀌었는지 알려 줌.&lt;/li&gt;
&lt;li&gt;pack() : 위젯을 선호하는 크기로 재조정&lt;/li&gt;
&lt;li&gt;pack(boolean) : 위젯을 선호하는 크기로 재조정하고, 위젯 특성이 바뀌었는지 알려줌.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해상도와 플랫폼 차이 때문에 getSize()보다 pack()을 권장합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;알아서 크기 조절이 되기 때문입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 컨테이너에 위젯을 추가할 때마다 pack()을 호출해야 합니다.&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;각 Control은 그 부모에 따라 각기 다른 상대적인 참조 위치를 사용합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 아래 처럼 위치를 조정하는 메소드들이 존재합니다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;Cotrol 위치를 설정하고 반환하는 메소드&lt;/blockquote&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;getLocation() : 위젯의 부모에 대한 상대 위치를 반환&lt;/li&gt;
&lt;li&gt;setLocation(int, int) : 위젯의 부모에 대한 상대 위치를 설정&lt;/li&gt;
&lt;li&gt;getBounds() : 위젯의 크기와 부모에 대한 상대 위치를 반환&lt;/li&gt;
&lt;li&gt;setBounds(int, int, int, int) : 위젯의 크기와 부모에 대한 상대 위치를 설정&lt;/li&gt;
&lt;li&gt;toControl(int, int) : 화면 기준 좌표를 컨트롤 기준 Point 값으로 바꿈&lt;/li&gt;
&lt;li&gt;toControl(Point) : 화면 기준 Point 값을 컨트롤 기준 Point 값으로 바꿈&lt;/li&gt;
&lt;li&gt;toDisplay(int, int) : 컨트롤 기준 좌표를 컨트롤 기준 Point 값으로 바꿈&lt;/li&gt;
&lt;li&gt;toDisplay(Point) : 컨트롤 기준 Point 값을 Point 값으로 바꿈.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Label&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Label 클래스는 문자열이나 이미지를 담아 표시하는 기능입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;각각의 스타일 값이 정수 값으로 저장되어 있는데 이를 상수로 표현하게 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어 문자열의 배치는 SWT.CENTER, SWT.LEFT, SWT.RIGHT 처럼 다루면 됩니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;getText() : Label의 문자열을 반환&lt;/li&gt;
&lt;li&gt;setText() : Label의 문자열을 지정&lt;/li&gt;
&lt;li&gt;getAlignment() : 정수값으로 표현되는 Label의 문자열의 배치를 반환&lt;/li&gt;
&lt;li&gt;setAlignment(int) : SWT.상수값 에 따라 문자열의 배치를 설정&lt;/li&gt;
&lt;li&gt;getImage() : Label의 이미지 객체를 반환&lt;/li&gt;
&lt;li&gt;setImage(Image) : Image객체를 Label에 설정&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Button&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;푸시 버튼 : SWT.PUSH&lt;/p&gt;
&lt;pre id=&quot;code_1705745840568&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;Button push = new Button(shell, SWT.PUSH | SWT.LEFT);
push.setText(&quot;버튼&quot;);
push.pack();&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;| 기호로 스타일과 함께 버튼 생성자에 지정해줄 수 있습니다.&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;pre id=&quot;code_1705746383646&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;Button push1 = new Button(shell, SWT.ARROW | SWT.RIGHT);
push1.setText(&quot;오른쪽&quot;);
push1.pack();&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;토글 버튼은 SWT.TOGGLE 을 사용합니다.&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;pre id=&quot;code_1705746861749&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;Button[] checks = new Button[2];
checks[0] = new Button(shell, SWT.CHECK);
checks[0].setText(&quot;선택1&quot;);
checks[0].setLocation(100, 50);
checks[0].pack();
	
checks[1] = new Button(shell, SWT.CHECK);
checks[1].setText(&quot;선택2&quot;);
checks[1].setLocation(300, 50);
checks[1].pack();&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;라디오 버튼 SWT.RADIO&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;pre id=&quot;code_1705747183334&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;Button[] radios = new Button[2];
radios[0] = new Button(shell, SWT.RADIO);
radios[0].setSelection(true);
radios[0].setText(&quot;선택1&quot;);
radios[0].setLocation(100, 50);
radios[0].pack();

radios[1] = new Button(shell, SWT.RADIO);
radios[1].setText(&quot;선택2&quot;);
radios[1].setLocation(300, 50);
radios[1].pack();
	
for(int i = 0; i&amp;lt;radios.length;i++) {
	if(radios[i].getSelection()) {
		System.out.println(i);
	}
}&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;라디오 버튼의 그룹을 모으고 관리하기 위한 기능은 org.eclipse.jface.preference 패키지에 RadioGroupFieldEditor 클래스에 있는데 나중에 더 자세히 다뤄보겠습니다.&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 alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;화면 캡처 2024-01-20 195424.png&quot; data-origin-width=&quot;459&quot; data-origin-height=&quot;201&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bmCYH2/btsDKRwEsRO/KiG6FhgMaI2zBwOqrJm8lK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bmCYH2/btsDKRwEsRO/KiG6FhgMaI2zBwOqrJm8lK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bmCYH2/btsDKRwEsRO/KiG6FhgMaI2zBwOqrJm8lK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbmCYH2%2FbtsDKRwEsRO%2FKiG6FhgMaI2zBwOqrJm8lK%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;459&quot; height=&quot;201&quot; data-filename=&quot;화면 캡처 2024-01-20 195424.png&quot; data-origin-width=&quot;459&quot; data-origin-height=&quot;201&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;&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;&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;&amp;nbsp;&lt;/p&gt;</description>
      <category>DEV&amp;amp;OPS/Java</category>
      <category>Control</category>
      <category>Java</category>
      <category>JFace</category>
      <category>SWT</category>
      <category>widget</category>
      <category>위젯</category>
      <category>자바</category>
      <author>ALEPH.GEM</author>
      <guid isPermaLink="true">https://aacii.tistory.com/388</guid>
      <comments>https://aacii.tistory.com/388#entry388comment</comments>
      <pubDate>Wed, 27 Nov 2024 21:47:25 +0900</pubDate>
    </item>
    <item>
      <title>[SWT/JFace] 모델 기반 어댑터</title>
      <link>https://aacii.tistory.com/387</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;모델 기반 어댑터&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;JFace는 SWT 위젯을 좀 더 쉽게 다룰 수 있도록 헬퍼 클래스들을 지원하는데 이들을 모델 기반 어댑터라고 부릅니다.&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;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;뷰어 : 위젯의 모양과 정보를 구별. 가장 많이 사용.&lt;/li&gt;
&lt;li&gt;액션과 컨트리뷰션 : 이벤트 처리 절차를 간단하게 만들고 조직화&lt;/li&gt;
&lt;li&gt;이미지와 폰트 레지스트리 : 폰트와 이미지의 할당과 해제를 관리&lt;/li&gt;
&lt;li&gt;대화상자와 마법사 : 사용자와의 상호작용을 위해 SWT Dialog의 기능을 확장&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;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;HelloSWT_JFace 예제&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 예제는 순수 SWT 예제와 비슷하지만 구조가 다릅니다.&lt;/p&gt;
&lt;pre id=&quot;code_1705582579118&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import org.eclipse.jface.window.ApplicationWindow;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Text;

public class HelloJFace extends ApplicationWindow{

	//윈도우 할당
	public HelloJFace() {
		super(null);
	}

	//윈도우 보여 줌
	protected Control createContents(Composite parent) {
		Text helloText = new Text(parent, SWT.CENTER);
		helloText.setText(&quot;Hello. my friends. stay awhile and listen.&quot;);
		parent.pack();
		return parent;
	}
	
	//윈도우 작동
	public static void main(String[] args) {
		HelloJFace appwin = new HelloJFace();		
		appwin.setBlockOnOpen(true);
		appwin.open();
		Display.getCurrent().dispose();
	}

}&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;&amp;nbsp;&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;순수 SWT 방식과 차이 점&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;순수 SWT는 shell 클래스에서 GUI 외양과 동작을 같이 기술합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;반면 SWT/JFace는 GUI의 외양과 동작을 분리하여 기술합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이런 모듈화된 구조는 코드를 재사용 할 수 있고 MVC 패턴으로 구조화 할 수 있습니다.&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;h3 data-ke-size=&quot;size23&quot;&gt;ApplicationWindow 클래스&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ApplicationWindow는 Shell클래스에서 JFace 어댑터로서 동작합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Shell 클래스가 윈도우의 크기와 스타일을 변경하는 메서드들을 갖고 있지만 ApplicationWindow의 메서드들을 사용하면 더 편리하게 설정할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SWT에서는 여러 속성과 기능들을 각각의 쉘에 대해 제공하고 설정해야 하는데 JFace에서는 자동으로 처리해줍니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;addMenuBar() : 메뉴 바 설정&lt;/li&gt;
&lt;li&gt;addToolBar(); 메뉴 아래 툴바 추가&lt;/li&gt;
&lt;li&gt;addStatusLine(): 윈도우 하단에 상태표시줄 추가&lt;/li&gt;
&lt;li&gt;setStatus(String): 상패 표시줄에 메시지를 보여줌&lt;/li&gt;
&lt;li&gt;getSeparator() : 윈도우의 메뉴를 구분하는 줄을 반환.&lt;/li&gt;
&lt;li&gt;setDefalutImage(Image): application에 shell이 없으면 이미지를 보여줌.&lt;/li&gt;
&lt;li&gt;setExceptionHandler(IExceptionHandler): application이 특정 인터페이스에 맞춰 예외 처리를 하도록 설정&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;WidgetWindow 예제&lt;/h3&gt;
&lt;pre id=&quot;code_1705584404940&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import org.eclipse.jface.window.ApplicationWindow;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;

public class WidgetWindow extends ApplicationWindow {

	public WidgetWindow() {
		super(null);
	}
	
	protected Control createContents(Composite parent) {
		getShell().setText(&quot;Widget Window&quot;);
		parent.setSize(600, 400);
		return parent;
	}

	public static void main(String[] args) {
		WidgetWindow wwin = new WidgetWindow();
		wwin.setBlockOnOpen(true);
		wwin.open();
		Display.getCurrent().dispose();
	}

}&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;실행 결과&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;화면 캡처 2024-01-18 222623.png&quot; data-origin-width=&quot;586&quot; data-origin-height=&quot;393&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lKoo2/btsDCSRqr0g/fm26Fayz5iLElzPZ2Vq961/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lKoo2/btsDCSRqr0g/fm26Fayz5iLElzPZ2Vq961/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lKoo2/btsDCSRqr0g/fm26Fayz5iLElzPZ2Vq961/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FlKoo2%2FbtsDCSRqr0g%2Ffm26Fayz5iLElzPZ2Vq961%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;586&quot; height=&quot;393&quot; data-filename=&quot;화면 캡처 2024-01-18 222623.png&quot; data-origin-width=&quot;586&quot; data-origin-height=&quot;393&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;&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>DEV&amp;amp;OPS/Java</category>
      <category>GUI</category>
      <category>Java</category>
      <category>JFace</category>
      <category>SWT</category>
      <category>모델 기반 어댑터</category>
      <category>어댑터</category>
      <category>이클립스</category>
      <author>ALEPH.GEM</author>
      <guid isPermaLink="true">https://aacii.tistory.com/387</guid>
      <comments>https://aacii.tistory.com/387#entry387comment</comments>
      <pubDate>Wed, 27 Nov 2024 21:47:15 +0900</pubDate>
    </item>
    <item>
      <title>[SWT/JFace] Display 클래스, Shell 클래스, 메시지 박스 예제</title>
      <link>https://aacii.tistory.com/386</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Display class&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Display 클래스가 외관을 보여주는 역할을 하지는 않지만 GUI 자원을 관리하고 운영체제와 소통을 담당합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;코드에 있는 SWT/JFace 명령들을 운영체제에 호환되도록 바꾸어 전달하는 일을 합니다.&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;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Display() : 플랫폼 자원을 할당하고 Display 객체를 생성.&lt;/li&gt;
&lt;li&gt;getCurrent() : 사용자 인터페이스 스레드를 반환.&lt;/li&gt;
&lt;li&gt;readAndDispatch() : Display 객체가 이벤트를 해석해서 리스너로 넘겨 줌.&lt;/li&gt;
&lt;li&gt;sleep() : Display 객체가 이벤트를 기다림.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Shell class&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Shell 클래스의 인스턴스는 위젯, 이벤트들과 연동하며, 시각적인 부분을 구현합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;운영체제에 접근하기는 하지만 윈도우 열기, 활성화, 최대화, 윈도우 닫기를 추적할 때만 접근합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모든 SWT/JFace application은 메인 Shell 객체(최상위 Shell) 위에 위젯을 올리지만, application에 다른 shell이 존재할 수도 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 shell 인스턴스는 여러 속성들이 있고 사용자들이 상태를 변경 할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Shell은 인자 값으로 display객체를 받습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;shell, 위젯들의 스타일 정보를 상수값(스타일 비트)을 설정 할 수 있습니다.&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;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;메시지 박스 예제&lt;/h3&gt;
&lt;pre id=&quot;code_1705394413869&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.MessageBox;
import org.eclipse.swt.widgets.Shell;

public class SWTMessageBox{
    public static void main(String[] args) {
        //디스플레이 객체 획득
        Display display = new Display();
        //shell 객체 획득
        Shell shell = new Shell(display);

        // MessageBox 생성: infomation아이콘, ok버튼
        // 위젯들은 shell의 하위 요소들이다.
        MessageBox messageBox = new MessageBox(shell, SWT.ICON_INFORMATION | SWT.OK);

        // MessageBox에 표시할 메시지 설정
        messageBox.setText(&quot;알림&quot;);	//제목
        messageBox.setMessage(&quot;이것은 SWT MessageBox 예제입니다.&quot;);	//내용

        // MessageBox를 표시하고 사용자의 응답을 기다림. 응답 값은 정수형.
        // shell의 open()메서드를 이용해서 창을 열 수 있다.
        int response = messageBox.open(); 

        // 사용자가 확인(OK) 버튼을 클릭한 경우
        if (response == SWT.OK) {
            System.out.println(&quot;사용자가 확인 버튼을 클릭했습니다.&quot;);
        }

        //로드 된 리소스 정리
        display.dispose();
    }
}&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;&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;</description>
      <category>DEV&amp;amp;OPS/Java</category>
      <category>GUI</category>
      <category>Java</category>
      <category>JFace</category>
      <category>SWT</category>
      <category>이클립스</category>
      <category>자바</category>
      <author>ALEPH.GEM</author>
      <guid isPermaLink="true">https://aacii.tistory.com/386</guid>
      <comments>https://aacii.tistory.com/386#entry386comment</comments>
      <pubDate>Wed, 27 Nov 2024 21:47:04 +0900</pubDate>
    </item>
    <item>
      <title>[SWT/JFace] 이클립스 플러그인 개발 환경 설정</title>
      <link>https://aacii.tistory.com/384</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;윈도우즈 환경에서 이클립스 플러그인 SWT/JFace 개발을 위한 환경 설정을 해보겠습니다.&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;JDK 설치&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서는 JDK11 을 기준으로 합니다. 다운로드 및 설치는 OpenJDK나 오라클에서 하시면 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://openjdk.org/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://openjdk.org/&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1705212179997&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;OpenJDK&quot; data-og-description=&quot;Learn about the key active Projects in the Community including Amber (high-productivity language features), Loom (lightweight concurrency), Panama (foreign functions and foreign data), Valhalla (primitive types and specialized generics), and, of course, th&quot; data-og-host=&quot;openjdk.org&quot; data-og-source-url=&quot;https://openjdk.org/&quot; data-og-url=&quot;https://openjdk.org/&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://openjdk.org/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://openjdk.org/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&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;OpenJDK&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Learn about the key active Projects in the Community including Amber (high-productivity language features), Loom (lightweight concurrency), Panama (foreign functions and foreign data), Valhalla (primitive types and specialized generics), and, of course, th&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;openjdk.org&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.oracle.com/kr/java/technologies/javase/jdk11-archive-downloads.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.oracle.com/kr/java/technologies/javase/jdk11-archive-downloads.html&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1705212222578&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;Java Archive Downloads - Java SE 11 | Oracle 대한민국&quot; data-og-description=&quot;WARNING: These older versions of the JRE and JDK are provided to help developers debug issues in older systems. They are not updated with the latest security patches and are not recommended for use in production. For production use Oracle recommends downlo&quot; data-og-host=&quot;www.oracle.com&quot; data-og-source-url=&quot;https://www.oracle.com/kr/java/technologies/javase/jdk11-archive-downloads.html&quot; data-og-url=&quot;https://www.oracle.com/kr/java/technologies/javase/jdk11-archive-downloads.html&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://www.oracle.com/kr/java/technologies/javase/jdk11-archive-downloads.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.oracle.com/kr/java/technologies/javase/jdk11-archive-downloads.html&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&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;Java Archive Downloads - Java SE 11 | Oracle 대한민국&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;WARNING: These older versions of the JRE and JDK are provided to help developers debug issues in older systems. They are not updated with the latest security patches and are not recommended for use in production. For production use Oracle recommends downlo&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.oracle.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;h3 data-ke-size=&quot;size23&quot;&gt;이클립스 설치&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이클립스는 전자정부프레임워크 개발환경이나 STS를 사용해도 무방합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다만 너무 최신 버전 보다 2~3년전 버전으로 하는 것이 좋습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;최신 버전은 JRE문제나 라이브러리 호환 문제 때문에 문제가 생길 가능성이 높습니다.&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;a href=&quot;https://www.egovframe.go.kr/home/sub.do?menuNo=94&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.egovframe.go.kr/home/sub.do?menuNo=94&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1705212329855&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;개발환경 - 4.x 다운로드  | 표준프레임워크 포털 eGovFrame&quot; data-og-description=&quot;처리중입니다. 잠시만 기다려주십시오.&quot; data-og-host=&quot;www.egovframe.go.kr&quot; data-og-source-url=&quot;https://www.egovframe.go.kr/home/sub.do?menuNo=94&quot; data-og-url=&quot;https://www.egovframe.go.kr/home/sub.do?menuNo=94&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://www.egovframe.go.kr/home/sub.do?menuNo=94&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.egovframe.go.kr/home/sub.do?menuNo=94&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&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;개발환경 - 4.x 다운로드 | 표준프레임워크 포털 eGovFrame&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;처리중입니다. 잠시만 기다려주십시오.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.egovframe.go.kr&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.eclipse.org/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.eclipse.org/&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1705212397015&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;The Community for Open Collaboration and Innovation  | The Eclipse Foundation&quot; data-og-description=&quot;The Eclipse Foundation provides our global community of individuals and organizations with a mature, scalable, and business-friendly environment for open source &amp;hellip;&quot; data-og-host=&quot;www.eclipse.org&quot; data-og-source-url=&quot;https://www.eclipse.org/&quot; data-og-url=&quot;https://www.eclipse.org/home/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/cjzbSk/hyU5PamyY8/AiEHMbsWWYbrEzea8V6rP0/img.png?width=400&amp;amp;height=400&amp;amp;face=0_0_400_400&quot;&gt;&lt;a href=&quot;https://www.eclipse.org/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.eclipse.org/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/cjzbSk/hyU5PamyY8/AiEHMbsWWYbrEzea8V6rP0/img.png?width=400&amp;amp;height=400&amp;amp;face=0_0_400_400');&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;The Community for Open Collaboration and Innovation | The Eclipse Foundation&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;The Eclipse Foundation provides our global community of individuals and organizations with a mature, scalable, and business-friendly environment for open source &amp;hellip;&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.eclipse.org&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;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;Market place&amp;nbsp;WindowBuilder 플러그인 설치&lt;/h3&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;market place에서 WindowBuilder 라는 플러그인을 찾아 설치해줍니다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;이 플러그인은 swt/jface에 의존성이 있기 때문에 설치 시 swt/jface 라이브러리도 같이 설치가 됩니다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;검색해보면 라이브러리를 일일이 추가해 주는 옛날 자료들이 나올 수 있는데... 편하게 WindowBuilder를 설치하시길 추천드립니다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;WindowBuilder 플러그인이 최신 버전 이클립스를 지원하지 않을 수 있음을 유의하십시오.&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;h3 style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;SWT 프로젝트 생성&lt;/h3&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;이클립스를 열고 File -&amp;gt; New -&amp;gt; Project를 클릭해줍니다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;그러면 WindowBuilder 항목 -&amp;gt; SWT Designer -&amp;gt;&amp;nbsp; SWT/JFace Java Project를 선택해서 next 버튼을 누릅니다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;프로젝트 이름과 JRE를 선택하고 Finish 버튼을 눌러 프로젝트를 생성해줍니다.&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;다시 File -&amp;gt; New -&amp;gt; Other 를 선택해줍니다.&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;WindowBuilder -&amp;gt; SWT Designer -&amp;gt; SWT -&amp;gt; Application Window를 선택하고 Next 버튼을 누릅니다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;이제 새로 생성할 SWT Application의 클래스 이름(예: HelloSWT)을 입력해주고 Finish 버튼을 누릅니다.&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;pre id=&quot;code_1705322708635&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;

public class HelloSWT {

	public static void main(String[] args) {
		Display display = new Display();
		Shell shell = new Shell(display);
		
		Text helloText = new Text(shell, SWT.CENTER);
		helloText.setText(&quot;Hello SWT&quot;);
		helloText.pack();
		shell.pack();
		shell.open();
		while(!shell.isDisposed()) {
			if(!display.readAndDispatch()) {
				display.sleep();
			}
		}
		display.dispose();
	}

}&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;실행은 Run -&amp;gt; Run as -&amp;gt; Java Application으로 실행하시면 됩니다.&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;&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;&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;&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;&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;</description>
      <category>DEV&amp;amp;OPS/Java</category>
      <category>Eclipse</category>
      <category>JFace</category>
      <category>plugin</category>
      <category>SWT</category>
      <category>windowbuilder</category>
      <category>개발</category>
      <category>설정</category>
      <category>이클립스</category>
      <category>플러그인</category>
      <category>환경</category>
      <author>ALEPH.GEM</author>
      <guid isPermaLink="true">https://aacii.tistory.com/384</guid>
      <comments>https://aacii.tistory.com/384#entry384comment</comments>
      <pubDate>Wed, 27 Nov 2024 21:46:43 +0900</pubDate>
    </item>
    <item>
      <title>Message Digest 메시지 다이제스트</title>
      <link>https://aacii.tistory.com/437</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;자바에서 메시지 다이제스트 값을 계산하려면 MessageDigest 클래스를 사용합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;메시지 다이제스트는 소스가 되는 이진(byte) 값에 대한 해시 값을 구하는 것입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해시 값도 이진(byte) 값이어서 16진수 String으로 변환해서 읽기 쉽게 변환해서 사용합니다.&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;pre id=&quot;code_1732496963445&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class FileHashCalculator {
    //파일을 읽어서 해시 계산후 String으로 리턴
    public String getHash(String filePath, String algorithm) {
        StringBuilder hashString = new StringBuilder();
        File file = new File(filePath);
        try {
            MessageDigest digest = MessageDigest.getInstance(algorithm);
            try(FileInputStream fis = new FileInputStream(file)){
                byte[] buffer = new byte[1024];
                int bytesRead;
                //파일 데이터를 읽으면서 해시 계산
                while((bytesRead = fis.read(buffer)) != -1) {
                    digest.update(buffer, 0, bytesRead);
                }
                byte[] encodedHash = digest.digest();
                for (byte b : encodedHash) {
              	    hashString.append(String.format(&quot;%02x&quot;, b));
                }        	
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return hashString.toString();
    }

    public boolean createHashFile(String fileName) {
        String path = fileName;
        String hashValue = getHash(path,&quot;SHA-256&quot;);
        path = fileName+&quot;.hash&quot;;
        try (BufferedWriter writer = new BufferedWriter(new FileWriter(path))) {
            writer.write(hashValue);
        }catch (IOException e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }

    public boolean createFile(String fileName) {
        String path = fileName;
        String contents = &quot;example text&quot;;
        try (BufferedWriter writer = new BufferedWriter(new FileWriter(path))) {
            writer.write(contents);
        }catch (IOException e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }	

    public boolean verifyHash(String fileName, String hashFileName) {
	    boolean isEqual = false;
	    String filePath1 = fileName;
	    String filePath2 = hashFileName;
	    //fileName 내용을 읽어서 해시값을 구한다.
	    String hash1 = getHash(filePath1, &quot;SHA-256&quot;);
	    //hashFileName의 내용을 읽는다.
	    String hash2 = readFile(filePath2);
	    //두 해시값을 비교한다.
	    if(hash1.equals(hash2)) {
		    isEqual = true;
	    }else {
		    isEqual = false;
	    }
	    return isEqual;
    }

    public String readFile(String filePath) {
        String savedHash = filePath;
        try (BufferedReader br = new BufferedReader(new FileReader(filePath))) {
            savedHash = br.readLine();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return savedHash;
    }

    public static void main(String[] args) {
        try {
            String filePath1 = &quot;hashTest.txt&quot;; // 해시 값을 구할 원본 소스 파일
            createFile(filePath1); //원본파일 생성
            String filePath2 = &quot;hashTest.txt.hash&quot;; // 해시 값이 저장된 파일
            //원본 파일에 대한 해시값을 저장할 파일 생성
            createHashFile(filePath1);
            //원본 파일에 대한 해시 값과 저장된 해시 파일과 비교
            boolean isEqual = verifyHash(filePath1, filePath2);
            if(isEqual){
                 System.out.println(&quot;Equal&quot;);
            }
        } catch (NoSuchAlgorithmException e) {
            System.err.println(&quot;Invalid algorithm: &quot; + e.getMessage());
        } catch (IOException e) {
            System.err.println(&quot;Error reading file: &quot; + e.getMessage());
        }
    }

}&lt;/code&gt;&lt;/pre&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;/h3&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;&lt;b&gt;문자 인코딩 차이&lt;/b&gt;:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;텍스트 파일의 인코딩이 다르면 동일한 내용을 가진 파일이라도 해시 값이 달라질 수 있습니다.&lt;/li&gt;
&lt;li&gt;그러나 위 메서드는 파일의 바이트 데이터를 그대로 읽으므로, 인코딩과는 무관하게 작동합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;운영 체제별 줄바꿈&lt;/b&gt;:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Windows는 \r\n, UNIX/Linux는 \n을 줄 바꿈 문자로 사용합니다.&lt;/li&gt;
&lt;li&gt;운영 체제 간 파일 이동 시 줄바꿈 문자가 변경되면 파일의 해시 값도 달라질 수 있습니다.&lt;/li&gt;
&lt;li&gt;파일 내용이 동일하더라도 줄바꿈 문자의 차이로 해시 값이 달라질 수 있습니다.&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&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;&amp;nbsp;&lt;/p&gt;</description>
      <category>DEV&amp;amp;OPS/Java</category>
      <category>Java</category>
      <category>md5</category>
      <category>SHA</category>
      <category>메시지 다이제스트</category>
      <category>자바</category>
      <category>파일 해시</category>
      <category>해시</category>
      <author>ALEPH.GEM</author>
      <guid isPermaLink="true">https://aacii.tistory.com/437</guid>
      <comments>https://aacii.tistory.com/437#entry437comment</comments>
      <pubDate>Mon, 25 Nov 2024 10:17:04 +0900</pubDate>
    </item>
    <item>
      <title>대항해시대 온라인 - 모험 컨텐츠 모음</title>
      <link>https://aacii.tistory.com/436</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;학문별 지도 복사, 랭작&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.inven.co.kr/board/dho/495/130192#csidxb593ef2d5bc04beb95a67ef1f60e716&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.inven.co.kr/board/dho/495/130192#csidxb593ef2d5bc04beb95a67ef1f60e716&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1722938295680&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;학문랭작, 자따랭작, 조사랭작 방법 소개&quot; data-og-description=&quot;학문,조사,자물쇠따기 스킬들을 연성만랭 찍었습니다.(전문스킬까지)마지막으로 올린 생태조사만 스샷 올렸습니다. 다른 스킬들은 생략 ^^연성 올클까지 남은 스킬 (일반스킬은 올클했습니다.)&quot; data-og-host=&quot;www.inven.co.kr&quot; data-og-source-url=&quot;https://www.inven.co.kr/board/dho/495/130192#csidxb593ef2d5bc04beb95a67ef1f60e716&quot; data-og-url=&quot;https://www.inven.co.kr/board/dho/495/130192&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/RoIth/hyWKGKbj4N/vyWlhYrFkDI90G14fPZrK0/img.jpg?width=789&amp;amp;height=786&amp;amp;face=0_0_789_786,https://scrap.kakaocdn.net/dn/N3sI9/hyWKKsi6SF/I8GyqZKO1NfeMecxnpChlK/img.jpg?width=1024&amp;amp;height=768&amp;amp;face=0_0_1024_768&quot;&gt;&lt;a href=&quot;https://www.inven.co.kr/board/dho/495/130192#csidxb593ef2d5bc04beb95a67ef1f60e716&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.inven.co.kr/board/dho/495/130192#csidxb593ef2d5bc04beb95a67ef1f60e716&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/RoIth/hyWKGKbj4N/vyWlhYrFkDI90G14fPZrK0/img.jpg?width=789&amp;amp;height=786&amp;amp;face=0_0_789_786,https://scrap.kakaocdn.net/dn/N3sI9/hyWKKsi6SF/I8GyqZKO1NfeMecxnpChlK/img.jpg?width=1024&amp;amp;height=768&amp;amp;face=0_0_1024_768');&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;학문랭작, 자따랭작, 조사랭작 방법 소개&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;학문,조사,자물쇠따기 스킬들을 연성만랭 찍었습니다.(전문스킬까지)마지막으로 올린 생태조사만 스샷 올렸습니다. 다른 스킬들은 생략 ^^연성 올클까지 남은 스킬 (일반스킬은 올클했습니다.)&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.inven.co.kr&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;h3 data-ke-size=&quot;size23&quot;&gt;호칭 퀘스트 정리&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.inven.co.kr/board/dho/498/14936&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.inven.co.kr/board/dho/498/14936&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1722938348838&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;대항해시대 시대 호칭 퀘스트 정리 No.2&quot; data-og-description=&quot;대항해시대 시대 호칭 퀘스트 정리 No.2 일단 들어가기전 설명을 해드리겠습니다. 초록색 네모 박스 : 생물학파란색 네모 박스 : 미술 하늘색 테두리 져있는 박스 : 발견물이 없는 퀘스트하늘색 &quot; data-og-host=&quot;www.inven.co.kr&quot; data-og-source-url=&quot;https://www.inven.co.kr/board/dho/498/14936&quot; data-og-url=&quot;https://www.inven.co.kr/board/dho/498/14936&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bQetg9/hyWKAb7qTn/nxqb9oW8R0bazUNfRaCd4k/img.png?width=346&amp;amp;height=245&amp;amp;face=0_0_346_245,https://scrap.kakaocdn.net/dn/SSamU/hyWKAiUvPX/dQ0EpMkQ4lGw0qQ4oynHl0/img.png?width=3072&amp;amp;height=2482&amp;amp;face=0_0_3072_2482,https://scrap.kakaocdn.net/dn/bP1MYP/hyWKCViMGW/KBVSOhr5qZAxOjK5xBOsD1/img.png?width=2933&amp;amp;height=2217&amp;amp;face=0_0_2933_2217&quot;&gt;&lt;a href=&quot;https://www.inven.co.kr/board/dho/498/14936&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.inven.co.kr/board/dho/498/14936&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bQetg9/hyWKAb7qTn/nxqb9oW8R0bazUNfRaCd4k/img.png?width=346&amp;amp;height=245&amp;amp;face=0_0_346_245,https://scrap.kakaocdn.net/dn/SSamU/hyWKAiUvPX/dQ0EpMkQ4lGw0qQ4oynHl0/img.png?width=3072&amp;amp;height=2482&amp;amp;face=0_0_3072_2482,https://scrap.kakaocdn.net/dn/bP1MYP/hyWKCViMGW/KBVSOhr5qZAxOjK5xBOsD1/img.png?width=2933&amp;amp;height=2217&amp;amp;face=0_0_2933_2217');&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;대항해시대 시대 호칭 퀘스트 정리 No.2&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;대항해시대 시대 호칭 퀘스트 정리 No.2 일단 들어가기전 설명을 해드리겠습니다. 초록색 네모 박스 : 생물학파란색 네모 박스 : 미술 하늘색 테두리 져있는 박스 : 발견물이 없는 퀘스트하늘색&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.inven.co.kr&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;h3 data-ke-size=&quot;size23&quot;&gt;함정 랭작&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=WgjGgU5J2WY&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.youtube.com/watch?v=WgjGgU5J2WY&lt;/a&gt;&lt;/p&gt;
&lt;figure data-ke-type=&quot;video&quot; data-ke-style=&quot;alignCenter&quot; data-video-host=&quot;youtube&quot; data-video-url=&quot;https://www.youtube.com/watch?v=WgjGgU5J2WY&quot; data-video-thumbnail=&quot;https://scrap.kakaocdn.net/dn/DU34Y/hyWKyyC8ua/n0611BRTZtxoSgEoLEquek/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720&quot; data-video-width=&quot;860&quot; data-video-height=&quot;484&quot; data-video-origin-width=&quot;860&quot; data-video-origin-height=&quot;484&quot; data-ke-mobilestyle=&quot;widthContent&quot; data-video-title=&quot;[대항해시대] 함정스킬 랭크를 올려보자 함정랭작 (uncharted water online)&quot; data-original-url=&quot;&quot;&gt;&lt;iframe src=&quot;https://www.youtube.com/embed/WgjGgU5J2WY&quot; width=&quot;860&quot; height=&quot;484&quot; frameborder=&quot;&quot; allowfullscreen=&quot;true&quot;&gt;&lt;/iframe&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;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;천체 발견&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.inven.co.kr/board/dho/498/17871&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.inven.co.kr/board/dho/498/17871&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1722938472457&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;항구관리가 내 아이디를?? 알고보면 정말 쉬운 천문학 유저천체 찾기&quot; data-og-description=&quot;안녕하세요. 헬레네서버에서 활동중인 Trexxx 입니다.인벤 첫 팁글로 유저의 아이디를 딴 월드천체 찾는방법을 써보고자 합니다인벤 팁게시판에 자세한 정보가 없을뿐더러 조이 위키에 있는정보&quot; data-og-host=&quot;www.inven.co.kr&quot; data-og-source-url=&quot;https://www.inven.co.kr/board/dho/498/17871&quot; data-og-url=&quot;https://www.inven.co.kr/board/dho/498/17871&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/cRtr04/hyWKu33WVg/KwgwvT2EKinZY4OhIWePc1/img.jpg?width=900&amp;amp;height=700&amp;amp;face=0_0_900_700,https://scrap.kakaocdn.net/dn/jVxXc/hyWKCudODM/kUphTXqf30L7DQSkpyyJ10/img.jpg?width=900&amp;amp;height=3600&amp;amp;face=0_0_900_3600,https://scrap.kakaocdn.net/dn/XyKcI/hyWKCgIZTy/Y4szITDaZCp7MJYcfvZb5K/img.jpg?width=4096&amp;amp;height=2048&amp;amp;face=0_0_4096_2048&quot;&gt;&lt;a href=&quot;https://www.inven.co.kr/board/dho/498/17871&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.inven.co.kr/board/dho/498/17871&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/cRtr04/hyWKu33WVg/KwgwvT2EKinZY4OhIWePc1/img.jpg?width=900&amp;amp;height=700&amp;amp;face=0_0_900_700,https://scrap.kakaocdn.net/dn/jVxXc/hyWKCudODM/kUphTXqf30L7DQSkpyyJ10/img.jpg?width=900&amp;amp;height=3600&amp;amp;face=0_0_900_3600,https://scrap.kakaocdn.net/dn/XyKcI/hyWKCgIZTy/Y4szITDaZCp7MJYcfvZb5K/img.jpg?width=4096&amp;amp;height=2048&amp;amp;face=0_0_4096_2048');&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;항구관리가 내 아이디를?? 알고보면 정말 쉬운 천문학 유저천체 찾기&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;안녕하세요. 헬레네서버에서 활동중인 Trexxx 입니다.인벤 첫 팁글로 유저의 아이디를 딴 월드천체 찾는방법을 써보고자 합니다인벤 팁게시판에 자세한 정보가 없을뿐더러 조이 위키에 있는정보&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.inven.co.kr&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;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;레거시&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.inven.co.kr/board/dho/498/19464&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.inven.co.kr/board/dho/498/19464&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1722938497083&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;[레거시 테마의 이해 ; 예지의 서] 처음 시작하시는 분들을 위해 적어보는 레거시 테마&quot; data-og-description=&quot;안녕하세요.&amp;nbsp;레거시 처음 시작하시는 분들을 위해,&amp;nbsp;레거시에 대해 도움이 되길 바라면서 진행&amp;nbsp;TIP에 대하여 설명드리고자 합니다.1. 레거시와 소피아1.1&amp;nbsp; 레거시(Legacy)말 그대로 레거시는 유산(&quot; data-og-host=&quot;www.inven.co.kr&quot; data-og-source-url=&quot;https://www.inven.co.kr/board/dho/498/19464&quot; data-og-url=&quot;https://www.inven.co.kr/board/dho/498/19464&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/cvAm0C/hyWKKy1r1g/KXnSz2OuuLwK0gtHGX6V9k/img.png?width=1215&amp;amp;height=501&amp;amp;face=0_0_1215_501,https://scrap.kakaocdn.net/dn/BNHBs/hyWKI2i2ne/T9hynj5BEKAXr0btccnbEK/img.jpg?width=1229&amp;amp;height=518&amp;amp;face=0_0_1229_518,https://scrap.kakaocdn.net/dn/BTXgL/hyWKB9WfoD/dWtKO2xd1YMVLqHPmYqdgk/img.jpg?width=1222&amp;amp;height=730&amp;amp;face=0_0_1222_730&quot;&gt;&lt;a href=&quot;https://www.inven.co.kr/board/dho/498/19464&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.inven.co.kr/board/dho/498/19464&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/cvAm0C/hyWKKy1r1g/KXnSz2OuuLwK0gtHGX6V9k/img.png?width=1215&amp;amp;height=501&amp;amp;face=0_0_1215_501,https://scrap.kakaocdn.net/dn/BNHBs/hyWKI2i2ne/T9hynj5BEKAXr0btccnbEK/img.jpg?width=1229&amp;amp;height=518&amp;amp;face=0_0_1229_518,https://scrap.kakaocdn.net/dn/BTXgL/hyWKB9WfoD/dWtKO2xd1YMVLqHPmYqdgk/img.jpg?width=1222&amp;amp;height=730&amp;amp;face=0_0_1222_730');&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;[레거시 테마의 이해 ; 예지의 서] 처음 시작하시는 분들을 위해 적어보는 레거시 테마&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;안녕하세요.&amp;nbsp;레거시 처음 시작하시는 분들을 위해,&amp;nbsp;레거시에 대해 도움이 되길 바라면서 진행&amp;nbsp;TIP에 대하여 설명드리고자 합니다.1. 레거시와 소피아1.1&amp;nbsp; 레거시(Legacy)말 그대로 레거시는 유산(&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.inven.co.kr&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;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;응검 저격 활쏘기 던지기 랭작&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.inven.co.kr/board/dho/498/18142&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.inven.co.kr/board/dho/498/18142&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1722938726363&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;응검, 저격술, 던지기기술, 활쏘기 랭작&quot; data-og-description=&quot;0. 장비세팅공격력이 없고 방어력이 있으며 내구 높은 장비 추천영화보시면서 스페이스만 편하게 눌러두시려면 방어구는 가급적 다 갖추시는편이 좋습니다.&amp;nbsp;-투구&amp;nbsp;(스키피오의 투구, 크로스 &quot; data-og-host=&quot;www.inven.co.kr&quot; data-og-source-url=&quot;https://www.inven.co.kr/board/dho/498/18142&quot; data-og-url=&quot;https://www.inven.co.kr/board/dho/498/18142&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/olJvX/hyWKElhSb4/eKbVfyno1q1cttIFLwBmd1/img.png?width=1770&amp;amp;height=993&amp;amp;face=0_0_1770_993,https://scrap.kakaocdn.net/dn/c3i36l/hyWKwAMJOH/mrF7nkcK2h1c4MvS0cnglk/img.png?width=1753&amp;amp;height=989&amp;amp;face=0_0_1753_989,https://scrap.kakaocdn.net/dn/zhV3d/hyWKE6EGkN/66g6prKMWkJfJpAGL0dgJK/img.png?width=638&amp;amp;height=340&amp;amp;face=0_0_638_340&quot;&gt;&lt;a href=&quot;https://www.inven.co.kr/board/dho/498/18142&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.inven.co.kr/board/dho/498/18142&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/olJvX/hyWKElhSb4/eKbVfyno1q1cttIFLwBmd1/img.png?width=1770&amp;amp;height=993&amp;amp;face=0_0_1770_993,https://scrap.kakaocdn.net/dn/c3i36l/hyWKwAMJOH/mrF7nkcK2h1c4MvS0cnglk/img.png?width=1753&amp;amp;height=989&amp;amp;face=0_0_1753_989,https://scrap.kakaocdn.net/dn/zhV3d/hyWKE6EGkN/66g6prKMWkJfJpAGL0dgJK/img.png?width=638&amp;amp;height=340&amp;amp;face=0_0_638_340');&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;응검, 저격술, 던지기기술, 활쏘기 랭작&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;0. 장비세팅공격력이 없고 방어력이 있으며 내구 높은 장비 추천영화보시면서 스페이스만 편하게 눌러두시려면 방어구는 가급적 다 갖추시는편이 좋습니다.&amp;nbsp;-투구&amp;nbsp;(스키피오의 투구, 크로스&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.inven.co.kr&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;&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;&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;&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;&amp;nbsp;&lt;/p&gt;</description>
      <category>GAME/대항해시대</category>
      <category>대항해시대</category>
      <category>레거시</category>
      <category>모음</category>
      <category>모험</category>
      <category>온라인</category>
      <category>컨텐츠</category>
      <author>ALEPH.GEM</author>
      <guid isPermaLink="true">https://aacii.tistory.com/436</guid>
      <comments>https://aacii.tistory.com/436#entry436comment</comments>
      <pubDate>Tue, 6 Aug 2024 19:02:19 +0900</pubDate>
    </item>
    <item>
      <title>대항해시대 온라인 - 아크로폴리스</title>
      <link>https://aacii.tistory.com/432</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;선행 퀘스트&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.ssjoy.org/dho/quest/505667&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.ssjoy.org/dho/quest/505667&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1722211568706&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;DHO - 퀘스트 - [퀘스트] 전설의 왕의 땅&quot; data-og-description=&quot;공략 1. 런던 모험가조합, 모험가 조합 마스터와 대화 2. 런던 모험가조합, 안쪽 길드 사무원과 대화 3. 옥스포드, 교수와 대화 4. 세비야 주점, 모험가풍 남자 또는 단골 손님과 대화 5. 간디아, 항&quot; data-og-host=&quot;www.ssjoy.org&quot; data-og-source-url=&quot;https://www.ssjoy.org/dho/quest/505667&quot; data-og-url=&quot;https://www.ssjoy.org/dho/quest/505667&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/ccB2Ad/hyWGYjEsF9/Nc2ZxybkrNgNKq6bLdwnbK/img.png?width=400&amp;amp;height=300&amp;amp;face=0_0_400_300&quot;&gt;&lt;a href=&quot;https://www.ssjoy.org/dho/quest/505667&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.ssjoy.org/dho/quest/505667&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/ccB2Ad/hyWGYjEsF9/Nc2ZxybkrNgNKq6bLdwnbK/img.png?width=400&amp;amp;height=300&amp;amp;face=0_0_400_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;DHO - 퀘스트 - [퀘스트] 전설의 왕의 땅&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;공략 1. 런던 모험가조합, 모험가 조합 마스터와 대화 2. 런던 모험가조합, 안쪽 길드 사무원과 대화 3. 옥스포드, 교수와 대화 4. 세비야 주점, 모험가풍 남자 또는 단골 손님과 대화 5. 간디아, 항&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.ssjoy.org&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&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;h2 data-ke-size=&quot;size26&quot;&gt;연속 퀘스트&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.ssjoy.org/dho/quest/704657&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.ssjoy.org/dho/quest/704657&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1722211711466&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;DHO - 퀘스트 - [퀘스트] 이집트와 아틀란티스&quot; data-og-description=&quot;진행 1. 런던 모험가조합 - 의뢰 계속 익명의 의뢰자에게서 온「환상의 대륙」을 찾는다는 일을 계속 맡기로 했다. 이번에는 「이집트와 환상의 대륙의 관계」라는 전언이 붙어있었지. 그것을 &quot; data-og-host=&quot;www.ssjoy.org&quot; data-og-source-url=&quot;https://www.ssjoy.org/dho/quest/704657&quot; data-og-url=&quot;https://www.ssjoy.org/dho/quest/704657&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://www.ssjoy.org/dho/quest/704657&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.ssjoy.org/dho/quest/704657&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&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;DHO - 퀘스트 - [퀘스트] 이집트와 아틀란티스&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;진행 1. 런던 모험가조합 - 의뢰 계속 익명의 의뢰자에게서 온「환상의 대륙」을 찾는다는 일을 계속 맡기로 했다. 이번에는 「이집트와 환상의 대륙의 관계」라는 전언이 붙어있었지. 그것을&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.ssjoy.org&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;&lt;a href=&quot;https://www.ssjoy.org/dho/quest/795373&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.ssjoy.org/dho/quest/795373&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1722211739288&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;DHO - 퀘스트 - [퀘스트] 아틀라스의 바다에서의 해후&quot; data-og-description=&quot;공략 1. 런던 서고, 트라데스칸트와 대화 2. 안틸 제도 앞바다, 산토도밍고 남쪽(좌표: 13496, 4083)에 있는 상선 클릭 - 전투 혹은 퇴각(상납품 사용 가능) - 전투 걸리기 전에 따라가기가 해제되니 주&quot; data-og-host=&quot;www.ssjoy.org&quot; data-og-source-url=&quot;https://www.ssjoy.org/dho/quest/795373&quot; data-og-url=&quot;https://www.ssjoy.org/dho/quest/795373&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://www.ssjoy.org/dho/quest/795373&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.ssjoy.org/dho/quest/795373&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&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;DHO - 퀘스트 - [퀘스트] 아틀라스의 바다에서의 해후&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;공략 1. 런던 서고, 트라데스칸트와 대화 2. 안틸 제도 앞바다, 산토도밍고 남쪽(좌표: 13496, 4083)에 있는 상선 클릭 - 전투 혹은 퇴각(상납품 사용 가능) - 전투 걸리기 전에 따라가기가 해제되니 주&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.ssjoy.org&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;&lt;a href=&quot;https://www.ssjoy.org/dho/quest/874227&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.ssjoy.org/dho/quest/874227&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1722211760834&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;DHO - 퀘스트 - [퀘스트] 더럽혀지지 않은 세계를 찾아서&quot; data-og-description=&quot;진행 1. 발렌슈타인의 주선 「환상의 대륙」을 찾는 의뢰인과 만나게 해 준다는 용건으로, 발렌슈타인으로부터 호출을 받았다. 트라데스칸트에 함께 가지는 않지만, 약속장소에서 합류할 것 같&quot; data-og-host=&quot;www.ssjoy.org&quot; data-og-source-url=&quot;https://www.ssjoy.org/dho/quest/874227&quot; data-og-url=&quot;https://www.ssjoy.org/dho/quest/874227&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://www.ssjoy.org/dho/quest/874227&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.ssjoy.org/dho/quest/874227&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&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;DHO - 퀘스트 - [퀘스트] 더럽혀지지 않은 세계를 찾아서&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;진행 1. 발렌슈타인의 주선 「환상의 대륙」을 찾는 의뢰인과 만나게 해 준다는 용건으로, 발렌슈타인으로부터 호출을 받았다. 트라데스칸트에 함께 가지는 않지만, 약속장소에서 합류할 것 같&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.ssjoy.org&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;이후 퀘스트는 모험/상인/군인 계열로 나뉘는데 군인퀘스트가 짧게 끝납니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.ssjoy.org/dho/quest/874570&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.ssjoy.org/dho/quest/874570&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1722211953424&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;DHO - 퀘스트 - [퀘스트] 거칠어지는 카리브해&quot; data-og-description=&quot;연결 지도/퀘스트 [퀘스트] 상인 | 가죽끈의 납품 (3 스페인어 1) - 런던, &amp;hellip;[퀘스트] 해양 | 구 하프스 왕조 함대 토벌 (3) - 런던, &amp;hellip;[퀘스트] 상인 | 귀환의 바람의 납품 (3 노르웨이어 1) - 런던, &amp;hellip;[&quot; data-og-host=&quot;www.ssjoy.org&quot; data-og-source-url=&quot;https://www.ssjoy.org/dho/quest/874570&quot; data-og-url=&quot;https://www.ssjoy.org/dho/quest/874570&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://www.ssjoy.org/dho/quest/874570&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.ssjoy.org/dho/quest/874570&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&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;DHO - 퀘스트 - [퀘스트] 거칠어지는 카리브해&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;연결 지도/퀘스트 [퀘스트] 상인 | 가죽끈의 납품 (3 스페인어 1) - 런던, &amp;hellip;[퀘스트] 해양 | 구 하프스 왕조 함대 토벌 (3) - 런던, &amp;hellip;[퀘스트] 상인 | 귀환의 바람의 납품 (3 노르웨이어 1) - 런던, &amp;hellip;[&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.ssjoy.org&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;h2 data-ke-size=&quot;size26&quot;&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;밀칙은 매주마다 다른데 난이도는 어렵지 않습니다.&lt;/p&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;/h2&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;&lt;a href=&quot;https://www.ssjoy.org/dho/title/878454&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.ssjoy.org/dho/title/878454&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1722212411701&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;DHO - 호칭 - [호칭] 고대기술 능통자&quot; data-og-description=&quot;필요 「아크로폴리스」국가 연구 진척도 일정 수준 도달(국가 전체) 총 점유 합 에 따라서 필요 진척도가 다릅니다. 2020년 점수 증가&quot; data-og-host=&quot;www.ssjoy.org&quot; data-og-source-url=&quot;https://www.ssjoy.org/dho/title/878454&quot; data-og-url=&quot;https://www.ssjoy.org/dho/title/878454&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://www.ssjoy.org/dho/title/878454&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.ssjoy.org/dho/title/878454&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&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;DHO - 호칭 - [호칭] 고대기술 능통자&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;필요 「아크로폴리스」국가 연구 진척도 일정 수준 도달(국가 전체) 총 점유 합 에 따라서 필요 진척도가 다릅니다. 2020년 점수 증가&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.ssjoy.org&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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;아크로폴리스 활용&lt;/h2&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;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;태양의 배는 교역품을 실은 채로 본국에서 3~4일이면 도달 할 수 있습니다.&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;h2 data-ke-size=&quot;size26&quot;&gt;가호의 수정&lt;/h2&gt;
&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;li&gt;아레스이 가호 - 미궁 10구획 이상 탐험&lt;/li&gt;
&lt;li&gt;아테나의 가호 - 가나돌 보스 클리어&lt;/li&gt;
&lt;li&gt;메티스의 가호 - 고대기술 연구칙명 클리어(점수 50 이상)&lt;/li&gt;
&lt;li&gt;헤파이토스의 가호 - 변성연금 1회 실행(귀환의 바람 추천)&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;이렇게 하루 최대 5개의 가호의 수정을 얻을 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 얻은 가호의 수정을 40회 사용하면 3랭크에 도달하게 되는데 각 효과는 아래와 같습니다.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;table style=&quot;background-color: #ffffff; color: #000000; text-align: start; border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span&gt;&lt;span&gt;종류&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;&lt;span&gt;효과&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;&lt;span&gt;1R&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;&lt;span&gt;2R&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;&lt;span&gt;3R&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span&gt;&lt;span&gt;포세이돈&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;&lt;span&gt;(60&lt;/span&gt;&lt;span&gt;분 동안&lt;/span&gt;&lt;span&gt;)&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;교역품을 일정 개수&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;최대&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;n&lt;/span&gt;&lt;span&gt;개&lt;/span&gt;&lt;span&gt;)&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;소지한 상태로&lt;/span&gt;&lt;br /&gt;&lt;span&gt;운하&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;amp;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;육로 이동 가능&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;&lt;span&gt;1000&lt;/span&gt;&lt;span&gt;개&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;&lt;span&gt;2000&lt;/span&gt;&lt;span&gt;개&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;&lt;span&gt;3000&lt;/span&gt;&lt;span&gt;개&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span&gt;&lt;span&gt;아레스&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;&lt;span&gt;대포의 관통력&lt;/span&gt;&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;탄속 증가&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;br /&gt;&lt;span&gt;대인전&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;X&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span&gt;&lt;span&gt;아테나&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;&lt;span&gt;포격 방어&lt;/span&gt;&lt;span&gt;. (n&lt;/span&gt;&lt;span&gt;회&lt;/span&gt;&lt;span&gt;)&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;데미지 무시&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;br /&gt;&lt;span&gt;대인전&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;X&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;&lt;span&gt;2&lt;/span&gt;&lt;span&gt;회&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;&lt;span&gt;4&lt;/span&gt;&lt;span&gt;회&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;&lt;span&gt;6&lt;/span&gt;&lt;span&gt;회&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span&gt;&lt;span&gt;메티스&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;&lt;span&gt;(30&lt;/span&gt;&lt;span&gt;분 동안&lt;/span&gt;&lt;span&gt;)&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;고대 기술 연구 획득 포인트 증가&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;&lt;span&gt;+1/+1/+1&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;&lt;span&gt;+2/+2/+2&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;&lt;span&gt;+3/+3/+3&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span&gt;&lt;span&gt;헤파이스토스&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;&lt;span&gt;(30&lt;/span&gt;&lt;span&gt;분 동안&lt;/span&gt;&lt;span&gt;)&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;생산 시 일정&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;(p%)&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;확률로&lt;/span&gt;&lt;br /&gt;&lt;span&gt;행동력을&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;전혀&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;소비하지 않음&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;&lt;span&gt;40%&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;&lt;span&gt;60%(?)&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;&lt;span&gt;100%(?)&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&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;a href=&quot;https://www.inven.co.kr/board/dho/498/19800&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.inven.co.kr/board/dho/498/19800&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1722937977573&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;[끌올팁] 런 각잡고 가호얻기&quot; data-og-description=&quot;&quot; data-og-host=&quot;www.inven.co.kr&quot; data-og-source-url=&quot;https://www.inven.co.kr/board/dho/498/19800&quot; data-og-url=&quot;https://www.inven.co.kr/board/dho/498/19800&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bNvM8c/hyWKy6rDru/dU5EWWzUhBVtRZsFcpDsKk/img.jpg?width=800&amp;amp;height=600&amp;amp;face=0_0_800_600,https://scrap.kakaocdn.net/dn/vcCb3/hyWKwneUbq/tzIFwjTYLhBSjOw6oD8Wc0/img.jpg?width=800&amp;amp;height=600&amp;amp;face=0_0_800_600,https://scrap.kakaocdn.net/dn/w9Gpw/hyWKJtlW4h/K5NlrnUobV85gPUd7k3wQ1/img.jpg?width=800&amp;amp;height=600&amp;amp;face=0_0_800_600&quot;&gt;&lt;a href=&quot;https://www.inven.co.kr/board/dho/498/19800&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.inven.co.kr/board/dho/498/19800&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bNvM8c/hyWKy6rDru/dU5EWWzUhBVtRZsFcpDsKk/img.jpg?width=800&amp;amp;height=600&amp;amp;face=0_0_800_600,https://scrap.kakaocdn.net/dn/vcCb3/hyWKwneUbq/tzIFwjTYLhBSjOw6oD8Wc0/img.jpg?width=800&amp;amp;height=600&amp;amp;face=0_0_800_600,https://scrap.kakaocdn.net/dn/w9Gpw/hyWKJtlW4h/K5NlrnUobV85gPUd7k3wQ1/img.jpg?width=800&amp;amp;height=600&amp;amp;face=0_0_800_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;[끌올팁] 런 각잡고 가호얻기&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.inven.co.kr&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.inven.co.kr/board/dho/498/17021&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.inven.co.kr/board/dho/498/17021&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1722938005116&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;가호작-하루 20분이면 충분&quot; data-og-description=&quot;1. 고대 기술 연구 밀칙 수령2. 포세이돈 신전 10층까지 클리어 - 3개3. 가나돌 아무거나 쉬운거 - 1개 (16-2세기 호칭으로 아고스티노 추천)4. 변성연금 아무거나 쉬운거 - 1개 (바람의 요정의 부적 추&quot; data-og-host=&quot;www.inven.co.kr&quot; data-og-source-url=&quot;https://www.inven.co.kr/board/dho/498/17021&quot; data-og-url=&quot;https://www.inven.co.kr/board/dho/498/17021&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://www.inven.co.kr/board/dho/498/17021&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.inven.co.kr/board/dho/498/17021&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&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;가호작-하루 20분이면 충분&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;1. 고대 기술 연구 밀칙 수령2. 포세이돈 신전 10층까지 클리어 - 3개3. 가나돌 아무거나 쉬운거 - 1개 (16-2세기 호칭으로 아고스티노 추천)4. 변성연금 아무거나 쉬운거 - 1개 (바람의 요정의 부적 추&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.inven.co.kr&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;&amp;nbsp;&lt;/p&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;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;잃어버린 고대의 천구의 (고대기술 연구 600 달성시 3개) 아이템을 통해 아크로폴리스로 순간이동 할 수 있습니다.(개척 도시, 육상, 건물내부 불가)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.ssjoy.org/dho/consumable/876493&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.ssjoy.org/dho/consumable/876493&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1722254129144&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;DHO - 소비품 - [소비품] 잃어버린 고대의 천구의&quot; data-og-description=&quot;&quot; data-og-host=&quot;www.ssjoy.org&quot; data-og-source-url=&quot;https://www.ssjoy.org/dho/consumable/876493&quot; data-og-url=&quot;https://www.ssjoy.org/dho/consumable/876493&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://www.ssjoy.org/dho/consumable/876493&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.ssjoy.org/dho/consumable/876493&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&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;DHO - 소비품 - [소비품] 잃어버린 고대의 천구의&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.ssjoy.org&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;고대기술 연구&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;2024-07-29 20 58 13.png&quot; data-origin-width=&quot;688&quot; data-origin-height=&quot;381&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c4lp9p/btsIQ1hdMiu/JPk12wXH9u4zCmvheNOJEK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c4lp9p/btsIQ1hdMiu/JPk12wXH9u4zCmvheNOJEK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c4lp9p/btsIQ1hdMiu/JPk12wXH9u4zCmvheNOJEK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc4lp9p%2FbtsIQ1hdMiu%2FJPk12wXH9u4zCmvheNOJEK%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;688&quot; height=&quot;381&quot; data-filename=&quot;2024-07-29 20 58 13.png&quot; data-origin-width=&quot;688&quot; data-origin-height=&quot;381&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;400점을 채우면 자국의 서기관에게 연구 보고를 합니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;2024-07-29 21 00 30.png&quot; data-origin-width=&quot;509&quot; data-origin-height=&quot;247&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/HELGJ/btsIPV3loDF/jNgyPUsSsr7s41bIbSTBL0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/HELGJ/btsIPV3loDF/jNgyPUsSsr7s41bIbSTBL0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/HELGJ/btsIPV3loDF/jNgyPUsSsr7s41bIbSTBL0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FHELGJ%2FbtsIPV3loDF%2FjNgyPUsSsr7s41bIbSTBL0%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;509&quot; height=&quot;247&quot; data-filename=&quot;2024-07-29 21 00 30.png&quot; data-origin-width=&quot;509&quot; data-origin-height=&quot;247&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;잃어버린 고대의 천구의 3개,&amp;nbsp;국가 연구자 포상을 받을 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.ssjoy.org/dho/consumable/876499&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.ssjoy.org/dho/consumable/876499&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1722254736860&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;DHO - 소비품 - [소비품] 국가 연구자 포상&quot; data-og-description=&quot;&quot; data-og-host=&quot;www.ssjoy.org&quot; data-og-source-url=&quot;https://www.ssjoy.org/dho/consumable/876499&quot; data-og-url=&quot;https://www.ssjoy.org/dho/consumable/876499&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://www.ssjoy.org/dho/consumable/876499&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.ssjoy.org/dho/consumable/876499&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&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;DHO - 소비품 - [소비품] 국가 연구자 포상&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.ssjoy.org&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;&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;&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;&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;&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;</description>
      <category>GAME/대항해시대</category>
      <category>가호의 수정</category>
      <category>공략</category>
      <category>대항해시대</category>
      <category>아크로폴리스</category>
      <category>온라인</category>
      <category>잃어버린 고대의 천구의</category>
      <author>ALEPH.GEM</author>
      <guid isPermaLink="true">https://aacii.tistory.com/432</guid>
      <comments>https://aacii.tistory.com/432#entry432comment</comments>
      <pubDate>Tue, 6 Aug 2024 18:54:12 +0900</pubDate>
    </item>
    <item>
      <title>대항해시대 온라인 - 부관</title>
      <link>https://aacii.tistory.com/214</link>
      <description>&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;그래서 언어부관, 창당부관, 항해부관, 백병(수탈)부관, 조선부관, 탄방어부관, 던전부관, 대인전용부관 정도만이 장기적으로 유용한 부관이라고 생각합니다.&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;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;부관 육성&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.inven.co.kr/board/dho/498/20665&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.inven.co.kr/board/dho/498/20665&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1722937367021&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;[부관] 120SS 부관 효율적으로 육성하기!&quot; data-og-description=&quot;안녕하세요~오랜만에 팁글을 남깁니다.&amp;nbsp;한 4년만인듯 합니다. 현생이 바빠서....2024년 3월 21일 한섭에도 드디어 부관육성이 업데이트 되었습니다.[부관학교 업데이트]- 홈페이지 내용 :&amp;nbsp;대항해&quot; data-og-host=&quot;www.inven.co.kr&quot; data-og-source-url=&quot;https://www.inven.co.kr/board/dho/498/20665&quot; data-og-url=&quot;https://www.inven.co.kr/board/dho/498/20665&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/7Qhwn/hyWKzqJLN9/2rkTJjGv5SGlKUpvlAoyX1/img.png?width=346&amp;amp;height=239&amp;amp;face=0_0_346_239,https://scrap.kakaocdn.net/dn/c5mMsz/hyWKGXGUOd/KgJBOMgnnIuHqfcWQA3TOK/img.png?width=600&amp;amp;height=280&amp;amp;face=134_16_156_41,https://scrap.kakaocdn.net/dn/dwqfHy/hyWKB3apBT/EycVzkAbCkvMuuaEuLN5Yk/img.png?width=600&amp;amp;height=280&amp;amp;face=0_0_600_280&quot;&gt;&lt;a href=&quot;https://www.inven.co.kr/board/dho/498/20665&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.inven.co.kr/board/dho/498/20665&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/7Qhwn/hyWKzqJLN9/2rkTJjGv5SGlKUpvlAoyX1/img.png?width=346&amp;amp;height=239&amp;amp;face=0_0_346_239,https://scrap.kakaocdn.net/dn/c5mMsz/hyWKGXGUOd/KgJBOMgnnIuHqfcWQA3TOK/img.png?width=600&amp;amp;height=280&amp;amp;face=134_16_156_41,https://scrap.kakaocdn.net/dn/dwqfHy/hyWKB3apBT/EycVzkAbCkvMuuaEuLN5Yk/img.png?width=600&amp;amp;height=280&amp;amp;face=0_0_600_280');&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;[부관] 120SS 부관 효율적으로 육성하기!&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;안녕하세요~오랜만에 팁글을 남깁니다.&amp;nbsp;한 4년만인듯 합니다. 현생이 바빠서....2024년 3월 21일 한섭에도 드디어 부관육성이 업데이트 되었습니다.[부관학교 업데이트]- 홈페이지 내용 :&amp;nbsp;대항해&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.inven.co.kr&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;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;부관학교 : 부관 연구와 특별 연구&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.inven.co.kr/board/dho/498/20240&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.inven.co.kr/board/dho/498/20240&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1722940411648&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;[부관학교] 부관연구와 특별연구&quot; data-og-description=&quot;아래 글은 한섭 업데이트 Shipmate(2024년 3월 21일) 시점을 기준으로 작성되었습니다.현재 특별스킬 10개가 개방되어 있습니다.Summer Triangle(2024년 5월 21일) :&amp;nbsp; ▶ 여기를 누르세요!&amp;nbsp;(일반전공 6개 특&quot; data-og-host=&quot;www.inven.co.kr&quot; data-og-source-url=&quot;https://www.inven.co.kr/board/dho/498/20240&quot; data-og-url=&quot;https://www.inven.co.kr/board/dho/498/20240&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bTfucr/hyWKDGEUQ7/ycZqd5LKaVTy1qOWPiAs5K/img.jpg?width=365&amp;amp;height=143&amp;amp;face=0_0_365_143,https://scrap.kakaocdn.net/dn/h3Hqr/hyWKyk4bSU/b2laFBiP3BsEzJ6z9fKzK0/img.jpg?width=659&amp;amp;height=360&amp;amp;face=0_0_659_360,https://scrap.kakaocdn.net/dn/kJ9sV/hyWKwAMjuB/IcHyK4VKM5kuGJDf6XX4fk/img.jpg?width=655&amp;amp;height=353&amp;amp;face=0_0_655_353&quot;&gt;&lt;a href=&quot;https://www.inven.co.kr/board/dho/498/20240&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.inven.co.kr/board/dho/498/20240&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bTfucr/hyWKDGEUQ7/ycZqd5LKaVTy1qOWPiAs5K/img.jpg?width=365&amp;amp;height=143&amp;amp;face=0_0_365_143,https://scrap.kakaocdn.net/dn/h3Hqr/hyWKyk4bSU/b2laFBiP3BsEzJ6z9fKzK0/img.jpg?width=659&amp;amp;height=360&amp;amp;face=0_0_659_360,https://scrap.kakaocdn.net/dn/kJ9sV/hyWKwAMjuB/IcHyK4VKM5kuGJDf6XX4fk/img.jpg?width=655&amp;amp;height=353&amp;amp;face=0_0_655_353');&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;[부관학교] 부관연구와 특별연구&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;아래 글은 한섭 업데이트 Shipmate(2024년 3월 21일) 시점을 기준으로 작성되었습니다.현재 특별스킬 10개가 개방되어 있습니다.Summer Triangle(2024년 5월 21일) :&amp;nbsp; ▶ 여기를 누르세요!&amp;nbsp;(일반전공 6개 특&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.inven.co.kr&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;figure id=&quot;og_1722937251805&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;[부관학교] 부관연구와 특별연구&quot; data-og-description=&quot;아래 글은 한섭 업데이트 Shipmate(2024년 3월 21일) 시점을 기준으로 작성되었습니다.현재 특별스킬 10개가 개방되어 있습니다.Summer Triangle(2024년 5월 21일) :&amp;nbsp; ▶ 여기를 누르세요!&amp;nbsp;(일반전공 6개 특&quot; data-og-host=&quot;www.inven.co.kr&quot; data-og-source-url=&quot;https://www.inven.co.kr/board/dho/498/20240&quot; data-og-url=&quot;https://www.inven.co.kr/board/dho/498/20240&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bTfucr/hyWKDGEUQ7/ycZqd5LKaVTy1qOWPiAs5K/img.jpg?width=365&amp;amp;height=143&amp;amp;face=0_0_365_143,https://scrap.kakaocdn.net/dn/h3Hqr/hyWKyk4bSU/b2laFBiP3BsEzJ6z9fKzK0/img.jpg?width=659&amp;amp;height=360&amp;amp;face=0_0_659_360,https://scrap.kakaocdn.net/dn/kJ9sV/hyWKwAMjuB/IcHyK4VKM5kuGJDf6XX4fk/img.jpg?width=655&amp;amp;height=353&amp;amp;face=0_0_655_353&quot;&gt;&lt;a href=&quot;https://www.inven.co.kr/board/dho/498/20240&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.inven.co.kr/board/dho/498/20240&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bTfucr/hyWKDGEUQ7/ycZqd5LKaVTy1qOWPiAs5K/img.jpg?width=365&amp;amp;height=143&amp;amp;face=0_0_365_143,https://scrap.kakaocdn.net/dn/h3Hqr/hyWKyk4bSU/b2laFBiP3BsEzJ6z9fKzK0/img.jpg?width=659&amp;amp;height=360&amp;amp;face=0_0_659_360,https://scrap.kakaocdn.net/dn/kJ9sV/hyWKwAMjuB/IcHyK4VKM5kuGJDf6XX4fk/img.jpg?width=655&amp;amp;height=353&amp;amp;face=0_0_655_353');&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;[부관학교] 부관연구와 특별연구&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;아래 글은 한섭 업데이트 Shipmate(2024년 3월 21일) 시점을 기준으로 작성되었습니다.현재 특별스킬 10개가 개방되어 있습니다.Summer Triangle(2024년 5월 21일) :&amp;nbsp; ▶ 여기를 누르세요!&amp;nbsp;(일반전공 6개 특&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.inven.co.kr&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.inven.co.kr/board/dho/498/19768&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.inven.co.kr/board/dho/498/19768&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1722939972702&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;(일섭) 부관학교 횟수작과 포인트작&quot; data-og-description=&quot;1.횟수작창고당번 쪽 주조대성공으로 뚫는게 가장 빠릅니다.추천 방법은 사그에서 철광석을 2500개씩 산 다음 연속생산70~80번으로 연구 하나를 한큐에 끝내는 것입니다2.포인트작&amp;nbsp;-선의쪽 포르&quot; data-og-host=&quot;www.inven.co.kr&quot; data-og-source-url=&quot;https://www.inven.co.kr/board/dho/498/19768&quot; data-og-url=&quot;https://www.inven.co.kr/board/dho/498/19768&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://www.inven.co.kr/board/dho/498/19768&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.inven.co.kr/board/dho/498/19768&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&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;(일섭) 부관학교 횟수작과 포인트작&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;1.횟수작창고당번 쪽 주조대성공으로 뚫는게 가장 빠릅니다.추천 방법은 사그에서 철광석을 2500개씩 산 다음 연속생산70~80번으로 연구 하나를 한큐에 끝내는 것입니다2.포인트작&amp;nbsp;-선의쪽 포르&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.inven.co.kr&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://dolworld.notion.site/df95767a5021480ea5923d3102909b71?v=cdb0a6a44e294271874ace8edef708b5&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://dolworld.notion.site/df95767a5021480ea5923d3102909b71?v=cdb0a6a44e294271874ace8edef708b5&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1722940423786&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;부관학교 연구 | Notion&quot; data-og-description=&quot;￭ 연구 시작 1) 대상 부관의 특성치가 각 100 이상이고 부관선장인 상태로 사그레스로 가서 상한해제 퀘스트, 연구 해금 2) 상한해제 퀘는 해당 부관담당 분야(항해장, 감시등)의 특성치만 100이상&quot; data-og-host=&quot;dolworld.notion.site&quot; data-og-source-url=&quot;https://dolworld.notion.site/df95767a5021480ea5923d3102909b71?v=cdb0a6a44e294271874ace8edef708b5&quot; data-og-url=&quot;https://dolworld.notion.site/df95767a5021480ea5923d3102909b71&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/1M0HY/hyWKxzI2pq/wlcJfG9E7NlWTLOiJ1zId1/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/oyMiN/hyWKwOjmi9/g9vH8OqPKyzPoOliTzhHCK/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630&quot;&gt;&lt;a href=&quot;https://dolworld.notion.site/df95767a5021480ea5923d3102909b71?v=cdb0a6a44e294271874ace8edef708b5&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://dolworld.notion.site/df95767a5021480ea5923d3102909b71?v=cdb0a6a44e294271874ace8edef708b5&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/1M0HY/hyWKxzI2pq/wlcJfG9E7NlWTLOiJ1zId1/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/oyMiN/hyWKwOjmi9/g9vH8OqPKyzPoOliTzhHCK/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630');&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;부관학교 연구 | Notion&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;￭ 연구 시작 1) 대상 부관의 특성치가 각 100 이상이고 부관선장인 상태로 사그레스로 가서 상한해제 퀘스트, 연구 해금 2) 상한해제 퀘는 해당 부관담당 분야(항해장, 감시등)의 특성치만 100이상&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;dolworld.notion.site&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;&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;h3 data-ke-size=&quot;size23&quot;&gt;왕립 함대 사관&lt;/h3&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;조건&lt;/h4&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;부관 사관: 레벨 총합 50 이상&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;왕립 함대: 레벨 50/50/50 이상 + 특성치 100S + 신뢰도 100&lt;/p&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&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;부관의 항해 기록 획득&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;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;친밀도&lt;/h4&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;대국망명: 친밀도 신뢰(50이상) 필요&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;오스만망명: 친밀도 친애(80이상) 필요&lt;/p&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&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;상인: 육메,남만 드랍&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;a href=&quot;https://m.blog.naver.com/PostView.nhn?blogId=ladyju37&amp;amp;logNo=220893473189&amp;amp;proxyReferer=https:%2F%2Fwww.google.com%2F&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://m.blog.naver.com/PostView.nhn?blogId=ladyju37&amp;amp;logNo=220893473189&amp;amp;proxyReferer=https:%2F%2Fwww.google.com%2F&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1722940344484&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;임관: 부관을 왕립 함대로!&quot; data-og-description=&quot;대항해시대 온라인에서는 다른 RPG 게임과 다르게... 캐릭터가 배울 수 있는&amp;nbsp;스킬 습득 수가 보통 ...&quot; data-og-host=&quot;blog.naver.com&quot; data-og-source-url=&quot;https://m.blog.naver.com/PostView.nhn?blogId=ladyju37&amp;amp;logNo=220893473189&amp;amp;proxyReferer=https:%2F%2Fwww.google.com%2F&quot; data-og-url=&quot;https://blog.naver.com/ladyju37/220893473189&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/dfzLn9/hyWKCntOt4/vsv7RT4aVYGvKQodBR1Jfk/img.jpg?width=550&amp;amp;height=412&amp;amp;face=0_0_550_412&quot;&gt;&lt;a href=&quot;https://m.blog.naver.com/PostView.nhn?blogId=ladyju37&amp;amp;logNo=220893473189&amp;amp;proxyReferer=https:%2F%2Fwww.google.com%2F&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://m.blog.naver.com/PostView.nhn?blogId=ladyju37&amp;amp;logNo=220893473189&amp;amp;proxyReferer=https:%2F%2Fwww.google.com%2F&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/dfzLn9/hyWKCntOt4/vsv7RT4aVYGvKQodBR1Jfk/img.jpg?width=550&amp;amp;height=412&amp;amp;face=0_0_550_412');&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;임관: 부관을 왕립 함대로!&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;대항해시대 온라인에서는 다른 RPG 게임과 다르게... 캐릭터가 배울 수 있는&amp;nbsp;스킬 습득 수가 보통 ...&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;blog.naver.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;&amp;nbsp;&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;style6&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&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;유용한 스킬: 방화, 연막탄방어, 연발탄방어, 사슬탄 방어, 관통, 탄도학, 포술, 전투 태세&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;&lt;span&gt;유용한 스킬: 방화, 연막탄방어, 연발탄방어, 사슬탄 방어,&lt;span&gt;&amp;nbsp;&lt;/span&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;/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;에르난(세비야 고용): 구속or적강 계승 추천&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;h3 data-ke-size=&quot;size23&quot;&gt;백병 &amp;amp; 수탈 부관 추천&lt;/h3&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;- 수탈용으로도 좋고 오스만 망명작업까지 할 수 있습니다.&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;유용한 스킬: 기습, 방화, 통상탄방어, 검술, 노젓기, 돌격, 수탈, 응용검술, 그리스어, 이탈리아어, 터키어&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 유용한 스킬이 많고 언어도 동지중해 서고 언어 3종세트라 유용합니다. 노젓기 때문에 갤리선 항해용으로도 좋습니다.&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;유용한 스킬: 노젓기, 응용검술, 수탈, 방풍, 기습, 통상탄 방어, 적재화물 강탈&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;유용한 스킬: 기습, 방풍, 통상탄방어, 검술, 저격술, 총격, 포술, 회피, 전투 태세&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;유용한 스킬: 수탈, 수평사격, 포술, 기습, 적재화물 강탈, 휴대 식량&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;/h3&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;- 창고당번 최고 존엄입니다. 고양이 사육만 승계하면 완전체가 됩니다. 휴대식량으로 던전에서도 쓸모있습니다.&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;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이고르(베네치아 고용 가능): 방풍 or 기습 승계 추천&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;h3 data-ke-size=&quot;size23&quot;&gt;항해장 부관 추천&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;미선(한양 고용):&amp;nbsp; 방화 or 방풍 승계 추천&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;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;&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;&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;</description>
      <category>GAME/대항해시대</category>
      <category>대항해시대</category>
      <category>부관</category>
      <category>부관 연구</category>
      <category>온라인</category>
      <category>조합</category>
      <category>추천</category>
      <category>플랜</category>
      <author>ALEPH.GEM</author>
      <guid isPermaLink="true">https://aacii.tistory.com/214</guid>
      <comments>https://aacii.tistory.com/214#entry214comment</comments>
      <pubDate>Tue, 6 Aug 2024 18:47:14 +0900</pubDate>
    </item>
    <item>
      <title>대항해시대 온라인 - 캐릭터 공통 스펙 올리기</title>
      <link>https://aacii.tistory.com/29</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span&gt;입항허가&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;명성 3만까지 올리면 기본 해역은 다 열립니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;올리는 방법은 육메/남만품 끊어 팔기(지인찬스) or 항구 발견 후 보고 하기로 올리시면 됩니다.&lt;/span&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;b&gt;&lt;span&gt;칙명&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;중남미 동해안 -&amp;gt; 동남아시아 -&amp;gt; 중남미 서해안(2) -&amp;gt; 파나마 운하(3) -&amp;gt; 수에즈 운하 -&amp;gt; 동아시아(4)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;카리브&amp;amp;인도(1) -&amp;gt; 대여금고 5칸 증가&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;중남미 서해안(2) -&amp;gt; 대여금고 5칸 증가&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;파나마 운하(3) -&amp;gt; 대여금고 5칸 증가&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;동아시아(4) -&amp;gt; 아파트 대기부관 1명 증가&lt;/span&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;b&gt;&lt;span&gt;해역조사&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;해역조사를 통한 입항허가는 반드시 암스테르담의 메르카토르를 통해서만 가능합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;1)극북대서양 -&amp;gt; 유럽 극북 -&amp;gt; 유라시아 북쪽 -&amp;gt; 유라시아 극동 -&amp;gt; 베링해 -&amp;gt; 그린란드&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;2)동아시아+북해 해역조사 -&amp;gt; 북미 서해안&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;3)그린란드 + 북미 서해안 -&amp;gt; 동캐나다 -&amp;gt; 서캐나다 -&amp;gt; 홍해(메소포타미아 유역)&lt;/span&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;b&gt;&lt;span&gt;도시입항허가&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;전제조건: 동아시아 입항허가 + 북해 해역조사&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;마르세이유 모험 퀘스트 &quot;새로운 땅을 찾아서&quot; 수행&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;상트 페테르부르크: 스톡홀름 상인 퀘스트 &quot;러시아 수도의 납품의뢰&quot; 수행&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;포트 로얄: 안틸제도 앞바다 해역조사 종료 후 산토도밍고에서 해양 퀘스트 &quot;해적 국가&quot;-&amp;gt;&quot;포트 로얄에서 온 의뢰&quot; 수행&lt;/span&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&gt;&lt;b&gt;&lt;span&gt;&lt;span&gt;스킬 수&lt;/span&gt;&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;span&gt;총 52개&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;레벨합계: 190이상 -&amp;gt; 스킬45개&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;부관 1명 고용당 +1개 -&amp;gt; 최대 +5개&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;상트 페테르부르크 입항 후 서고 학자 -&amp;gt; 스킬 1칸 확장&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;스킬전수 -&amp;gt; 스킬 1칸 확장&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;1. 본캐 계정내 상인캐릭 1렙짜리를 만들어 200만두캇을 옮겨준다.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;2. 1렙캐릭터로 서고에 학자한테가서 200만을 지불하고 1랭크 도주스킬을 전수한다.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;3. 전수받을 본캐로 접속하여 서고에 가서 도주스킬을 전수받는다.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;4. 전수받은 도주스킬(불필요하므로)을 삭제하고 스킬수+1 영구효과를 받는다.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&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;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span&gt;작위&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;준팔등훈작사부터 은행 대여금고 사용 가능,&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;작위 25랭크에(백작, 오스만은 대영주) 대여금고 사용량 최대치&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;25개입항허가로 확장되는 대여금고 15개&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;은행 대여금고 최종 갯수(백작, 대영주,왕립함대는 소장 기준) 40개&lt;/span&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;b&gt;&lt;span&gt;아팔타멘토&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;기숙사 -&amp;gt; 1랭크 -&amp;gt; 2랭크 -&amp;gt; 3랭크 -&amp;gt; 4랭크 -&amp;gt; 5랭크(120레벨, 합계명성8만, 이등훈작사)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;기숙사 대기부관 X&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;1~2랭크 대기부관 최대 1명&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;3~5랭크 대기부관 최대 2명&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;동아시아 입항허가로 대기부관 1명 증가&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;총 부관 5명(데리고다니는 부관 2명, 대기부관 3명)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;아팔타멘토 5랭크장비품, 선박부품, 소비품, 서류, 교역품이 총 5칸으로 늘어남&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;마네킹 최대 4개: 머리, 몸, 장갑, 신발, 무기 각 4개씩 20개 장비 보관 가능&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;장식품 배치 5개: 방문자 20명으로 확장Type A, B 없어짐 전시실 구매 가능&lt;/span&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;b&gt;&lt;span&gt;마이레시피&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;국가공헌 훈장증서로 각 국 수도 궁전에 들어가서 서기관에게 마이레시피 확장 가능최초 30장으로 3칸 열림&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;국가공헌 훈장증서 520장으로 마이레시피 10칸 확장 가능&lt;/span&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;b&gt;&lt;span&gt;상트 페테르부르크 도시관리&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;모렙 76&amp;uarr; -&amp;gt; 캡틴가방, 바인더 1칸씩 확장&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;상렙 76&amp;uarr; -&amp;gt; 마이레시피 1칸 확장&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;군렙 76&amp;uarr; -&amp;gt; 특기무기 1칸 확장&lt;/span&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;b&gt;&lt;span&gt;샌프란시스코 각 계열 조합장&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;모렙 81&amp;uarr; -&amp;gt; 캡틴가방, 바인더 1칸씩 확장&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;상렙 81&amp;uarr; -&amp;gt; 마이레시피 1칸 확장&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;군렙 81&amp;uarr; -&amp;gt; 특기무기 1칸 확장&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;상트 페테르부르크에서 먼저 1칸씩 확장 받아야 샌프란시스코에서 확장가능합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;추가로 부관 고용을 할 때마다 캡틴가방이 1칸씩 증가하며 5명 고용 시 총 5칸 증가&lt;/span&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;b&gt;&lt;span&gt;도크(배보관,배내구회복)&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;최초 획득 -&amp;gt; 자국가 개척지가 중심도시일 때도크 관리인에게 국가공헌 훈장증서 50장 + 500만 두캇을 내면 도크 획득&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;망명시 사용권 소진되나 국가공헌 훈장증서 25장 + 250만 두캇으로 다시 획득 가능(중심도시일 필요 없음)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&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;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span&gt;개인농장&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&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;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;스킬 전수&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 본캐 계정내 상인캐릭 1렙짜리를 만들어 200만두캇을 옮겨준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 1렙캐릭터로 서고에 학자한테가서 200만을 지불하고 1랭크 도주스킬을 전수한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. 전수받을 본캐로 접속하여 서고에 가서 도주스킬을 전수받는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. 전수받은 도주스킬(불필요하므로)을 삭제하고 스킬수+1 영구효과를 받는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;5. 자신의 스킬전수 이전의 스킬최대갯수에서 +1이 되었는지 확인한다.&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;&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;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthContent&quot; data-filename=&quot;400X300-default.jpg&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;300&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lnANu/btqEtuWes2A/gItFIk31rROqp0bJIOejK0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lnANu/btqEtuWes2A/gItFIk31rROqp0bJIOejK0/img.jpg&quot; data-alt=&quot;AACII&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lnANu/btqEtuWes2A/gItFIk31rROqp0bJIOejK0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FlnANu%2FbtqEtuWes2A%2FgItFIk31rROqp0bJIOejK0%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;400&quot; height=&quot;300&quot; data-filename=&quot;400X300-default.jpg&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;300&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;AACII&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>GAME/대항해시대</category>
      <category>농장</category>
      <category>대항해시대온라인</category>
      <category>도크</category>
      <category>마이레시피</category>
      <category>스킬</category>
      <category>아팔타멘토</category>
      <category>작위</category>
      <category>창고</category>
      <category>캐릭터</category>
      <author>ALEPH.GEM</author>
      <guid isPermaLink="true">https://aacii.tistory.com/29</guid>
      <comments>https://aacii.tistory.com/29#entry29comment</comments>
      <pubDate>Tue, 6 Aug 2024 18:44:29 +0900</pubDate>
    </item>
    <item>
      <title>대항해시대 온라인 - 아팔토멘토</title>
      <link>https://aacii.tistory.com/435</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;구입&lt;/h3&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;h3 data-ke-size=&quot;size23&quot;&gt;랭크 올리기&lt;/h3&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;이후 작위가 오르면 더 상위 등급의 아파트를 개장할 수 있습니다.&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;/h3&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;&lt;a href=&quot;https://www.ssjoy.org/dho/wiki/?id=dho:apartment:furniture&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.ssjoy.org/dho/wiki/?id=dho:apartment:furniture&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1722935661176&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;DHO - 위키&quot; data-og-description=&quot;&quot; data-og-host=&quot;www.ssjoy.org&quot; data-og-source-url=&quot;https://www.ssjoy.org/dho/wiki/?id=dho:apartment:furniture&quot; data-og-url=&quot;https://www.ssjoy.org/dho/wiki/?id=dho%3Aapartment%3Afurniture&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://www.ssjoy.org/dho/wiki/?id=dho:apartment:furniture&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.ssjoy.org/dho/wiki/?id=dho:apartment:furniture&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&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;DHO - 위키&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.ssjoy.org&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;h3 data-ke-size=&quot;size23&quot;&gt;전시실&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아파트가 5랭크가 되면 전시실을 구매할 수 있습니다.&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;&lt;a href=&quot;https://www.ssjoy.org/dho/tip/1437054&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.ssjoy.org/dho/tip/1437054&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1722935742811&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;DHO - 아파트 장식품 고PT 나름 쓸만한 장식품들&quot; data-og-description=&quot;몇달 전쯤에 일섭 위키 보고 정리 했던 건데, 아직 조이에 업댓 전이라서 그 전까지 혹시나&amp;nbsp;뭐 만들어야 할지 모르시는 분 있으시면 참고하세요 (몇 달전 일섭 위키 자료라서 맞지 않는 정보도 &quot; data-og-host=&quot;www.ssjoy.org&quot; data-og-source-url=&quot;https://www.ssjoy.org/dho/tip/1437054&quot; data-og-url=&quot;https://www.ssjoy.org/dho/tip/1437054&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://www.ssjoy.org/dho/tip/1437054&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.ssjoy.org/dho/tip/1437054&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&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;DHO - 아파트 장식품 고PT 나름 쓸만한 장식품들&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;몇달 전쯤에 일섭 위키 보고 정리 했던 건데, 아직 조이에 업댓 전이라서 그 전까지 혹시나&amp;nbsp;뭐 만들어야 할지 모르시는 분 있으시면 참고하세요 (몇 달전 일섭 위키 자료라서 맞지 않는 정보도&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.ssjoy.org&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;&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;&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;&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;&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;&amp;nbsp;&lt;/p&gt;</description>
      <category>GAME/대항해시대</category>
      <category>가구</category>
      <category>대항해시대</category>
      <category>아파트</category>
      <category>아팔토멘토</category>
      <category>온라인</category>
      <category>전시실</category>
      <author>ALEPH.GEM</author>
      <guid isPermaLink="true">https://aacii.tistory.com/435</guid>
      <comments>https://aacii.tistory.com/435#entry435comment</comments>
      <pubDate>Tue, 6 Aug 2024 18:16:24 +0900</pubDate>
    </item>
    <item>
      <title>대항해시대 온라인 - 육지조사</title>
      <link>https://aacii.tistory.com/434</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&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;육지 재조사를 통한 발견물도 있으므로 모험가의 필수입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://aacii.tistory.com/207&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://aacii.tistory.com/207&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1722934353328&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;대항해시대 온라인 - 입항 허가, 칙명, 해역조사&quot; data-og-description=&quot;북대서양,북해,지중해,아프리카서부,아프리카,홍해,인도,카리브의 기본 해역은 명성치만으로 입항 허가를 받을 수 있습니다.그래서 기본해역은 육두구 메이스나 남만품을 끊어 팔기로 충분히 &quot; data-og-host=&quot;blog.aacii.net&quot; data-og-source-url=&quot;https://aacii.tistory.com/207&quot; data-og-url=&quot;https://blog.aacii.net/207&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/gKqZe/hyWKxzHARY/HUYJHSXXBKhcPslm8yLAUk/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/bi1ptv/hyWKGDoJrC/n6MRKY88o9Ke4RB9O7P8bK/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/RN9JL/hyWKDs8kcZ/GhPO1qIuuxKMRW4djieCJK/img.png?width=400&amp;amp;height=400&amp;amp;face=0_0_400_400&quot;&gt;&lt;a href=&quot;https://aacii.tistory.com/207&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://aacii.tistory.com/207&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/gKqZe/hyWKxzHARY/HUYJHSXXBKhcPslm8yLAUk/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/bi1ptv/hyWKGDoJrC/n6MRKY88o9Ke4RB9O7P8bK/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/RN9JL/hyWKDs8kcZ/GhPO1qIuuxKMRW4djieCJK/img.png?width=400&amp;amp;height=400&amp;amp;face=0_0_400_400');&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;대항해시대 온라인 - 입항 허가, 칙명, 해역조사&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;북대서양,북해,지중해,아프리카서부,아프리카,홍해,인도,카리브의 기본 해역은 명성치만으로 입항 허가를 받을 수 있습니다.그래서 기본해역은 육두구 메이스나 남만품을 끊어 팔기로 충분히&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;blog.aacii.net&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 북해 해역 조사를 완료한 후 암스테르담의 메르카토르와 대화 후 육지조사가 시작됩니다.&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;3. 육지 조사에 순서가 있어서 개방된 지역의 조사를 마친 후 대학 교수에게 보고해야 다음 지역이 열리게 되어있습니다.&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;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.ssjoy.org/dho/quest/15439&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.ssjoy.org/dho/quest/15439&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1722934546920&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;DHO - 퀘스트 - [퀘스트] 라비린토스의 전설&quot; data-og-description=&quot;진행 1. 아테네 서고, 학자 - 크레타 섬의 미궁 라비린토스란, 크레타 섬의 미노스 왕이 명공 다이달로스에게 만들게 한 미궁이지요. 미노스왕의 왕비가 낳은 미노타우로스를 묻어버리기 위해서&quot; data-og-host=&quot;www.ssjoy.org&quot; data-og-source-url=&quot;https://www.ssjoy.org/dho/quest/15439&quot; data-og-url=&quot;https://www.ssjoy.org/dho/quest/15439&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bRIpkh/hyWKyehvZm/jlB6GrqJRnShJKmXnqChK1/img.png?width=400&amp;amp;height=300&amp;amp;face=0_0_400_300,https://scrap.kakaocdn.net/dn/czt6Qn/hyWKKFOafK/Iu8HxjjpZDzytnjA99t8zk/img.png?width=400&amp;amp;height=300&amp;amp;face=0_0_400_300&quot;&gt;&lt;a href=&quot;https://www.ssjoy.org/dho/quest/15439&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.ssjoy.org/dho/quest/15439&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bRIpkh/hyWKyehvZm/jlB6GrqJRnShJKmXnqChK1/img.png?width=400&amp;amp;height=300&amp;amp;face=0_0_400_300,https://scrap.kakaocdn.net/dn/czt6Qn/hyWKKFOafK/Iu8HxjjpZDzytnjA99t8zk/img.png?width=400&amp;amp;height=300&amp;amp;face=0_0_400_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;DHO - 퀘스트 - [퀘스트] 라비린토스의 전설&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;진행 1. 아테네 서고, 학자 - 크레타 섬의 미궁 라비린토스란, 크레타 섬의 미노스 왕이 명공 다이달로스에게 만들게 한 미궁이지요. 미노스왕의 왕비가 낳은 미노타우로스를 묻어버리기 위해서&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.ssjoy.org&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;h3 data-ke-size=&quot;size23&quot;&gt;육지 조사 개방 순서&lt;/h3&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 15.814%;&quot;&gt;완료 횟수&lt;/td&gt;
&lt;td style=&quot;width: 84.186%;&quot;&gt;개방 지역&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 15.814%;&quot;&gt;0&lt;/td&gt;
&lt;td style=&quot;width: 84.186%;&quot;&gt;간디아 서쪽, 크레타섬 내륙&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 15.814%;&quot;&gt;20&lt;/td&gt;
&lt;td style=&quot;width: 84.186%;&quot;&gt;서시베리아 평원&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 15.814%;&quot;&gt;40&lt;/td&gt;
&lt;td style=&quot;width: 84.186%;&quot;&gt;코카서스&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 15.814%;&quot;&gt;70&lt;/td&gt;
&lt;td style=&quot;width: 84.186%;&quot;&gt;사하라, 잠베지 강 중류&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 15.814%;&quot;&gt;90&lt;/td&gt;
&lt;td style=&quot;width: 84.186%;&quot;&gt;파라과이 강 상류, 아마존 오지&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 15.814%;&quot;&gt;100&lt;/td&gt;
&lt;td style=&quot;width: 84.186%;&quot;&gt;록키 지방, 나이아가라 강 유역&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 15.814%;&quot;&gt;120&lt;/td&gt;
&lt;td style=&quot;width: 84.186%;&quot;&gt;시베리아 지방, 우스튜르트 고원, 히말라야 산맥 주변, 바이칼호 주변&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&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;h3 data-ke-size=&quot;size23&quot;&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;1. 측량 후 인식&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;3. 발견물&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;필수 행동에 발견물이 필요한 상륙지가 있습니다. 추천 지도와 퀘스트는 아래와 같습니다.&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #999999; text-align: left;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li style=&quot;color: #999999;&quot;&gt;
&lt;div style=&quot;color: #333333;&quot;&gt;살로니카 남서쪽 : 아테네 서고&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;a style=&quot;color: #2b73b7;&quot; href=&quot;https://www.ssjoy.org/dho/14768&quot;&gt;흰 꽃의 지도&lt;/a&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li style=&quot;color: #999999;&quot;&gt;
&lt;div style=&quot;color: #333333;&quot;&gt;터키 서쪽 해안 : 나폴리 서고&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;a style=&quot;color: #2b73b7;&quot; href=&quot;https://www.ssjoy.org/dho/14764&quot;&gt;빨간 꽃의 지도&lt;/a&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li style=&quot;color: #999999;&quot;&gt;
&lt;div style=&quot;color: #333333;&quot;&gt;베이루트 북쪽 : 아테네 모험 퀘스트&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;a style=&quot;color: #2b73b7;&quot; href=&quot;https://www.ssjoy.org/dho/15567&quot;&gt;십자군 시대의 기사단&lt;/a&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li style=&quot;color: #999999;&quot;&gt;
&lt;div style=&quot;color: #333333;&quot;&gt;이집트 북쪽 해안&lt;/div&gt;
&lt;/li&gt;
&lt;li style=&quot;color: #999999;&quot;&gt;
&lt;div style=&quot;color: #333333;&quot;&gt;올림피아 지방&lt;/div&gt;
&lt;/li&gt;
&lt;li style=&quot;color: #999999;&quot;&gt;
&lt;div style=&quot;color: #333333;&quot;&gt;포키스 지방&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. 육상전&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;&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>GAME/대항해시대</category>
      <category>대항해시대</category>
      <category>상륙지</category>
      <category>온라인</category>
      <category>육지</category>
      <category>조사</category>
      <author>ALEPH.GEM</author>
      <guid isPermaLink="true">https://aacii.tistory.com/434</guid>
      <comments>https://aacii.tistory.com/434#entry434comment</comments>
      <pubDate>Tue, 6 Aug 2024 18:03:19 +0900</pubDate>
    </item>
    <item>
      <title>대항해시대 온라인 - 입항 허가, 칙명, 해역조사</title>
      <link>https://aacii.tistory.com/207</link>
      <description>&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;하지만 중남미 동해안 부터는 칙명으로 입항허가를 받아야 합니다.&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;h3 data-ke-size=&quot;size23&quot;&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;1. 왕궁의 대신에게 칙명(신대륙의 정세 조사) 수락&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 카리브해 산후안으로 이동하여 항구관리와 &lt;span style=&quot;color: #f3c000;&quot;&gt;&lt;b&gt;2번&lt;/b&gt;&lt;/span&gt; 대화&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. 카옌과 페르남부쿠 사이 남미북동 상륙지점에 상륙 -&amp;gt; 겹바위 클릭&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. 본거지 왕궁에 보고&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;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해적피해의 대책 공략&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 토박이해적용 상납품 5개(런던, 리스본 대상인에게 구입) 준비&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;3. 캘리컷의 상인조합 마스터와 대화&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. 수마트라섬남서쪽 해안에 상륙 붉은 꽃 클릭&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;5. 캘리컷 집정관에게 퀘스트 완료 보고&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;6. 자국 왕궁 대신에게 보고&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;/h3&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;h3 data-ke-size=&quot;size23&quot;&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;1. 강장제 5개(리우데자네이루 도구점) 구입&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;3. 남미 남서해안 상륙, 겹바위 클릭&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. 리우데자네이루 집정관에게 보고&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;5. 자국 본거지 왕궁 대신에게 보고&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;/h3&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;1. 산티아고 집정관에게 칙명(포르토벨로 민심조사) 수락&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 포르토벨로 주점주인과 &lt;span style=&quot;color: #f3c000;&quot;&gt;&lt;b&gt;2회&lt;/b&gt;&lt;/span&gt; 대화&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. 포르토벨로 라울과 대화&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. 산티아고 집정관에게 보고&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;5. 자국 왕궁 대신에게 보고&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;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;카이로의 잠입 조사 공략&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 이슬람 변장도 옷 구입 후 카이로, 수에즈 발견&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;3. 모험가조합 마스터와 대화&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. 카이로 휴게소 옆 소녀와 대화&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;5. 카이로 교역소 주인과 대화&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;6. 카이로 도시관리 옆 주민과 대화&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;7. 카이로 도시관리와 대화&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;8. 자국 왕궁 대신에게 보고&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;h3 data-ke-size=&quot;size23&quot;&gt;마닐라 칙명: 동아시아&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #f3c000;&quot;&gt;- 동아시아 입항허가서 획득 시, 부관 총 고용 수가 5명으로 늘어납니다.&lt;/span&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;1. 토박이상납품 1개 구입(런던, 리스본 대상인)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 마닐라 집정관에게 칙명(&lt;span&gt;물자선의 해적 대책&lt;span&gt; )&lt;/span&gt;&lt;/span&gt; 수락&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. 부루나이 외곽(남동쪽) 폐허 더블클릭 -&amp;gt; 토박이 상납품 상납&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. 마닐라 집정관에게 보고&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;5. 자국 왕궁 대신에게 보고&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;h3 data-ke-size=&quot;size23&quot;&gt;상트페티르부르크 입항 허가&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot;&gt;상트페테르부르크는 러시아 수도의 납품 의뢰&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot;&gt;(&lt;/span&gt;&lt;u&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;&lt;/span&gt;&lt;/u&gt;&lt;u&gt;&lt;a href=&quot;https://www.ssjoy.org/dho/quest/61651&quot;&gt;https://www.ssjoy.org/dho/quest/61651&lt;/a&gt;&lt;/u&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot;&gt;라는 퀘스트를 수행해야 들어갈 수 있습니다&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot;&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot;&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000; 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;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot;&gt;&lt;span&gt;샌프란시스코 입항 허가&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot;&gt;&lt;span&gt;&lt;a href=&quot;https://aacii.tistory.com/213&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://aacii.tistory.com/213&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1722474557782&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;대항해시대 온라인 샌프란시스코 입항 퀘스트&quot; data-og-description=&quot;샌프란시스코 입항 퀘스트 새로운 땅을 찾아서 대항해시대 온라인에서 샌프란시스코는 퀘스트를 통해서 발견해야만 입항 할 수 있습니다. 선행 조건 북미 서해안 입항허가: 동아시아 입항허가(&quot; data-og-host=&quot;blog.aacii.net&quot; data-og-source-url=&quot;https://aacii.tistory.com/213&quot; data-og-url=&quot;https://blog.aacii.net/213&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/qO7Gd/hyWKFDycZJ/bJRMJgyPHkyIuJxKiPIcrk/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/czUrf4/hyWGUWGAME/j5acAxplqfMSdEYHr5NBtK/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/Juxyj/hyWGW1gBR1/7jVLyVUJtZQ6RaePnYPnNk/img.png?width=400&amp;amp;height=400&amp;amp;face=0_0_400_400&quot;&gt;&lt;a href=&quot;https://aacii.tistory.com/213&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://aacii.tistory.com/213&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/qO7Gd/hyWKFDycZJ/bJRMJgyPHkyIuJxKiPIcrk/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/czUrf4/hyWGUWGAME/j5acAxplqfMSdEYHr5NBtK/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/Juxyj/hyWGW1gBR1/7jVLyVUJtZQ6RaePnYPnNk/img.png?width=400&amp;amp;height=400&amp;amp;face=0_0_400_400');&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;대항해시대 온라인 샌프란시스코 입항 퀘스트&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;샌프란시스코 입항 퀘스트 새로운 땅을 찾아서 대항해시대 온라인에서 샌프란시스코는 퀘스트를 통해서 발견해야만 입항 할 수 있습니다. 선행 조건 북미 서해안 입항허가: 동아시아 입항허가(&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;blog.aacii.net&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;&amp;nbsp;&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;/h3&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;1. 중급 학교 수료&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;암스테르담의 메르카토르를 만나서 월드 아틀라스를 클릭하면 시작됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000;&quot; data-ke-size=&quot;size16&quot;&gt;1. 조사 시작&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;- &amp;nbsp;&lt;b&gt;북해&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;조사&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000;&quot; data-ke-size=&quot;size16&quot;&gt;2. 극북대서양의 해역조사&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&amp;nbsp; -&amp;nbsp;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;극북대서양의 입항허가&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;획득.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&amp;nbsp; 해당 해역 : 프람 해협, 로포텐 해저분지, 덴마크 해저분지, 노르웨이 해저분지&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000;&quot; data-ke-size=&quot;size16&quot;&gt;3. 유럽 극북의 해역조사&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;유럽 극북의 입항허가&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;획득.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&amp;nbsp; 해당 해역 :&amp;nbsp; 북 노르웨이해, 서 바렌츠해, 동 바렌츠해, 백해&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000;&quot; data-ke-size=&quot;size16&quot;&gt;4. 유라시아의 북쪽의 해역조사&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&amp;nbsp; -&amp;nbsp;&amp;nbsp;&lt;b&gt;유라시아 북쪽의&amp;nbsp;입항허가&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;획득.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&amp;nbsp; 해당 해역 :&amp;nbsp; 서 카라해, 동 카라해, 라프테프 해&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000;&quot; data-ke-size=&quot;size16&quot;&gt;5. 유라시아의 극동의 해역조사&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;유라시아 극동의 입항허가&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;획득.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&amp;nbsp; 해당 해역 :&amp;nbsp; 코텔니 섬 앞바다, 동 시베리아해, 추크치 해&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000;&quot; data-ke-size=&quot;size16&quot;&gt;6. 베링 해의 해역조사&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;&amp;nbsp;&lt;b&gt;베링 해의 입항허가&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;획득.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&amp;nbsp; 해당 해역 :&amp;nbsp; 서 베링해, 동 베링해, 캄차카 반도 앞바다, 오호츠크 해&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000;&quot; data-ke-size=&quot;size16&quot;&gt;7. 완료&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&amp;nbsp; -&amp;nbsp; 메르카토르에게&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;항로 개척자&lt;/b&gt;&lt;span&gt;&amp;nbsp;&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;h3 data-ke-size=&quot;size23&quot;&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;북동 항로와 마찬가지로 암스테르담의 메르카토를 찾아가서 월드 아틀라스를 클릭하면 시작됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;북서 항로 조건&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 유럽 서부에 해당하는 모든 해역 조사 완료&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;3. 북미 서해안 해역조사&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000;&quot; data-ke-size=&quot;size16&quot;&gt;1.&amp;nbsp;그린란드 해역조사 의뢰&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;b&gt;시작조건&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;:&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;유럽 서부의 전 해역&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;해역조사 완료&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;b&gt;-&lt;/b&gt;&amp;nbsp;&amp;nbsp;북그린란드 섬 앞바다, 남그린란드 섬 앞바다&amp;nbsp;조사&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;b&gt;완료&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;:&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;특주 사분의&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/b&gt;보상 획득.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000;&quot; data-ke-size=&quot;size16&quot;&gt;2. 북서 항로의 해역조사&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;시작조건&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;:&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;북미서해안 해역조사&lt;/b&gt;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;그란란드 해역조사&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/b&gt;완료&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&amp;nbsp; -&amp;nbsp;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;동캐나다, 서캐나다의 입항허가&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;획득.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&amp;nbsp; 해당 해역 : 허드슨 해협, 허드슨 만, 배핀 앞바다, 배핀 만,&amp;nbsp;엘즈미어섬 앞바다,&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 북극제도 앞바다, 보퍼트 해, 베로곶 앞바다&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;완료&lt;/b&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;:&amp;nbsp;&lt;/span&gt;&lt;b&gt;휘광석의 반지&amp;nbsp;&lt;/b&gt;&lt;span&gt;보상 획득&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000;&quot; data-ke-size=&quot;size16&quot;&gt;3.&amp;nbsp;메소포타미아 해역조사&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;b&gt;시작조건&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;:&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;북서항로&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;이벤트 완료&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&amp;nbsp; 해당 해역 :&amp;nbsp; 메소포타미아 유역.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;b&gt;완료&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;:&amp;nbsp;&lt;b&gt;천고의 왕관&lt;/b&gt;&lt;span&gt;&amp;nbsp;&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;&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;&amp;nbsp;&lt;/p&gt;</description>
      <category>GAME/대항해시대</category>
      <category>대항해시대</category>
      <category>메르카토르</category>
      <category>온라인</category>
      <category>입항</category>
      <category>칙명</category>
      <category>해역 조사</category>
      <category>허가</category>
      <author>ALEPH.GEM</author>
      <guid isPermaLink="true">https://aacii.tistory.com/207</guid>
      <comments>https://aacii.tistory.com/207#entry207comment</comments>
      <pubDate>Thu, 1 Aug 2024 09:31:59 +0900</pubDate>
    </item>
    <item>
      <title>대항해시대 온라인 - 마카로니펭귄 대만파랑까치 두통약 앵벌</title>
      <link>https://aacii.tistory.com/28</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;마스터브리더 칭호&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;필요스킬: 조교15랭&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;&lt;span&gt;애완동물: 마카로니펭귄, 대만파랑까치&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;애완동물로 아래 해역과 필드에서 채집을 하면 두통약을 물어옵니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;마스터브리더 칭호가 있는 경우 5개 없으면 1개 물어옵니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;마스터브리더 칭호는 조교 15랭이 되어야 합니다.&lt;/span&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;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span data-sheets-root=&quot;1&quot;&gt;베네치아 조련사: 세우타(보리3),트리폴리(메귀리3,밀3) &lt;/span&gt;&lt;span style=&quot;letter-spacing: 0px;&quot; data-sheets-root=&quot;1&quot;&gt;&amp;rarr; 보리 껍질을 벗겨 만든 먹이(조리7)&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;letter-spacing: 0px;&quot; data-sheets-root=&quot;1&quot;&gt;마르세이유 조련사: 보리 껍질을 벗겨 만든 먹이3, 벵가지(나무열매5), 산후안(땅콩5)&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;letter-spacing: 0px;&quot; data-sheets-root=&quot;1&quot;&gt; &amp;rarr; 믹스푸드(조리9)&lt;/span&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&gt;조교 랭작&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;- 1일이상 &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;장거리 항해하고 도시 항구 진입&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- 펫의 친밀도가 높을 수록 숙련도가 높음&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- 펫보유 스킬중 채집 조달 낚시등의 조건으로 발동하는 스킬이 있다면 발동될때마다 숙련도 획득&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;필드&lt;/td&gt;
&lt;td&gt;동남아시아&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;https://www.ssjoy.org/dho/11987&quot;&gt;벵갈만 북동쪽 해안&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td rowspan=&quot;3&quot;&gt;해역&lt;/td&gt;
&lt;td&gt;카리브, 중미&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;https://www.ssjoy.org/dho/3172&quot;&gt;산후안 앞바다&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;남미&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;https://www.ssjoy.org/dho/3207&quot;&gt;페루 해저분지&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;캐나다&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;https://www.ssjoy.org/dho/138080&quot;&gt;북그린란드섬 앞바다&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;두통약은 300만~500만 두캇 정도하며 경숙이 때 거래가 활발합니다.&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;a href=&quot;https://www.ssjoy.org/dho/quest/17677&quot;&gt;https://www.ssjoy.org/dho/quest/17677&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;까치 얻는 퀘스트:&amp;nbsp;&lt;a href=&quot;https://www.ssjoy.org/dho/quest/18515&quot;&gt;https://www.ssjoy.org/dho/quest/18515&lt;/a&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://www.ssjoy.org/dho/skill/1536097&quot;&gt;https://www.ssjoy.org/dho/skill/1536097&lt;/a&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 alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;대만파랑까치.png&quot; data-origin-width=&quot;368&quot; data-origin-height=&quot;326&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/BTFLb/btrAcULTATJ/l4n6cpK0ncqSzDag2yXxC1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/BTFLb/btrAcULTATJ/l4n6cpK0ncqSzDag2yXxC1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/BTFLb/btrAcULTATJ/l4n6cpK0ncqSzDag2yXxC1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FBTFLb%2FbtrAcULTATJ%2Fl4n6cpK0ncqSzDag2yXxC1%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;368&quot; height=&quot;326&quot; data-filename=&quot;대만파랑까치.png&quot; data-origin-width=&quot;368&quot; data-origin-height=&quot;326&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 data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;친밀도에 관하여(위키 참조)&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;5일 항해에 &quot;최대 친밀도&quot; 1씩 상승 가능합니다.&lt;/li&gt;
&lt;li&gt;먹이를 줄때 &quot;기뻐한다&quot; 등의 반응이 있다고 친밀도가 더 상승하지 않습니다.&lt;/li&gt;
&lt;li&gt;친밀도 2짜리 먹이로는 친밀도 120까지 밖에 오르지 않는다는 제보가 있습니다. (친밀도 5짜리 추천)&lt;/li&gt;
&lt;li&gt;100일 이상 항해 후 마을에서 한번에 먹이를 먹일 때 상승 가능한 친밀도가 제한이 있습니다.&lt;/li&gt;
&lt;li&gt;먹이를 주지 않아도 친밀도는 떨어지지 않습니다.&lt;/li&gt;
&lt;li&gt;증서상태로 오래두면 친밀도가 떨어질 수 있습니다.&lt;/li&gt;
&lt;li&gt;다른 케릭으로 옮기면 친밀도가 초기화 됩니다.&lt;/li&gt;
&lt;li&gt;친밀도 100~200 구간에는 항해외에도 애완동물과의 교류가 필요합니다.&lt;/li&gt;
&lt;li&gt;최대 친밀도가 제한된 상태에서도 항해 시간은 누적되는 것으로 보입니다.&lt;/li&gt;
&lt;/ul&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;/h3&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;친밀도 5짜리 먹이는 100개면 충분합니다.&lt;br /&gt;25일 항해에 친밀도 5짜리 먹이를 먹이면 친밀도가 5 상승합니다.&lt;br /&gt;친밀도 100 이전에는 항해후 한번 씩 먹이를 줍니다.&lt;br /&gt;친밀도 100 이후에는 애완동물 교류 반응 오는거에 맞춰서 먹이를 줍니다.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;권리서:&amp;nbsp;&amp;nbsp;&lt;br /&gt;애완동물을 권리서로 변경하고 가지고 다니면 친밀도가 떨어지므로 권리서는 은행에 맡겨놓아야 합니다.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;</description>
      <category>GAME/대항해시대</category>
      <category>대만파랑까치</category>
      <category>대항해시대</category>
      <category>두통약</category>
      <category>마스터브리더</category>
      <category>브리더</category>
      <category>온라인</category>
      <category>조교</category>
      <category>친밀도</category>
      <author>ALEPH.GEM</author>
      <guid isPermaLink="true">https://aacii.tistory.com/28</guid>
      <comments>https://aacii.tistory.com/28#entry28comment</comments>
      <pubDate>Tue, 30 Jul 2024 17:40:45 +0900</pubDate>
    </item>
  </channel>
</rss>