<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>웹개발 일지</title>
    <link>https://jckim-dev.tistory.com/</link>
    <description>웹개발을 하며 공부하고 경험한 것을 작성합니다</description>
    <language>ko</language>
    <pubDate>Fri, 7 Aug 2026 11:56:55 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>jckim</managingEditor>
    <item>
      <title>크롬 확장 프로그램 Mybatis Log To SQL</title>
      <link>https://jckim-dev.tistory.com/entry/%ED%81%AC%EB%A1%AC-%ED%99%95%EC%9E%A5-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%A8-Mybatis-Log-To-SQL</link>
      <description>&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&lt;b&gt;MyBatis Log To SQL (Chrome Extension)&lt;/b&gt;&lt;br&gt;&lt;br&gt;MyBatis 로그의 Preparing 문과 Parameters 문을 결합하여, DB에서 즉시 실행 가능한 완성된 SQL로 변환해주는 크롬 확장프로그램 유틸리티입니다.&lt;br&gt;&lt;br&gt;[LOG 예시]&lt;/p&gt;&lt;pre data-ke-type=&quot;codeblock&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot;&gt;&lt;code&gt;Preparing: SELECT * FROM board WHERE title = ? AND writer = ? AND hits = ?
Parameters: MyBatis 사용법(String), 홍길동(String), 10(Integer)&lt;/code&gt;&lt;/pre&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&lt;br&gt;  주요 기능 자동 접두어 처리: Preparing: 또는 Parameters: 접두어가 포함된 로그를 그대로 붙여넣어도 자동으로 핵심 쿼리와 값만 추출합니다.&lt;br&gt;&lt;br&gt;특수문자 무결성 보장: 데이터 내부에 물음표(?), 쉼표(,), 괄호(())가 포함되어 있어도 쿼리 구조를 정확하게 유지하며 치환합니다.&lt;br&gt;&lt;br&gt;지능형 타입 매핑:&lt;br&gt;&lt;br&gt;String, Date, Timestamp, ?? 등 문자열 계열은 자동으로 ' '를 감쌉니다.&lt;br&gt;&lt;br&gt;Integer, Long, Double 등 숫자 계열은 따옴표 없이 처리합니다.&lt;br&gt;&lt;br&gt;null 값은 SQL의 NULL 상수로 변환합니다.&lt;br&gt;&lt;br&gt;실시간 검증: 쿼리의 ? 개수와 파라미터 개수를 비교하여 불일치 시 사용자에게 알림을 제공합니다.&lt;br&gt;&lt;br&gt;클립보드 자동 복사: 변환 완료 시 별도의 동작 없이 클립보드에 결과가 저장됩니다.&lt;/p&gt;&lt;hr data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot;&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&lt;br&gt;  설치 방법 (개발자 모드) 소스코드 다운로드: 본 저장소의 코드를 내려받거나 폴더를 생성합니다.&lt;br&gt;&lt;br&gt;확장 도구 이동: 크롬 브라우저에서 chrome://extensions/ 주소로 이동합니다.&lt;br&gt;&lt;br&gt;개발자 모드 활성화: 우측 상단의 [개발자 모드] 스위치를 켭니다.&lt;br&gt;&lt;br&gt;폴더 로드: [압축해제된 확장 프로그램을 로드합니다] 버튼을 클릭하고 프로젝트 폴더를 선택합니다.&lt;br&gt;&lt;br&gt;핀 고정: 크롬 우측 상단 퍼즐 아이콘을 클릭하여 해당 앱을 고정(Pin)합니다.&lt;br&gt;&lt;br&gt;&lt;/p&gt;&lt;hr data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot;&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&lt;br&gt;  사용 가이드 로그 복사: 개발 도구(Console)에서 Preparing: 문장과 Parameters: 문장을 각각 복사합니다.&lt;br&gt;&lt;br&gt;입력:&lt;br&gt;&lt;br&gt;Step 1: 복사한 쿼리 문장을 입력창에 붙여넣습니다.&lt;br&gt;&lt;br&gt;Step 2: 복사한 파라미터 문장을 입력창에 붙여넣습니다.&lt;br&gt;&lt;br&gt;변환: [SQL 변환 및 복사] 버튼을 누릅니다.&lt;br&gt;&lt;br&gt;실행: DB 도구(DBeaver, DataGrip 등)에서 Ctrl + V로 붙여넣고 쿼리를 실행합니다.&lt;br&gt;⚠️ 주의 사항 및 알림 개수 불일치: 쿼리 내의 ? 개수와 파라미터 개수가 다를 경우 화면에 에러 메시지가 붉은색으로 표시됩니다.&lt;br&gt;&lt;br&gt;데이터 내 괄호: 데이터 내부에 괄호가 많을 경우, 로직은 항상 가장 마지막에 등장하는 괄호를 (타입) 정보로 인식하므로 그 외의 내부 괄호는 안전하게 보호됩니다.&lt;br&gt;&lt;br&gt;&lt;/p&gt;&lt;hr data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot;&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt; &lt;b&gt; SQL 주석 변환 유틸리티 가이드&lt;/b&gt;&lt;br&gt;&lt;br&gt;개요 (Overview)&lt;br&gt;이 유틸리티는 SQL 문이 한 줄로 나열될 때 발생하는 주석 처리 오류를 방지하기 위해 설계되었습니다. SQL 표준에서 한 줄 주석(--)은 해당 줄의 끝까지를 모두 주석으로 인식합니다. 따라서 쿼리가 한 줄로 합쳐지면 -- 이후의 모든 실행 코드(WHERE, AND 등)가 무력화되어 쿼리 오류가 발생합니다.&lt;br&gt;&lt;br&gt;본 툴은 이러한 한 줄 주석(--) 범위를 지능적으로 파악하여 블록 주석(/* ... */)으로 변환함으로써 쿼리의 실행력을 보장합니다.&lt;br&gt;&lt;br&gt;주요 기능 (Key Features) 지능적 주석 감지: 단순 치환이 아니라, 주석 뒤에 오는 SQL 키워드(AND, OR, FROM 등)를 감지하여 주석의 끝을 자동으로 식별합니다.&lt;br&gt;블록 주석 치환: -- 주석내용을 /* 주석내용 */으로 변경하여 물리적으로 한 줄인 상태에서도 쿼리가 정상 작동하게 합니다.&lt;br&gt;&lt;br&gt;공백 최적화: 쿼리 내의 불필요한 줄바꿈이나 중복된 공백을 정리하여 깔끔한 단일 라인 쿼리를 생성합니다.&lt;br&gt;&lt;br&gt;클립보드 자동 복사: 변환 버튼 클릭 한 번으로 결과물이 복사되어 즉시 DB 툴에 붙여넣을 수 있습니다.&lt;br&gt;&lt;br&gt;사용 방법 (How to Use) SQL 입력: 로그 파일이나 소스 코드에서 복사한 '문제가 되는 한 줄 SQL'을 입력창에 붙여넣습니다.&lt;br&gt;변환 실행: [안전한 주석으로 변환 및 복사] 버튼을 클릭합니다.&lt;br&gt;&lt;br&gt;결과 확인: 하단 결과 창에 주석이 /* */로 감싸진 것을 확인합니다.&lt;br&gt;&lt;br&gt;적용: 이미 클립보드에 복사되었으므로, 원하는 DB 환경(DBeaver, SQL Developer 등)에 Ctrl + V로 붙여넣어 실행합니다.&lt;br&gt;&lt;br&gt;변환 예시 (Examples)&lt;br&gt;❌ 변환 전 (실행 시 오류 발생) &lt;/p&gt;&lt;pre data-ke-type=&quot;codeblock&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot;&gt;&lt;code&gt;SQL select * from users where id = 'admin' --사용자확인 and status = 'active'; &lt;/code&gt;&lt;/pre&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&lt;br&gt;결과: -- 이후의 and status = 'active';까지 주석으로 인식되어 쿼리가 미완성 상태로 종료됨.&lt;br&gt;&lt;br&gt;✅ 변환 후 (정상 실행)&lt;br&gt;&lt;br&gt;&lt;/p&gt;&lt;pre data-ke-type=&quot;codeblock&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot;&gt;&lt;code&gt;SQL select * from users where id = 'admin' /* 사용자확인 */ and status = 'active';&lt;/code&gt;&lt;/pre&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&lt;br&gt; 결과: 주석이 닫혔으므로 and 조건이 정상적으로 실행됨.&lt;br&gt;&lt;br&gt;기술적 상세 (Technical Details) 본 유틸리티는 다음과 같은 SQL 예약어를 기준으로 주석의 종료 지점을 판별합니다:&lt;br&gt;WHERE, AND, OR, FROM, GROUP BY, ORDER BY, LIMIT, SET, JOIN 등&lt;br&gt;&lt;br&gt;[!CAUTION] 주의사항 주석 내용 안에 위와 같은 SQL 키워드가 포함되어 있을 경우, 주석이 의도보다 일찍 닫힐 수 있습니다. 변환 후 결과창을 통해 쿼리 내용을 한 번 더 확인하시길 권장합니다.&lt;br&gt;&lt;br&gt;&lt;/p&gt;&lt;hr data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot;&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&lt;br&gt;  문의 및 피드백 사용 중 오류가 발생하거나 기능 개선이 필요한 경우 아래 댓글로 문의해 주세요.&lt;/p&gt;</description>
      <author>jckim</author>
      <guid isPermaLink="true">https://jckim-dev.tistory.com/63</guid>
      <comments>https://jckim-dev.tistory.com/entry/%ED%81%AC%EB%A1%AC-%ED%99%95%EC%9E%A5-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%A8-Mybatis-Log-To-SQL#entry63comment</comments>
      <pubDate>Tue, 12 May 2026 16:26:34 +0900</pubDate>
    </item>
    <item>
      <title>java 임시파일 삭제 처리 안됨 문제 해결</title>
      <link>https://jckim-dev.tistory.com/entry/java-%EC%9E%84%EC%8B%9C%ED%8C%8C%EC%9D%BC-%EC%82%AD%EC%A0%9C-%EC%B2%98%EB%A6%AC-%EC%95%88%EB%90%A8-%EB%AC%B8%EC%A0%9C-%ED%95%B4%EA%B2%B0</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;Java, Spring Boot, Tomcat 환경에서 파일 업로드 기능을 구현하면서 겪었던 임시 파일 삭제 문제에 대해 공유하고자 합니다. &lt;br /&gt;&lt;br /&gt;특히,&amp;nbsp;File.deleteOnExit()&amp;nbsp;메소드를&amp;nbsp;사용했을&amp;nbsp;때의&amp;nbsp;한계와&amp;nbsp;이를&amp;nbsp;해결하기&amp;nbsp;위해&amp;nbsp;Files.delete()&amp;nbsp;메소드로&amp;nbsp;전환한&amp;nbsp;경험을&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;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;b&gt;문제의&amp;nbsp;배경&lt;/b&gt; &lt;br /&gt;파일&amp;nbsp;업로드&amp;nbsp;기능을&amp;nbsp;구현할&amp;nbsp;때,&amp;nbsp;사용자가&amp;nbsp;업로드한&amp;nbsp;파일은&amp;nbsp;일반적으로&amp;nbsp;서버의&amp;nbsp;임시&amp;nbsp;디렉토리에&amp;nbsp;저장됩니다.&amp;nbsp;Tomcat은&amp;nbsp;요청이&amp;nbsp;완료되면&amp;nbsp;자동으로&amp;nbsp;이&amp;nbsp;임시&amp;nbsp;파일들을&amp;nbsp;삭제하는&amp;nbsp;기능을&amp;nbsp;제공하지만,&amp;nbsp;비동기&amp;nbsp;처리나&amp;nbsp;지속적인&amp;nbsp;파일&amp;nbsp;업로드가&amp;nbsp;이루어지는&amp;nbsp;환경에서는&amp;nbsp;이&amp;nbsp;기능이&amp;nbsp;제대로&amp;nbsp;작동하지&amp;nbsp;않을&amp;nbsp;수&amp;nbsp;있습니다.&amp;nbsp;이로&amp;nbsp;인해&amp;nbsp;임시&amp;nbsp;파일이&amp;nbsp;쌓여&amp;nbsp;서버의&amp;nbsp;디스크&amp;nbsp;공간을&amp;nbsp;차지하게&amp;nbsp;되는&amp;nbsp;문제가&amp;nbsp;발생했습니다. &lt;br /&gt;&lt;br /&gt;&lt;b&gt;File.deleteOnExit()&amp;nbsp;메소드&amp;nbsp;현재&amp;nbsp;로직에&amp;nbsp;부적합&lt;/b&gt; &lt;br /&gt;현재&amp;nbsp;개발환경의&amp;nbsp;공통로직에&amp;nbsp;의하여&amp;nbsp;File.deleteOnExit()&amp;nbsp;메소드를&amp;nbsp;사용하여&amp;nbsp;임시&amp;nbsp;파일을&amp;nbsp;삭제하려고&amp;nbsp;했습니다.&amp;nbsp;이&amp;nbsp;메소드는&amp;nbsp;JVM이&amp;nbsp;종료될&amp;nbsp;때&amp;nbsp;삭제할&amp;nbsp;파일을&amp;nbsp;예약하는&amp;nbsp;기능을&amp;nbsp;가지고&amp;nbsp;있습니다.&amp;nbsp;그러나,&amp;nbsp;이&amp;nbsp;방법은&amp;nbsp;진행중이였던&amp;nbsp;작업인&amp;nbsp;지속적으로&amp;nbsp;파일을&amp;nbsp;업로드하는&amp;nbsp;환경에서는&amp;nbsp;적합하지&amp;nbsp;않았습니다.&amp;nbsp;JVM이&amp;nbsp;종료되지&amp;nbsp;않는&amp;nbsp;한,&amp;nbsp;예약된&amp;nbsp;파일&amp;nbsp;삭제가&amp;nbsp;이루어지지&amp;nbsp;않기&amp;nbsp;때문입니다.&amp;nbsp;따라서,&amp;nbsp;이&amp;nbsp;방법은&amp;nbsp;임시&amp;nbsp;파일을&amp;nbsp;관리하는&amp;nbsp;데&amp;nbsp;있어&amp;nbsp;실질적인&amp;nbsp;해결책이&amp;nbsp;되지&amp;nbsp;못했습니다. &lt;br /&gt;&lt;br /&gt;&lt;b&gt;Files.delete()&amp;nbsp;메소드로의&amp;nbsp;전환&lt;/b&gt; &lt;br /&gt;이러한&amp;nbsp;문제를&amp;nbsp;해결하기&amp;nbsp;위해&amp;nbsp;Files.delete()&amp;nbsp;메소드로&amp;nbsp;전환하기로&amp;nbsp;결정했습니다.&amp;nbsp;이&amp;nbsp;메소드는&amp;nbsp;지정된&amp;nbsp;파일을&amp;nbsp;즉시&amp;nbsp;삭제할&amp;nbsp;수&amp;nbsp;있는&amp;nbsp;기능을&amp;nbsp;제공하므로,&amp;nbsp;임시&amp;nbsp;파일을&amp;nbsp;필요할&amp;nbsp;때마다&amp;nbsp;즉시&amp;nbsp;삭제할&amp;nbsp;수&amp;nbsp;있습니다.&amp;nbsp;이를&amp;nbsp;통해&amp;nbsp;서버의&amp;nbsp;디스크&amp;nbsp;공간을&amp;nbsp;효율적으로&amp;nbsp;관리할&amp;nbsp;수&amp;nbsp;있게&amp;nbsp;되었습니다. &lt;br /&gt;&lt;br /&gt;소스코드 &lt;/p&gt;
&lt;pre id=&quot;code_1765511802799&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;File tempFile = null;
tempFile = File.createTempFile(&quot;upload_&quot;, &quot;.tmp&quot;, new File(TEMP_DIR)); // 임시 파일 생성
...
...
//파일 처리 로직
...
...
// JVM 종료 시 파일 삭제 예약(기존)
tempFile.deleteOnExit();

//즉시 삭제(개선)
Path tempFilePath = tempFile.toPath();
Files.delete(tempFilePath); // 임시 파일 삭제&lt;/code&gt;&lt;/pre&gt;</description>
      <category>JAVA</category>
      <category>deleteOnExit</category>
      <category>files.delete</category>
      <category>Java</category>
      <category>SpringBoot</category>
      <category>tomcat</category>
      <category>임시파일삭제</category>
      <category>파일업로드</category>
      <category>프로그래밍</category>
      <author>jckim</author>
      <guid isPermaLink="true">https://jckim-dev.tistory.com/62</guid>
      <comments>https://jckim-dev.tistory.com/entry/java-%EC%9E%84%EC%8B%9C%ED%8C%8C%EC%9D%BC-%EC%82%AD%EC%A0%9C-%EC%B2%98%EB%A6%AC-%EC%95%88%EB%90%A8-%EB%AC%B8%EC%A0%9C-%ED%95%B4%EA%B2%B0#entry62comment</comments>
      <pubDate>Fri, 12 Dec 2025 12:58:15 +0900</pubDate>
    </item>
    <item>
      <title>AWS 대규모 S3 객체 작업 전략</title>
      <link>https://jckim-dev.tistory.com/entry/AWS-%EB%8C%80%EA%B7%9C%EB%AA%A8-S3-%EA%B0%9D%EC%B2%B4-%EC%9E%91%EC%97%85-%EC%A0%84%EB%9E%B5</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;문제&amp;nbsp;상황&lt;/b&gt; &lt;br /&gt;spring&amp;nbsp;java&amp;nbsp;환경&amp;nbsp;내에서&amp;nbsp;SDK를&amp;nbsp;활용한&amp;nbsp;AWS&amp;nbsp;S3&amp;nbsp;객체&amp;nbsp;목록&amp;nbsp;조회&amp;nbsp;한계와&amp;nbsp;대량&amp;nbsp;작업의&amp;nbsp;어려움 &lt;br /&gt;&lt;br /&gt;AWS&amp;nbsp;S3는&amp;nbsp;수천&amp;nbsp;개의&amp;nbsp;객체를&amp;nbsp;대상으로&amp;nbsp;반복&amp;nbsp;작업을&amp;nbsp;수행할&amp;nbsp;때&amp;nbsp;AWS&amp;nbsp;SDK의&amp;nbsp;listObjects&amp;nbsp;API가&amp;nbsp;가진&amp;nbsp;고유한&amp;nbsp;제약&amp;nbsp;사항으로&amp;nbsp;원하는&amp;nbsp;결과를&amp;nbsp;얻지&amp;nbsp;못하는&amp;nbsp;경우가&amp;nbsp;발생. &lt;br /&gt;&lt;br /&gt;제한된&amp;nbsp;반환&amp;nbsp;개수:&amp;nbsp;listObjects&amp;nbsp;API&amp;nbsp;호출은&amp;nbsp;기본적으로&amp;nbsp;한&amp;nbsp;번에&amp;nbsp;최대&amp;nbsp;1000개의&amp;nbsp;객체만&amp;nbsp;반환하도록&amp;nbsp;설계되어&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;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;해결방안&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Java&amp;nbsp;AWS&amp;nbsp;SDK&amp;nbsp;v1&amp;nbsp;사용하는&amp;nbsp;경우(수동&amp;nbsp;while&amp;nbsp;루프&amp;nbsp;방식) &lt;/b&gt;&lt;br /&gt;수동으로&amp;nbsp;while&amp;nbsp;루프와&amp;nbsp;withContinuationToken&amp;nbsp;토큰을&amp;nbsp;활용하여&amp;nbsp;페이지네이션을&amp;nbsp;구현&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1764312632059&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;String continuationToken = null;
do {
    ListObjectsRequest request = new ListObjectsRequest()
            .withBucketName(&quot;bucket-name&quot;)
            .withPrefix(&quot;folder/&quot;)
            .withMaxKeys(1000) // 최대 1000개
            .withContinuationToken(continuationToken); // 이전 호출의 다음 토큰 설정

    ListObjectsResult result = s3Client.listObjects(request);

    // 현재 페이지의 객체들에 대한 작업 수행
    for (S3ObjectSummary objectSummary : result.getObjectSummaries()) {
        System.out.println(&quot;처리 중인 파일: &quot; + objectSummary.getKey());
        // ... 로직 수행 ...
    }

    // 다음 페이지를 위한 토큰 획득
    continuationToken = result.getNextContinuationToken();

} while (continuationToken != null); // 토큰이 null이 될 때까지 반복&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;Java&amp;nbsp;AWS&amp;nbsp;SDK&amp;nbsp;v2&amp;nbsp;사용하는&amp;nbsp;경우 &lt;/b&gt;&lt;br /&gt;listObjectsV2가&amp;nbsp;아닌&amp;nbsp;Paginator(페이지네이터)&amp;nbsp;패턴을&amp;nbsp;제공하는&amp;nbsp;listObjectsV2Paginator를&amp;nbsp;호출하여&amp;nbsp;구현&lt;/p&gt;
&lt;pre id=&quot;code_1764312668143&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;S3Client s3Client = S3Client.create(); 
String bucketName = &quot;bucket-name&quot;;
String prefix = &quot;folder/&quot;; 

// 1. 요청 객체 생성
ListObjectsV2Request request = ListObjectsV2Request.builder()
    .bucket(bucketName)
    .prefix(prefix)
    .build();

// 2. Paginator 객체(Iterable) 획득
// Paginator는 필요할 때(Iterating)만 S3 API를 호출
ListObjectsV2Iterable responseIterable = s3Client.listObjectsV2Paginator(request);

// 3. Paginator를 활용하여 모든 객체 순회 및 작업
// forEach를 사용하여 모든 페이지의 객체를 순차적으로 처리
long fileCount = 0;
responseIterable.contents().forEach(s3Object -&amp;gt; {
    // 5000개 이상의 모든 객체에 대해 원하는 로직 수행
    System.out.println(&quot;처리 중인 파일: &quot; + s3Object.key());
    // ...
});&lt;/code&gt;&lt;/pre&gt;</description>
      <category>JAVA</category>
      <category>1000</category>
      <category>AWS</category>
      <category>listobjects</category>
      <category>s3</category>
      <category>SDK</category>
      <category>대량</category>
      <author>jckim</author>
      <guid isPermaLink="true">https://jckim-dev.tistory.com/61</guid>
      <comments>https://jckim-dev.tistory.com/entry/AWS-%EB%8C%80%EA%B7%9C%EB%AA%A8-S3-%EA%B0%9D%EC%B2%B4-%EC%9E%91%EC%97%85-%EC%A0%84%EB%9E%B5#entry61comment</comments>
      <pubDate>Fri, 28 Nov 2025 15:52:21 +0900</pubDate>
    </item>
    <item>
      <title>로컬 Elasticsearch HTTPS 접속 불가 해결하기</title>
      <link>https://jckim-dev.tistory.com/entry/%EB%A1%9C%EC%BB%AC-Elasticsearch-HTTPS-%EC%A0%91%EC%86%8D-%EB%B6%88%EA%B0%80-%ED%95%B4%EA%B2%B0%ED%95%98%EA%B8%B0</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;로컬에&amp;nbsp;Elasticsearch를&amp;nbsp;처음&amp;nbsp;세팅하고&amp;nbsp;브라우저에서&amp;nbsp;https://localhost:9200에&amp;nbsp;접속하였는데 &lt;br /&gt;&quot;이&amp;nbsp;사이트는&amp;nbsp;안전하지&amp;nbsp;않습니다&quot;라는&amp;nbsp;SSL&amp;nbsp;오류&amp;nbsp;메시지가&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&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;ssl접속실패.png&quot; data-origin-width=&quot;856&quot; data-origin-height=&quot;589&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/mCsbS/btsQ4ADv6rI/zyeNbjqkaXHWu6lMYb1QP1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/mCsbS/btsQ4ADv6rI/zyeNbjqkaXHWu6lMYb1QP1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/mCsbS/btsQ4ADv6rI/zyeNbjqkaXHWu6lMYb1QP1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FmCsbS%2FbtsQ4ADv6rI%2FzyeNbjqkaXHWu6lMYb1QP1%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;589&quot; data-filename=&quot;ssl접속실패.png&quot; data-origin-width=&quot;856&quot; data-origin-height=&quot;589&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;로컬&amp;nbsp;개발&amp;nbsp;환경에서는&amp;nbsp;정식&amp;nbsp;인증서를&amp;nbsp;발급하기&amp;nbsp;번거롭기&amp;nbsp;때문에&amp;nbsp;빈번하게&amp;nbsp;발생하는&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;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;HTTPS&amp;nbsp;접근&amp;nbsp;비활성화로&amp;nbsp;문제&amp;nbsp;해결&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1760077218436&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;ssl errorLog
&quot;error&quot;: &quot;Internal Server Error&quot;,
&quot;trace&quot;: &quot;java.net.ConnectException: Connection refused: no further information\r\n\tat org.elasticsearch.client.RestClient.extractAndWrapCause(RestClient.java:934)\r\n\tat org&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;로컬 환경에서 테스트 목적으로 Elasticsearch를 구동할 때는 HTTPS 접근을 비활성화하는 것이 가장 빠르고 쉬운 해결책입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Elasticsearch는 기본적으로 보안을 위해 HTTPS(SSL) 접근이 활성화되어 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 설정을 변경하려면 Elasticsearch 설치 경로에 있는 elasticsearch.yml 파일을 수정해야 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;elasticsearch.yml&amp;nbsp;파일에서&amp;nbsp;xpack.security.http.ssl&amp;nbsp;섹션을&amp;nbsp;찾아&amp;nbsp;다음과&amp;nbsp;같이&amp;nbsp;enabled&amp;nbsp;값을&amp;nbsp;false로&amp;nbsp;변경해 주면&amp;nbsp;됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1760077270780&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;elasticsearch.yml
# Enable encryption for HTTP API client connections, such as Kibana, Logstash, and Agents

xpack.security.http.ssl:
&amp;nbsp; # enabled: true &amp;lt;&amp;lt; 기본 설정 (주석 처리 또는 삭제)
&amp;nbsp; enabled: false # &amp;lt;&amp;lt; 추가 또는 변경
&amp;nbsp; keystore.path: certs/http.p12&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;후에는&amp;nbsp;Elasticsearch&amp;nbsp;서비스를&amp;nbsp;재시작해야&amp;nbsp;적용됩니다. &lt;br /&gt;서비스를&amp;nbsp;재시작하면&amp;nbsp;https://localhost:9200으로&amp;nbsp;정상적으로&amp;nbsp;접속되는&amp;nbsp;것을&amp;nbsp;확인할&amp;nbsp;수&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;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;간혹 위 설정 변경 이후 사용자 ID와 비밀번호를 요구하는 경우가 있습니다.&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;계정요.png&quot; data-origin-width=&quot;996&quot; data-origin-height=&quot;318&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/WYJVJ/btsQ5BIeV8T/dEHPdyN4eQxBA4hqwQA5o0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/WYJVJ/btsQ5BIeV8T/dEHPdyN4eQxBA4hqwQA5o0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/WYJVJ/btsQ5BIeV8T/dEHPdyN4eQxBA4hqwQA5o0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FWYJVJ%2FbtsQ5BIeV8T%2FdEHPdyN4eQxBA4hqwQA5o0%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;873&quot; height=&quot;279&quot; data-filename=&quot;계정요.png&quot; data-origin-width=&quot;996&quot; data-origin-height=&quot;318&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음과&amp;nbsp;같은&amp;nbsp;오류&amp;nbsp;로그가&amp;nbsp;발생&lt;/p&gt;
&lt;pre id=&quot;code_1760077351626&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;userInfo errorLog
&quot;error&quot;: &quot;Internal Server Error&quot;,
&quot;trace&quot;: &quot;co.elastic.clients.elasticsearch._types.ElasticsearchException: [es/search] failed: [security_exception] missing authentication credentials for REST request [/topic/_search?typed_keys=true]\r\n\tat co.elastic.clients.transport.ElasticsearchTransportBase.getApiResponse(ElasticsearchTransportBase.java:357)\r\n\tat co.elastic.clients.transport&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;사용자&amp;nbsp;ID/PW&amp;nbsp;요구&amp;nbsp;시&amp;nbsp;해결&amp;nbsp;방법&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1.&amp;nbsp;사용자&amp;nbsp;추가&amp;nbsp;및&amp;nbsp;역할&amp;nbsp;지정&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가장 권장되는 방법은 테스트용 사용자를 추가하고 superuser 역할을 부여하는 것입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음 명령어를 사용하여 사용자를 추가할 수 있습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1760077386993&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;elasticsearch-users useradd testId -p testPwd -r superuser
elasticsearch-users roles testId -a superuser&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위&amp;nbsp;명령어에서&amp;nbsp;testId&amp;nbsp;사용자&amp;nbsp;ID이고&amp;nbsp;-p&amp;nbsp;testPwd&amp;nbsp;비밀번호입니다. &lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2.&amp;nbsp;사용자&amp;nbsp;인증&amp;nbsp;설정&amp;nbsp;제거&amp;nbsp;(보안에&amp;nbsp;취약)&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또 다른 방법은 사용자 인증 자체를 비활성화하는 것입니다.&lt;br /&gt;이는 로컬 테스트 환경에서만 사용해야 하며,&lt;br /&gt;보안상 매우 취약하므로 실제 운영 환경에서는 절대 사용해서는 안 됩니다.&lt;br /&gt;elasticsearch.yml&amp;nbsp;파일에서&amp;nbsp;xpack.security.enabled&amp;nbsp;키워드를&amp;nbsp;찾아&amp;nbsp;false로&amp;nbsp;변경&amp;nbsp;후&amp;nbsp;서비스를&amp;nbsp;재시작하면&amp;nbsp;됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1760077432289&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# Enable security features
#xpack.security.enabled: true # &amp;lt;&amp;lt; 기본 설정 (주석 처리 또는 삭제)
xpack.security.enabled: false # &amp;lt;&amp;lt; 추가 또는 변경&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;접속성공.png&quot; data-origin-width=&quot;521&quot; data-origin-height=&quot;369&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/xxOgt/btsQ5bQDBgP/zkP7hBdVkQxbdkRe8OHUT1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/xxOgt/btsQ5bQDBgP/zkP7hBdVkQxbdkRe8OHUT1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/xxOgt/btsQ5bQDBgP/zkP7hBdVkQxbdkRe8OHUT1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FxxOgt%2FbtsQ5bQDBgP%2FzkP7hBdVkQxbdkRe8OHUT1%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;521&quot; height=&quot;369&quot; data-filename=&quot;접속성공.png&quot; data-origin-width=&quot;521&quot; data-origin-height=&quot;369&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>기타</category>
      <category>elasticsearch</category>
      <category>HTTPS</category>
      <category>SSL</category>
      <category>로컬</category>
      <category>접속불가</category>
      <author>jckim</author>
      <guid isPermaLink="true">https://jckim-dev.tistory.com/60</guid>
      <comments>https://jckim-dev.tistory.com/entry/%EB%A1%9C%EC%BB%AC-Elasticsearch-HTTPS-%EC%A0%91%EC%86%8D-%EB%B6%88%EA%B0%80-%ED%95%B4%EA%B2%B0%ED%95%98%EA%B8%B0#entry60comment</comments>
      <pubDate>Fri, 10 Oct 2025 15:28:06 +0900</pubDate>
    </item>
    <item>
      <title>GitHub Push 실패와 Secret Scanning 위반 해결</title>
      <link>https://jckim-dev.tistory.com/entry/GitHub-Push-%EC%8B%A4%ED%8C%A8%EC%99%80-Secret-Scanning-%EC%9C%84%EB%B0%98-%ED%95%B4%EA%B2%B0</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;개발을&amp;nbsp;마치고&amp;nbsp;git&amp;nbsp;commit&amp;nbsp;후&amp;nbsp;push를&amp;nbsp;실행한&amp;nbsp;순간,&amp;nbsp;git&amp;nbsp;push&amp;nbsp;거절&amp;nbsp;메시지에&amp;nbsp;대한&amp;nbsp;직접&amp;nbsp;겪고&amp;nbsp;해결한&amp;nbsp;과정을&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;p data-ke-size=&quot;size16&quot;&gt;✅&amp;nbsp; 문제&amp;nbsp;발생:&amp;nbsp;Push가&amp;nbsp;거부되었습니다 &lt;br /&gt;작업을 완료하고 소스를 원격 저장소에 올리기 위해 commit 후 push를 실행했지만,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래와 같은 경고창의 메시지와 함께 실패했습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;git push 거절.png&quot; data-origin-width=&quot;497&quot; data-origin-height=&quot;114&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/k8pEj/btsO5tNucSH/YqmhPW5vy4u3RJAT23dD8K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/k8pEj/btsO5tNucSH/YqmhPW5vy4u3RJAT23dD8K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/k8pEj/btsO5tNucSH/YqmhPW5vy4u3RJAT23dD8K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fk8pEj%2FbtsO5tNucSH%2FYqmhPW5vy4u3RJAT23dD8K%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;497&quot; height=&quot;114&quot; data-filename=&quot;git push 거절.png&quot; data-origin-width=&quot;497&quot; data-origin-height=&quot;114&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;경고창의 메시지처럼 pull을 시도했지만 이미 로컬 저장소는 최신 상태였고&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&quot;git 로그 확인&quot; 버튼을 클릭하여 확인해 보기로 하였습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1751847853665&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;! [remote rejected] branch_name -&amp;gt; branch_name (push declined due to repository rule violations)
error: failed to push some refs to 'git 주소'&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;메시지는&amp;nbsp;저장소의&amp;nbsp;규칙&amp;nbsp;위반으로&amp;nbsp;푸시가&amp;nbsp;거부되었다고&amp;nbsp;알려주고&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;p data-ke-size=&quot;size16&quot;&gt;✅&amp;nbsp; 원인&amp;nbsp;분석:&amp;nbsp;GitHub의&amp;nbsp;Secret&amp;nbsp;Scanning&amp;nbsp;기능 &lt;br /&gt;에러&amp;nbsp;메시지의&amp;nbsp;핵심은&amp;nbsp;**&quot;repository&amp;nbsp;rule&amp;nbsp;violations&quot;**였습니다.&amp;nbsp;GitHub&amp;nbsp;저장소의&amp;nbsp;규칙을&amp;nbsp;위반했다는&amp;nbsp;뜻이었죠. &lt;br /&gt;&lt;br /&gt;이는&amp;nbsp;GitHub가&amp;nbsp;제공하는&amp;nbsp;비밀&amp;nbsp;스캔(Secret&amp;nbsp;Scanning)&amp;nbsp;기능&amp;nbsp;때문이었습니다.&amp;nbsp;이&amp;nbsp;기능은&amp;nbsp;저장소에&amp;nbsp;Access&amp;nbsp;Token,&amp;nbsp;API&amp;nbsp;Key&amp;nbsp;등&amp;nbsp;민감한&amp;nbsp;정보가&amp;nbsp;커밋되는&amp;nbsp;것을&amp;nbsp;자동으로&amp;nbsp;탐지하고&amp;nbsp;푸시를&amp;nbsp;차단하여&amp;nbsp;보안&amp;nbsp;위협을&amp;nbsp;사전에&amp;nbsp;방지합니다. &lt;br /&gt;&lt;br /&gt;저의&amp;nbsp;경우,&amp;nbsp;테스트&amp;nbsp;과정에서&amp;nbsp;실수로&amp;nbsp;API&amp;nbsp;호출에&amp;nbsp;사용한&amp;nbsp;토큰&amp;nbsp;값을&amp;nbsp;소스&amp;nbsp;코드에&amp;nbsp;그대로&amp;nbsp;하드코딩했고,&amp;nbsp;이&amp;nbsp;변경사항을&amp;nbsp;커밋에&amp;nbsp;포함하여&amp;nbsp;푸시를&amp;nbsp;시도하다가&amp;nbsp;비밀&amp;nbsp;스캔&amp;nbsp;규칙에&amp;nbsp;걸려&amp;nbsp;차단된&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;p data-ke-size=&quot;size16&quot;&gt;✅&amp;nbsp;해결&amp;nbsp;과정:&amp;nbsp;안전하게&amp;nbsp;과거로&amp;nbsp;돌아가기 &lt;br /&gt;문제를&amp;nbsp;해결하기&amp;nbsp;위해&amp;nbsp;민감한&amp;nbsp;정보가&amp;nbsp;포함된&amp;nbsp;가장&amp;nbsp;최신&amp;nbsp;커밋을&amp;nbsp;취소해야&amp;nbsp;했습니다.&amp;nbsp;이때&amp;nbsp;작업&amp;nbsp;내용은&amp;nbsp;그대로&amp;nbsp;유지하면서&amp;nbsp;커밋&amp;nbsp;기록만&amp;nbsp;이전으로&amp;nbsp;되돌리는&amp;nbsp;git&amp;nbsp;reset&amp;nbsp;명령어를&amp;nbsp;사용했습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1751847893609&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;git reset --soft HEAD~1&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;--soft&amp;nbsp;옵션&amp;nbsp;덕분에&amp;nbsp;마지막&amp;nbsp;커밋은&amp;nbsp;취소되었지만,&amp;nbsp;변경된&amp;nbsp;파일들은&amp;nbsp;모두&amp;nbsp;Staging&amp;nbsp;Area에&amp;nbsp;그대로&amp;nbsp;남아있었습니다.&amp;nbsp;이후&amp;nbsp;코드에서&amp;nbsp;토큰&amp;nbsp;값을&amp;nbsp;제거하고&amp;nbsp;다시&amp;nbsp;커밋하여&amp;nbsp;안전하게&amp;nbsp;푸시를&amp;nbsp;완료할&amp;nbsp;수&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;p data-ke-size=&quot;size16&quot;&gt;✅&amp;nbsp; 민감&amp;nbsp;정보&amp;nbsp;관리&amp;nbsp;예방&amp;nbsp;방법 &lt;br /&gt;이번&amp;nbsp;경험을&amp;nbsp;통해&amp;nbsp;민감한&amp;nbsp;정보를&amp;nbsp;안전하게&amp;nbsp;관리하는&amp;nbsp;것의&amp;nbsp;중요성을&amp;nbsp;다시&amp;nbsp;한번&amp;nbsp;깨달았습니다.&amp;nbsp;토큰이나&amp;nbsp;API&amp;nbsp;Key&amp;nbsp;같은&amp;nbsp;비밀&amp;nbsp;정보는&amp;nbsp;다음과&amp;nbsp;같은&amp;nbsp;방법을&amp;nbsp;사용하여&amp;nbsp;관리하는&amp;nbsp;것이&amp;nbsp;안전하고&amp;nbsp;권장됩니다. &lt;br /&gt;&lt;br /&gt;프로퍼티(.properties,&amp;nbsp;.yml)&amp;nbsp;파일&amp;nbsp;분리:&amp;nbsp;설정&amp;nbsp;파일을&amp;nbsp;통해&amp;nbsp;외부에서&amp;nbsp;값을&amp;nbsp;주입합니다. &lt;br /&gt;&lt;br /&gt;환경&amp;nbsp;변수(Environment&amp;nbsp;Variables)&amp;nbsp;사용:&amp;nbsp;시스템의&amp;nbsp;환경&amp;nbsp;변수에&amp;nbsp;값을&amp;nbsp;저장하고&amp;nbsp;코드에서는&amp;nbsp;변수를&amp;nbsp;참조합니다. &lt;br /&gt;&lt;br /&gt;암호화(Encryption):&amp;nbsp;Vault나&amp;nbsp;KMS와&amp;nbsp;같은&amp;nbsp;암호화&amp;nbsp;솔루션을&amp;nbsp;사용하여&amp;nbsp;민감&amp;nbsp;정보를&amp;nbsp;암호화하여&amp;nbsp;저장하고&amp;nbsp;필요할&amp;nbsp;때&amp;nbsp;복호화하여&amp;nbsp;사용합니다.&lt;/p&gt;</description>
      <category>형상관리</category>
      <category>failed to push some refs to</category>
      <category>Git</category>
      <category>Push</category>
      <category>push declined due to repository rule violations</category>
      <category>remote rejected</category>
      <category>secret scanning</category>
      <category>비밀스캔</category>
      <author>jckim</author>
      <guid isPermaLink="true">https://jckim-dev.tistory.com/59</guid>
      <comments>https://jckim-dev.tistory.com/entry/GitHub-Push-%EC%8B%A4%ED%8C%A8%EC%99%80-Secret-Scanning-%EC%9C%84%EB%B0%98-%ED%95%B4%EA%B2%B0#entry59comment</comments>
      <pubDate>Mon, 7 Jul 2025 09:25:49 +0900</pubDate>
    </item>
    <item>
      <title>Spring Bean은 싱글톤인데, 사용자 정보 유출이 발생하지 않는 이유</title>
      <link>https://jckim-dev.tistory.com/entry/Spring-Bean%EC%9D%80-%EC%8B%B1%EA%B8%80%ED%86%A4%EC%9D%B8%EB%8D%B0-%EC%82%AC%EC%9A%A9%EC%9E%90-%EC%A0%95%EB%B3%B4-%EC%9C%A0%EC%B6%9C%EC%9D%B4-%EB%B0%9C%EC%83%9D%ED%95%98%EC%A7%80-%EC%95%8A%EB%8A%94-%EC%9D%B4%EC%9C%A0</link>
      <description>&lt;p data-end=&quot;289&quot; data-start=&quot;167&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;289&quot; data-start=&quot;167&quot; data-ke-size=&quot;size16&quot;&gt;Spring에서 대부분의 Bean은 기본적으로 &lt;b&gt;싱글톤(Singleton)&lt;/b&gt; 스코프로 관리됩니다. 즉, 애플리케이션 컨텍스트 내에서 해당 Bean의 인스턴스는 하나만 생성되고, 모든 요청에서 이를 공유해 사용합니다.&lt;/p&gt;
&lt;p data-end=&quot;373&quot; data-start=&quot;291&quot; data-ke-size=&quot;size16&quot;&gt;이러한 구조는 성능 측면에서는 효율적이지만, 요청 간 자원 공유로 인해 &lt;b&gt;사용자 정보가 노출되는 것이 아닌가?&lt;/b&gt; 하는 우려가 생길 수 있습니다.&lt;/p&gt;
&lt;p data-end=&quot;467&quot; data-start=&quot;375&quot; data-ke-size=&quot;size16&quot;&gt;그러나 실제로는 잘 설계된 Bean이라면 싱글톤 방식에서도 사용자 정보 유출 없이 안전하게 동작할 수 있습니다. 그 핵심은 바로 &lt;b&gt;Stateless 설계&lt;/b&gt;입니다.&lt;/p&gt;
&lt;p data-end=&quot;467&quot; data-start=&quot;375&quot; 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;h2 data-end=&quot;497&quot; data-start=&quot;474&quot; data-ke-size=&quot;size26&quot;&gt;싱글톤(Singleton) 방식이란?&lt;/h2&gt;
&lt;p data-end=&quot;623&quot; data-start=&quot;499&quot; data-ke-size=&quot;size16&quot;&gt;&quot;싱글톤&quot;이란 객체가 &lt;b&gt;애플리케이션 전체에서 단 하나만 생성되어 재사용&lt;/b&gt;되는 디자인 패턴입니다. Spring에서는 기본 스코프가 Singleton이므로, 특별한 설정이 없는 한 Bean은 하나의 인스턴스로만 유지됩니다.&lt;/p&gt;
&lt;p data-end=&quot;467&quot; data-start=&quot;375&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style6&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h2 data-end=&quot;660&quot; data-start=&quot;630&quot; data-ke-size=&quot;size26&quot;&gt;싱글톤임에도 안전한 이유: Stateless 설계&lt;/h2&gt;
&lt;p data-end=&quot;770&quot; data-start=&quot;662&quot; data-ke-size=&quot;size16&quot;&gt;싱글톤 Bean이 사용자 정보를 공유하지 않으려면, 해당 Bean이 &lt;b&gt;상태(State)를 갖지 않아야&lt;/b&gt; 합니다. 즉, 요청 간 정보를 인스턴스의 필드에 저장하지 않는 구조로 설계해야 합니다.&lt;/p&gt;
&lt;p data-end=&quot;806&quot; data-start=&quot;772&quot; data-ke-size=&quot;size16&quot;&gt;이러한 Stateless 방식은 다음과 같은 원칙을 따릅니다:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;931&quot; data-start=&quot;808&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;851&quot; data-start=&quot;808&quot;&gt;모든 요청 데이터를 &lt;b&gt;지역 변수(local variable)&lt;/b&gt; 로 처리&lt;/li&gt;
&lt;li data-end=&quot;884&quot; data-start=&quot;852&quot;&gt;&lt;b&gt;필드(field)&lt;/b&gt; 에 요청 정보를 저장하지 않음&lt;/li&gt;
&lt;li data-end=&quot;931&quot; data-start=&quot;885&quot;&gt;외부 상태(세션, 쿠키, 헤더 등) 또는 메소드 인자를 통해 필요한 정보만 활용&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style6&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;p data-end=&quot;467&quot; data-start=&quot;375&quot; data-ke-size=&quot;size16&quot;&gt;잘못된 설계 예시: 상태를 저장하는 Bean&lt;/p&gt;
&lt;pre id=&quot;code_1745288554951&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;@Service
public class UserService {
    private String userName; // 상태 저장 &amp;rarr; 위험

    public void process(String name) {
        this.userName = name;
        // 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;위 코드는 userName이라는 필드에 요청 데이터를 저장하고 있어 &lt;b&gt;Thread 간 정보가 섞이는 문제&lt;/b&gt;가 발생할 수 있습니다. 여러 사용자가 동시에 이 메서드를 호출할 경우, 이전 사용자 정보가 새로운 요청에 의해 덮어쓰여 &lt;b&gt;정보 유출&lt;/b&gt;이 발생할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style6&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;올바른 설계 예시: Thread-safe &amp;amp; Stateless&lt;/p&gt;
&lt;pre id=&quot;code_1745288576111&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;@Service
public class UserService {
    public void process(String name) {
        // 지역 변수로만 처리 &amp;rarr; 동시 요청에서도 서로 간섭 없음
        String processedName = name.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;위 코드에서는 요청 정보를 &lt;b&gt;지역 변수&lt;/b&gt;로 처리하고 있어, 각 요청마다 &lt;b&gt;스레드의 Stack 영역에 독립적으로 메모리가 할당&lt;/b&gt;됩니다. 따라서 동시 요청이 발생하더라도 사용자 간 간섭이 없습니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style6&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h2 data-end=&quot;1688&quot; data-start=&quot;1671&quot; data-ke-size=&quot;size26&quot;&gt;상태가 필요한 경우의 대안&lt;/h2&gt;
&lt;p data-end=&quot;1739&quot; data-start=&quot;1690&quot; data-ke-size=&quot;size16&quot;&gt;Bean에서 상태를 꼭 유지해야 하는 경우에는 다음과 같은 방식들을 고려할 수 있습니다:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1928&quot; data-start=&quot;1741&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1846&quot; data-start=&quot;1741&quot;&gt;&lt;b&gt;사용자별 상태 저장&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1846&quot; data-start=&quot;1762&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1779&quot; data-start=&quot;1762&quot;&gt;HttpSession&lt;/li&gt;
&lt;li data-end=&quot;1800&quot; data-start=&quot;1782&quot;&gt;RequestScope&lt;/li&gt;
&lt;li data-end=&quot;1820&quot; data-start=&quot;1803&quot;&gt;ThreadLocal&lt;/li&gt;
&lt;li data-end=&quot;1846&quot; data-start=&quot;1823&quot;&gt;JWT 토큰 기반 사용자 정보 유지 등&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;1928&quot; data-start=&quot;1848&quot;&gt;&lt;b&gt;매 요청마다 새로운 Bean 생성&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1928&quot; data-start=&quot;1877&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1900&quot; data-start=&quot;1877&quot;&gt;@Scope(&quot;request&quot;)&lt;/li&gt;
&lt;li data-end=&quot;1928&quot; data-start=&quot;1903&quot;&gt;@Scope(&quot;prototype&quot;)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style6&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h2 data-end=&quot;1941&quot; data-start=&quot;1935&quot; data-ke-size=&quot;size26&quot;&gt;마무리&lt;/h2&gt;
&lt;p data-end=&quot;2116&quot; data-start=&quot;1943&quot; data-ke-size=&quot;size16&quot;&gt;Spring의 싱글톤 Bean은 성능과 구조 측면에서 유리하지만, 설계 방식에 따라 보안 문제가 발생할 수 있습니다. &lt;b&gt;Bean은 Stateless하게 설계하고, 상태가 필요한 경우는 외부 저장소나 스코프 변경을 활용&lt;/b&gt;해야 합니다. 이를 통해 싱글톤 구조에서도 안전하고 견고한 시스템을 설계할 수 있습니다.&lt;/p&gt;</description>
      <category>spring</category>
      <category>@scope</category>
      <category>spring bean</category>
      <category>Spring bean scope</category>
      <category>stateless 설계</category>
      <category>thread-safe</category>
      <category>동시성 문제</category>
      <category>멀티스레드</category>
      <category>사용자 정보 유출</category>
      <category>싱글톤</category>
      <author>jckim</author>
      <guid isPermaLink="true">https://jckim-dev.tistory.com/58</guid>
      <comments>https://jckim-dev.tistory.com/entry/Spring-Bean%EC%9D%80-%EC%8B%B1%EA%B8%80%ED%86%A4%EC%9D%B8%EB%8D%B0-%EC%82%AC%EC%9A%A9%EC%9E%90-%EC%A0%95%EB%B3%B4-%EC%9C%A0%EC%B6%9C%EC%9D%B4-%EB%B0%9C%EC%83%9D%ED%95%98%EC%A7%80-%EC%95%8A%EB%8A%94-%EC%9D%B4%EC%9C%A0#entry58comment</comments>
      <pubDate>Tue, 22 Apr 2025 11:24:26 +0900</pubDate>
    </item>
    <item>
      <title>Netty에서 총 길이를 알 수 없는 데이터 수신 처리 전략</title>
      <link>https://jckim-dev.tistory.com/entry/Netty%EC%97%90%EC%84%9C-%EC%B4%9D-%EA%B8%B8%EC%9D%B4%EB%A5%BC-%EC%95%8C-%EC%88%98-%EC%97%86%EB%8A%94-%EB%8D%B0%EC%9D%B4%ED%84%B0-%EC%88%98%EC%8B%A0-%EC%B2%98%EB%A6%AC-%EC%A0%84%EB%9E%B5</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;Java 기반의 비동기 네트워크 프레임워크인 Netty는 고성능 서버/클라이언트 애플리케이션 개발에 자주 활용됩니다.&lt;br /&gt;이번 글에서는 &lt;b&gt;총길이를 사전에 알 수 없는 바이트 스트림 데이터를 수신&lt;/b&gt;해야 하는 상황에서 Netty를 활용해 어떻게 문제를 해결할 수 있었는지 정리해 보겠습니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-end=&quot;360&quot; data-start=&quot;340&quot; data-ke-size=&quot;size26&quot;&gt;Netty와 데이터 수신의 특징&lt;/h2&gt;
&lt;p data-end=&quot;507&quot; data-start=&quot;362&quot; data-ke-size=&quot;size16&quot;&gt;Netty는 비동기 이벤트 기반 네트워크 프레임워크로, TCP와 같은 연결 지향 프로토콜 기반의 통신에서 널리 사용됩니다.&lt;br /&gt;우리는 외부 기관과 통신할 때 Netty를 통해 데이터를 바이트 스트림 형태로 수신하고 있으며, 다음과 같은 상황을 마주하게 됩니다:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;598&quot; data-start=&quot;509&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;553&quot; data-start=&quot;509&quot;&gt;데이터는 여러 조각으로 나뉘어 들어오며 한 번에 도착한다는 보장이 없다.&lt;/li&gt;
&lt;li data-end=&quot;598&quot; data-start=&quot;554&quot;&gt;연결을 유지하자니 언제 끝날지 모르고, 끊자니 데이터가 누락될 위험이 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;661&quot; data-start=&quot;600&quot; data-ke-size=&quot;size16&quot;&gt;즉, &lt;b&gt;메시지의 경계를 알 수 없는 스트림&lt;/b&gt;을 다루기 때문에 프레이밍(Framing)이 반드시 필요합니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-end=&quot;704&quot; data-start=&quot;668&quot; data-ke-size=&quot;size26&quot;&gt;Netty가 제공하는 프레이밍(Framing) Decoder&lt;/h2&gt;
&lt;p data-end=&quot;757&quot; data-start=&quot;706&quot; data-ke-size=&quot;size16&quot;&gt;Netty는 다양한 유형의 메시지 분할 처리를 위한 Decoder를 기본 제공하고 있습니다:&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-end=&quot;1144&quot; data-start=&quot;759&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li data-end=&quot;871&quot; data-start=&quot;759&quot;&gt;&lt;b&gt;LineBasedFrameDecoder&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;871&quot; data-start=&quot;793&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;833&quot; data-start=&quot;793&quot;&gt;개행 문자(\n, \r\n) 기준으로 메시지를 분리합니다.&lt;/li&gt;
&lt;li data-end=&quot;871&quot; data-start=&quot;837&quot;&gt;텍스트 기반 프로토콜(ex. Telnet)에서 사용됩니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;956&quot; data-start=&quot;873&quot;&gt;&lt;b&gt;DelimiterBasedFrameDecoder&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;956&quot; data-start=&quot;912&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;956&quot; data-start=&quot;912&quot;&gt;사용자 정의 구분자(ex. @@END@@)를 기준으로 메시지를 나눕니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;1030&quot; data-start=&quot;958&quot;&gt;&lt;b&gt;FixedLengthFrameDecoder&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1030&quot; data-start=&quot;994&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1030&quot; data-start=&quot;994&quot;&gt;고정된 길이의 메시지를 처리합니다. (ex. 1024바이트씩)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;1144&quot; data-start=&quot;1032&quot;&gt;&lt;b&gt;LengthFieldBasedFrameDecoder&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1144&quot; data-start=&quot;1073&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1108&quot; data-start=&quot;1073&quot;&gt;메시지의 헤더에 포함된 길이 필드를 기반으로 동작합니다.&lt;/li&gt;
&lt;li data-end=&quot;1144&quot; data-start=&quot;1112&quot;&gt;대부분의 TCP 기반 바이너리 프로토콜에서 활용됩니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-end=&quot;1210&quot; data-start=&quot;1146&quot; data-ke-size=&quot;size16&quot;&gt;이러한 Decoder들은 메시지 구조가 명확히 정의되어 있고 송수신 간 협의가 잘 되어 있을 때 매우 효과적입니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-end=&quot;1236&quot; data-start=&quot;1217&quot; data-ke-size=&quot;size26&quot;&gt;프레이밍이 어려운 특수한 상황&lt;/h2&gt;
&lt;p data-end=&quot;1290&quot; data-start=&quot;1238&quot; data-ke-size=&quot;size16&quot;&gt;그러나 다음과 같은 요구사항이 있는 경우, 위의 Decoder 방식으로는 처리하기 어렵습니다:&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-end=&quot;1383&quot; data-start=&quot;1292&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li data-end=&quot;1315&quot; data-start=&quot;1292&quot;&gt;&lt;b&gt;메시지 길이가 가변적이다.&lt;/b&gt;&lt;/li&gt;
&lt;li data-end=&quot;1352&quot; data-start=&quot;1316&quot;&gt;&lt;b&gt;메시지가 매우 길다.&lt;/b&gt; (예: 50만 바이트 이상)&lt;/li&gt;
&lt;li data-end=&quot;1383&quot; data-start=&quot;1353&quot;&gt;&lt;b&gt;헤더에 전체 길이 정보를 포함할 수 없다.&lt;/b&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-end=&quot;1437&quot; data-start=&quot;1385&quot; data-ke-size=&quot;size16&quot;&gt;이러한 경우, 메시지 경계를 일반적인 방식으로 판단하기 어려워 별도의 처리 전략이 필요합니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-end=&quot;1494&quot; data-start=&quot;1444&quot; data-ke-size=&quot;size26&quot;&gt;해결 전략: IdleStateHandler + userEventTriggered 활용&lt;/h2&gt;
&lt;p data-end=&quot;1645&quot; data-start=&quot;1496&quot; data-ke-size=&quot;size16&quot;&gt;총 길이를 알 수 없는 메시지를 다룰 때는 &lt;b&gt;연결 유휴 상태(Idle)를 기반으로 메시지 수신 완료를 판단&lt;/b&gt;하는 방식이 유효합니다.&lt;br /&gt;이를 위해 Netty에서는 IdleStateHandler와 userEventTriggered를 함께 사용할 수 있습니다.&lt;/p&gt;
&lt;h3 data-end=&quot;1671&quot; data-start=&quot;1647&quot; data-ke-size=&quot;size23&quot;&gt;userEventTriggered란?&lt;/h3&gt;
&lt;p data-end=&quot;1804&quot; data-start=&quot;1673&quot; data-ke-size=&quot;size16&quot;&gt;Netty의 ChannelInboundHandler에는 userEventTriggered라는 메서드가 있습니다.&lt;br /&gt;이 메서드는 일반적인 읽기/쓰기 이벤트가 아닌 &lt;b&gt;프레임워크나 사용자 정의 이벤트&lt;/b&gt;를 처리하는 데 사용됩니다.&lt;/p&gt;
&lt;pre id=&quot;code_1744853864520&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;@Override
public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
    // 사용자 정의 이벤트 처리
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-end=&quot;1804&quot; data-start=&quot;1673&quot; data-ke-size=&quot;size16&quot;&gt;ctx.fireUserEventTriggered(event) 형태로 파이프라인을 따라 이벤트가 전달됩니다.&lt;/p&gt;
&lt;p data-end=&quot;1804&quot; data-start=&quot;1673&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-end=&quot;2039&quot; data-start=&quot;2009&quot; data-ke-size=&quot;size26&quot;&gt;IdleStateHandler로 타임아웃 감지하기&lt;/h2&gt;
&lt;p data-end=&quot;2121&quot; data-start=&quot;2041&quot; data-ke-size=&quot;size16&quot;&gt;Netty의 IdleStateHandler는 지정한 시간 동안 &lt;b&gt;읽기/쓰기 이벤트가 없을 경우&lt;/b&gt; 자동으로 idle 이벤트를 발생시킵니다.&lt;/p&gt;
&lt;pre id=&quot;code_1744853883559&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;pipeline.addLast(new IdleStateHandler(10, 0, 0, TimeUnit.SECONDS)); 
pipeline.addLast(new MyIdleHandler());&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_1744853899696&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public IdleStateHandler(
    long readerIdleTime,
    long writerIdleTime,
    long allIdleTime,
    TimeUnit unit
)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;2446&quot; data-start=&quot;2387&quot;&gt;readerIdleTime: 지정 시간 동안 &lt;b&gt;읽기 없음&lt;/b&gt; &amp;rarr; READER_IDLE 발생&lt;/li&gt;
&lt;li data-end=&quot;2506&quot; data-start=&quot;2447&quot;&gt;writerIdleTime: 지정 시간 동안 &lt;b&gt;쓰기 없음&lt;/b&gt; &amp;rarr; WRITER_IDLE 발생&lt;/li&gt;
&lt;li data-end=&quot;2557&quot; data-start=&quot;2507&quot;&gt;allIdleTime: 읽기/쓰기 &lt;b&gt;모두 없음&lt;/b&gt; &amp;rarr; ALL_IDLE 발생&lt;/li&gt;
&lt;li data-end=&quot;2597&quot; data-start=&quot;2558&quot;&gt;unit: 시간 단위 (예: TimeUnit.SECONDS)&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1744853915463&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public class MyIdleHandler extends ChannelInboundHandlerAdapter {

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) {
        // 데이터 수신 시 Idle 타이머 재설정 가능
        // pipeline에서 IdleStateHandler는 처음부터 설정되어 있어야 함
        ... 메시지 적재 ...
    }

    @Override
    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
        if (evt instanceof IdleStateEvent) {
            IdleStateEvent e = (IdleStateEvent) evt;
            if (e.state() == IdleState.READER_IDLE) {
                System.out.println(&quot;10초 동안 읽기 없음 &amp;rarr; 메시지 수신 완료로 간주&quot;);
                ... 메시지 처리 로직 ...
                ctx.close(); // 연결 종료
            }
        } else {
            super.userEventTriggered(ctx, evt);
        }
    }
}&lt;/code&gt;&lt;/pre&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;h2 data-end=&quot;3405&quot; data-start=&quot;3400&quot; data-ke-size=&quot;size26&quot;&gt;정리&lt;/h2&gt;
&lt;p data-end=&quot;3549&quot; data-start=&quot;3407&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;클라이언트 측에서 스트림 형태로 데이터를 전송&lt;/b&gt;할 때,&lt;br /&gt;특정 시간(예: 10초) 동안 추가 데이터가 수신되지 않는다면 더 이상 전송할 메시지가 없는 것으로 간주하고&lt;br /&gt;수신 완료 후 후속 처리 로직을 진행하는 방식으로 문제를 해결할 수 있습니다.&lt;/p&gt;
&lt;p data-end=&quot;3641&quot; data-start=&quot;3551&quot; data-ke-size=&quot;size16&quot;&gt;이러한 방식은 프레이밍 조건을 정의하기 어려운 통신 환경에서 유용하며,&lt;br /&gt;Netty의 유휴 감지 기능을 적절히 활용하면 안정적인 데이터 수신 처리가 가능합니다.&lt;/p&gt;</description>
      <category>JAVA</category>
      <category>framing</category>
      <category>idlestatehandler</category>
      <category>Java</category>
      <category>Netty</category>
      <category>NIO</category>
      <category>usereventtriggered</category>
      <category>가변길이</category>
      <category>고정길이</category>
      <category>메시지</category>
      <category>스트림</category>
      <author>jckim</author>
      <guid isPermaLink="true">https://jckim-dev.tistory.com/57</guid>
      <comments>https://jckim-dev.tistory.com/entry/Netty%EC%97%90%EC%84%9C-%EC%B4%9D-%EA%B8%B8%EC%9D%B4%EB%A5%BC-%EC%95%8C-%EC%88%98-%EC%97%86%EB%8A%94-%EB%8D%B0%EC%9D%B4%ED%84%B0-%EC%88%98%EC%8B%A0-%EC%B2%98%EB%A6%AC-%EC%A0%84%EB%9E%B5#entry57comment</comments>
      <pubDate>Thu, 17 Apr 2025 10:41:33 +0900</pubDate>
    </item>
    <item>
      <title>Resin 서버에서 MultipartFile 호환성 이슈 및 해결 과정</title>
      <link>https://jckim-dev.tistory.com/entry/Resin-%EC%84%9C%EB%B2%84%EC%97%90%EC%84%9C-MultipartFile-%ED%98%B8%ED%99%98%EC%84%B1-%EC%9D%B4%EC%8A%88-%EB%B0%8F-%ED%95%B4%EA%B2%B0-%EA%B3%BC%EC%A0%95</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;1. 개요 &lt;br /&gt;로컬&amp;nbsp;환경은&amp;nbsp;Spring&amp;nbsp;Framework와&amp;nbsp;Tomcat&amp;nbsp;서버를&amp;nbsp;기반으로&amp;nbsp;개발되어&amp;nbsp;있었으며,&amp;nbsp;파일&amp;nbsp;업로드&amp;nbsp;기능은&amp;nbsp;MultipartFile을&amp;nbsp;활용하여&amp;nbsp;구현되어&amp;nbsp;있었다. &lt;br /&gt;프로젝트의&amp;nbsp;서버&amp;nbsp;환경의&amp;nbsp;경우&amp;nbsp;WAS(Web&amp;nbsp;Application&amp;nbsp;Server)를&amp;nbsp;Tomcat이&amp;nbsp;아닌&amp;nbsp;Resin을&amp;nbsp;사용하는&amp;nbsp;것을&amp;nbsp;뒤늦게&amp;nbsp;확인하였고 &lt;br /&gt;이&amp;nbsp;과정에서&amp;nbsp;파일&amp;nbsp;업로드&amp;nbsp;기능에&amp;nbsp;문제가&amp;nbsp;발생하였다. &lt;br /&gt;&lt;br /&gt;2.&amp;nbsp;문제&amp;nbsp;상황 &lt;br /&gt;Resin&amp;nbsp;서버로&amp;nbsp;이관&amp;nbsp;후,&amp;nbsp;클라이언트에서&amp;nbsp;전송한&amp;nbsp;파일이&amp;nbsp;서버에서&amp;nbsp;MultipartFile&amp;nbsp;객체로&amp;nbsp;정상적으로&amp;nbsp;매핑되지&amp;nbsp;않거나, &lt;br /&gt;transferTo()&amp;nbsp;호출&amp;nbsp;시&amp;nbsp;내부적으로&amp;nbsp;발생하는&amp;nbsp;권한/호환성&amp;nbsp;오류로&amp;nbsp;인해&amp;nbsp;업로드가&amp;nbsp;실패하였다. &lt;br /&gt;대표적인&amp;nbsp;예외&amp;nbsp;메시지는&amp;nbsp;다음과&amp;nbsp;같았다. &lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1743410136560&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;java.lang.NullPointerException : null
at cohttp://m.caucho.server.http.MultipartRequest$PartImpl.write(AbstractCauchoRequest.java:xxxx)
at org.springframework.web.multipart.support.StandardMultipartHttpServletRequest$StandardMultipartFile.transferTo(StandardMultipartHttpServletRequest.java:xxx)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;br /&gt;3.&amp;nbsp;원인&amp;nbsp;분석 &lt;br /&gt;&lt;br /&gt;Resin&amp;nbsp;서버가&amp;nbsp;multipart&amp;nbsp;처리&amp;nbsp;과정에서&amp;nbsp;자체적으로&amp;nbsp;파일을&amp;nbsp;기록하려&amp;nbsp;할&amp;nbsp;때&amp;nbsp;문제가&amp;nbsp;발생. &lt;br /&gt;&lt;br /&gt;이는&amp;nbsp;Resin&amp;nbsp;내부의&amp;nbsp;가상&amp;nbsp;파일&amp;nbsp;시스템(VFS)&amp;nbsp;처리&amp;nbsp;방식과&amp;nbsp;Spring의&amp;nbsp;Multipart&amp;nbsp;처리&amp;nbsp;방식이&amp;nbsp;충돌한&amp;nbsp;것으로&amp;nbsp;보여짐. &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;* Resin 의 버전별로 MultipartFile.transferTo() 호환여부 &lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; Resin 4.0.65 및 이전 버전: 호환되지 않음 &lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; Resin 4.0.66 이후 버전: 호환 &lt;br /&gt;&lt;br /&gt;4.&amp;nbsp;해결&amp;nbsp;방안 &lt;br /&gt;transferTo()&amp;nbsp;대신&amp;nbsp;FileOutputStream을&amp;nbsp;사용하여&amp;nbsp;업로드된&amp;nbsp;파일의&amp;nbsp;바이트를&amp;nbsp;직접&amp;nbsp;저장하는&amp;nbsp;방식으로&amp;nbsp;변경함으로써&amp;nbsp;문제를&amp;nbsp;해결 &lt;br /&gt;&lt;br /&gt;5. 적용 코드&lt;br /&gt;기존&amp;nbsp;소스코드 &lt;/p&gt;
&lt;pre id=&quot;code_1743410167864&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;@PostMapping(&quot;/upload&quot;)
public String handleFileUpload(@RequestParam(&quot;file&quot;) MultipartFile file) {
    if (file.isEmpty()) {
        return &quot;업로드할 파일을 선택해주세요.&quot;;
    }

    try {
        // 저장할 경로 설정
        String uploadDir = &quot;/data/uploads/&quot;;
        String filePath = uploadDir + file.getOriginalFilename();

        // 디렉토리 없을 경우 생성
        File dir = new File(uploadDir);
        if (!dir.exists()) dir.mkdirs();

//MultipartFile의 transferTo 사용
       file.transferTo(filePath);

        return &quot;업로드 성공: &quot; + file.getOriginalFilename();
    } catch (IOException e) {
        e.printStackTrace();
        return &quot;업로드 실패: &quot; + e.getMessage();
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;br /&gt;해결&amp;nbsp;소스코드 &lt;/p&gt;
&lt;pre id=&quot;code_1743410186135&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;@PostMapping(&quot;/upload&quot;)
public String handleFileUpload(@RequestParam(&quot;file&quot;) MultipartFile file) {
    if (file.isEmpty()) {
        return &quot;업로드할 파일을 선택해주세요.&quot;;
    }

    try {
        // 저장할 경로 설정
        String uploadDir = &quot;/data/uploads/&quot;;
        String filePath = uploadDir + file.getOriginalFilename();

        // 디렉토리 없을 경우 생성
        File dir = new File(uploadDir);
        if (!dir.exists()) dir.mkdirs();

        // FileOutputStream을 통한 수동 저장
        try (FileOutputStream fos = new FileOutputStream(filePath)) {
            fos.write(file.getBytes());
        }

        return &quot;업로드 성공: &quot; + file.getOriginalFilename();
    } catch (IOException e) {
        e.printStackTrace();
        return &quot;업로드 실패: &quot; + e.getMessage();
    }
}&lt;/code&gt;&lt;/pre&gt;</description>
      <category>server</category>
      <category>abstractcauchorequest</category>
      <category>caucho</category>
      <category>Java</category>
      <category>multipartfile</category>
      <category>NullPointerException</category>
      <category>resin</category>
      <category>standardmultiparthttpservletrequest</category>
      <category>tomcat</category>
      <category>transferTo</category>
      <author>jckim</author>
      <guid isPermaLink="true">https://jckim-dev.tistory.com/56</guid>
      <comments>https://jckim-dev.tistory.com/entry/Resin-%EC%84%9C%EB%B2%84%EC%97%90%EC%84%9C-MultipartFile-%ED%98%B8%ED%99%98%EC%84%B1-%EC%9D%B4%EC%8A%88-%EB%B0%8F-%ED%95%B4%EA%B2%B0-%EA%B3%BC%EC%A0%95#entry56comment</comments>
      <pubDate>Mon, 31 Mar 2025 17:37:48 +0900</pubDate>
    </item>
    <item>
      <title>PostgreSQL MyBatis &amp;quot;invalid input syntax for type numeric&amp;quot; 오류 해결</title>
      <link>https://jckim-dev.tistory.com/entry/PostgreSQL-MyBatis-invalid-input-syntax-for-type-numeric-%EC%98%A4%EB%A5%98-%ED%95%B4%EA%B2%B0</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;1.&amp;nbsp;오류&amp;nbsp;개요 &lt;br /&gt;&lt;br /&gt;PostgreSQL과&amp;nbsp;MyBatis를&amp;nbsp;사용하여&amp;nbsp;데이터베이스&amp;nbsp;작업을&amp;nbsp;수행하는&amp;nbsp;중&amp;nbsp;&quot;invalid&amp;nbsp;input&amp;nbsp;syntax&amp;nbsp;for&amp;nbsp;type&amp;nbsp;numeric&quot;&amp;nbsp;오류가&amp;nbsp;발생하였다. &lt;br /&gt;&lt;br /&gt;2.&amp;nbsp;오류&amp;nbsp;발생&amp;nbsp;위치&amp;nbsp;및&amp;nbsp;원인&amp;nbsp;분석 &lt;br /&gt;&lt;br /&gt;2.1&amp;nbsp;오류&amp;nbsp;발생&amp;nbsp;위치 &lt;br /&gt;&lt;br /&gt;오류가&amp;nbsp;발생한&amp;nbsp;위치는&amp;nbsp;MyBatis&amp;nbsp;SQL을&amp;nbsp;선언한&amp;nbsp;XML&amp;nbsp;파일&amp;nbsp;내의&amp;nbsp;쿼리에서&amp;nbsp;확인되었다. &lt;br /&gt;&lt;br /&gt;문제&amp;nbsp;발생&amp;nbsp;쿼리&amp;nbsp;(일부) &lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1742979172628&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;update test_table
set num = nullif(#{paramNum}, '')::numeric
where id = #{id}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;br /&gt;2.2&amp;nbsp;오류&amp;nbsp;메시지&amp;nbsp;및&amp;nbsp;원인&amp;nbsp;분석 &lt;br /&gt;&lt;br /&gt;오류&amp;nbsp;메시지:&amp;nbsp;invalid&amp;nbsp;input&amp;nbsp;syntax&amp;nbsp;for&amp;nbsp;type&amp;nbsp;numeric&amp;nbsp;:&amp;nbsp;&quot;&quot; &lt;br /&gt;&lt;br /&gt;파라미터&amp;nbsp;paramNum이&amp;nbsp;빈&amp;nbsp;문자열&amp;nbsp;('')로&amp;nbsp;전달되는&amp;nbsp;경우&amp;nbsp;발생 &lt;br /&gt;&lt;br /&gt;이미&amp;nbsp;nullif(파라미터,&amp;nbsp;'')&amp;nbsp;함수를&amp;nbsp;사용하여&amp;nbsp;빈&amp;nbsp;문자열을&amp;nbsp;NULL로&amp;nbsp;변환하는&amp;nbsp;처리&amp;nbsp;적용 &lt;br /&gt;&lt;br /&gt;그러나,&amp;nbsp;동일한&amp;nbsp;SQL&amp;nbsp;문&amp;nbsp;내의&amp;nbsp;INSERT&amp;nbsp;문에서&amp;nbsp;nullif&amp;nbsp;처리가&amp;nbsp;누락된&amp;nbsp;것이&amp;nbsp;원인으로&amp;nbsp;확인됨 &lt;br /&gt;&lt;br /&gt;3.&amp;nbsp;상세&amp;nbsp;분석 &lt;br /&gt;&lt;br /&gt;PostgreSQL은&amp;nbsp;Oracle의&amp;nbsp;MERGE&amp;nbsp;INTO&amp;nbsp;구문을&amp;nbsp;지원하지&amp;nbsp;않기&amp;nbsp;때문에&amp;nbsp;UPSERT&amp;nbsp;방식으로&amp;nbsp;데이터를&amp;nbsp;갱신한다.&amp;nbsp;해당&amp;nbsp;코드에서&amp;nbsp;다음과&amp;nbsp;같은&amp;nbsp;WITH&amp;nbsp;upsert&amp;nbsp;구문이&amp;nbsp;사용되었다. &lt;br /&gt;&lt;br /&gt;쿼리&amp;nbsp;내용&amp;nbsp;(상세) &lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1742979183140&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;WITH upsert AS (
    UPDATE test_table
    SET num = nullif(#{paramNum}, '')::numeric
    WHERE id = #{id}
)

INSERT INTO test_table (num, id)
SELECT #{paramNum}::numeric, #{id}
WHERE NOT EXISTS (SELECT * FROM upsert)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;3.1&amp;nbsp;문제&amp;nbsp;발생&amp;nbsp;원인 &lt;br /&gt;&lt;br /&gt;UPDATE&amp;nbsp;문에서는&amp;nbsp;nullif(#{paramNum},&amp;nbsp;'')::numeric&amp;nbsp;처리를&amp;nbsp;적용하여&amp;nbsp;빈&amp;nbsp;문자열('')이&amp;nbsp;NULL로&amp;nbsp;변환됨. &lt;br /&gt;&lt;br /&gt;그러나&amp;nbsp;INSERT&amp;nbsp;문에서는&amp;nbsp;#{paramNum}::numeric로&amp;nbsp;직접&amp;nbsp;변환을&amp;nbsp;수행하면서&amp;nbsp;빈&amp;nbsp;문자열('')이&amp;nbsp;numeric&amp;nbsp;타입으로&amp;nbsp;캐스팅될&amp;nbsp;때&amp;nbsp;오류&amp;nbsp;발생. &lt;br /&gt;&lt;br /&gt;MyBatis는&amp;nbsp;쿼리를&amp;nbsp;한&amp;nbsp;줄씩&amp;nbsp;검증하며&amp;nbsp;실행하므로,&amp;nbsp;조건문&amp;nbsp;없이&amp;nbsp;그대로&amp;nbsp;INSERT&amp;nbsp;문이&amp;nbsp;생성되면서&amp;nbsp;오류가&amp;nbsp;발생함. &lt;br /&gt;&lt;br /&gt;&amp;lt;if&amp;nbsp;test=&quot;&quot;&amp;gt;&amp;nbsp;구문을&amp;nbsp;사용하여&amp;nbsp;실행&amp;nbsp;여부를&amp;nbsp;제어하면,&amp;nbsp;동일한&amp;nbsp;상황에서&amp;nbsp;오류를&amp;nbsp;방지할&amp;nbsp;수&amp;nbsp;있음. &lt;br /&gt;&lt;br /&gt;4.&amp;nbsp;해결&amp;nbsp;방법 &lt;br /&gt;&lt;br /&gt;4.1&amp;nbsp;INSERT&amp;nbsp;문에서도&amp;nbsp;nullif&amp;nbsp;적용 &lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1742979202268&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;INSERT INTO test_table (num, id)
SELECT nullif(#{paramNum}, '')::numeric, #{id}
WHERE NOT EXISTS (SELECT * FROM upsert)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;br /&gt;4.2&amp;nbsp;&amp;lt;if&amp;nbsp;test=&quot;&quot;&amp;gt;&amp;nbsp;적용하여&amp;nbsp;조건부&amp;nbsp;실행 &lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1742979210860&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;if test=&quot;paramNum != null and paramNum != ''&quot;&amp;gt;
    INSERT INTO test_table (num, id)
    SELECT #{paramNum}::numeric, #{id}
    WHERE NOT EXISTS (SELECT * FROM upsert)
&amp;lt;/if&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;br /&gt;5.&amp;nbsp;결론 &lt;br /&gt;&lt;br /&gt;numeric&amp;nbsp;타입의&amp;nbsp;컬럼에&amp;nbsp;빈&amp;nbsp;문자열이&amp;nbsp;입력되면&amp;nbsp;invalid&amp;nbsp;input&amp;nbsp;syntax&amp;nbsp;for&amp;nbsp;type&amp;nbsp;numeric&amp;nbsp;오류가&amp;nbsp;발생할&amp;nbsp;수&amp;nbsp;있음. &lt;br /&gt;&lt;br /&gt;nullif(#{paramNum},&amp;nbsp;'')::numeric&amp;nbsp;함수를&amp;nbsp;UPDATE뿐만&amp;nbsp;아니라&amp;nbsp;INSERT에도&amp;nbsp;적용하여&amp;nbsp;해결&amp;nbsp;가능. &lt;br /&gt;&lt;br /&gt;&amp;lt;if&amp;nbsp;test=&quot;&quot;&amp;gt;&amp;nbsp;구문을&amp;nbsp;활용하여&amp;nbsp;빈&amp;nbsp;문자열&amp;nbsp;입력&amp;nbsp;시&amp;nbsp;INSERT&amp;nbsp;문이&amp;nbsp;생성되지&amp;nbsp;않도록&amp;nbsp;제어&amp;nbsp;가능. &lt;br /&gt;&lt;br /&gt;해당&amp;nbsp;방식&amp;nbsp;적용&amp;nbsp;후&amp;nbsp;동일한&amp;nbsp;오류가&amp;nbsp;발생하지&amp;nbsp;않음을&amp;nbsp;확인함.&lt;/p&gt;</description>
      <category>DB</category>
      <category>invalid input syntax for type numeric</category>
      <category>mybatis</category>
      <category>NULLIF</category>
      <category>Numeric</category>
      <category>PostgreSQL</category>
      <author>jckim</author>
      <guid isPermaLink="true">https://jckim-dev.tistory.com/55</guid>
      <comments>https://jckim-dev.tistory.com/entry/PostgreSQL-MyBatis-invalid-input-syntax-for-type-numeric-%EC%98%A4%EB%A5%98-%ED%95%B4%EA%B2%B0#entry55comment</comments>
      <pubDate>Wed, 26 Mar 2025 17:54:41 +0900</pubDate>
    </item>
    <item>
      <title>[java] jdom xPath 호출 시 멈춤 현상 해결</title>
      <link>https://jckim-dev.tistory.com/entry/java-jdom-xPath-%ED%98%B8%EC%B6%9C-%EC%8B%9C-%EB%A9%88%EC%B6%A4-%ED%98%84%EC%83%81-%ED%95%B4%EA%B2%B0</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;jdom의&amp;nbsp;xPath&amp;nbsp;기능을&amp;nbsp;활용하여 &lt;br /&gt;xml&amp;nbsp;전문&amp;nbsp;내에서&amp;nbsp;특정&amp;nbsp;항목의&amp;nbsp;값을&amp;nbsp;추출하려 하였으나 &lt;br /&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;사용하고 있는 xPath 관련 코드는 아래와 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1728628645621&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;Document documentData

selectElement = (Element)XPath.selectSingleNode(documentData,pm_sPath);&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;XPath&amp;nbsp;class&amp;nbsp;정의를&amp;nbsp;보기&amp;nbsp;위해&amp;nbsp;declaration&amp;nbsp;open을&amp;nbsp;해보았을 때&amp;nbsp;jdom.jar&amp;nbsp;내에&amp;nbsp;있다고&amp;nbsp;확인되었고 &lt;br /&gt;해당&amp;nbsp;메소드를&amp;nbsp;사용하는&amp;nbsp;소스상에도&lt;/p&gt;
&lt;pre id=&quot;code_1728628691708&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import org.jdom.xpath.XPath;&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;import&amp;nbsp;정보를&amp;nbsp;확인할&amp;nbsp;수&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;p data-ke-size=&quot;size16&quot;&gt;jdom.jar에서&amp;nbsp;해당&amp;nbsp;메서드를&amp;nbsp;호출하는&amp;nbsp;소스를&amp;nbsp;디컴파일&amp;nbsp;해보았음. &lt;br /&gt;&lt;br /&gt;XPath.class의&amp;nbsp;일부&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1728628730140&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;  public static Object selectSingleNode(Object context, String path)
    throws JDOMException
  {
    return newInstance(path).selectSingleNode(context);
  }&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;&amp;nbsp;newInstance&amp;nbsp;메소드에&amp;nbsp;path&amp;nbsp;매개변수를&amp;nbsp;활용하여&amp;nbsp;selectSingleNode&amp;nbsp;메서드를&amp;nbsp;호출하는&amp;nbsp;것으로&amp;nbsp;보여 &lt;br /&gt;&amp;nbsp;&amp;nbsp;newInstance&amp;nbsp;메소드&amp;nbsp;로직을&amp;nbsp;먼저&amp;nbsp;확인&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1728628752670&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;  public static XPath newInstance(String path)
    throws JDOMException
  {
    try
    {
      if (constructor == null) {
        String className;
        try {
          className = System.getProperty(&quot;org.jdom.xpath.class&quot;, &quot;org.jdom.xpath.JaxenXPath&quot;);
        }
        catch (SecurityException ex1)
        {
          className = &quot;org.jdom.xpath.JaxenXPath&quot;;
        }
        setXPathClass(Class.forName(className));
      }

      return (XPath)constructor.newInstance(new Object[] { path });
    }
    catch (JDOMException ex1) {
      throw ex1;
    }
    catch (InvocationTargetException ex2)
    {
      Throwable t = ex2.getTargetException();

      throw ((t instanceof JDOMException) ? (JDOMException)t : new JDOMException(t.toString(), t));
    }
    catch (Exception ex3)
    {
    }
    throw new JDOMException(ex3.toString(), ex3);
  }&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;System.getProperty(&quot;org.jdom.xpath.class&quot;,&amp;nbsp;&quot;org.jdom.xpath.JaxenXPath&quot;);&lt;/b&gt;&lt;br /&gt;&lt;b&gt;으로&amp;nbsp;시스템&amp;nbsp;등록정보의&amp;nbsp;값을&amp;nbsp;className로&amp;nbsp;선언하는데 &lt;/b&gt;&lt;br /&gt;&lt;b&gt;위처럼 getProperty 내 매개변수가 2개인 경우 &quot;org.jdom.xpath.class&quot;&amp;nbsp;시스템&amp;nbsp;등록정보가&amp;nbsp;없는&amp;nbsp;경우&amp;nbsp;&quot;org.jdom.xpath.JaxenXPath&quot;라는&amp;nbsp;값으로&amp;nbsp;기본값으로&amp;nbsp;가져오는&amp;nbsp;기능이다. &lt;/b&gt;&lt;br /&gt;&lt;b&gt;작업 중인 시스템은 &quot;org.jdom.xpath.class&quot;에&amp;nbsp;대한&amp;nbsp;시스템&amp;nbsp;등록정보&amp;nbsp;선언이&amp;nbsp;없기&amp;nbsp;때문에&amp;nbsp;className은&amp;nbsp;&quot;org.jdom.xpath.JaxenXPath&quot;이&amp;nbsp;된다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;동일한&amp;nbsp;jdom.jar에&amp;nbsp;&quot;org.jdom.xpath.JaxenXPath&quot;&amp;nbsp;class가&amp;nbsp;존재하여&amp;nbsp;확인함. &lt;br /&gt;해당&amp;nbsp;class에서&amp;nbsp;XPath.selectSingleNode&amp;nbsp;기능을&amp;nbsp;호출하는&amp;nbsp;메서드를&amp;nbsp;확인하였음.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1728628970021&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;class JaxenXPath extends XPath
	
	private transient JDOMXPath xPath;
	
	  public Object selectSingleNode(Object context)
    throws JDOMException
  {
    try
    {
      this.currentContext = context;

      Object localObject1 = this.xPath.selectSingleNode(context);
      return localObject1;
    }
    catch (JaxenException ex1)
    {
      throw new JDOMException(&quot;XPath error while evaluating \&quot;&quot; + this.xPath.toString() + &quot;\&quot;: &quot; + ex1.getMessage(), ex1);
    }
    finally
    {
      this.currentContext = null; } throw localObject2;
  }&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;소스에서는&amp;nbsp;&quot;this.xPath.selectSingleNode&quot;&amp;nbsp;부분이&amp;nbsp;주요&amp;nbsp;로직인데&amp;nbsp;xPath로&amp;nbsp;선언된&amp;nbsp;JDOMXPath&amp;nbsp;class를&amp;nbsp;확인해&amp;nbsp;보고자&amp;nbsp;해당&amp;nbsp;class를&amp;nbsp;조회해&amp;nbsp;보았으나&amp;nbsp;class&amp;nbsp;파일을&amp;nbsp;확인할&amp;nbsp;수&amp;nbsp;없었다. &lt;br /&gt;&lt;br /&gt;JDOMXPath&amp;nbsp;class를&amp;nbsp;import&amp;nbsp;하는&amp;nbsp;부분을&amp;nbsp;확인해보았다. &lt;br /&gt;&lt;br /&gt;JaxenXPath&amp;nbsp;class에서&amp;nbsp;import&amp;nbsp;하고&amp;nbsp;있는&amp;nbsp;목록이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1728628994493&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;package org.jdom.xpath;

import java.util.List;
import org.jaxen.JaxenException;
import org.jaxen.SimpleNamespaceContext;
import org.jaxen.SimpleVariableContext;
import org.jaxen.jdom.JDOMXPath;
import org.jdom.Attribute;
import org.jdom.Content;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.Namespace;&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.jaxen&amp;nbsp;이라는&amp;nbsp;패키지&amp;nbsp;경로를&amp;nbsp;가리키고&amp;nbsp;있지만&amp;nbsp;jdom.jar&amp;nbsp;및&amp;nbsp;프로젝트에서&amp;nbsp;해당&amp;nbsp;소스를&amp;nbsp;볼&amp;nbsp;수&amp;nbsp;있는&amp;nbsp;경로는&amp;nbsp;확인할&amp;nbsp;수&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;p data-ke-size=&quot;size16&quot;&gt;확인해 본&amp;nbsp;결과&amp;nbsp;jaxen.jar를&amp;nbsp;별도로&amp;nbsp;추가하여&amp;nbsp;xPath&amp;nbsp;기능을&amp;nbsp;사용하는&amp;nbsp;방법이&amp;nbsp;잘&amp;nbsp;알려져&amp;nbsp;있었음. &lt;br /&gt;&lt;br /&gt;j&lt;b&gt;axen.jar&amp;nbsp;파일을&amp;nbsp;추가&lt;/b&gt;하여&amp;nbsp;서버&amp;nbsp;재기동을&amp;nbsp;해본&amp;nbsp;결과&amp;nbsp;정상적으로&amp;nbsp;동작하는&amp;nbsp;것을&amp;nbsp;확인함. &lt;br /&gt;&lt;br /&gt;jdom에서&amp;nbsp;xPath&amp;nbsp;기능을&amp;nbsp;사용하고자&amp;nbsp;하는&amp;nbsp;경우&amp;nbsp;아래&amp;nbsp;라이브러리&amp;nbsp;파일&amp;nbsp;2개를&amp;nbsp;함께&amp;nbsp;추가해주어야&amp;nbsp;함. &lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;jdom.jar,&amp;nbsp;jaxen.jar&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;</description>
      <category>JAVA</category>
      <category>Java</category>
      <category>jaxen</category>
      <category>jdom</category>
      <category>parse</category>
      <category>XML</category>
      <category>XPath</category>
      <author>jckim</author>
      <guid isPermaLink="true">https://jckim-dev.tistory.com/54</guid>
      <comments>https://jckim-dev.tistory.com/entry/java-jdom-xPath-%ED%98%B8%EC%B6%9C-%EC%8B%9C-%EB%A9%88%EC%B6%A4-%ED%98%84%EC%83%81-%ED%95%B4%EA%B2%B0#entry54comment</comments>
      <pubDate>Fri, 11 Oct 2024 15:47:57 +0900</pubDate>
    </item>
    <item>
      <title>[java] 인코딩이 다른 시스템간 byte 데이터 주고받기</title>
      <link>https://jckim-dev.tistory.com/entry/java-%EC%9D%B8%EC%BD%94%EB%94%A9%EC%9D%B4-%EB%8B%A4%EB%A5%B8-%EC%8B%9C%EC%8A%A4%ED%85%9C%EA%B0%84-byte-%EB%8D%B0%EC%9D%B4%ED%84%B0-%EC%A3%BC%EA%B3%A0%EB%B0%9B%EA%B8%B0</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;서로&amp;nbsp;다른&amp;nbsp;시스템&amp;nbsp;간&amp;nbsp;byte&amp;nbsp;데이터를&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;&lt;b&gt;조건&lt;/b&gt; &lt;br /&gt;1.byte&amp;nbsp;데이터를&amp;nbsp;String형으로&amp;nbsp;송수신 &lt;br /&gt;2.시스템간&amp;nbsp;인스턴스&amp;nbsp;문자&amp;nbsp;인코딩(UTF-8,&amp;nbsp;EUC-KR&amp;nbsp;등)이&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;p data-ke-size=&quot;size16&quot;&gt;바이트&amp;nbsp;데이터&amp;nbsp;추출하기&lt;/p&gt;
&lt;pre id=&quot;code_1727340559092&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;    	System.out.println(&quot;===현재 프로젝트 문자 인코딩 UTF-8===&quot;);
    	System.out.println(&quot;===byte 데이터 문자 인코딩 확인===&quot;);
    	String testStr = &quot;테스트&quot;;
		
		byte[] euckrByte = testStr.getBytes(&quot;EUC-KR&quot;);
		byte[] utf8Byte = testStr.getBytes(&quot;UTF-8&quot;);
		
		String euckrStrToUtf8 = new String(euckrByte,&quot;UTF-8&quot;);
		String utf8StrToUtf8 = new String(utf8Byte,&quot;UTF-8&quot;);
		
		String euckrStrToEuckr = new String(euckrByte,&quot;EUC-KR&quot;);
		String utf8StrToEuckr = new String(utf8Byte,&quot;EUC-KR&quot;);
		
		System.out.println(&quot;수신인코딩 &amp;gt;&amp;gt; 디코딩 : 결과&quot;);
		System.out.println(&quot;euckr &amp;gt;&amp;gt; utf8 : &quot; + euckrStrToUtf8);
		System.out.println(&quot;utf8 &amp;gt;&amp;gt; utf8 : &quot; + utf8StrToUtf8);
		System.out.println(&quot;euckr &amp;gt;&amp;gt; euckr : &quot; + euckrStrToEuckr);
		System.out.println(&quot;utf8 &amp;gt;&amp;gt; euckr : &quot; + utf8StrToEuckr);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1727340573753&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;===현재 프로젝트 문자 인코딩 UTF-8===
===byte 데이터 문자 인코딩 확인===
수신인코딩 &amp;gt;&amp;gt; 디코딩 : 결과
euckr &amp;gt;&amp;gt; utf8 : �׽�Ʈ
utf8 &amp;gt;&amp;gt; utf8 : 테스트
euckr &amp;gt;&amp;gt; euckr : 테스트
utf8 &amp;gt;&amp;gt; euckr : ���ㅽ��&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;방식으로&amp;nbsp;바이트&amp;nbsp;데이터&amp;nbsp;추출하여&amp;nbsp;값을&amp;nbsp;확인할&amp;nbsp;수도&amp;nbsp;있지만&amp;nbsp;문자열로&amp;nbsp;전달이&amp;nbsp;필요하기에&amp;nbsp;추가&amp;nbsp;작업이&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;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;작업방법&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;byte[]을&amp;nbsp;전달하려면&amp;nbsp;해당&amp;nbsp;바이트&amp;nbsp;배열을&amp;nbsp;BASE64&amp;nbsp;인코딩하여&amp;nbsp;전달하는&amp;nbsp;방법이&amp;nbsp;있음. &lt;br /&gt;통신하는&amp;nbsp;두&amp;nbsp;시스템의&amp;nbsp;문자&amp;nbsp;인코딩이&amp;nbsp;다른&amp;nbsp;것이&amp;nbsp;우려될&amp;nbsp;수&amp;nbsp;있지만&amp;nbsp;BASE64을&amp;nbsp;사용하여&amp;nbsp;전달하면 &lt;br /&gt;수신받는&amp;nbsp;시스템에서도&amp;nbsp;동일한&amp;nbsp;문자&amp;nbsp;인코딩으로&amp;nbsp;디코딩하면&amp;nbsp;정상적으로&amp;nbsp;파싱이&amp;nbsp;가능하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1727340610736&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;    	System.out.println(&quot;===현재 프로젝트 인코딩 UTF-8===&quot;);
    	System.out.println(&quot;===byte 데이터 BASE64Encode 데이터 인코딩 확인===&quot;);
    	BASE64Encoder encoder = new BASE64Encoder();
    	BASE64Decoder decoder = new BASE64Decoder();
    	
    	String testStr = &quot;테스트&quot;;

    	byte[] euckrByte = testStr.getBytes(&quot;EUC-KR&quot;);
		byte[] utf8Byte = testStr.getBytes(&quot;UTF-8&quot;);
		
    	String euckrByteEncode = encoder.encodeBuffer(euckrByte);
    	String utf8ByteEncode = encoder.encodeBuffer(utf8Byte);
    	
    	System.out.println(&quot;===문자형으로 BASE64Encode된 바이트 데이터 수신===&quot;);
		
		String euckrStrToUtf8Encode = new String(euckrByteEncode);
		String utf8StrToUtf8Encode = new String(utf8ByteEncode);
		
		System.out.println(&quot;수신인코딩 &amp;gt;&amp;gt; 디코딩 : 결과&quot;);
		System.out.println(&quot;euckr &amp;gt;&amp;gt; utf8 : &quot; + euckrStrToUtf8Encode);
		System.out.println(&quot;utf8 &amp;gt;&amp;gt; utf8 : &quot; + utf8StrToUtf8Encode);
		System.out.println(&quot;euckr &amp;gt;&amp;gt; euckr : &quot; + &quot;불가&quot;);
		System.out.println(&quot;utf8 &amp;gt;&amp;gt; euckr : &quot; + &quot;불가&quot;);	

		//디코딩 하여 byte 형식으로 변환
		byte[] euckrByteDecode = decoder.decodeBuffer(euckrByteEncode);
		byte[] utf8ByteDecode = decoder.decodeBuffer(utf8ByteEncode);
		
		String euckrStrToUtf8 = new String(euckrByteDecode,&quot;UTF-8&quot;);
		String utf8StrToUtf8 = new String(utf8ByteDecode,&quot;UTF-8&quot;);
		
		String euckrStrToEuckr = new String(euckrByteDecode,&quot;EUC-KR&quot;);
		String utf8StrToEuckr = new String(utf8ByteDecode,&quot;EUC-KR&quot;);
		System.out.println(&quot;===문자형 데이터 BASE64Decode 후 문자 인코딩 변환===&quot;);		
		System.out.println(&quot;수신인코딩 &amp;gt;&amp;gt; 디코딩 : 결과&quot;);
		System.out.println(&quot;euckr &amp;gt;&amp;gt; utf8 : &quot; + euckrStrToUtf8);
		System.out.println(&quot;utf8 &amp;gt;&amp;gt; utf8 : &quot; + utf8StrToUtf8);
		System.out.println(&quot;euckr &amp;gt;&amp;gt; euckr : &quot; + euckrStrToEuckr);
		System.out.println(&quot;utf8 &amp;gt;&amp;gt; euckr : &quot; + utf8StrToEuckr);&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1727340635374&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;===현재 프로젝트 인코딩 UTF-8===
===byte 데이터 BASE64Encode 데이터 인코딩 확인===
===문자형으로 BASE64Encode된 바이트 데이터 수신===
수신인코딩 &amp;gt;&amp;gt; 디코딩 : 결과
euckr &amp;gt;&amp;gt; utf8 : xde9usau
utf8 &amp;gt;&amp;gt; utf8 : 7YWM7Iqk7Yq4
euckr &amp;gt;&amp;gt; euckr : 불가
utf8 &amp;gt;&amp;gt; euckr : 불가
===문자형 데이터 BASE64Decode 후 문자 인코딩 변환===
수신인코딩 &amp;gt;&amp;gt; 디코딩 : 결과
euckr &amp;gt;&amp;gt; utf8 : �׽�Ʈ
utf8 &amp;gt;&amp;gt; utf8 : 테스트
euckr &amp;gt;&amp;gt; euckr : 테스트
utf8 &amp;gt;&amp;gt; euckr : ���ㅽ��&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;결론&lt;/b&gt; &lt;br /&gt;통신할때&amp;nbsp;문자&amp;nbsp;인코딩(UTF-8,&amp;nbsp;EUC-KR&amp;nbsp;등)을&amp;nbsp;어떤 것으로&amp;nbsp;할&amp;nbsp;것인지&amp;nbsp;사전에&amp;nbsp;협의하여&amp;nbsp;동일한&amp;nbsp;문자&amp;nbsp;인코딩으로&amp;nbsp;BASE64&amp;nbsp;인코딩&amp;nbsp;디코딩을&amp;nbsp;하여&amp;nbsp;데이터&amp;nbsp;손실&amp;nbsp;없이&amp;nbsp;정상적으로&amp;nbsp;바이트&amp;nbsp;데이터를&amp;nbsp;송수신하여&amp;nbsp;처리할&amp;nbsp;수&amp;nbsp;있음.&lt;/p&gt;</description>
      <category>JAVA</category>
      <category>BASE64</category>
      <category>btye</category>
      <category>깨짐</category>
      <category>다름</category>
      <category>디코딩</category>
      <category>인코딩</category>
      <author>jckim</author>
      <guid isPermaLink="true">https://jckim-dev.tistory.com/53</guid>
      <comments>https://jckim-dev.tistory.com/entry/java-%EC%9D%B8%EC%BD%94%EB%94%A9%EC%9D%B4-%EB%8B%A4%EB%A5%B8-%EC%8B%9C%EC%8A%A4%ED%85%9C%EA%B0%84-byte-%EB%8D%B0%EC%9D%B4%ED%84%B0-%EC%A3%BC%EA%B3%A0%EB%B0%9B%EA%B8%B0#entry53comment</comments>
      <pubDate>Thu, 26 Sep 2024 17:52:06 +0900</pubDate>
    </item>
    <item>
      <title>Jquery append 시 연관없는 이벤트 발생 해결</title>
      <link>https://jckim-dev.tistory.com/entry/Jquery-append-%EC%8B%9C-%EC%97%B0%EA%B4%80%EC%97%86%EB%8A%94-%EC%9D%B4%EB%B2%A4%ED%8A%B8-%EB%B0%9C%EC%83%9D-%ED%95%B4%EA%B2%B0</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;HTML과 Jquery 활용한 화면 프론트 작업 중 발생한 문제이다. &lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;br /&gt;&lt;b&gt;문제&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;Jquery를 통하여 특정 영역에 html을 append 해주는 기능을 작업하던 중&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;서버에서&amp;nbsp;요청받은&amp;nbsp;데이터가&amp;nbsp;해당&amp;nbsp;기능&amp;nbsp;추가&amp;nbsp;전과&amp;nbsp;후의&amp;nbsp;차이가&amp;nbsp;확인되었음. &lt;br /&gt;&lt;br /&gt;설명을 위해 필요한 부분만 작성한 html 코드 예시&lt;/p&gt;
&lt;pre id=&quot;code_1719363660352&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;form&amp;gt;
    &amp;lt;div id=&quot;baseInfo&quot; style=&quot;display:none;&quot;&amp;gt;
        &amp;lt;input type=&quot;text&quot; name=&quot;testName&quot; id=&quot;testName&quot;/&amp;gt;
        &amp;lt;input type=&quot;password&quot; name=&quot;testNumber&quot; id=&quot;testNumber&quot; onblur=&quot;testFunc();&quot;/&amp;gt;
    &amp;lt;/div&amp;gt;

    &amp;lt;div id=&quot;testArea&quot;&amp;gt;
    &amp;lt;/div&amp;gt;
&amp;lt;/form&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;br /&gt;우선&amp;nbsp;결과&amp;nbsp;데이터를&amp;nbsp;기준으로&amp;nbsp;비교&amp;nbsp;결과&amp;nbsp;testFunc()&amp;nbsp;함수가&amp;nbsp;실행된&amp;nbsp;결과임을&amp;nbsp;알&amp;nbsp;수&amp;nbsp;있었음. &lt;br /&gt;&lt;br /&gt;다만&amp;nbsp;해당&amp;nbsp;함수&amp;nbsp;위치한&amp;nbsp;영역은&amp;nbsp;숨겨져&amp;nbsp;있으며&amp;nbsp;특정조건에&amp;nbsp;일치하는&amp;nbsp;경우에&amp;nbsp;대해서만&amp;nbsp;표출해주고&amp;nbsp;있는&amp;nbsp;형태이다. &lt;br /&gt;&lt;br /&gt;함수가&amp;nbsp;실행되기&amp;nbsp;위해서는&amp;nbsp;onblur&amp;nbsp;이벤트가&amp;nbsp;발생해야함. &lt;br /&gt;&lt;br /&gt;하지만&amp;nbsp;테스트한&amp;nbsp;케이스는&amp;nbsp;해당&amp;nbsp;영역이&amp;nbsp;표출되어있지&amp;nbsp;않음. &lt;br /&gt;&lt;br /&gt;append&amp;nbsp;시&amp;nbsp;사용하는&amp;nbsp;Jquery&amp;nbsp;소스코드 &lt;br /&gt;$('#testArea').append(&quot;&amp;lt;input&amp;nbsp;type='text'/&amp;gt;&quot;); &lt;br /&gt;&lt;br /&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 data-ke-size=&quot;size18&quot;&gt;&lt;br /&gt;&lt;b&gt;원인분석&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;아래&amp;nbsp;브라우저&amp;nbsp;네이티브&amp;nbsp;함수를&amp;nbsp;활용하여&amp;nbsp;문제가&amp;nbsp;발생하는&amp;nbsp;요소에&amp;nbsp;발생하는&amp;nbsp;이벤트를&amp;nbsp;모니터링함. &lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1719363689693&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;//이벤트 모니터링 설정 id가 &quot;testNumber&quot; 인 요소에서 발생하는 모든 이벤트 모니터링
monitorEvents($('#testNumber')[0]);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;br /&gt;모니터링&amp;nbsp;설정&amp;nbsp;후&amp;nbsp;브라우저의&amp;nbsp;콘솔창을&amp;nbsp;확인하면서&amp;nbsp;테스트를&amp;nbsp;진행하였음. &lt;br /&gt;&lt;br /&gt;append&amp;nbsp;시&amp;nbsp;아래와&amp;nbsp;같은&amp;nbsp;이벤트&amp;nbsp;발생 &lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;01event.png&quot; data-origin-width=&quot;989&quot; data-origin-height=&quot;86&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/I87XB/btsIdzY60uB/m20gQAYQjSvukskXz3t9Hk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/I87XB/btsIdzY60uB/m20gQAYQjSvukskXz3t9Hk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/I87XB/btsIdzY60uB/m20gQAYQjSvukskXz3t9Hk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FI87XB%2FbtsIdzY60uB%2Fm20gQAYQjSvukskXz3t9Hk%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;989&quot; height=&quot;86&quot; data-filename=&quot;01event.png&quot; data-origin-width=&quot;989&quot; data-origin-height=&quot;86&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;발생한&amp;nbsp;이벤트를&amp;nbsp;보면&amp;nbsp;focus,&amp;nbsp;keydown,&amp;nbsp;keyup,&amp;nbsp;blur&amp;nbsp;이벤트가&amp;nbsp;순차적으로&amp;nbsp;발생하였음. &lt;br /&gt;해당&amp;nbsp;요소에는&amp;nbsp;직접적으로&amp;nbsp;한것이&amp;nbsp;없는데&amp;nbsp;이러한&amp;nbsp;이벤트가&amp;nbsp;발생하는 것을&amp;nbsp;확인. &lt;br /&gt;&lt;br /&gt;좀&amp;nbsp;더&amp;nbsp;정확하게&amp;nbsp;확인하기&amp;nbsp;위해&amp;nbsp;숨김처리&amp;nbsp;해두었던&amp;nbsp;baseInfo&amp;nbsp;태그를&amp;nbsp;표출로&amp;nbsp;해두고&amp;nbsp;테스트를&amp;nbsp;다시&amp;nbsp;진행함. &lt;br /&gt;&lt;br /&gt;다시&amp;nbsp;진행을&amp;nbsp;하는&amp;nbsp;순간&amp;nbsp;브라우저의&amp;nbsp;비밀번호&amp;nbsp;자동완성&amp;nbsp;기능이&amp;nbsp;동작하여&amp;nbsp;이미&amp;nbsp;해당&amp;nbsp;칸을&amp;nbsp;채워둔&amp;nbsp;것이&amp;nbsp;확인되었음. &lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;03auto.png&quot; data-origin-width=&quot;309&quot; data-origin-height=&quot;86&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/IauXP/btsIdGcNsCY/jJckLwSuN1TGtETyaNI27k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/IauXP/btsIdGcNsCY/jJckLwSuN1TGtETyaNI27k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/IauXP/btsIdGcNsCY/jJckLwSuN1TGtETyaNI27k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FIauXP%2FbtsIdGcNsCY%2FjJckLwSuN1TGtETyaNI27k%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;309&quot; height=&quot;86&quot; data-filename=&quot;03auto.png&quot; data-origin-width=&quot;309&quot; data-origin-height=&quot;86&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;br /&gt;재현을&amp;nbsp;하기위해서&amp;nbsp;해당&amp;nbsp;영역은&amp;nbsp;그대로&amp;nbsp;두고&amp;nbsp;다음&amp;nbsp;append&amp;nbsp;하는&amp;nbsp;부분을&amp;nbsp;진행하였음. &lt;br /&gt;&lt;br /&gt;역시나&amp;nbsp;onblur&amp;nbsp;이벤트가&amp;nbsp;발생하면서&amp;nbsp;testFunc()&amp;nbsp;함수가&amp;nbsp;실행됨을&amp;nbsp;확인. &lt;br /&gt;&lt;br /&gt;append&amp;nbsp;시&amp;nbsp;다른&amp;nbsp;type인&amp;nbsp;경우도&amp;nbsp;영향이&amp;nbsp;있는지&amp;nbsp;확인해&amp;nbsp;본&amp;nbsp;결과&amp;nbsp;hidden을&amp;nbsp;제외한&amp;nbsp;type은&amp;nbsp;모두&amp;nbsp;동일한&amp;nbsp;이벤트가&amp;nbsp;발생하였음. &lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1719363794050&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;//이벤트발생
$('#testArea').append(&quot;&amp;lt;input type='text'/&amp;gt;&quot;)
$('#testArea').append(&quot;&amp;lt;input type='tel'/&amp;gt;&quot;)
$('#testArea').append(&quot;&amp;lt;input type='nember'/&amp;gt;&quot;)
//select, radio 등

//이벤트 미발생
$('#testArea').append(&quot;&amp;lt;input type='hidden'/&amp;gt;&quot;)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;br /&gt;그렇다면&amp;nbsp;현재&amp;nbsp;영역은&amp;nbsp;표출되고&amp;nbsp;있으니&amp;nbsp;자동완성된&amp;nbsp;값을&amp;nbsp;지우고&amp;nbsp;다시&amp;nbsp;append를&amp;nbsp;진행하면&amp;nbsp;정상적으로&amp;nbsp;동작하는지&amp;nbsp;확인하였음.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;04nonauto.png&quot; data-origin-width=&quot;307&quot; data-origin-height=&quot;76&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bRUZAi/btsIcUQcgnO/ppqryilIaHtRH2TrPepd0K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bRUZAi/btsIcUQcgnO/ppqryilIaHtRH2TrPepd0K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bRUZAi/btsIcUQcgnO/ppqryilIaHtRH2TrPepd0K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbRUZAi%2FbtsIcUQcgnO%2FppqryilIaHtRH2TrPepd0K%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;307&quot; height=&quot;76&quot; data-filename=&quot;04nonauto.png&quot; data-origin-width=&quot;307&quot; data-origin-height=&quot;76&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&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;02event.png&quot; data-origin-width=&quot;943&quot; data-origin-height=&quot;130&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cNUSAq/btsIcXlQCKK/KxpmBnrP2B9nrSEUHdVi6K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cNUSAq/btsIcXlQCKK/KxpmBnrP2B9nrSEUHdVi6K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cNUSAq/btsIcXlQCKK/KxpmBnrP2B9nrSEUHdVi6K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcNUSAq%2FbtsIcXlQCKK%2FKxpmBnrP2B9nrSEUHdVi6K%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;943&quot; height=&quot;130&quot; data-filename=&quot;02event.png&quot; data-origin-width=&quot;943&quot; data-origin-height=&quot;130&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;br /&gt;오히려&amp;nbsp;기존&amp;nbsp;이벤트에&amp;nbsp;input과&amp;nbsp;change&amp;nbsp;이벤트가&amp;nbsp;추가되며&amp;nbsp;자동완성&amp;nbsp;데이터가&amp;nbsp;다시&amp;nbsp;입력되는 것이&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;p data-ke-size=&quot;size18&quot;&gt;&lt;br /&gt;&lt;b&gt;해결방법&lt;/b&gt; &lt;br /&gt;브라우저&amp;nbsp;비밀번호&amp;nbsp;자동완성&amp;nbsp;방지&amp;nbsp;방법은&amp;nbsp;해당&amp;nbsp;form&amp;nbsp;및&amp;nbsp;input&amp;nbsp;태그에&amp;nbsp;선언해주면&amp;nbsp;됨. &lt;/p&gt;
&lt;pre id=&quot;code_1719363846517&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;autocomplete=&quot;new-password&quot;
또는
autocomplete=&quot;off&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;/p&gt;
&lt;div id=&quot;gtx-trans&quot; style=&quot;position: absolute; left: 219px; top: 23.2222px;&quot;&gt;
&lt;div class=&quot;gtx-trans-icon&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;</description>
      <category>jQuery</category>
      <category>append</category>
      <category>autocomplete</category>
      <category>html</category>
      <category>jQuery</category>
      <category>onblur</category>
      <category>이벤트발생</category>
      <category>자동완성</category>
      <author>jckim</author>
      <guid isPermaLink="true">https://jckim-dev.tistory.com/52</guid>
      <comments>https://jckim-dev.tistory.com/entry/Jquery-append-%EC%8B%9C-%EC%97%B0%EA%B4%80%EC%97%86%EB%8A%94-%EC%9D%B4%EB%B2%A4%ED%8A%B8-%EB%B0%9C%EC%83%9D-%ED%95%B4%EA%B2%B0#entry52comment</comments>
      <pubDate>Wed, 26 Jun 2024 10:06:54 +0900</pubDate>
    </item>
    <item>
      <title>MyBatis ORACLE SEQUENCE 미증가 해결</title>
      <link>https://jckim-dev.tistory.com/entry/MyBatis-ORACLE-SEQUENCE-%EB%AF%B8%EC%A6%9D%EA%B0%80-%ED%95%B4%EA%B2%B0</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;오라클&amp;nbsp;시퀀스를&amp;nbsp;사용한&amp;nbsp;기능을&amp;nbsp;추가하던&amp;nbsp;중&amp;nbsp;시퀀스가&amp;nbsp;증가하지&amp;nbsp;않는&amp;nbsp;현상이&amp;nbsp;발생하였음. &lt;br /&gt;&lt;br /&gt;간략한&amp;nbsp;작업&amp;nbsp;내용은&amp;nbsp;특정&amp;nbsp;시퀀스를&amp;nbsp;조회하여&amp;nbsp;보관하고 &lt;br /&gt;다시&amp;nbsp;동일한&amp;nbsp;시퀀스를&amp;nbsp;조회하여&amp;nbsp;함께&amp;nbsp;사용하는&amp;nbsp;작업이었음. &lt;br /&gt;&lt;br /&gt;첫 번째&amp;nbsp;시퀀스&amp;nbsp;조회&amp;nbsp;시&amp;nbsp;증가된&amp;nbsp;번호를&amp;nbsp;가져왔으나 &lt;br /&gt;두 번째&amp;nbsp;시퀀스&amp;nbsp;조회&amp;nbsp;시&amp;nbsp;첫 번째에&amp;nbsp;조회된&amp;nbsp;번호가&amp;nbsp;그대로&amp;nbsp;들어있었음.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1713501377418&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;첫번째 시퀀스 조회 결과 : 1
두번째 시퀀스 조회 결과 : 1&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당&amp;nbsp;기능과&amp;nbsp;관련된&amp;nbsp;일부&amp;nbsp;소스는&amp;nbsp;아래와&amp;nbsp;같음. &lt;br /&gt;&lt;br /&gt;MyBatis&amp;nbsp;영역&lt;/p&gt;
&lt;pre id=&quot;code_1713501416410&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;select id=&quot;getSeq&quot; resultType=&quot;int&quot;&amp;gt;
	SELECT SEQ.NEXTVAL FROM DUAL
&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;Repository&amp;nbsp;영역&lt;/p&gt;
&lt;pre id=&quot;code_1713501544456&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;TestDAO interface 작성 생략

@Repository
public class TestDAOImpl implements TestDAO{
	@Override
	public int getTestSeq() {
		return selectOne(&quot;getSeq&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;Service&amp;nbsp;영역&lt;/p&gt;
&lt;pre id=&quot;code_1713501521482&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;TestService interface 작성 생략

@Transactional(rollbackFor = Exception.class)
@Service
public class TestServiceImpl implements TestService {
	@Autowired
	TestDao testDao;

	@Override
	public void getTestSeq() {
		//첫번째 시퀀스 호출
		int firstSeq = testDao.getTestSeq();

		int secondSeq = testDao.getTestSeq();

		Logger.debug(&quot;첫번째 시퀀스 조회 결과 : &quot; + firstSeq);

		Logger.debug(&quot;두번째 시퀀스 조회 결과 : &quot; + secondSeq);

		//위에 값을 활용해서 진행
		testDao.insert(...);

	}

}&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;트랜잭션이&amp;nbsp;문제인가&amp;nbsp;싶어&amp;nbsp;@Transactional(propagation,&amp;nbsp;isolation)&amp;nbsp;옵션에&amp;nbsp;대해서&amp;nbsp;변경해 보고&amp;nbsp;테스트해보았으나&amp;nbsp;현상은&amp;nbsp;동일하였음. &lt;br /&gt;&lt;br /&gt;&lt;b&gt;MyBatis의&amp;nbsp;Cache&amp;nbsp;관련&amp;nbsp;정보를&amp;nbsp;확인&lt;/b&gt; &lt;br /&gt;&lt;br /&gt;Local&amp;nbsp;Session&amp;nbsp;Cache &lt;br /&gt;세션이&amp;nbsp;생성될때&amp;nbsp;마다&amp;nbsp;로컬캐시를&amp;nbsp;생성하고 &lt;br /&gt;동일한&amp;nbsp;쿼리에&amp;nbsp;대한&amp;nbsp;결과는&amp;nbsp;캐시에서&amp;nbsp;조회하여&amp;nbsp;반환. &lt;br /&gt;commit,&amp;nbsp;rollback,&amp;nbsp;insert,&amp;nbsp;delete,&amp;nbsp;update&amp;nbsp;동작&amp;nbsp;및&amp;nbsp;트랜잭션이&amp;nbsp;종료되면&amp;nbsp;캐시를&amp;nbsp;비움. &lt;br /&gt;&lt;br /&gt;Second&amp;nbsp;Level&amp;nbsp;Cache &lt;br /&gt;mapper&amp;nbsp;namespace&amp;nbsp;단위로&amp;nbsp;적용&amp;nbsp;가능하고&amp;nbsp;옵션으로&amp;nbsp;사용여부&amp;nbsp;설정이&amp;nbsp;가능함. &lt;br /&gt;&lt;br /&gt;&lt;b&gt;MyBatis의&amp;nbsp;Cache&amp;nbsp;관련&amp;nbsp;옵션을&amp;nbsp;확인&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1713501833436&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;configuration&amp;gt;
	&amp;lt;settings&amp;gt;
		&amp;lt;setting name=&quot;cacheEnabled&quot; value=&quot;false&quot; /&amp;gt;
	&amp;lt;/settings&amp;gt;
	...
	...
	...
&amp;lt;/configuration&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;옵션이&amp;nbsp;설정되어있기&amp;nbsp;때문에&amp;nbsp;Second&amp;nbsp;Level&amp;nbsp;Cache&amp;nbsp;기능은&amp;nbsp;사용하지&amp;nbsp;않고 있는&amp;nbsp;것으로&amp;nbsp;확인. &lt;br /&gt;&lt;br /&gt;Local&amp;nbsp;Session&amp;nbsp;Cache&amp;nbsp;로&amp;nbsp;인해&amp;nbsp;동일한&amp;nbsp;결과가&amp;nbsp;나오는&amp;nbsp;것으로&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;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;b&gt;해결방법&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1.해당&amp;nbsp;쿼리&amp;nbsp;MyBatis&amp;nbsp;영역&amp;nbsp;flushCache&amp;nbsp;옵션&amp;nbsp;설정&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1713501899879&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;select id=&quot;getSeq&quot; resultType=&quot;int&quot; flushCache = true&amp;gt;
	SELECT SEQ.NEXTVAL FROM DUAL
&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;flushCache&amp;nbsp;옵션을&amp;nbsp;true로&amp;nbsp;설정해 주면&amp;nbsp;트랜잭션이&amp;nbsp;끝나지&amp;nbsp;않아도&amp;nbsp;재조회시&amp;nbsp;동일&amp;nbsp;쿼리&amp;nbsp;조회&amp;nbsp;시&amp;nbsp;캐시가&amp;nbsp;flush 되어&amp;nbsp;새로운&amp;nbsp;값을&amp;nbsp;가져오게 됨. &lt;br /&gt;&lt;br /&gt;&lt;b&gt;2.&amp;nbsp;서비스&amp;nbsp;계층이&amp;nbsp;아닌&amp;nbsp;컨트롤러&amp;nbsp;계층에서&amp;nbsp;채번하는&amp;nbsp;방법&lt;/b&gt; &lt;br /&gt;컨트롤러에서&amp;nbsp;채번을&amp;nbsp;하게 되면&amp;nbsp;동일한&amp;nbsp;트랜잭션이&amp;nbsp;아니기&amp;nbsp;때문에&amp;nbsp;중복되는&amp;nbsp;값을&amp;nbsp;조회하지&amp;nbsp;않게 된다.&amp;nbsp;하지만&amp;nbsp;해당&amp;nbsp;기능을&amp;nbsp;호출하는&amp;nbsp;부분에&amp;nbsp;동일하게&amp;nbsp;작업을&amp;nbsp;해주어야 하는 게&amp;nbsp;작업영역이&amp;nbsp;커지면&amp;nbsp;공수가&amp;nbsp;많이 들게&amp;nbsp;됨. &lt;br /&gt;&lt;br /&gt;&lt;b&gt;3.&amp;nbsp;로직상&amp;nbsp;첫번째&amp;nbsp;채번&amp;nbsp;후&amp;nbsp;insert&amp;nbsp;작업&amp;nbsp;진행&amp;nbsp;후&amp;nbsp;두 번째&amp;nbsp;채번을&amp;nbsp;진행&amp;nbsp;후&amp;nbsp;비지니스&amp;nbsp;로직을&amp;nbsp;수정하는&amp;nbsp;방법&lt;/b&gt; &lt;br /&gt;로컬캐시가&amp;nbsp;초기화되는&amp;nbsp;조건&amp;nbsp;중&amp;nbsp;하나인&amp;nbsp;commit,&amp;nbsp;rollback,&amp;nbsp;insert,&amp;nbsp;delete,&amp;nbsp;update&amp;nbsp;동작&amp;nbsp;및&amp;nbsp;트랜잭션이&amp;nbsp;종료를&amp;nbsp;활용하는&amp;nbsp;방법으로&amp;nbsp;서비스&amp;nbsp;계층의&amp;nbsp;비지니스&amp;nbsp;로직을&amp;nbsp;아래와&amp;nbsp;같이&amp;nbsp;변경할&amp;nbsp;수&amp;nbsp;있음. &lt;br /&gt;&lt;br /&gt;Service&amp;nbsp;영역&lt;/p&gt;
&lt;pre id=&quot;code_1713501931011&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;TestService interface 작성 생략

@Transactional(rollbackFor = Exception.class)
@Service
public class TestServiceImpl implements TestService {
	@Autowired
	TestDao testDao;

	@Override
	public void getTestSeq() {
		//첫번째 시퀀스 호출
		int firstSeq = testDao.getTestSeq();

		//위에 값을 활용해서 진행
		testDao.insert(...);

		int secondSeq = testDao.getTestSeq();

		//위에 값을 활용해서 진행
		testDao.insert(...);

		Logger.debug(&quot;첫번째 시퀀스 조회 결과 : &quot; + firstSeq);

		Logger.debug(&quot;두번째 시퀀스 조회 결과 : &quot; + secondSeq);

	}

}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1713501946977&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;첫번째 시퀀스 조회 결과 : 1
두번째 시퀀스 조회 결과 : 2&lt;/code&gt;&lt;/pre&gt;</description>
      <category>JAVA</category>
      <category>Cache</category>
      <category>mybatis</category>
      <category>Oracle</category>
      <category>Sequence</category>
      <category>Transaction</category>
      <category>시퀀스</category>
      <category>증가안됨</category>
      <author>jckim</author>
      <guid isPermaLink="true">https://jckim-dev.tistory.com/51</guid>
      <comments>https://jckim-dev.tistory.com/entry/MyBatis-ORACLE-SEQUENCE-%EB%AF%B8%EC%A6%9D%EA%B0%80-%ED%95%B4%EA%B2%B0#entry51comment</comments>
      <pubDate>Fri, 19 Apr 2024 13:54:50 +0900</pubDate>
    </item>
    <item>
      <title>ObjectMapper 결과 값 주입이 안되는 경우</title>
      <link>https://jckim-dev.tistory.com/entry/ObjectMapper-%EA%B2%B0%EA%B3%BC-%EA%B0%92-%EC%A3%BC%EC%9E%85%EC%9D%B4-%EC%95%88%EB%90%98%EB%8A%94-%EA%B2%BD%EC%9A%B0</link>
      <description>&lt;h2 style=&quot;text-align: left;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;발단상황&lt;/b&gt;&lt;/h2&gt;&lt;p data-ke-size=&quot;size18&quot; style=&quot;text-align: left;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;java를 사용하고 데이터베이스에서 조회된 데이터 목록을&lt;/span&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;JSON 형태로 응답을 해주는 방법 중 하나로는 &lt;/span&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;ObjectMapper Class ( &lt;b&gt;import&amp;nbsp;com.fasterxml.jackson.databind.ObjectMapper;&lt;/b&gt; )가 있다&lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;.&lt;/span&gt;&lt;/b&gt; &lt;br&gt;&amp;nbsp;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;ObjectMapper Class 내에 여러 메소드 중 하나인&lt;/span&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;writeValueAsString 메소드는 java의 Object를 &lt;b&gt;직렬화 과정&lt;/b&gt;을 통하여&lt;/span&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;json 형태의 String 형으로 변환해 주는 역할을 한다.&lt;/span&gt;&lt;br&gt;&amp;nbsp;&lt;/p&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;이러한 기능을 이용하여 기능을 개발을 진행하던 중 원하는 결과를 반환하지 않는 경우가 발생하였다.&lt;/span&gt;&lt;/p&gt;&lt;p data-ke-size=&quot;size18&quot; style=&quot;text-align: left;&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;데이터베이스에서 데이터 목록을 조회하여&lt;/span&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;ObjectMapper의 writeValueAsString 메소드를 이용하여&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;size18&quot; style=&quot;text-align: left;&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&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;&amp;nbsp;&lt;/p&gt;&lt;pre data-ke-type=&quot;codeblock&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot;&gt;&lt;code&gt;ObjectMapper om = new ObjectMapper();
String resData;
List&amp;lt;TestEntity&amp;gt; list = TestService.selectTestList();
resData = om.writeValueAsString(list);&lt;/code&gt;&lt;/pre&gt;&lt;p data-ke-size=&quot;size18&quot; style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;어느 부분에서 문제가 발생하는지 찾기 위해 순차적으로 디버깅을 진행해 보았다.&lt;/span&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;3번 라인의 list 객체에는 값이 정상적으로 담기는 것을 확인하였다.&lt;/span&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;하지만 4번 라인 resData 변수에는 아래와 같이 데이터가 담겨있었다.&lt;/span&gt;&lt;/p&gt;&lt;pre data-ke-type=&quot;codeblock&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;[{},{}]&lt;/code&gt;&lt;/pre&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;테스트를 위해 데이터는 2개를 입력해 둔 상태였다.&lt;/span&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;json 형태의 데이터가 배열 형태로 2개가 존재함은 확인하였음&lt;/span&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;key와 value 값이 존재하지 않는 것을 확인하였다.&lt;/span&gt;&lt;br&gt;&amp;nbsp;&lt;/p&gt;&lt;hr data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot;&gt;&lt;h2 style=&quot;text-align: left;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;문제해결&lt;/b&gt;&lt;/h2&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;먼저 문제를 해결한 방법은 아래와 같다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;pre data-ke-type=&quot;codeblock&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot;&gt;&lt;code&gt;@Entity
@Table
@Data //해당 어노테이션을 추가해주었음. @Getter도 가능
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class TestEntity {


	private Long aId;
	private String bId;
}&lt;/code&gt;&lt;/pre&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Entity Class에 Data 어노테이션을 추가해 주었다. (Getter 어노테이션도 가능 이유는 아래에 계속)&lt;/span&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Dto Class의 toEntity 기능을 활용하려다가 누락된 것으로 보인다;;;&lt;/span&gt;&lt;br&gt;&amp;nbsp;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;어노테이션을 추가해 준 후 아래와 같이 데이터가 정상적으로 조회되는 것을 확인할 수 있었다.&lt;/span&gt;&lt;/p&gt;&lt;pre data-ke-type=&quot;codeblock&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;[{&quot;aId&quot;:11,&quot;bId&quot;:&quot;33&quot;},{&quot;aId&quot;:22,&quot;bId&quot;:&quot;44&quot;}]&lt;/code&gt;&lt;/pre&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;hr data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot;&gt;&lt;h2 style=&quot;text-align: left;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;원인분석&lt;/b&gt;&lt;/h2&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;문제는 해결하였는데 문제가 발생한 원인을 좀 더 찾아보았다.&lt;/span&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt;ObjectMapper 생성자부터&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; 소스코드를 따라가 보았다.&lt;/span&gt;&lt;br&gt;&amp;nbsp;&lt;/p&gt;&lt;pre data-ke-type=&quot;codeblock&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot;&gt;&lt;code&gt;ObjectMapper.java

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;	public ObjectMapper() {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;this(null, null, null);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;public ObjectMapper(JsonFactory jf,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;DefaultSerializerProvider sp, DefaultDeserializationContext dc)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;	...
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;_configOverrides = new ConfigOverrides();
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;...
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/code&gt;&lt;/pre&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;ObjectMapper Class 내 생성자를 따라가다 보면&lt;/span&gt;&lt;br&gt;&lt;span style=&quot;color: #000000;&quot;&gt; ConfigOverrides Class의 생성자를 생성하는 부분이 존재합니다.&lt;/span&gt;&lt;br&gt;&amp;nbsp;&lt;/p&gt;&lt;pre data-ke-type=&quot;codeblock&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot;&gt;&lt;code&gt;ConfigOverrides.java

	public ConfigOverrides() {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;this(null,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;// !!! TODO: change to (ALWAYS, ALWAYS)?
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;JsonInclude.Value.empty(),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;JsonSetter.Value.empty(),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;VisibilityChecker.Std.defaultInstance(),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;null, null
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/code&gt;&lt;/pre&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;ConfigOverrides 생성자의 VisibilityChecker.Std.defaultInstance() 매개변수를 따라가 봅니다.&lt;/span&gt;&lt;br&gt;&amp;nbsp;&lt;/p&gt;&lt;pre data-ke-type=&quot;codeblock&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot;&gt;&lt;code&gt;VisibilityCheckerjava
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;public static Std defaultInstance() { return DEFAULT; }

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;protected final static Std DEFAULT = new Std(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Visibility.PUBLIC_ONLY, // getter
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Visibility.PUBLIC_ONLY, // is-getter
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Visibility.ANY, // setter
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Visibility.ANY, // creator -- legacy, to support single-arg ctors
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Visibility.PUBLIC_ONLY // field
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;);&lt;/code&gt;&lt;/pre&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;br&gt;Instance는 DEFAULT 옵션으로 선언되어있으며 해당 옵션의 값은 그 아래 코드 내에 선언되어 있습니다.&lt;br&gt;해당 옵션의 의미는 직렬화 진행 시 객체 생성을 위해 방식에 따라서&lt;br&gt;gettet, isGetter, filed(변수)의 해당 접근제어자는 public이어야만 하며&lt;br&gt;setter, creator(생성자)는 조건을&amp;nbsp; 특정 짓지 않는다는 것이다.&lt;br&gt;&amp;nbsp;&lt;br&gt;이러한 내용을 기반으로 문제가 발생한 상황에 적용해 보면&lt;br&gt;json으로 직렬화해야 하는 객체에 getter 메소드 선언을 누락하였던 것이고&lt;br&gt;filed는 private 접근제어자로 선언이 되어있기 때문에 값을 가져올 수 없었던 것이었다.&lt;br&gt;만약 변수가 public이었다면 값을 가져올 수 있었지만&lt;br&gt;사용자에 의하여 값이 변경될 수 있으니 해당 경우는 흔하지 않을 것으로 보인다.&lt;br&gt;&amp;nbsp;&lt;br&gt;&amp;nbsp;&lt;br&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>JAVA</category>
      <category>fasterxml</category>
      <category>Java</category>
      <category>JSON</category>
      <category>ObjectMapper</category>
      <category>writeValueAsString</category>
      <author>jckim</author>
      <guid isPermaLink="true">https://jckim-dev.tistory.com/50</guid>
      <comments>https://jckim-dev.tistory.com/entry/ObjectMapper-%EA%B2%B0%EA%B3%BC-%EA%B0%92-%EC%A3%BC%EC%9E%85%EC%9D%B4-%EC%95%88%EB%90%98%EB%8A%94-%EA%B2%BD%EC%9A%B0#entry50comment</comments>
      <pubDate>Wed, 17 Jan 2024 00:24:53 +0900</pubDate>
    </item>
    <item>
      <title>java RSA decryption is failed (bouncycastleprovider 관련)</title>
      <link>https://jckim-dev.tistory.com/entry/java-RSA-decryption-is-failed-bouncycastleprovider-%EA%B4%80%EB%A0%A8</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;발단&lt;/b&gt; &lt;br /&gt;java&amp;nbsp;환경에서&amp;nbsp;작업을&amp;nbsp;진행하던&amp;nbsp;중&amp;nbsp;아래와&amp;nbsp;같은&amp;nbsp;오류&amp;nbsp;로그&amp;nbsp;발생 &lt;br /&gt;로컬&amp;nbsp;작업환경에서는&amp;nbsp;정상적으로&amp;nbsp;테스트되었으나&amp;nbsp;서버상에서&amp;nbsp;테스트 시&amp;nbsp;발생&lt;/p&gt;
&lt;pre id=&quot;code_1696578288390&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;Java security providerexception could not derive key

java rsa decryption is failed&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당&amp;nbsp;에러가&amp;nbsp;발생하는&amp;nbsp;부분에서&amp;nbsp;사용하고&amp;nbsp;있는&amp;nbsp;메소드&amp;nbsp;확인 시&amp;nbsp;아래와&amp;nbsp;같음&lt;/p&gt;
&lt;pre id=&quot;code_1696578303684&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import org.bouncycastle.util.encoders.Base64&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;잘&amp;nbsp;알려진&amp;nbsp;JCE(Java&amp;nbsp;Cryptography&amp;nbsp;Extension)&amp;nbsp;라이브러리&amp;nbsp;보안&amp;nbsp;공급자&amp;nbsp;중&amp;nbsp;하나인&amp;nbsp;&quot;bouncycastleprovider&quot;를&amp;nbsp;호출하다&amp;nbsp;발생하는&amp;nbsp;것으로&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;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;원인파악&lt;/b&gt; &lt;br /&gt;bouncycastleprovider 사용시 기본 설정하는 부분에 대하여 로컬과 서버 환경을 비교하였음.&lt;/p&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_1696578394669&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;로컬
C:\Program Files\Java\jdk1.8.0_202\jre\lib\security\java.security

서버
[JAVA_HOME]/jre/lib/security/java.security&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1696578419387&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;파일 내용
security.provider.1=sun.security.provider.Sun
security.provider.2=sun.security.rsa.SunRsaSign
security.provider.3=sun.security.ec.SunEC
security.provider.4=com.sun.net.ssl.internal.ssl.Provider
security.provider.5=com.sun.crypto.provider.SunJCE
security.provider.6=sun.security.jgss.SunProvider
security.provider.7=com.sun.security.sasl.Provider
security.provider.8=org.jcp.xml.dsig.internal.dom.XMLDSigRI
security.provider.9=sun.security.smartcardio.SunPCSC
security.provider.10=sun.security.mscapi.SunMSCAPI

security.provider.11=org.bouncycastle.jce.provider.bouncycastleprovider&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;security.provider.11&amp;nbsp;존재&amp;nbsp;여부&amp;nbsp;확인&amp;nbsp;두&amp;nbsp;환경&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;2.Extension&amp;nbsp;ClassLoader&amp;nbsp;라이브러리&amp;nbsp;존재&amp;nbsp;여부&lt;/p&gt;
&lt;pre id=&quot;code_1696578478140&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;로컬
C:\Program Files\Java\jdk1.8.0_202\jre\lib\ext

서버
[JAVA_HOME]/jre/lib/ext&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당&amp;nbsp;경로에&amp;nbsp;&quot;bcproc-ext-jdk15-145.jar&quot;&amp;nbsp;파일&amp;nbsp;존재&amp;nbsp;여부&amp;nbsp;확인 &lt;br /&gt;로컬환경에서&amp;nbsp;해당&amp;nbsp;파일&amp;nbsp;확인&amp;nbsp;되나&amp;nbsp;서버환경에서&amp;nbsp;해당&amp;nbsp;파일&amp;nbsp;존재하지&amp;nbsp;않음&amp;nbsp;확인 &lt;br /&gt;&lt;br /&gt;서버 측&amp;nbsp;&quot;bcproc-ext-jdk15-145.jar&quot;&amp;nbsp;현행화&amp;nbsp;후&amp;nbsp;application&amp;nbsp;재기동&amp;nbsp;후&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;확인하던&amp;nbsp;중&amp;nbsp;서버의&amp;nbsp;해당&amp;nbsp;프로젝트&amp;nbsp;경로의&amp;nbsp;라이브러리&amp;nbsp;폴더&amp;nbsp;/lib&amp;nbsp;내에&amp;nbsp;&quot;bcproc-ext-jdk15-145.jar&quot;&amp;nbsp;파일이&amp;nbsp;존재하였으나&amp;nbsp;해당&amp;nbsp;에러메시지가&amp;nbsp;발생하는&amp;nbsp;것에&amp;nbsp;대하여&amp;nbsp;확인이&amp;nbsp;필요하다&amp;nbsp;생각이&amp;nbsp;되었음. &lt;br /&gt;&lt;br /&gt;현재&amp;nbsp;작업 중인&amp;nbsp;환경은&amp;nbsp;프로젝트&amp;nbsp;소스에서&amp;nbsp;직접&amp;nbsp;호출하는&amp;nbsp;것이&amp;nbsp;아닌&amp;nbsp;프로젝트&amp;nbsp;내&amp;nbsp;다른&amp;nbsp;jar&amp;nbsp;파일&amp;nbsp;내부에서&amp;nbsp;bouncycastleprovider의&amp;nbsp;메서드를&amp;nbsp;호출하는&amp;nbsp;로직으로&amp;nbsp;확인됨. &lt;br /&gt;classpath&amp;nbsp;내&amp;nbsp;jar 간&amp;nbsp;참조는&amp;nbsp;불가하고&amp;nbsp;jar내&amp;nbsp;MENIFEST.MF&amp;nbsp;파일 내&amp;nbsp;별도&amp;nbsp;정의가&amp;nbsp;없었으므로 &lt;br /&gt;classpath의&amp;nbsp;/lib&amp;nbsp;경로의&amp;nbsp;파일이&amp;nbsp;아닌&amp;nbsp;Extension&amp;nbsp;ClassLoader를&amp;nbsp;통한&amp;nbsp;참조를&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;p data-ke-size=&quot;size16&quot;&gt;*&amp;nbsp;ClassLoader&amp;nbsp;종류 &lt;br /&gt;-&amp;nbsp;Bootstrap&amp;nbsp;ClassLoader&amp;nbsp;:&amp;nbsp;$JAVA_HOME/jre/lib/rt.jar &lt;br /&gt;-&amp;nbsp;Extension&amp;nbsp;ClassLoader&amp;nbsp;:&amp;nbsp;$JAVA_HOME/jre/lib/ext/*.jar &lt;br /&gt;-&amp;nbsp;Application&amp;nbsp;ClassLoader&amp;nbsp;:&amp;nbsp;$CLASSPATH &lt;br /&gt;&lt;br /&gt;*&amp;nbsp;ClassLoader&amp;nbsp;우선순위 &lt;br /&gt;상위&amp;nbsp;ClassLoader에&amp;nbsp;있는&amp;nbsp;Class가&amp;nbsp;우선순위가&amp;nbsp;높다 &lt;br /&gt;Bootstrap&amp;nbsp;&amp;gt;&amp;nbsp;Extension&amp;nbsp;&amp;gt;&amp;nbsp;Application &lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;*&amp;nbsp;ClassLoader에서&amp;nbsp;로드된&amp;nbsp;클래스가&amp;nbsp;참조하는&amp;nbsp;다른&amp;nbsp;클래스는&amp;nbsp;상위의&amp;nbsp;ClassLoader에서&amp;nbsp;찾을&amp;nbsp;수&amp;nbsp;있어야 함.&lt;/p&gt;</description>
      <category>JAVA</category>
      <category>bouncycastleprovider</category>
      <category>ClassLoader</category>
      <category>providerexception</category>
      <category>RSA</category>
      <author>jckim</author>
      <guid isPermaLink="true">https://jckim-dev.tistory.com/49</guid>
      <comments>https://jckim-dev.tistory.com/entry/java-RSA-decryption-is-failed-bouncycastleprovider-%EA%B4%80%EB%A0%A8#entry49comment</comments>
      <pubDate>Fri, 6 Oct 2023 16:51:52 +0900</pubDate>
    </item>
    <item>
      <title>세션 일부 값 누락 현상 조치하기(세션 클러스터링)</title>
      <link>https://jckim-dev.tistory.com/entry/%EC%84%B8%EC%85%98-%EC%9D%BC%EB%B6%80-%EA%B0%92-%EB%88%84%EB%9D%BD-%ED%98%84%EC%83%81-%EC%A1%B0%EC%B9%98%ED%95%98%EA%B8%B0%EC%84%B8%EC%85%98-%ED%81%B4%EB%9F%AC%EC%8A%A4%ED%84%B0%EB%A7%81</link>
      <description>&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&lt;b&gt;발단&lt;/b&gt; &lt;br&gt;사용자&amp;nbsp;사용&amp;nbsp;이력을&amp;nbsp;분석 중&amp;nbsp;일부&amp;nbsp;데이터에&amp;nbsp;특정&amp;nbsp;값이&amp;nbsp;누락되어&amp;nbsp;저장되는&amp;nbsp;현상을&amp;nbsp;확인하였음. &lt;br&gt;&lt;br&gt;해당&amp;nbsp;이력이&amp;nbsp;저장되는&amp;nbsp;로직을&amp;nbsp;분석한&amp;nbsp;결과&amp;nbsp;A&amp;nbsp;메소드를&amp;nbsp;진행 시&amp;nbsp;객체에&amp;nbsp;저장된&amp;nbsp;값을&amp;nbsp;세션에&amp;nbsp;저장하여 &lt;br&gt;B화면으로&amp;nbsp;이동&amp;nbsp;후&amp;nbsp;화면내&amp;nbsp;작업&amp;nbsp;완료&amp;nbsp;시 &lt;br&gt;B&amp;nbsp;메소드로&amp;nbsp;가지고 가서&amp;nbsp;이력을&amp;nbsp;남기는&amp;nbsp;로직으로&amp;nbsp;확인하였음. &lt;br&gt;&lt;br&gt;&lt;/p&gt;&lt;pre data-ke-type=&quot;codeblock&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot;&gt;&lt;code&gt;public String A(HttpServletRequest request){
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;TestVo testVo = new TestVo();
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;testVo.setOne(&quot;1&quot;);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;testVo.setTwo(&quot;2&quot;);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;testVo.setThree(&quot;3&quot;);

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;HttpSession session = request.getSession();
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;session.setAttribute(&quot;TestSession&quot;, vo);

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//현시점 TestSession 값 확인 시 누락없이 정상적으로 저장되어 있음

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return &quot;B()메소드 호출하기 위한 화면&quot;;
}&lt;/code&gt;&lt;/pre&gt;&lt;pre data-ke-type=&quot;codeblock&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot;&gt;&lt;code&gt;public void B(HttpServletRequest request){
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;HttpSession session = request.getSession();

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;TestVo testVo = (TestVo)session.getAttribute(&quot;TestSession&quot;);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//현시점 TestSession 값 확인 시 누락발생되어 있음 확인 (Three 변수 값 null 확인)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;historySave(testVo); //이력 저장 메소드

}&lt;/code&gt;&lt;/pre&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&lt;br&gt;&lt;b&gt;원인파악&lt;/b&gt; &lt;br&gt;멀티서버&amp;nbsp;및&amp;nbsp;이기종&amp;nbsp;WAS&amp;nbsp;사용&amp;nbsp;중이기&amp;nbsp;때문에&amp;nbsp;현재&amp;nbsp;시스템&amp;nbsp;세션 관련&amp;nbsp;설정&amp;nbsp;확인 &lt;br&gt;&lt;br&gt;-&amp;nbsp;application&amp;nbsp;기준&amp;nbsp;확인(jboss) &lt;br&gt;WAS&amp;nbsp;standalone.xml&amp;nbsp;파일&amp;nbsp;내&amp;nbsp;&amp;nbsp;org.jboss.as.clustering.web.infinispan&amp;nbsp;모듈은&amp;nbsp;존재하나&amp;nbsp;관련&amp;nbsp;설정은&amp;nbsp;없음. &lt;br&gt;jboss-web.xml&amp;nbsp;파일&amp;nbsp;내&amp;nbsp;세션&amp;nbsp;공유&amp;nbsp;관련&amp;nbsp;설정&amp;nbsp;존재하지&amp;nbsp;않음. &lt;br&gt;web.xml&amp;nbsp;내&amp;nbsp;세션&amp;nbsp;공유&amp;nbsp;관련&amp;nbsp;설정인&amp;nbsp;&amp;lt;distributable/&amp;gt;&amp;nbsp;태그가&amp;nbsp;존재하지&amp;nbsp;않음. &lt;br&gt;다만&amp;nbsp;상용&amp;nbsp;세션클러스터링&amp;nbsp;솔루션&amp;nbsp;관련&amp;nbsp;filter와&amp;nbsp;servlet&amp;nbsp;선언이&amp;nbsp;존재. &lt;br&gt;&lt;br&gt;상용&amp;nbsp;세션클러스터링&amp;nbsp;솔루션&amp;nbsp;관련&amp;nbsp;jar를&amp;nbsp;decompile 하여&amp;nbsp;확인&amp;nbsp;시&amp;nbsp;TestVo&amp;nbsp;class가&amp;nbsp;확인되었고 &lt;br&gt;현재&amp;nbsp;TestVo가&amp;nbsp;현행화되지&amp;nbsp;않고&amp;nbsp;초기&amp;nbsp;상태임을&amp;nbsp;확인하였음. &lt;br&gt;&lt;br&gt;프로젝트 내 TestVo.java 파일&lt;/p&gt;&lt;pre data-ke-type=&quot;codeblock&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot;&gt;&lt;code&gt;public class TestVo implements Serializable{

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;private String one;

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;private String two;

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;private String three;

}&lt;/code&gt;&lt;/pre&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&lt;br&gt;솔루션 내 TestVo.java 파일&lt;/p&gt;&lt;pre data-ke-type=&quot;codeblock&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot;&gt;&lt;code&gt;public class TestVo implements Serializable{

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;private String one;

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;private String two;

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//변수 three 추가 현행화 되어있지 않음

}&lt;/code&gt;&lt;/pre&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&lt;br&gt;&lt;br&gt;해당&amp;nbsp;부분&amp;nbsp;소스는&amp;nbsp;솔루션업체에&amp;nbsp;요청이&amp;nbsp;필요하고&amp;nbsp;객체를&amp;nbsp;세션에&amp;nbsp;바로&amp;nbsp;저장하는&amp;nbsp;경우는&amp;nbsp;이상 없이&amp;nbsp;사용&amp;nbsp;가능하고 &lt;br&gt;확인된&amp;nbsp;로직처럼&amp;nbsp;사용시&amp;nbsp;값&amp;nbsp;누락이&amp;nbsp;발생하기&amp;nbsp;때문에&amp;nbsp;직접&amp;nbsp;조치하는&amp;nbsp;방안으로&amp;nbsp;결정하였음. &lt;br&gt;&lt;br&gt;&lt;b&gt;해결방법&lt;/b&gt; &lt;br&gt;세션으로&amp;nbsp;TestVo&amp;nbsp;객체를&amp;nbsp;전달하는&amp;nbsp;방법을&amp;nbsp;다른 방법으로&amp;nbsp;전달하고자 함. &lt;br&gt;json으로&amp;nbsp;전달시&amp;nbsp;해당&amp;nbsp;값을&amp;nbsp;다시&amp;nbsp;파싱 해야 하는&amp;nbsp;추가&amp;nbsp;작업&amp;nbsp;필요. &lt;br&gt;메서드 A()에서&amp;nbsp;TestVo&amp;nbsp;객체를&amp;nbsp;직렬화하여&amp;nbsp;세션에&amp;nbsp;String&amp;nbsp;형으로&amp;nbsp;저장&amp;nbsp;후 &lt;br&gt;메서드 B()에서&amp;nbsp;역직렬화를&amp;nbsp;통하여&amp;nbsp;객체를&amp;nbsp;활용하는&amp;nbsp;방법 &lt;br&gt;&lt;br&gt;&lt;/p&gt;&lt;pre data-ke-type=&quot;codeblock&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot;&gt;&lt;code&gt;public String A(HttpServletRequest request){
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;TestVo testVo = new TestVo();
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;testVo.setOne(&quot;1&quot;);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;testVo.setTwo(&quot;2&quot;);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;testVo.setThree(&quot;3&quot;);

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;HttpSession session = request.getSession();

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;byte[] encodeByteTestVo = null;
	String serializedTestVo = null;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;try (ObjectOutputStream oos = new ObjectOutputStream(baos)) {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;oos.writeObject(testVo);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;encodeByteTestVo = Base64.encodeBase64(baos.toByteArray());
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;serializedAgreeTestVo = new String(encodeByteTestVo);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;session.setAttribute(&quot;TestSession&quot;, serializedAgreeTestVo);

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return &quot;B()메소드 호출하기 위한 화면&quot;;
}&lt;/code&gt;&lt;/pre&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&lt;br&gt;&lt;br&gt;&lt;/p&gt;&lt;pre data-ke-type=&quot;codeblock&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot;&gt;&lt;code&gt;public String B(HttpServletRequest request){

&amp;nbsp;&amp;nbsp; HttpSession session = request.getSession(false);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//직렬화된 데이터
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;String serializedTestSession = (String)session.getAttribute(&quot;TestSession&quot;);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;TestVo testVo = new TestVo();
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;byte[] decodeByteTestVo = Base64.decodeBase64(serializedTestSession.getBytes());
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;try(ByteArrayInputStream bais = new ByteArrayInputStream(decodeByteTestVo)) {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;	try (ObjectInputStream ois = new ObjectInputStream(bais)) {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Object objectTestVo = ois.readObject();
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;testVo = (TestVo)objectTestVo;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;historySave(testVo); //이력 저장 메소드
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;	}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
}&lt;/code&gt;&lt;/pre&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&lt;br&gt;&lt;br&gt;&lt;b&gt;결과&lt;/b&gt; &lt;br&gt;메서드 A()에서&amp;nbsp;저장한&amp;nbsp;세션정보가 &lt;br&gt;중간&amp;nbsp;화면을&amp;nbsp;거쳐 &lt;br&gt;메소드&amp;nbsp;B()&amp;nbsp;호출까지&amp;nbsp;누락&amp;nbsp;및&amp;nbsp;유실&amp;nbsp;없이&amp;nbsp;정상적으로&amp;nbsp;사용됨을&amp;nbsp;확인하였음. &lt;/p&gt;</description>
      <category>JAVA</category>
      <category>clustering</category>
      <category>Session</category>
      <category>객체</category>
      <category>누락</category>
      <category>세션</category>
      <category>클러스터링</category>
      <author>jckim</author>
      <guid isPermaLink="true">https://jckim-dev.tistory.com/48</guid>
      <comments>https://jckim-dev.tistory.com/entry/%EC%84%B8%EC%85%98-%EC%9D%BC%EB%B6%80-%EA%B0%92-%EB%88%84%EB%9D%BD-%ED%98%84%EC%83%81-%EC%A1%B0%EC%B9%98%ED%95%98%EA%B8%B0%EC%84%B8%EC%85%98-%ED%81%B4%EB%9F%AC%EC%8A%A4%ED%84%B0%EB%A7%81#entry48comment</comments>
      <pubDate>Mon, 7 Aug 2023 12:32:02 +0900</pubDate>
    </item>
    <item>
      <title>웹서버 이미지 호출이 안되는 경우(이기종 WAS 운영 환경)</title>
      <link>https://jckim-dev.tistory.com/entry/%EC%9B%B9%EC%84%9C%EB%B2%84-%EC%9D%B4%EB%AF%B8%EC%A7%80-%ED%98%B8%EC%B6%9C%EC%9D%B4-%EC%95%88%EB%90%98%EB%8A%94-%EA%B2%BD%EC%9A%B0%EC%9D%B4%EA%B8%B0%EC%A2%85-WAS-%EC%9A%B4%EC%98%81-%ED%99%98%EA%B2%BD</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;배포&amp;nbsp;준비를&amp;nbsp;하기 위해&amp;nbsp;배포&amp;nbsp;작업을&amp;nbsp;준비하던&amp;nbsp;중&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;작업 전&amp;nbsp;개발서버와&amp;nbsp;운영서버의&amp;nbsp;화면을&amp;nbsp;비교를&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;경우&amp;nbsp;화면 내&amp;nbsp;웹서버에&amp;nbsp;존재하는&amp;nbsp;특정&amp;nbsp;이미지가&amp;nbsp;정상적으로&amp;nbsp;표출됨을&amp;nbsp;확인하였음.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;개발서버의&amp;nbsp;경우&amp;nbsp;동일한&amp;nbsp;화면 내&amp;nbsp;웹서버에&amp;nbsp;존재하는&amp;nbsp;특정&amp;nbsp;이미지가&amp;nbsp;표출되지&amp;nbsp;않고&amp;nbsp;엑스박스로&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;경우&amp;nbsp;이미지를&amp;nbsp;정상적으로&amp;nbsp;가져오지&amp;nbsp;못하는&amp;nbsp;경우로&amp;nbsp;판단하여&amp;nbsp;원인을&amp;nbsp;파악하기&amp;nbsp;위해&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;해당&amp;nbsp;이미지의&amp;nbsp;경로를&amp;nbsp;노출할&amp;nbsp;수&amp;nbsp;없기 때문에&amp;nbsp;가상의&amp;nbsp;경로를&amp;nbsp;기준으로&amp;nbsp;설명을&amp;nbsp;진행하겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1687854551186&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;호출 이미지 경로 : /service/img/test.jpg&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;확인방법&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1.&amp;nbsp;개발&amp;nbsp;웹서버&amp;nbsp;해당&amp;nbsp;위치에&amp;nbsp;실제로&amp;nbsp;이미지가&amp;nbsp;존재하는가&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2.&amp;nbsp;웹서버&amp;nbsp;아파치&amp;nbsp;설정&amp;nbsp;확인&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3.&amp;nbsp;운영서버와&amp;nbsp;개발서버의&amp;nbsp;환경차이&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;p data-ke-size=&quot;size16&quot;&gt;1. 개발 웹서버 해당 위치에 실제로 이미지가 존재하는가&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;먼저&amp;nbsp;기본적인&amp;nbsp;방법으로&amp;nbsp;현재&amp;nbsp;호출하고&amp;nbsp;있는&amp;nbsp;웹서버에&amp;nbsp;해당&amp;nbsp;경로에&amp;nbsp;동일한&amp;nbsp;이름으로&amp;nbsp;이미지&amp;nbsp;파일이&amp;nbsp;존재하는지&amp;nbsp;확인을&amp;nbsp;하였음.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;확인결과&amp;nbsp;경로,&amp;nbsp;파일명,&amp;nbsp;권한&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;2.&amp;nbsp;웹서버&amp;nbsp;아파치&amp;nbsp;설정&amp;nbsp;확인&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;혹시라도&amp;nbsp;웹서버상에서&amp;nbsp;WAS와&amp;nbsp;연결하기&amp;nbsp;위한&amp;nbsp;jkmod&amp;nbsp;설정&amp;nbsp;시&amp;nbsp;설정 부분에&amp;nbsp;누락&amp;nbsp;및&amp;nbsp;잘못된&amp;nbsp;설정이&amp;nbsp;있는지&amp;nbsp;확인하였음.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당&amp;nbsp;VirtualHost의&amp;nbsp;설정부분을&amp;nbsp;확인해 보았음.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;JkMountFile에&amp;nbsp;이미지&amp;nbsp;시작&amp;nbsp;경로인&amp;nbsp;service가&amp;nbsp;등록되어&amp;nbsp;있는지&amp;nbsp;확인해&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;같은&amp;nbsp;설정이&amp;nbsp;있었다면&amp;nbsp;웹서버에서&amp;nbsp;이미지를&amp;nbsp;요청하지&amp;nbsp;않고&amp;nbsp;WAS로&amp;nbsp;요청이&amp;nbsp;전달되었을&amp;nbsp;것이다.&lt;/p&gt;
&lt;pre id=&quot;code_1687854724631&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/service=[인스턴스명]
/service*=[인스턴스명]&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다만,&amp;nbsp;해당&amp;nbsp;설정을&amp;nbsp;확인하면서&amp;nbsp;찾은&amp;nbsp;다른&amp;nbsp;설정을&amp;nbsp;확인하였음.&lt;/p&gt;
&lt;pre id=&quot;code_1687854739361&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;	&amp;lt;IfModule mod_weblogic.c&amp;gt;
        Include [경로]/[weblogic 설정 파일]
    &amp;lt;/IfModule&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당&amp;nbsp;설정은&amp;nbsp;mod_weblogic.c&amp;nbsp;모듈이&amp;nbsp;존재하는&amp;nbsp;경우&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;weblogic&amp;nbsp;WAS&amp;nbsp;연동&amp;nbsp;관련&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;서버환경은&amp;nbsp;이기종&amp;nbsp;WAS가&amp;nbsp;다수&amp;nbsp;있기&amp;nbsp;때문에&amp;nbsp;해당&amp;nbsp;설정을&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;2번&amp;nbsp;확인방법에서&amp;nbsp;획득한&amp;nbsp;정보인&amp;nbsp;[경로]/[weblogic&amp;nbsp;설정&amp;nbsp;파일](이하&amp;nbsp;weblogic&amp;nbsp;설정&amp;nbsp;파일)라&amp;nbsp;을&amp;nbsp;가지고&amp;nbsp;3번&amp;nbsp;확인방법으로&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;3.&amp;nbsp;운영서버와&amp;nbsp;개발서버의&amp;nbsp;환경차이&amp;nbsp;확인하기&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;개발서버와&amp;nbsp;운영서버의&amp;nbsp;weblogic&amp;nbsp;설정&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;운영서버의&amp;nbsp;weblogic&amp;nbsp;설정&amp;nbsp;파일의&amp;nbsp;경우&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;/service&amp;nbsp;url&amp;nbsp;관련&amp;nbsp;제어&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;weblogic&amp;nbsp;설정&amp;nbsp;파일의&amp;nbsp;경우&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래와&amp;nbsp;같은&amp;nbsp;설정이&amp;nbsp;확인되었음.&lt;/p&gt;
&lt;pre id=&quot;code_1687854936624&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;MatchExpression /service/*&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당&amp;nbsp;설정은&amp;nbsp;/service로&amp;nbsp;시작하는&amp;nbsp;url&amp;nbsp;요청이&amp;nbsp;들어오는&amp;nbsp;경우&amp;nbsp;weblogic&amp;nbsp;was로&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;운영환경에는&amp;nbsp;없고&amp;nbsp;개발환경에만&amp;nbsp;존재하는&amp;nbsp;설정으로&amp;nbsp;담당자와&amp;nbsp;협의&amp;nbsp;후&amp;nbsp;해당&amp;nbsp;설정을&amp;nbsp;제거&amp;nbsp;후&amp;nbsp;해당&amp;nbsp;경로의&amp;nbsp;이미지를&amp;nbsp;정상적으로&amp;nbsp;표출하는 것을&amp;nbsp;확인하였다.&lt;/p&gt;</description>
      <category>server</category>
      <category>IMAGE</category>
      <category>WAS</category>
      <category>web</category>
      <category>미표출</category>
      <category>웹서버</category>
      <category>이기종</category>
      <category>이미지</category>
      <author>jckim</author>
      <guid isPermaLink="true">https://jckim-dev.tistory.com/47</guid>
      <comments>https://jckim-dev.tistory.com/entry/%EC%9B%B9%EC%84%9C%EB%B2%84-%EC%9D%B4%EB%AF%B8%EC%A7%80-%ED%98%B8%EC%B6%9C%EC%9D%B4-%EC%95%88%EB%90%98%EB%8A%94-%EA%B2%BD%EC%9A%B0%EC%9D%B4%EA%B8%B0%EC%A2%85-WAS-%EC%9A%B4%EC%98%81-%ED%99%98%EA%B2%BD#entry47comment</comments>
      <pubDate>Tue, 27 Jun 2023 17:37:54 +0900</pubDate>
    </item>
    <item>
      <title>다중 컨테이너 일괄 관리 docker compose 적용해보기</title>
      <link>https://jckim-dev.tistory.com/entry/%EB%8B%A4%EC%A4%91-%EC%BB%A8%ED%85%8C%EC%9D%B4%EB%84%88-%EC%9D%BC%EA%B4%84-%EA%B4%80%EB%A6%AC-docker-compose-%EC%A0%81%EC%9A%A9%ED%95%B4%EB%B3%B4%EA%B8%B0</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;이전에 docker를 이용하여 컨테이너를 생성하여 보았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이후 관련 서비스를 추가하면서 컨테이너의 수가 증가하여 개발환경의 PC를 재부팅 시&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기동 해야 하는 컨테이너의 개수 또한 증가하였고 반복적인 일이기 때문에 보다 간편하게 관리가 필요했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이를 해결하기 위해 docker-compose를 적용해 보았다.&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;현재 환경에서 docker-compose 설치여부 확인&lt;/h2&gt;
&lt;pre id=&quot;code_1684502017807&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;docker-compose version&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 버전확인 명령어를 입력하여 docker-compose 설치여부를 확인하는데 설치가 되어있다면 아래와 같이 버전정보 확인이 가능하다.&lt;/p&gt;
&lt;pre id=&quot;code_1684502133901&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;docker-compose version 1.17.1, build unknown
docker-py version: 2.5.1
CPython version: 2.7.17
OpenSSL version: OpenSSL 1.1.1  11 Sep 2018&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;메시지 내에 docker-compose 설치 명령어를 포함하여 안내를 해주고 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1684502197159&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;Command 'docker-compose' not found, but can be installed with:

apt install docker-compose&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 alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1070&quot; data-origin-height=&quot;427&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/5SQq5/btsgDKHq8nx/A181aKg6oxdeMpNmUVyk0K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/5SQq5/btsgDKHq8nx/A181aKg6oxdeMpNmUVyk0K/img.png&quot; data-alt=&quot;docker-compose 설치 진행&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/5SQq5/btsgDKHq8nx/A181aKg6oxdeMpNmUVyk0K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F5SQq5%2FbtsgDKHq8nx%2FA181aKg6oxdeMpNmUVyk0K%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;1070&quot; height=&quot;427&quot; data-origin-width=&quot;1070&quot; data-origin-height=&quot;427&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;docker-compose 설치 진행&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;docker-compose.yml&amp;nbsp;파일&amp;nbsp;생성&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;docker-compose가 관리할 컨테이너 정보들을 입력합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래 예시는&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Redis를 위한 redis이미지 기반의 redis 컨테이너&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;NoSQL DB를 위한 mongo DB 이미지 기반의 mongo 컨테이너&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;에 대한 정보입니다.&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1684502375520&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;version: &quot;3&quot;

services: 
	redis: 
		container_name: redis
		image: redis:latest
		ports:
			- 6379:6379
			
	mongo:
		container_name: mongo
		image: mongo:latest
		ports:
			- 27017:27017&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;docker-compose&amp;nbsp;실행하기&lt;/h2&gt;
&lt;pre id=&quot;code_1684502622287&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;docker-compose up -d

Creating mongo ...
Creating redis ...
Creating mongo
Creating redis ... done&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;docker-compose.yml 파일을 작성한 경로에서 위 명령어를 입력하면 컨데이터가 생성되었다는 메시지를 확인할 수 있습니다.&lt;/p&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;h2 data-ke-size=&quot;size26&quot;&gt;컨테이너 실행상태 확인&lt;/h2&gt;
&lt;pre id=&quot;code_1684502836185&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;docker ps&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;docker-compse up 명령 후 컨테이너 생성 완료 메시지를 확인하였지만&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;docker 명령어로 한번 더 잘 생성되어 실행 중인지 확인하기 위해&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 명령어 실행 후 아래 결과처럼 실행상태를 확인할 수 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1325&quot; data-origin-height=&quot;70&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bh0OW5/btsgEasjpYk/CyRPp3GsM0fPZq4neLP3R1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bh0OW5/btsgEasjpYk/CyRPp3GsM0fPZq4neLP3R1/img.png&quot; data-alt=&quot;docker 컨테이너 실행 상태&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bh0OW5/btsgEasjpYk/CyRPp3GsM0fPZq4neLP3R1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbh0OW5%2FbtsgEasjpYk%2FCyRPp3GsM0fPZq4neLP3R1%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;1325&quot; height=&quot;70&quot; data-origin-width=&quot;1325&quot; data-origin-height=&quot;70&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;docker 컨테이너 실행 상태&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 하여 docker-compose를 처음 도입하는 경우 필요한 최소한의 과정을 정리해 보았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;확실히 많은 컨테이너를 하나하나 실행하는 것보다 시간이 적게 소요되며 실수를 줄일 수 있는 것을 확인할 수 있었다.&lt;/p&gt;</description>
      <category>server</category>
      <category>Compose</category>
      <category>docker</category>
      <category>일괄</category>
      <category>컨테이너</category>
      <author>jckim</author>
      <guid isPermaLink="true">https://jckim-dev.tistory.com/46</guid>
      <comments>https://jckim-dev.tistory.com/entry/%EB%8B%A4%EC%A4%91-%EC%BB%A8%ED%85%8C%EC%9D%B4%EB%84%88-%EC%9D%BC%EA%B4%84-%EA%B4%80%EB%A6%AC-docker-compose-%EC%A0%81%EC%9A%A9%ED%95%B4%EB%B3%B4%EA%B8%B0#entry46comment</comments>
      <pubDate>Fri, 19 May 2023 22:33:49 +0900</pubDate>
    </item>
    <item>
      <title>java Optional orElse() 의도하지 않은 로직 수행 시 확인사항</title>
      <link>https://jckim-dev.tistory.com/entry/java-Optional-orElse-%EC%9D%98%EB%8F%84%ED%95%98%EC%A7%80-%EC%95%8A%EC%9D%80-%EB%A1%9C%EC%A7%81-%EC%88%98%ED%96%89-%EC%8B%9C-%ED%99%95%EC%9D%B8%EC%82%AC%ED%95%AD</link>
      <description>&lt;h4 data-pm-slice=&quot;1 1 []&quot; data-en-clipboard=&quot;true&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Optional이란&lt;/b&gt;&lt;/h4&gt;
&lt;div data-pm-slice=&quot;1 1 []&quot; data-en-clipboard=&quot;true&quot;&gt;java 8버전 이후 부터 java.util 패키지 내 Optional이라는&amp;nbsp; class를 제공한다.&lt;/div&gt;
&lt;div data-pm-slice=&quot;1 1 []&quot; data-en-clipboard=&quot;true&quot;&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;용도는 java 비지니스 로직을 구현하며 많이 발생하는 NPE(NullPointException)을 방지하기 위함이다.&lt;/span&gt;&lt;/div&gt;
&lt;div data-pm-slice=&quot;1 1 []&quot; data-en-clipboard=&quot;true&quot;&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;&lt;/span&gt;&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Optional 사용 시 발생하는 문제점&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Optional get 종류에 따른 결과확인을 위한 소스코드&lt;/p&gt;
&lt;/div&gt;
&lt;pre id=&quot;code_1680877403337&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public static void main(String[] args) {
	System.out.println(&quot;case1 - Optional.get() 수행&quot;);
	Optional&amp;lt;String&amp;gt; case1 = Optional.of(&quot;case1 data&quot;);
	System.out.println(&quot;case1 &quot; + case1.get());
	System.out.println(&quot;====================&quot;);
	System.out.println(&quot;case2 - Optional.get() 수행 (null인 경우)&quot;);
	Optional&amp;lt;String&amp;gt; case2 = Optional.ofNullable(null);
	if(case2.isPresent()){
		System.out.println(case2.get());
	} else {
		System.out.println(&quot;case2 null isPresent() 분기 처리&quot;);
	}

	System.out.println(&quot;====================&quot;);
	System.out.println(&quot;case3 - Optional.orElse() 수행 (null인 경우)&quot;);
	Optional&amp;lt;String&amp;gt; case3 = Optional.ofNullable(null);
	String  case3_rs = case3.orElse(callBase());
	System.out.println(&quot;case3 : &quot; + case3_rs);
	System.out.println(&quot;====================&quot;);
	System.out.println(&quot;case4 - Optional.orElseGet() 수행 (null인 경우)&quot;);
	Optional&amp;lt;String&amp;gt; case4 = Optional.ofNullable(null);
	String case4_rs = case4.orElseGet(()-&amp;gt;callBase());
	System.out.println(&quot;case4 : &quot; + case4_rs);
	System.out.println(&quot;====================&quot;);

	System.out.println(&quot;case5 - Optional.orElse() 수행 &quot;);
	Optional&amp;lt;String&amp;gt; case5 = Optional.ofNullable(&quot;case5 data&quot;);
	String case5_rs = case5.orElse(callBase());
	System.out.println(&quot;case5 : &quot; + case5_rs);

	System.out.println(&quot;====================&quot;);
	System.out.println(&quot;case6 - Optional.orElseGet() 수행&quot;);
	Optional&amp;lt;String&amp;gt; case6 = Optional.ofNullable(&quot;case6 data&quot;);
	String case6_rs = case6.orElseGet(()-&amp;gt;callBase());
	System.out.println(&quot;case6 : &quot; + case6_rs);
}

//호출 테스트용도 메소드
public static String callBase(){
	System.out.println(&quot;callBase...&quot;);
	return &quot;callBase&quot;;
}&lt;/code&gt;&lt;/pre&gt;
&lt;div data-pm-slice=&quot;1 1 []&quot; data-en-clipboard=&quot;true&quot;&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1680877513707&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;실행결과	
case1 - Optional.get() 수행
case1 case1 data
====================
case2 - Optional.get() 수행 (null인 경우)
case2 null isPresent() 분기 처리
====================
case3 - Optional.orElse() 수행 (null인 경우)
callBase...
case3 : callBase
====================
case4 - Optional.orElseGet() 수행 (null인 경우)
callBase...
case4 : callBase
====================
case5 - Optional.orElse() 수행 
callBase...
case5 : case5 data
====================
case6 - Optional.orElseGet() 수행
case6 : case6 data&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div data-pm-slice=&quot;1 1 []&quot; data-en-clipboard=&quot;true&quot;&gt;&lt;b&gt;orElse()로 호출 시 의도하지 않은 로직이 추가적으로 발생하는 경우에 대하여 확인함.&lt;/b&gt;&lt;/div&gt;
&lt;div data-pm-slice=&quot;1 1 []&quot; data-en-clipboard=&quot;true&quot;&gt;case5의 경우 null이 아니기에 해당 객체를 가져오기만 하면 되지만 callBase 메소드가 실행이 되었다.&lt;/div&gt;
&lt;div&gt;테스트 소스코드의 로직상 callBase 메소드가 로그를 출력하는 기능을 담당하지만 비지니스로직을 수행하여 데이터 변경을 수행하였다면 예상하지 않은 결과를 확인할 수 있을 것이다.&lt;/div&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;객체를 가져오는 주요 메소드&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div data-pm-slice=&quot;1 1 []&quot; data-en-clipboard=&quot;true&quot;&gt;&lt;b&gt;Optional.get()&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;Optional 내 객체가 null이 아닌 경우 객체 반환.&lt;/div&gt;
&lt;div&gt;null인 경우 NoSuchElementException 발생.&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;&lt;b&gt;Optional.orElseGet(()-&amp;gt;methodA)&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;Optional 내 객체가 null인 경우에만 methodA가 동작후 값 반환.&lt;/div&gt;
&lt;div&gt;null이 아닌 경우 methodA 미동작 Optional 내 객체 반환.&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;&lt;b&gt;Optional.orElse(methodA)&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;Optional 내 객체가 null여부 상관없이 methodA가 동작&lt;/div&gt;
&lt;div&gt;Optional 내 객체가 null인 경우 methodA의 결과값 반환.&lt;/div&gt;
&lt;div&gt;null이 아닌 경우 Optional 내 객체 반환.&lt;/div&gt;
&lt;div&gt;&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;&lt;/div&gt;
&lt;div&gt;&lt;b&gt;Optional Class 선언된 소스코드 확인&lt;/b&gt;&lt;/div&gt;
&lt;pre id=&quot;code_1680877714345&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;//Optional.class 일부

public T get() {
	if (value == null) {
		throw new NoSuchElementException(&quot;No value present&quot;);
	}
	return value;
}

public T orElseGet(Supplier&amp;lt;? extends T&amp;gt; other) {
	return value != null ? value : other.get();
}

public T orElse(T other) {
	return value != null ? value : other;
}&lt;/code&gt;&lt;/pre&gt;
&lt;div data-pm-slice=&quot;1 1 []&quot; data-en-clipboard=&quot;true&quot;&gt;&lt;b&gt;함수형 인터페이스 중 하나인 Supplier&lt;/b&gt;는 &lt;b&gt;Lazy Evaluation (지연연산)&lt;/b&gt; 할 수 있도록 지원한다.&lt;/div&gt;
&lt;div&gt;따라서 Optional의 orElseGet() 사용시 불필요한 호출을 하지 않아 성능 향상 및 부하를 방지할 수 있다.&lt;/div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1680877944176&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;@FunctionalInterface
public interface Supplier&amp;lt;T&amp;gt; {

    /**
     * Gets a result.
     *
     * @return a result
     */
    T get();
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;div data-pm-slice=&quot;1 1 []&quot; data-en-clipboard=&quot;true&quot;&gt;&lt;b&gt;&lt;/b&gt;&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;&lt;/div&gt;
&lt;div data-pm-slice=&quot;1 1 []&quot; data-en-clipboard=&quot;true&quot;&gt;&lt;b&gt;java7 이전 버전에서의 Lazy Evaluation (지연연산) 예시&lt;/b&gt;&lt;/div&gt;
&lt;pre id=&quot;code_1680878010835&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) {
	if(method1() &amp;amp;&amp;amp; method2()){
		System.out.println(&quot;end in if&quot;);
	}
    System.out.println(&quot;end main&quot;);
}

static boolean method1(){
	System.out.println(&quot;method1 cal...&quot;);
	return false;
}

static boolean method2(){
	System.out.println(&quot;method1 cal2...&quot;);
	return true;
}&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1680878088500&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;실행결과	
method1 cal...
end main&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실행결과를 확인해 보면 if문 내의 조건이 2개 이상이고 and 조건으로 이루어져 있는 경우 선행 조건에서 false로 결정이 되면 이후 조건은 수행하지 않고 다음 로직으로 흘러가는 것을 확인할 수 있다.&lt;/p&gt;</description>
      <category>JAVA</category>
      <category>evaluation</category>
      <category>Java</category>
      <category>java7</category>
      <category>java8</category>
      <category>Lazy</category>
      <category>optional</category>
      <category>orElse</category>
      <category>orElseGet</category>
      <category>Supplier</category>
      <category>지연연산</category>
      <author>jckim</author>
      <guid isPermaLink="true">https://jckim-dev.tistory.com/45</guid>
      <comments>https://jckim-dev.tistory.com/entry/java-Optional-orElse-%EC%9D%98%EB%8F%84%ED%95%98%EC%A7%80-%EC%95%8A%EC%9D%80-%EB%A1%9C%EC%A7%81-%EC%88%98%ED%96%89-%EC%8B%9C-%ED%99%95%EC%9D%B8%EC%82%AC%ED%95%AD#entry45comment</comments>
      <pubDate>Fri, 7 Apr 2023 23:51:47 +0900</pubDate>
    </item>
    <item>
      <title>한정수량 무작위 즉석 당첨 이벤트 개발(동시성 문제 해결)</title>
      <link>https://jckim-dev.tistory.com/entry/%ED%95%9C%EC%A0%95%EC%88%98%EB%9F%89-%EB%AC%B4%EC%9E%91%EC%9C%84-%EC%A6%89%EC%84%9D-%EB%8B%B9%EC%B2%A8-%EC%9D%B4%EB%B2%A4%ED%8A%B8-%EA%B0%9C%EB%B0%9C%EB%8F%99%EC%8B%9C%EC%84%B1-%EB%AC%B8%EC%A0%9C-%ED%95%B4%EA%B2%B0</link>
      <description>&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;작업내용&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;매일 한정된 수의 사용자를 접속시점 무작위로 당첨시켜 사용자 정보를 적재 및 즉석으로 확인 가능한 기능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;현재 상황&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;작업환경&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;2대 이상의 다중 서버 환경&lt;/li&gt;
&lt;li&gt;messageQueue 용도 서버 도입 불가&lt;/li&gt;
&lt;li&gt;oracle DB RAC 환경&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;최초로직&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;쿠폰을&amp;nbsp;지급하기 전&amp;nbsp;현재까지&amp;nbsp;당첨된&amp;nbsp;사용자의&amp;nbsp;수를&amp;nbsp;조회하여&amp;nbsp;한정된&amp;nbsp;수치에&amp;nbsp;도달하지&amp;nbsp;않은&amp;nbsp;경우&amp;nbsp;당첨자&amp;nbsp;정보를&amp;nbsp;DB에&amp;nbsp;적재하는&amp;nbsp;방법&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;&lt;b&gt;최초로직 문제점&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를들어&amp;nbsp;100개&amp;nbsp;한정된&amp;nbsp;수량의&amp;nbsp;쿠폰을&amp;nbsp;지급&amp;nbsp;시&amp;nbsp;&lt;b&gt;다중서버&amp;nbsp;및&amp;nbsp;동시응모에&amp;nbsp;의한&amp;nbsp;100명을&amp;nbsp;초과하는&amp;nbsp;당첨자가&amp;nbsp;발생&lt;/b&gt;하는&amp;nbsp;경우를&amp;nbsp;확인 &lt;br /&gt;(이때&amp;nbsp;테스트는&amp;nbsp;junit을&amp;nbsp;통하여&amp;nbsp;멀티스레드&amp;nbsp;환경으로&amp;nbsp;진행)&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;&lt;b&gt;최초로직&amp;nbsp;원인&lt;/b&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1679704918941&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;A트랜잭션과 B트랜잭션이 거의 동시에 진행된 경우
A트랜잭션 조회 시점에 당첨자 수 99명
	당첨자 적재 100명
	커밋
B트랜잭션 조회 시점에 당첨자 수 99명
	당첨자 적재 101명
	커밋&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약&amp;nbsp;서버&amp;nbsp;수와&amp;nbsp;동시진행&amp;nbsp;숫자에&amp;nbsp;따라서&amp;nbsp;초과한&amp;nbsp;숫자는&amp;nbsp;더&amp;nbsp;커질&amp;nbsp;수&amp;nbsp;있다.&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;&lt;b&gt;최초로직 개선&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가능한&amp;nbsp;비즈니스&amp;nbsp;로직으로&amp;nbsp;풀어보려&amp;nbsp;당첨자&amp;nbsp;적재&amp;nbsp;후&amp;nbsp;일일&amp;nbsp;한정된&amp;nbsp;수치를&amp;nbsp;초과한&amp;nbsp;경우&amp;nbsp;해당&amp;nbsp;당첨자를&amp;nbsp;낙첨으로&amp;nbsp;업데이트하려고&amp;nbsp;하였으나&amp;nbsp;이&amp;nbsp;방법&amp;nbsp;역시&amp;nbsp;동일한&amp;nbsp;원인으로&amp;nbsp;동일한&amp;nbsp;문제점이&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;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;개선로직 1&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;당첨자&amp;nbsp;적재하는&amp;nbsp;메서드에&amp;nbsp;@Transactional&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;&lt;b&gt;개선로직 1.1&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;적재&amp;nbsp;메서드에&amp;nbsp;@Transactional(isolation=Isolation.READ_UNCOMMITTED)&amp;nbsp;격리레벨을&amp;nbsp;적용하여&amp;nbsp;적재시점에&amp;nbsp;커밋되지&amp;nbsp;않은&amp;nbsp;내용까지&amp;nbsp;조회&amp;nbsp;후&amp;nbsp;한정&amp;nbsp;수치&amp;nbsp;초과&amp;nbsp;여부를&amp;nbsp;판단&amp;nbsp;후&amp;nbsp;당첨자&amp;nbsp;적재하는&amp;nbsp;방법&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1679705035273&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;org.springframework.transaction.CannotCreateTransactionException: Could not open JDBC Connection for transaction; nested exception is java.sql.SQLException:
READ_COMMITTED와 SERIALIZABLE만이 적합한 트랜잭션 레벨입니다&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;오라클&amp;nbsp;DB는&amp;nbsp;해당&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;&lt;b&gt;개선로직 1.2&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;적재&amp;nbsp;메서드에&amp;nbsp;@Transactional(isolation=Isolation.SERIALIZABLE)&amp;nbsp;격리레벨을&amp;nbsp;적용하여&amp;nbsp;현재&amp;nbsp;총&amp;nbsp;당첨자&amp;nbsp;수를&amp;nbsp;저장하는&amp;nbsp;레코드를&amp;nbsp;동시에&amp;nbsp;수정할&amp;nbsp;수&amp;nbsp;없도록&amp;nbsp;하는&amp;nbsp;방법 &lt;br /&gt;&lt;br /&gt;해당 격리레벨을 적용하였을 때 테스트 환경임에도 성능이 감소되어 운영환경에 적용 시 &lt;b&gt;성능저하 및 장애발생 우려&lt;/b&gt;되어 보류.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&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;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;개선로직 2(성공)&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;oracle&amp;nbsp;시퀀스를&amp;nbsp;활용&lt;/b&gt;하여&amp;nbsp;당첨일련번호&amp;nbsp;발급하는&amp;nbsp;방법 &lt;br /&gt;&lt;br /&gt;DB서버가&amp;nbsp;1대&amp;nbsp;이상인&amp;nbsp;RAC환경이지만&amp;nbsp;시퀀스&amp;nbsp;옵션을&amp;nbsp;조정하여&amp;nbsp;WAS서버의&amp;nbsp;대수와&amp;nbsp;동시응모와&amp;nbsp;상관없이&amp;nbsp;시퀀스를&amp;nbsp;순차적으로&amp;nbsp;증가할&amp;nbsp;수&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;용도의&amp;nbsp;오라클&amp;nbsp;시퀀스를&amp;nbsp;생성&lt;/p&gt;
&lt;pre id=&quot;code_1679705154427&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;CREATE SEQUENCE 당첨일련번호_시퀀스
  START WITH 1
  MAXVALUE 999999
  MINVALUE 0
  NOCYCLE
  NOCACHE
  ORDER;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;NOCACHE와&amp;nbsp;ORDER&amp;nbsp;옵션을&amp;nbsp;선언하여&amp;nbsp;어떤&amp;nbsp;DB서버가&amp;nbsp;여러 대인&amp;nbsp;경우에도&amp;nbsp;일련번호를&amp;nbsp;순차적으로&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;시퀀스를 활용하여 작성한 주요 로직은 아래와 같다.&lt;/p&gt;
&lt;pre id=&quot;code_1679705295129&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;if(당첨자인 경우){
	int 당첨자일련번호 = 적재하기 전 시퀀스를 통하여 당첨자일련번호 채번;
    
    if(당첨자일련번호 &amp;gt; 일일 당첨자한정수치){
        당첨되었지만 동시응모 후순위 상황으로 낙첨 처리
    } else {
        당첨정보와 함께 당첨자일련번호 적재
    }
}&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;로직상 시퀀스 증가를 계속해서 하는 경우라면 DB에도 부하가 발생할 수 있으나 현재 상황에서&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;span&gt;messageQueue를 사용하여 동시성 문제를 해결하는 로직을 개인 프로젝트에 적용을 고려해보려 한다.&lt;/span&gt;&lt;/p&gt;</description>
      <category>설계</category>
      <category>Oracle</category>
      <category>동시성</category>
      <category>선착순</category>
      <category>초과</category>
      <category>쿠폰이벤트</category>
      <category>한정수량</category>
      <author>jckim</author>
      <guid isPermaLink="true">https://jckim-dev.tistory.com/44</guid>
      <comments>https://jckim-dev.tistory.com/entry/%ED%95%9C%EC%A0%95%EC%88%98%EB%9F%89-%EB%AC%B4%EC%9E%91%EC%9C%84-%EC%A6%89%EC%84%9D-%EB%8B%B9%EC%B2%A8-%EC%9D%B4%EB%B2%A4%ED%8A%B8-%EA%B0%9C%EB%B0%9C%EB%8F%99%EC%8B%9C%EC%84%B1-%EB%AC%B8%EC%A0%9C-%ED%95%B4%EA%B2%B0#entry44comment</comments>
      <pubDate>Sat, 25 Mar 2023 10:02:48 +0900</pubDate>
    </item>
    <item>
      <title>Eclipse Save could not be completed. character encoding.</title>
      <link>https://jckim-dev.tistory.com/entry/Eclipse-Save-could-not-be-completed-character-encoding</link>
      <description>&lt;div data-pm-slice=&quot;1 1 []&quot; data-en-clipboard=&quot;true&quot;&gt;IDE로 Eclipse를 사용하여 작업하는 환경에서 기존에 생성되어있는 java 파일을 작업하던 중&lt;/div&gt;
&lt;div data-pm-slice=&quot;1 1 []&quot; data-en-clipboard=&quot;true&quot;&gt;수정 후 저장을 시도하는 순간아래와 같은 메시지창이 표출되었다.&lt;/div&gt;
&lt;div data-pm-slice=&quot;1 1 []&quot; data-en-clipboard=&quot;true&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;20230323_1.png&quot; data-origin-width=&quot;534&quot; data-origin-height=&quot;205&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/YMZLy/btr5E25F9NZ/DrX10oJ2w26OWmmNGUUYW1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/YMZLy/btr5E25F9NZ/DrX10oJ2w26OWmmNGUUYW1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/YMZLy/btr5E25F9NZ/DrX10oJ2w26OWmmNGUUYW1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FYMZLy%2Fbtr5E25F9NZ%2FDrX10oJ2w26OWmmNGUUYW1%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;534&quot; height=&quot;205&quot; data-filename=&quot;20230323_1.png&quot; data-origin-width=&quot;534&quot; data-origin-height=&quot;205&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1679579370932&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;Eclipse Save could not be completed. Try File &amp;gt; Save As... if the problem persists.

Reason:
Some characters cannot be mapped using &quot;EUC-KR&quot; character encoding.
Either change the encoding or remove the characters which are not supported by the &quot;EUC-KR&quot; character encoding.&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;div&gt;&lt;b&gt;해당 메시지에서 안내해주는 원인은 EUC-KR 인코딩이 지원되지 않는 문자가 존재하여 저장이 불가능하다는 내용이었다.&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;현재 작업을 진행하고 있는 프로젝트의 인코딩은 EUC-KR로 IDE editor의 인코딩 역시 EUC-KR로 설정되어있다.&lt;/div&gt;
&lt;div&gt;&lt;b&gt;인코딩 설정 방법&lt;/b&gt;은 아래와 같다.&lt;/div&gt;
&lt;div&gt;IDE 상단 - Window - Prefrerences - General - Content Types - Content Types와 File associations 항목에서 파일 유형을 선택 후 Default encoding 항목에 설정할 인코딩 값을 입력 후 Update 버튼을 클릭&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;20230323_2.png&quot; data-origin-width=&quot;642&quot; data-origin-height=&quot;706&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c8xZv8/btr5CvAy8vm/N5S4NHuwJEx8EWFvIfEM81/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c8xZv8/btr5CvAy8vm/N5S4NHuwJEx8EWFvIfEM81/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c8xZv8/btr5CvAy8vm/N5S4NHuwJEx8EWFvIfEM81/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc8xZv8%2Fbtr5CvAy8vm%2FN5S4NHuwJEx8EWFvIfEM81%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;642&quot; height=&quot;706&quot; data-filename=&quot;20230323_2.png&quot; data-origin-width=&quot;642&quot; data-origin-height=&quot;706&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;그동안 정상적으로 수정 후 저장을 진행하였는데 갑작스럽게 해당 메시지가 확인이 되어 작업한 부분을 확인해보았다.&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;문제가 발생하는 파일의 작업한 부분을 확인한 결과 주석부분이 문제인 것으로 확인이 되었다.&lt;/div&gt;
&lt;div&gt;주석부분에 한글로 내용을 작성한 부분인데 한글 자체가 문제가 되는 것은 아니었으며&lt;/div&gt;
&lt;div&gt;&lt;b&gt;오타가 발생하였으나 EUC-KR에서 지원하지 않는 한글형식&lt;/b&gt;이었음을 확인하였다.&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1679579442727&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;문제가 발생한 주석 부분
//츸출 -&amp;gt; 추출&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;해당 주석 부분을 수정 후 정상적으로 저장됨을 확인하였다.&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;애초에 기존에 작업물의 인코딩을 따라가는 것이 보편적인 방법이기에 오타 부분을 수정하였으나&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;혹시라도 신규 프로젝트 및 파일에서 해당 문제가 발생하는 경우 &lt;b&gt;인코딩 설정 방법&lt;/b&gt;을 통하여 확장자별 올바른 인코딩을&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;지정해 주어 문제를 해결하는 방법도 있을 것으로 보인다.&lt;/p&gt;</description>
      <category>기타</category>
      <category>Character</category>
      <category>Eclipse</category>
      <category>encoding</category>
      <category>Save could not be completed</category>
      <category>저장불가</category>
      <author>jckim</author>
      <guid isPermaLink="true">https://jckim-dev.tistory.com/43</guid>
      <comments>https://jckim-dev.tistory.com/entry/Eclipse-Save-could-not-be-completed-character-encoding#entry43comment</comments>
      <pubDate>Thu, 23 Mar 2023 22:55:40 +0900</pubDate>
    </item>
    <item>
      <title>vscode Execution failed for task ':compileJava' 해결</title>
      <link>https://jckim-dev.tistory.com/entry/vscode-Execution-failed-for-task-compileJava-%ED%95%B4%EA%B2%B0</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;vscode 환경에서 JAVA, SpringBoot, Gradle의 개발환경에서&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;최초 작업하였던 PC가 아닌 다른 PC에서 소스를 내려받은 후&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;작업을&amp;nbsp;진행하기&amp;nbsp;위해&amp;nbsp;프로젝트&amp;nbsp;실행을&amp;nbsp;하던 중&amp;nbsp;아래와&amp;nbsp;같은&amp;nbsp;오류메시지가&amp;nbsp;발생하였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1677499295682&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;PS 프로젝트경로위치&amp;gt; .\gradlew.bat bootrun
Starting a Gradle Daemon, 1 incompatible Daemon could not be reused, use --status for details

&amp;gt; Configure project :
zone: null

&amp;gt; Task :compileJava FAILED

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':compileJava'.
&amp;gt; invalid source release: 11

* Try:
&amp;gt; Run with --stacktrace option to get the stack trace.
&amp;gt; Run with --info or --debug option to get more log output.
&amp;gt; Run with --scan to get full insights.

* Get more help at https://help.gradle.org

BUILD FAILED in 11s
1 actionable task: 1 executed&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당&amp;nbsp;메시지는&amp;nbsp;JAVA&amp;nbsp;컴파일에&amp;nbsp;실패하였다는&amp;nbsp;내용의&amp;nbsp;메시지로&amp;nbsp;현재&amp;nbsp;상황에서&amp;nbsp;확인할&amp;nbsp;수&amp;nbsp;있는&amp;nbsp;방법을&amp;nbsp;아래와&amp;nbsp;같이&amp;nbsp;순차적으로&amp;nbsp;진행해보려고&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;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;현재&amp;nbsp;작업을&amp;nbsp;진행중인&amp;nbsp;PC의&amp;nbsp;JAVA&amp;nbsp;버전&amp;nbsp;확인하기&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CMD&amp;nbsp;또는&amp;nbsp;터미널&amp;nbsp;창을&amp;nbsp;열고&amp;nbsp;아래&amp;nbsp;명령어를&amp;nbsp;입력&amp;nbsp;후&amp;nbsp;환경변수로&amp;nbsp;잡혀있는&amp;nbsp;JAVA&amp;nbsp;버전을&amp;nbsp;확인한다.&lt;/p&gt;
&lt;pre id=&quot;code_1677499343351&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;java -version
java version &quot;1.8.0_301&quot;
Java(TM) SE Runtime Environment (build 1.8.0_301-b09)   
Java HotSpot(TM) 64-Bit Server VM (build 25.301-b09, mixed mode)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;현재&amp;nbsp;작업중인&amp;nbsp;PC의&amp;nbsp;JAVA&amp;nbsp;버전은&amp;nbsp;1.8 임을&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;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;실행하고자&amp;nbsp;하는&amp;nbsp;프로젝트의&amp;nbsp;빌드&amp;nbsp;설정&amp;nbsp;확인하기&lt;/b&gt; &lt;br /&gt;&lt;br /&gt;현재&amp;nbsp;작업중인&amp;nbsp;프로젝트의&amp;nbsp;빌드도구는&amp;nbsp;gradle&amp;nbsp;이기&amp;nbsp;때문에&amp;nbsp;아래&amp;nbsp;경로에서&amp;nbsp;설정값을&amp;nbsp;확인한다.&lt;/p&gt;
&lt;pre id=&quot;code_1677499366502&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;프로젝트경로위치\build.gradle

sourceCompatibility = '11'&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위항목에서&amp;nbsp;확인한&amp;nbsp;설정으로는&amp;nbsp;gradle로&amp;nbsp;빌드&amp;nbsp;시&amp;nbsp;JAVA&amp;nbsp;11 버전으로&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;&lt;b&gt;정리&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;현재&amp;nbsp;상황을&amp;nbsp;정리하면&amp;nbsp;최초&amp;nbsp;작업하였던&amp;nbsp;PC에서는&amp;nbsp;환경변수의&amp;nbsp;JAVA&amp;nbsp;버전이&amp;nbsp;11로&amp;nbsp;설정되어 있던&amp;nbsp;상태이고&amp;nbsp;프로젝트의&amp;nbsp;gradle&amp;nbsp;빌드&amp;nbsp;설정&amp;nbsp;내에&amp;nbsp;JAVA&amp;nbsp;11 버전으로&amp;nbsp;컴파일을&amp;nbsp;진행하도록&amp;nbsp;선언되어 있었다. &lt;br /&gt;&lt;br /&gt;하지만 다른 PC에서 작업을 진행하려고 하니 현재 PC에서는 환경변수의 JAVA 버전이 8로 선언되어있었으며 프로젝트의&amp;nbsp;gradle 빌드 설정 내 컴파일 버전선언은 그대로 JAVA 11 버전으로 선언되어 있던 것이다.&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;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;빌드오류를 조치하기&lt;/b&gt;&lt;br /&gt;gradle&amp;nbsp;프로퍼티&amp;nbsp;내에&amp;nbsp;java&amp;nbsp;위치를&amp;nbsp;직접&amp;nbsp;선언하기&lt;/p&gt;
&lt;pre id=&quot;code_1677499408917&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;프로젝트경로위치\gradle.properties

org.gradle.java.home=C:\\Program Files\\Java\\java-11-openjdk-11.0.13.8-1.windows.redhat.x86_64&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;재설정&amp;nbsp;후&amp;nbsp;정상적으로&amp;nbsp;bootRun&amp;nbsp;된&amp;nbsp;상태&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;bootRun-2.png&quot; data-origin-width=&quot;366&quot; data-origin-height=&quot;140&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kY9mv/btr0JA872Mx/X1iJxYKC4QAK2A2xgMNQaK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kY9mv/btr0JA872Mx/X1iJxYKC4QAK2A2xgMNQaK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kY9mv/btr0JA872Mx/X1iJxYKC4QAK2A2xgMNQaK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FkY9mv%2Fbtr0JA872Mx%2FX1iJxYKC4QAK2A2xgMNQaK%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;366&quot; height=&quot;140&quot; data-filename=&quot;bootRun-2.png&quot; data-origin-width=&quot;366&quot; data-origin-height=&quot;140&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;bootrun-1.png&quot; data-origin-width=&quot;311&quot; data-origin-height=&quot;42&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/k6pgP/btr0KG2pt61/u3FrqIKhBcmq5auEPzIIy0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/k6pgP/btr0KG2pt61/u3FrqIKhBcmq5auEPzIIy0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/k6pgP/btr0KG2pt61/u3FrqIKhBcmq5auEPzIIy0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fk6pgP%2Fbtr0KG2pt61%2Fu3FrqIKhBcmq5auEPzIIy0%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;311&quot; height=&quot;42&quot; data-filename=&quot;bootrun-1.png&quot; data-origin-width=&quot;311&quot; data-origin-height=&quot;42&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;</description>
      <category>JAVA</category>
      <category>bootrun</category>
      <category>build</category>
      <category>compileJava</category>
      <category>Execution failed for task</category>
      <category>Fail</category>
      <category>gradle</category>
      <category>Java</category>
      <category>javahome</category>
      <category>SpringBoot</category>
      <category>vscode</category>
      <author>jckim</author>
      <guid isPermaLink="true">https://jckim-dev.tistory.com/42</guid>
      <comments>https://jckim-dev.tistory.com/entry/vscode-Execution-failed-for-task-compileJava-%ED%95%B4%EA%B2%B0#entry42comment</comments>
      <pubDate>Mon, 27 Feb 2023 21:08:17 +0900</pubDate>
    </item>
    <item>
      <title>Docker 다량 컨테이너 실행 간소화</title>
      <link>https://jckim-dev.tistory.com/entry/Docker-%EB%8B%A4%EB%9F%89-%EC%BB%A8%ED%85%8C%EC%9D%B4%EB%84%88-%EC%8B%A4%ED%96%89-%EA%B0%84%EC%86%8C%ED%99%94</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;최근 MSA기반으로 진행 중인 개인 프로젝트를 작업하다 보니 &lt;br /&gt;서비스별로&amp;nbsp;프로젝트를&amp;nbsp;분리하고&amp;nbsp;연관된&amp;nbsp;데몬을&amp;nbsp;Docker&amp;nbsp;컨테이너로&amp;nbsp;관리하는데 &lt;br /&gt;시작이 반이라고 작업전 컨테이너를 실행 전 개발 작업을 시작하기까지 &lt;br /&gt;시간이 다소 소요되니 작업을 하고자 행동에 옮기는 횟수가 줄어들어 버렸다. &lt;br /&gt;&lt;br /&gt;현재 보유하고 있는 docker image와 container는 아래와 같다. &lt;br /&gt;개인프로젝트로&amp;nbsp;테스트용도로&amp;nbsp;생성된&amp;nbsp;이미지도&amp;nbsp;많지만&amp;nbsp;현재&amp;nbsp;하나의&amp;nbsp;프로젝트를 &lt;br /&gt;개발&amp;nbsp;및&amp;nbsp;테스트하기&amp;nbsp;위해서는&amp;nbsp;최소&amp;nbsp;3개&amp;nbsp;이상의&amp;nbsp;컨테이너를&amp;nbsp;실행해야한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;621&quot; data-origin-height=&quot;197&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/TpZuq/btrWRzrmMZb/0Fh2qtoRkTLTW8vd81VCQK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/TpZuq/btrWRzrmMZb/0Fh2qtoRkTLTW8vd81VCQK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/TpZuq/btrWRzrmMZb/0Fh2qtoRkTLTW8vd81VCQK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FTpZuq%2FbtrWRzrmMZb%2F0Fh2qtoRkTLTW8vd81VCQK%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;621&quot; height=&quot;197&quot; data-origin-width=&quot;621&quot; data-origin-height=&quot;197&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1627&quot; data-origin-height=&quot;295&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bEgaSq/btrWQLzcZJc/Ik7UU0VasqlK4aJRbWebP0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bEgaSq/btrWQLzcZJc/Ik7UU0VasqlK4aJRbWebP0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bEgaSq/btrWQLzcZJc/Ik7UU0VasqlK4aJRbWebP0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbEgaSq%2FbtrWQLzcZJc%2FIk7UU0VasqlK4aJRbWebP0%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;1627&quot; height=&quot;295&quot; data-origin-width=&quot;1627&quot; data-origin-height=&quot;295&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;br /&gt;컨테이너를&amp;nbsp;실행하기&amp;nbsp;위해서는&amp;nbsp;아래와&amp;nbsp;같은&amp;nbsp;명령어를&amp;nbsp;입력한다.&lt;/p&gt;
&lt;pre id=&quot;code_1674228751165&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;docker start redis
docker start mongodb-container
docker start mysql-container
docker start mbtidiscovery&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;docker가 실행되고 있는 환경이 리눅스 환경이기 때문에 알고있는 지식과 빠르게 적용이 가능한&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;리눅스 쉘을 활용하여 동일하게 반복되는 명령어를 최소의 동작으로 대체할 수 있도록 하였다. &lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1674228800107&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;vi docker_container_start.sh

#!/bin/sh

echo &quot;docker container auto start&quot;

echo &quot;docker start mongodb-container&quot;
docker start mongodb-container

echo &quot;docker start redis&quot;
docker start redis

echo &quot;docker start mysql-container&quot;
docker start mysql-container

echo &quot;docker start mbtidiscovery&quot;
docker start mbtidiscovery

docker ps&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;br /&gt;해당&amp;nbsp;쉘을&amp;nbsp;실행&amp;nbsp;후&amp;nbsp;모든&amp;nbsp;컨테이너가&amp;nbsp;정상적으로&amp;nbsp;실행된&amp;nbsp;것을&amp;nbsp;확인할&amp;nbsp;수&amp;nbsp;있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1095&quot; data-origin-height=&quot;422&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bSMax3/btrWR7gPZVb/C2jx2Q8RcFeo14SK9FdyX0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bSMax3/btrWR7gPZVb/C2jx2Q8RcFeo14SK9FdyX0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bSMax3/btrWR7gPZVb/C2jx2Q8RcFeo14SK9FdyX0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbSMax3%2FbtrWR7gPZVb%2FC2jx2Q8RcFeo14SK9FdyX0%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;1095&quot; height=&quot;422&quot; data-origin-width=&quot;1095&quot; data-origin-height=&quot;422&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;br /&gt;컨테이너&amp;nbsp;종료도&amp;nbsp;마찬가지다&amp;nbsp;start&amp;nbsp;&amp;nbsp;명령어를&amp;nbsp;stop으로&amp;nbsp;변경해&amp;nbsp;주었다. &lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1674228837778&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;vi docker_container_stop.sh

#!/bin/sh

echo &quot;docker container auto stop&quot;

echo &quot;docker stop mongodb-container&quot;
docker stop mongodb-container

echo &quot;docker stop redis&quot;
docker stop redis

echo &quot;docker stop mysql-container&quot;
docker stop mysql-container

echo &quot;docker stop mbtidiscovery&quot;
docker stop mbtidiscovery

docker ps&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당&amp;nbsp;쉘을&amp;nbsp;실행&amp;nbsp;후&amp;nbsp;모든&amp;nbsp;컨테이너가&amp;nbsp;정상적으로&amp;nbsp;종료된&amp;nbsp;것을&amp;nbsp;확인할&amp;nbsp;수&amp;nbsp;있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;700&quot; data-origin-height=&quot;276&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/6Z21N/btrWQazDRmj/JYUeG42hb40i6IXBCtI1W1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/6Z21N/btrWQazDRmj/JYUeG42hb40i6IXBCtI1W1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/6Z21N/btrWQazDRmj/JYUeG42hb40i6IXBCtI1W1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F6Z21N%2FbtrWQazDRmj%2FJYUeG42hb40i6IXBCtI1W1%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;700&quot; height=&quot;276&quot; data-origin-width=&quot;700&quot; data-origin-height=&quot;276&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;현재는&amp;nbsp;개인&amp;nbsp;프로젝트로&amp;nbsp;실행해야하는&amp;nbsp;컨테이너의&amp;nbsp;수가&amp;nbsp;적지만 &lt;br /&gt;보다&amp;nbsp;&lt;b&gt;프로젝트&amp;nbsp;규모&lt;/b&gt;가&amp;nbsp;커지는&amp;nbsp;경우와&amp;nbsp;제어를하는&amp;nbsp;&lt;b&gt;사용자가&amp;nbsp;여러명인&amp;nbsp;경우&lt;/b&gt; &lt;br /&gt;하나의&amp;nbsp;쉘파일을&amp;nbsp;계속하여&amp;nbsp;수정하기에는&amp;nbsp;관리하기&amp;nbsp;힘들어질&amp;nbsp;수&amp;nbsp;있다. &lt;br /&gt;&lt;br /&gt;지금&amp;nbsp;당장은&amp;nbsp;쉘파일을&amp;nbsp;작성하여&amp;nbsp;반복되는&amp;nbsp;작업을&amp;nbsp;대처하였지만 &lt;br /&gt;규모와 협업을 위해서라도 &lt;b&gt;docker compose, 쿠버네티스 등의 컨테이너 관리 도구의 기능을 활용&lt;/b&gt;해야 할 것으로 보인다.&lt;/p&gt;</description>
      <category>server</category>
      <category>Container</category>
      <category>docker</category>
      <category>IMAGE</category>
      <category>START</category>
      <category>반복</category>
      <category>쉘</category>
      <category>실행</category>
      <category>컨테이너</category>
      <author>jckim</author>
      <guid isPermaLink="true">https://jckim-dev.tistory.com/41</guid>
      <comments>https://jckim-dev.tistory.com/entry/Docker-%EB%8B%A4%EB%9F%89-%EC%BB%A8%ED%85%8C%EC%9D%B4%EB%84%88-%EC%8B%A4%ED%96%89-%EA%B0%84%EC%86%8C%ED%99%94#entry41comment</comments>
      <pubDate>Sat, 21 Jan 2023 00:39:27 +0900</pubDate>
    </item>
    <item>
      <title>캐시 시스템 선택시 고려사항(Redis, Memcached)</title>
      <link>https://jckim-dev.tistory.com/entry/%EC%BA%90%EC%8B%9C-%EC%8B%9C%EC%8A%A4%ED%85%9C-%EC%84%A0%ED%83%9D%EC%8B%9C-%EA%B3%A0%EB%A0%A4%EC%82%AC%ED%95%ADRedis-Memcached</link>
      <description>&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;캐시 시스템을 사용하는 이유&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;DB, API 등의 호출이 빈번한 경우&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;서버에 많은 요청으로 인한 부하를 방지하기 위함이다. &lt;br /&gt;&lt;br /&gt;캐시 시스템하면 가장 대표적이고 많이 비교하는 캐시 시스템인&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;Memcached와 Redis에 대하여 확인해 보았습니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;br /&gt;&lt;b&gt;Memcached&amp;nbsp;특징&lt;/b&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;LRU 알고리즘만 채택&lt;/li&gt;
&lt;li&gt;Master/Master 리플리케이션 지원&lt;/li&gt;
&lt;li&gt;Consistent Hashing을 통한 데이터 분산 지원&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;br /&gt;&lt;b&gt;Redis&amp;nbsp;특징&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&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;복제&lt;/li&gt;
&lt;li&gt;트랜잭션&lt;/li&gt;
&lt;li&gt;Pub(발행) Sub(구독) 메시지 패턴 지원&lt;/li&gt;
&lt;li&gt;루아 스크립트 지원&lt;/li&gt;
&lt;li&gt;위치기반 데이터 타입 지원&lt;/li&gt;
&lt;li&gt;다양한&amp;nbsp;data&amp;nbsp;eviction&amp;nbsp;전략&amp;nbsp;지원&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;br /&gt;&lt;b&gt;Memcached를&amp;nbsp;채택하는&amp;nbsp;경우&lt;/b&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;스케일업&amp;nbsp;형태의&amp;nbsp;확장&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;br /&gt;&lt;b&gt;Redis를&amp;nbsp;채택하는&amp;nbsp;경우&lt;/b&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;캐싱하고자&amp;nbsp;하는&amp;nbsp;데이터가&amp;nbsp;복잡한&amp;nbsp;형태인&amp;nbsp;경우&lt;/li&gt;
&lt;li&gt;캐싱하고자&amp;nbsp;하는&amp;nbsp;데이터의&amp;nbsp;변경이&amp;nbsp;잦은&amp;nbsp;경우&lt;/li&gt;
&lt;li&gt;메모리가&amp;nbsp;소멸되면&amp;nbsp;서비스&amp;nbsp;장애를&amp;nbsp;유발하는&amp;nbsp;경우&lt;/li&gt;
&lt;li&gt;스케일아웃 형태와 확장&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;그 외 자주 사용하는 캐시 라이브러리&lt;/b&gt;&lt;br /&gt;&lt;b&gt;Ehcache&lt;/b&gt; &lt;br /&gt;&lt;br /&gt;Ehcache&amp;nbsp;Spring에서&amp;nbsp;간단하게&amp;nbsp;사용할&amp;nbsp;수&amp;nbsp;있는&amp;nbsp;Java기반&amp;nbsp;오픈소스&amp;nbsp;캐시&amp;nbsp;라이브러리이다. &lt;br /&gt;&lt;br /&gt;redis나&amp;nbsp;memcached&amp;nbsp;같은&amp;nbsp;캐시&amp;nbsp;엔진과는&amp;nbsp;달리&amp;nbsp;ehcache는&amp;nbsp;별도의&amp;nbsp;데몬&amp;nbsp;형태의&amp;nbsp;구동&amp;nbsp;없이&amp;nbsp;애플리케이션&amp;nbsp;구동 시&amp;nbsp;Spring&amp;nbsp;내부적으로&amp;nbsp;캐싱&amp;nbsp;처리를&amp;nbsp;지원한다. &lt;br /&gt;&lt;br /&gt;로컬&amp;nbsp;캐시&amp;nbsp;환경으로&amp;nbsp;캐시&amp;nbsp;서버와의&amp;nbsp;통신&amp;nbsp;장애에&amp;nbsp;대한&amp;nbsp;문제를&amp;nbsp;방지할&amp;nbsp;수&amp;nbsp;있고&amp;nbsp;애플리케이션과&amp;nbsp;라이프사이클이&amp;nbsp;함께&amp;nbsp;관리되는&amp;nbsp;장점이&amp;nbsp;있다.&lt;/p&gt;</description>
      <category>기타</category>
      <category>ehcache</category>
      <category>memcached</category>
      <category>redis</category>
      <category>캐시</category>
      <author>jckim</author>
      <guid isPermaLink="true">https://jckim-dev.tistory.com/40</guid>
      <comments>https://jckim-dev.tistory.com/entry/%EC%BA%90%EC%8B%9C-%EC%8B%9C%EC%8A%A4%ED%85%9C-%EC%84%A0%ED%83%9D%EC%8B%9C-%EA%B3%A0%EB%A0%A4%EC%82%AC%ED%95%ADRedis-Memcached#entry40comment</comments>
      <pubDate>Wed, 28 Dec 2022 00:09:17 +0900</pubDate>
    </item>
    <item>
      <title>VScode 콘솔창 gradle profiles 적용이 안됨 조치</title>
      <link>https://jckim-dev.tistory.com/entry/VScode-%EC%BD%98%EC%86%94%EC%B0%BD-gradle-profiles-%EC%A0%81%EC%9A%A9%EC%9D%B4-%EC%95%88%EB%90%A8-%EC%A1%B0%EC%B9%98</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;발단&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;윈도우즈&amp;nbsp;환경에서&amp;nbsp;VScode&amp;nbsp;IDE를&amp;nbsp;사용하여&amp;nbsp;SpringBoot&amp;nbsp;+&amp;nbsp;Gradle&amp;nbsp;작업을&amp;nbsp;하던&amp;nbsp;중 &lt;br /&gt;프로젝트&amp;nbsp;실행 시&amp;nbsp;profile&amp;nbsp;별로&amp;nbsp;동작을&amp;nbsp;구분하기&amp;nbsp;위해&amp;nbsp;yml&amp;nbsp;파일에&amp;nbsp;profile을&amp;nbsp;분리&amp;nbsp;후 &lt;br /&gt;해당&amp;nbsp;profile로&amp;nbsp;Run을&amp;nbsp;하는데&amp;nbsp;아래와&amp;nbsp;같은&amp;nbsp;오류가&amp;nbsp;발생하였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1668075879815&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;PS 프로젝트경로&amp;gt; .\gradlew.bat -Dspring.profiles.active=test bootRun

&amp;gt; Configure project :
profiles 확인 : null

FAILURE: Build failed with an exception.

* What went wrong:
Task '.profiles.active=test' not found in root project '프로젝트 상위 폴더'.

* Try:
&amp;gt; Run gradlew tasks to get a list of available tasks.
&amp;gt; Run with --stacktrace option to get the stack trace.
&amp;gt; Run with --info or --debug option to get more log output.
&amp;gt; Run with --scan to get full insights.

* Get more help at https://help.gradle.org

BUILD FAILED in 6s&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&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;size18&quot;&gt;gradle&amp;nbsp;bootRun&amp;nbsp;실행&amp;nbsp;시&amp;nbsp;profile명&amp;nbsp;부분이&amp;nbsp;잘린&amp;nbsp;부분이&amp;nbsp;의심되어 &lt;br /&gt;인자 값&amp;nbsp;옵션 부분의&amp;nbsp;&quot;.&quot;&amp;nbsp;마침표를&amp;nbsp;제거&amp;nbsp;후&amp;nbsp;Run을 하니&amp;nbsp;정상적으로&amp;nbsp;동작하였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;br /&gt;VScode&amp;nbsp;콘솔창에서는&amp;nbsp;마침표를&amp;nbsp;경로로&amp;nbsp;보는 것으로&amp;nbsp;보여&amp;nbsp;&lt;b&gt;인자 값을&amp;nbsp;&quot;따옴표로&amp;nbsp;묶어준&amp;nbsp;후&amp;nbsp;실행&lt;/b&gt;을&amp;nbsp;해보았다. &lt;br /&gt;&lt;br /&gt;아래와&amp;nbsp;같이&amp;nbsp;정상적으로&amp;nbsp;올라간&amp;nbsp;것을&amp;nbsp;확인하였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1668076062663&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;PS 프로젝트경로&amp;gt; .\gradlew.bat &quot;-Dspring.profiles.active=test&quot; bootRun

&amp;gt; Configure project :
profiles 확인 : test

&amp;gt; Task :bootRun

&amp;lt;==========---&amp;gt; 80% EXECUTING [5s]
&amp;gt; :bootRun&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>spring</category>
      <category>Build failed with an exception</category>
      <category>Dspring.profiles.active</category>
      <category>gradle</category>
      <category>not found in root project</category>
      <category>Profiles</category>
      <category>vscode</category>
      <author>jckim</author>
      <guid isPermaLink="true">https://jckim-dev.tistory.com/39</guid>
      <comments>https://jckim-dev.tistory.com/entry/VScode-%EC%BD%98%EC%86%94%EC%B0%BD-gradle-profiles-%EC%A0%81%EC%9A%A9%EC%9D%B4-%EC%95%88%EB%90%A8-%EC%A1%B0%EC%B9%98#entry39comment</comments>
      <pubDate>Thu, 10 Nov 2022 19:31:36 +0900</pubDate>
    </item>
    <item>
      <title>readonly 속성이 적용되지 않는 경우</title>
      <link>https://jckim-dev.tistory.com/entry/readonly-%EC%86%8D%EC%84%B1%EC%9D%B4-%EC%A0%81%EC%9A%A9%EB%90%98%EC%A7%80-%EC%95%8A%EB%8A%94-%EA%B2%BD%EC%9A%B0</link>
      <description>&lt;p data-ke-size=&quot;size18&quot;&gt;view&amp;nbsp;작업을&amp;nbsp;할&amp;nbsp;때&amp;nbsp;다양한&amp;nbsp;jsp,&amp;nbsp;php,&amp;nbsp;react&amp;nbsp;등&amp;nbsp;다양한&amp;nbsp;언어를&amp;nbsp;사용한다. &lt;br /&gt;이를&amp;nbsp;이용한&amp;nbsp;결과물을&amp;nbsp;브라우저에서&amp;nbsp;서비스를&amp;nbsp;제공하는&amp;nbsp;경우&amp;nbsp;작업 결과물은&amp;nbsp;html로&amp;nbsp;표출이 된다. &lt;br /&gt;&lt;br /&gt;필자는&amp;nbsp;jsp&amp;nbsp;환경에서&amp;nbsp;작업을&amp;nbsp;하던&amp;nbsp;중&amp;nbsp;html&amp;nbsp;input&amp;nbsp;태그에&amp;nbsp;reonly&amp;nbsp;속성을&amp;nbsp;주어 &lt;br /&gt;사용자가&amp;nbsp;직접&amp;nbsp;값을&amp;nbsp;입력하지&amp;nbsp;못하도록&amp;nbsp;의도하였으나&amp;nbsp;브라우저&amp;nbsp;상에서&amp;nbsp;테스트를&amp;nbsp;진행하였을&amp;nbsp;때 &lt;br /&gt;값을&amp;nbsp;입력할&amp;nbsp;수&amp;nbsp;있는&amp;nbsp;경우가&amp;nbsp;확인&amp;nbsp;되었다. &lt;br /&gt;&lt;br /&gt;작업한&amp;nbsp;소스는&amp;nbsp;아래와&amp;nbsp;같이&amp;nbsp;태그에&amp;nbsp;readonly=&quot;readonly&quot;&amp;nbsp;속성을&amp;nbsp;작성하였다. &lt;/p&gt;
&lt;pre id=&quot;code_1666591178505&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;textarea readonly=&quot;readonly&quot;&amp;gt;읽기만 가능합니다.&amp;lt;/textarea&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;br /&gt;&lt;br /&gt;브라우저&amp;nbsp;개발자모드로&amp;nbsp;확인한&amp;nbsp;html 소스는&amp;nbsp;아래와&amp;nbsp;같이&amp;nbsp;잘&amp;nbsp;적용되었으나&amp;nbsp;클릭&amp;nbsp;후&amp;nbsp;입력이&amp;nbsp;가능하여&amp;nbsp;readonly의&amp;nbsp;목적인&amp;nbsp;읽기 전용의&amp;nbsp;역할을&amp;nbsp;수행하지&amp;nbsp;못하였다. &lt;/p&gt;
&lt;pre id=&quot;code_1666591186547&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;input type=&quot;hidden&quot; readonly=&quot;readonly&quot; value=&quot;&quot;/&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;br /&gt;&lt;br /&gt;확인 결과&amp;nbsp;필자의&amp;nbsp;작업&amp;nbsp;환경은&amp;nbsp;html&amp;nbsp;화면이었고,&amp;nbsp;태그에&amp;nbsp;작성한&amp;nbsp;readonly=&quot;readonly&quot;&amp;nbsp;속성은&amp;nbsp;xhtml에&amp;nbsp;적용&amp;nbsp;가능한&amp;nbsp;것이었으며 &lt;br /&gt;&lt;br /&gt;따라서&amp;nbsp;기존에&amp;nbsp;작업하였던&amp;nbsp;속성을&amp;nbsp;html에&amp;nbsp;적용할&amp;nbsp;수&amp;nbsp;있도록&amp;nbsp;아래와&amp;nbsp;같이&amp;nbsp;수정하였다. &lt;/p&gt;
&lt;pre id=&quot;code_1666591193500&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;textarea readonly&amp;gt;읽기만 가능합니다.&amp;lt;/textarea&amp;gt;
또는
&amp;lt;textarea readonly=&quot;true&quot;&amp;gt;읽기만 가능합니다.&amp;lt;/textarea&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;br /&gt;&lt;br /&gt;다만&amp;nbsp;개발자&amp;nbsp;모드로&amp;nbsp;확인했을&amp;nbsp;때는&amp;nbsp;처음&amp;nbsp;확인한&amp;nbsp;결과와&amp;nbsp;동일하게&amp;nbsp;아래와&amp;nbsp;같이&amp;nbsp;표시되는&amp;nbsp;점을&amp;nbsp;유의해야한다. &lt;/p&gt;
&lt;pre id=&quot;code_1666591200080&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;input type=&quot;hidden&quot; readonly=&quot;readonly&quot; value=&quot;&quot;/&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;br /&gt;&lt;br /&gt;html과&amp;nbsp;xhtml의&amp;nbsp;차이는&amp;nbsp;xhtm의&amp;nbsp;경우&amp;nbsp;문법&amp;nbsp;적용이&amp;nbsp;더&amp;nbsp;엄격하다는&amp;nbsp;점&amp;nbsp;이다. &lt;br /&gt;&lt;br /&gt;태그 이름의&amp;nbsp;대소문자,&amp;nbsp;빈 태그의&amp;nbsp;여닫음&amp;nbsp;여부,&amp;nbsp;속성 값&amp;nbsp;따옴표&amp;nbsp;기입&amp;nbsp;여부&amp;nbsp;등&amp;nbsp;html&amp;nbsp;보다&amp;nbsp;엄격하게&amp;nbsp;문법을&amp;nbsp;작성해주어야 한다. &lt;br /&gt;&lt;br /&gt;현재 페이지가 html인지 xhtml인지 구분하는 방법은 아래와 같이 html 최상단에 DOCTYPE 부분에 XHTML 관련 선언이 되어있는지 확인이 필요하다. &lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1666591230387&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD XHTML 1.0 Transitional//EN&quot; &quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;br /&gt;&lt;br /&gt;참고자료 &lt;br /&gt;&lt;a href=&quot;https://tcpschool.com/html/html_expand_xhtml&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://tcpschool.com/html/html_expand_xhtml&lt;/a&gt;&lt;/p&gt;</description>
      <category>기타</category>
      <category>html</category>
      <category>ReadOnly</category>
      <category>xhtml</category>
      <author>jckim</author>
      <guid isPermaLink="true">https://jckim-dev.tistory.com/38</guid>
      <comments>https://jckim-dev.tistory.com/entry/readonly-%EC%86%8D%EC%84%B1%EC%9D%B4-%EC%A0%81%EC%9A%A9%EB%90%98%EC%A7%80-%EC%95%8A%EB%8A%94-%EA%B2%BD%EC%9A%B0#entry38comment</comments>
      <pubDate>Mon, 24 Oct 2022 15:02:14 +0900</pubDate>
    </item>
    <item>
      <title>React 'react-scripts'은(는) 내부 또는 외부 명령, 실행할 수 있는 프로그램, 또는 배치 파일이 아닙니다. 에러 해결</title>
      <link>https://jckim-dev.tistory.com/entry/React-react-scripts%EC%9D%80%EB%8A%94-%EB%82%B4%EB%B6%80-%EB%98%90%EB%8A%94-%EC%99%B8%EB%B6%80-%EB%AA%85%EB%A0%B9-%EC%8B%A4%ED%96%89%ED%95%A0-%EC%88%98-%EC%9E%88%EB%8A%94-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%A8-%EB%98%90%EB%8A%94-%EB%B0%B0%EC%B9%98-%ED%8C%8C%EC%9D%BC%EC%9D%B4-%EC%95%84%EB%8B%99%EB%8B%88%EB%8B%A4-%EC%97%90%EB%9F%AC-%ED%95%B4%EA%B2%B0</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;React 프로젝트를 진행하던 중에 react-bootstrap을 적용하기 위해 해당 패키지를 설치 후 작업을 진행하였다.&lt;/p&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;처음 작업을 진행하였던 1번 기기에서는 패키지 설치치 후 bootstrap이 잘 적용되는 것을 확인하였다.&lt;/p&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번 기기에서 작업한 소스를 git pull 진행 후 로컬에서 구동을 진해하였으나 아래와 같은 에러 메시지가 발생하였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1664627824368&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;PS 프로젝트경로&amp;gt; npm run start
npm WARN config global `--global`, `--local` are deprecated. Use `--location=global` instead.
npm WARN npm npm does not support Node.js v16.16.0
npm WARN npm You should probably upgrade to a newer version of node as we
npm WARN npm can't make any promises that npm will work with this version.
npm WARN npm Supported releases of Node.js are the latest release of 6, 8, 9, 10, 11, 12, 13.
npm WARN npm You can find the latest version at https://nodejs.org/

&amp;gt; 프젝트명@0.1.0 start 프로젝트경로
&amp;gt; react-scripts start

'react-scripts'은(는) 내부 또는 외부 명령, 실행할 수 있는 프로그램, 또는
배치 파일이 아닙니다.
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! 프로잭트명@0.1.0 start: `react-scripts start`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the 프젝트명@0.1.0 start script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
npm WARN Local package.json exists, but node_modules missing, did you mean to install?&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;원인은 프로젝트를 pull 한 2번 기기에서는 해당 npm&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;react-bootstrap 패키지를 설치하지 않았기 때문에 발생한 에러였다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;조치방법으로는 아래와&amp;nbsp;같이 해당 패키지를 업데이트 및 설치를 진행해 주면 된다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1664633457362&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;npm update
또는
npm install -g react-script&lt;/code&gt;&lt;/pre&gt;</description>
      <category>기타</category>
      <category>npm</category>
      <category>React</category>
      <category>react-script</category>
      <category>배치파일이</category>
      <author>jckim</author>
      <guid isPermaLink="true">https://jckim-dev.tistory.com/37</guid>
      <comments>https://jckim-dev.tistory.com/entry/React-react-scripts%EC%9D%80%EB%8A%94-%EB%82%B4%EB%B6%80-%EB%98%90%EB%8A%94-%EC%99%B8%EB%B6%80-%EB%AA%85%EB%A0%B9-%EC%8B%A4%ED%96%89%ED%95%A0-%EC%88%98-%EC%9E%88%EB%8A%94-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%A8-%EB%98%90%EB%8A%94-%EB%B0%B0%EC%B9%98-%ED%8C%8C%EC%9D%BC%EC%9D%B4-%EC%95%84%EB%8B%99%EB%8B%88%EB%8B%A4-%EC%97%90%EB%9F%AC-%ED%95%B4%EA%B2%B0#entry37comment</comments>
      <pubDate>Sat, 1 Oct 2022 23:19:20 +0900</pubDate>
    </item>
    <item>
      <title>spring, react 사용 CORS 오류 조치</title>
      <link>https://jckim-dev.tistory.com/entry/spring-react-%EC%82%AC%EC%9A%A9-CORS-%EC%98%A4%EB%A5%98-%EC%A1%B0%EC%B9%98</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;발단&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;개인&amp;nbsp;프로젝트&amp;nbsp;진행&amp;nbsp;중&amp;nbsp;백엔드&amp;nbsp;API&amp;nbsp;서버&amp;nbsp;완성&amp;nbsp;후&amp;nbsp;프론트&amp;nbsp;프로젝트를&amp;nbsp;React를&amp;nbsp;통하여&amp;nbsp;구현 중이었음. &lt;br /&gt;POSTMAN 툴을 사용하여 백엔드 API 서버를 호출하였을 때 결과는 의도한대로 동작하는 것을 확인하였음. &lt;br /&gt;React에서&amp;nbsp;axios&amp;nbsp;라이브러리를&amp;nbsp;활용하여&amp;nbsp;백엔드&amp;nbsp;API&amp;nbsp;서버를&amp;nbsp;호출하는&amp;nbsp;과정에서&amp;nbsp;결과가&amp;nbsp;넘어오지&amp;nbsp;않는&amp;nbsp;상황이&amp;nbsp;발생하였음. &lt;br /&gt;콘솔창을&amp;nbsp;확인한&amp;nbsp;결과&amp;nbsp;CORS&amp;nbsp;에러가&amp;nbsp;발생하고&amp;nbsp;있었음. &lt;br /&gt;두 부분에&amp;nbsp;걸쳐서&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;&lt;b&gt;작업 구성&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 프론트서버 : http://localhost:3000 &lt;br /&gt;- 백엔드서버(apigateway의 역할) : http://localhost:5555&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;원인 분석 및 조치&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;CORS란?&lt;/b&gt; &lt;br /&gt;Cross-Origin&amp;nbsp;Resource&amp;nbsp;Sharing의&amp;nbsp;약자로&amp;nbsp;교차&amp;nbsp;출처&amp;nbsp;리소스&amp;nbsp;공유를&amp;nbsp;의미. &lt;br /&gt;브라우저에서&amp;nbsp;서로&amp;nbsp;다른&amp;nbsp;출처 간에&amp;nbsp;자원에&amp;nbsp;접근할&amp;nbsp;수&amp;nbsp;있는&amp;nbsp;권한을&amp;nbsp;제어하는&amp;nbsp;정책으로&amp;nbsp;여기서&amp;nbsp;출처는&amp;nbsp;url이며&amp;nbsp;도메인,&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;&lt;b&gt;첫 번째&amp;nbsp;콘솔에러메시지&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1661872531327&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;Access to fetch at &amp;lsquo;https://localhost:5555/user/signup&amp;rsquo; from origin &amp;lsquo;http://localhost:3000&amp;rsquo; has been blocked by CORS policy: No &amp;lsquo;Access-Control-Allow-Origin&amp;rsquo; header is present on the requested resource.
If an opaque response serves your needs, set the request&amp;rsquo;s mode to &amp;lsquo;no-cors&amp;rsquo; to fetch the resource with CORS disabled.&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;첫 번째&amp;nbsp;오류분석&lt;/b&gt; &lt;br /&gt;요청한&amp;nbsp;출처는&amp;nbsp;서버에서&amp;nbsp;허용되지&amp;nbsp;않은&amp;nbsp;출처이기 때문에&amp;nbsp;발생한&amp;nbsp;에러로&amp;nbsp;필자의&amp;nbsp;경우는&amp;nbsp;백엔드서버(apigateway)에서&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;&lt;b&gt;조치 소스&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1661872610416&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;//apigateway 서버는 WebFlux 프로젝트로 WebFluxConfigure 설정에서 추가
@Configuration
@EnableWebFlux
public class CorsGlobalConfiguration implements WebFluxConfigurer{

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping(&quot;/**&quot;)
                .allowedOrigins(&quot;*&quot;) //테스트 환경이기에 모든 url을 허용하도록 &quot;*&quot; 기입
                .allowedMethods(&quot;*&quot;)
                .allowedHeaders(&quot;*&quot;)
                .maxAge(3600);
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;두 번째&amp;nbsp;콘솔에러&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1661872672637&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;OPTIONS http://localhost:5555/user/signup 401 (Unauthorized) Failed to load http://localhost:5555/user/signup: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
Origin 'http://localhost:3000' is therefore not allowed access. The response had HTTP status code 401.
If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;두 번째&amp;nbsp;오류분석&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;첫 번째&amp;nbsp;오류에&amp;nbsp;대하여&amp;nbsp;조치를&amp;nbsp;하였지만&amp;nbsp;두 번째&amp;nbsp;에러가&amp;nbsp;발생하였다.&amp;nbsp;해당&amp;nbsp;에러는&amp;nbsp;요청&amp;nbsp;url에&amp;nbsp;대하여&amp;nbsp;preflight&amp;nbsp;request&amp;nbsp;시에&amp;nbsp;권한이&amp;nbsp;없어서&amp;nbsp;401&amp;nbsp;코드를&amp;nbsp;응답한&amp;nbsp;상황이다. &lt;br /&gt;확인&amp;nbsp;결과&amp;nbsp;호출한&amp;nbsp;url은&amp;nbsp;apigateway를&amp;nbsp;통하여&amp;nbsp;사용자&amp;nbsp;인증서버로&amp;nbsp;전달되며&amp;nbsp;해당&amp;nbsp;서버는&amp;nbsp;Spring&amp;nbsp;Security에&amp;nbsp;의하여&amp;nbsp;요청을&amp;nbsp;인증&amp;nbsp;및&amp;nbsp;인가를&amp;nbsp;처리하는데&amp;nbsp;HttpMethod에&amp;nbsp;대하여&amp;nbsp;허용 여부를&amp;nbsp;설정하지&amp;nbsp;않아&amp;nbsp;기본&amp;nbsp;설정인&amp;nbsp;모든&amp;nbsp;요청에&amp;nbsp;대하여&amp;nbsp;제한이&amp;nbsp;된&amp;nbsp;상태임을&amp;nbsp;확인하였다.&amp;nbsp;따라서&amp;nbsp;인증서버의&amp;nbsp;Spring&amp;nbsp;Security&amp;nbsp;설정&amp;nbsp;중&amp;nbsp;HttpMethod.OPTIONS에&amp;nbsp;대하여&amp;nbsp;권한을&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;&lt;b&gt;Preflight&amp;nbsp;Request란?&lt;/b&gt; &lt;br /&gt;서로&amp;nbsp;다른&amp;nbsp;출처 간에&amp;nbsp;요청을&amp;nbsp;보내야 하는&amp;nbsp;경우&amp;nbsp;브라우저&amp;nbsp;자체적으로&amp;nbsp;본 요청을&amp;nbsp;보내기&amp;nbsp;전에&amp;nbsp;예비요청을&amp;nbsp;보내어&amp;nbsp;안전한&amp;nbsp;요청인지&amp;nbsp;확인&amp;nbsp;후&amp;nbsp;본요청을&amp;nbsp;보내는&amp;nbsp;방법입니다.&amp;nbsp;이때&amp;nbsp;http&amp;nbsp;OPTIONS&amp;nbsp;메소드를&amp;nbsp;사용합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;조치 소스&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1661872776457&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter{
@Override
    protected void configure(HttpSecurity http) throws Exception {
        http
        ...
        ...
        ...
        .mvcMatchers(HttpMethod.OPTIONS, &quot;/**&quot;).permitAll()
        ...
        ...
        ...
    }
}&lt;/code&gt;&lt;/pre&gt;</description>
      <category>server</category>
      <category>401</category>
      <category>cors</category>
      <category>prelight</category>
      <category>React</category>
      <category>spring</category>
      <author>jckim</author>
      <guid isPermaLink="true">https://jckim-dev.tistory.com/36</guid>
      <comments>https://jckim-dev.tistory.com/entry/spring-react-%EC%82%AC%EC%9A%A9-CORS-%EC%98%A4%EB%A5%98-%EC%A1%B0%EC%B9%98#entry36comment</comments>
      <pubDate>Wed, 31 Aug 2022 00:25:04 +0900</pubDate>
    </item>
    <item>
      <title>Docker WEB WAS AJP 연결 실패 해결</title>
      <link>https://jckim-dev.tistory.com/entry/Docker-WEB-WAS-AJP-%EC%97%B0%EA%B2%B0-%EC%8B%A4%ED%8C%A8-%ED%95%B4%EA%B2%B0</link>
      <description>&lt;h2 style=&quot;text-align: left;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;발단&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&lt;br&gt;Windows10 개인 로컬 환경에서 WSL2를 활용하여 docker를 실행하여 apahch와 tomcat을 연동하는 중 발생한 문제 &lt;br&gt;&lt;br&gt;docker에서 apache 컨테이너와 tomcat 컨테이너를 실행하였고 각각 호출 시에는 정상적으로 호출되었음 &lt;br&gt;&lt;br&gt;&lt;b&gt;http://localhost 호출&lt;/b&gt;&lt;/p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;459&quot; data-origin-height=&quot;100&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/biBqTd/btrF5crL1ny/nldSpeQzcH7ro9iLoPEQzK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/biBqTd/btrF5crL1ny/nldSpeQzcH7ro9iLoPEQzK/img.png&quot; data-alt=&quot; apache index 화면 &quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/biBqTd/btrF5crL1ny/nldSpeQzcH7ro9iLoPEQzK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbiBqTd%2FbtrF5crL1ny%2FnldSpeQzcH7ro9iLoPEQzK%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;100&quot; data-origin-width=&quot;459&quot; data-origin-height=&quot;100&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt; apache index 화면 &lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&lt;br&gt;&lt;br&gt;&lt;b&gt;http://localhost:8080 호출&lt;/b&gt;&lt;/p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;385&quot; data-origin-height=&quot;113&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ld9Xg/btrF0tCvpoM/7oXcqn7JAOwbKKq2e9lh6k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ld9Xg/btrF0tCvpoM/7oXcqn7JAOwbKKq2e9lh6k/img.png&quot; data-alt=&quot; tomcat index화면&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ld9Xg/btrF0tCvpoM/7oXcqn7JAOwbKKq2e9lh6k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fld9Xg%2FbtrF0tCvpoM%2F7oXcqn7JAOwbKKq2e9lh6k%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;385&quot; height=&quot;113&quot; data-origin-width=&quot;385&quot; data-origin-height=&quot;113&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt; tomcat index화면&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&lt;br&gt;&lt;br&gt;그러나 Web 서버와 Was의 처리를 분리하 mod_jk와 ajp 프로토콜을 적용하였을 때 문제가 발생하였음.&lt;br&gt; &lt;br&gt;&lt;b&gt;ajp 적용 후 http://localhost 호출 시 에러 화면&lt;/b&gt;&lt;br&gt; &lt;/p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;951&quot; data-origin-height=&quot;186&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bmvX8R/btrF5cFhz72/ldvKMOKNlDeQ8zNvsBgJyK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bmvX8R/btrF5cFhz72/ldvKMOKNlDeQ8zNvsBgJyK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bmvX8R/btrF5cFhz72/ldvKMOKNlDeQ8zNvsBgJyK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbmvX8R%2FbtrF5cFhz72%2FldvKMOKNlDeQ8zNvsBgJyK%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;951&quot; height=&quot;186&quot; data-origin-width=&quot;951&quot; data-origin-height=&quot;186&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;hr data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot;&gt;
&lt;h2 style=&quot;text-align: left;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;원인&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&lt;br&gt;mod_jk.log를 확인하였을 때 &lt;br&gt;WEB에서 WAS로 AJP통신을 요청할 떄 해당 ip와 port로 연결을 실패하였다는 것임.&lt;br&gt; &lt;br&gt;&lt;b&gt;에러 메시지&lt;/b&gt;&lt;/p&gt;
&lt;pre data-ke-type=&quot;codeblock&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot;&gt;&lt;code&gt;[info] ajp_service::jk_ajp_common.c (2774): (worker1) sending request to tomcat failed (recoverable), because of error during request sending (attempt=1)
[info] jk_open_socket::jk_connect.c (815): connect to 172.17.0.3:8009 failed (errno=111)
[info] ajp_connect_to_endpoint::jk_ajp_common.c (1064): (worker1) Failed opening socket to (172.17.0.3:8009) (errno=111)
[error] ajp_send_request::jk_ajp_common.c (1724): (worker1) connecting to backend failed. Tomcat is probably not started or is listening on the wrong port (errno=111)
[info] ajp_service::jk_ajp_common.c (2774): (worker1) sending request to tomcat failed (recoverable), because of error during request sending (attempt=2)
[error] ajp_service::jk_ajp_common.c (2795): (worker1) connecting to tomcat failed (rc=-3, errors=1, client_errors=0).
[info] jk_handler::mod_jk.c (2991): Service error=-3 for worker=worker1&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt; &lt;br&gt;로그 중 이 부분을 확인해보면 &lt;br&gt;IP 172.17.0.3 tomcat 서버에 8009 포트로 요청하는 것인데 &lt;br&gt;현재 사용 중인 개발 환경이라면 docker에서 컨테이너 간에 통신을 관리하는데 &lt;br&gt;172.17.0.3 IP는 tomcat 컨테이너 IP 이기 때문에 docker에서는 연결을 해줄 수 없는 것임.&lt;br&gt; &lt;br&gt;&lt;b&gt;ajp 설정 시 tomcat 기본 설정 부분&lt;/b&gt;&lt;/p&gt;
&lt;pre data-ke-type=&quot;codeblock&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot;&gt;&lt;code&gt;#/usr/local/tomcat/conf/server.xml
 &amp;lt;Connector protocol=&quot;AJP/1.3&quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; address=&quot;localhost&quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; port=&quot;8009&quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; redirectPort=&quot;8443&quot; secretRequired=&quot;false&quot;/&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt; &lt;br&gt;해당 IP가 표시된 것 또한 ajp 설정 부분에 address를 localhost로 선언을 하였기에 현재 컨테이너의 IP로 받아들이는 것이었음. &lt;br&gt;docker에서 localhost는 해당 컨테이너 안에서 사용 가능하며 외부로는 통신이 불가.&lt;/p&gt;
&lt;hr data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot;&gt;
&lt;h2 style=&quot;text-align: left;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;조치&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&lt;br&gt;WSL2 환경이기에 같은 서버에서 돌아간다고 생각을 하고 작업을 진행하였으나 &lt;br&gt;docker 환경이기에 서로 다른 컨테이너라는 점을 놓친 것이 가장 큰 실수였음.&lt;br&gt; &lt;br&gt;docker에서 컨테이너 간 통신을 설정하려면 &lt;br&gt;localhost가 아닌 0.0.0.0로 설정하여 같은 머신에서의 통신할 수 있도록 설정&lt;br&gt; &lt;/p&gt;
&lt;pre data-ke-type=&quot;codeblock&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot;&gt;&lt;code&gt; &amp;lt;Connector protocol=&quot;AJP/1.3&quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; address=&quot;0.0.0.0&quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; port=&quot;8009&quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; redirectPort=&quot;8443&quot; secretRequired=&quot;false&quot;/&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt; &lt;br&gt;추가적으로 WEB 서버에서 mod_jk 설정을 할 때 host명은 tomcat 컨테이너 명으로 잘 설정한 부분&lt;br&gt; &lt;/p&gt;
&lt;pre data-ke-type=&quot;codeblock&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot;&gt;&lt;code&gt;worker.list=worker1
worker.worker1.type=ajp13
worker.worker1.host=tomcat-jc2
worker.worker1.port=8009&lt;/code&gt;&lt;/pre&gt;</description>
      <category>server</category>
      <category>AJP</category>
      <category>apache</category>
      <category>because of error during request sending</category>
      <category>docker</category>
      <category>Failed opening socket to</category>
      <category>sending request to tomcat failed</category>
      <category>tomcat</category>
      <category>WAS</category>
      <category>web</category>
      <author>jckim</author>
      <guid isPermaLink="true">https://jckim-dev.tistory.com/35</guid>
      <comments>https://jckim-dev.tistory.com/entry/Docker-WEB-WAS-AJP-%EC%97%B0%EA%B2%B0-%EC%8B%A4%ED%8C%A8-%ED%95%B4%EA%B2%B0#entry35comment</comments>
      <pubDate>Wed, 29 Jun 2022 18:15:28 +0900</pubDate>
    </item>
    <item>
      <title>[웹] 화면 중복 호출 되는 경우 css background : url(&amp;quot;&amp;quot;)</title>
      <link>https://jckim-dev.tistory.com/entry/%EC%9B%B9-%ED%99%94%EB%A9%B4-%EC%A4%91%EB%B3%B5-%ED%98%B8%EC%B6%9C-%EB%90%98%EB%8A%94-%EA%B2%BD%EC%9A%B0-css-background-url</link>
      <description>&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;발단&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;화면 진입하여 생성된 토큰 값을 서버로 보내 검증하는 작업을 진행하던 중&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;동일한 기능을 여러 페이지에 삽입하던 중 특정 페이지에서&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;토큰 값이 일치하지 않다는 오류 로그를 확인하게 되었음.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;원인&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;디버깅과 로그를 확인하며 원인을 찾아보던 중 의심이 가는 부분을 확인하였음.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;확인한 로그에서는 토큰을 두번 생성하고 있었음.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;두 번 생성한 원인은 해당 페이지를 재호출하는 것으로 확인이 되었음.&lt;/p&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;JavaScript 부분에서는 호출되는 부분을 확인할 수 없었음.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;페이지 내에 라인 별로 콘솔창에서 확인할 수 있도록 &lt;b&gt;콘솔 로그를 삽입한&lt;/b&gt; 결과&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;특정 라인 이후로 콘솔 로그까지 표출되었다가 다시 처음부터 콘솔 로그가 표출되는 것을 확인하였음.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;확인된 부분은 CSS style 태그 안에 있었음.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1653822172478&quot; class=&quot;css&quot; data-ke-language=&quot;css&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;style&amp;gt;
	#select { background: url(&quot;&quot;) no-reoeat;)
&amp;lt;/style&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 코드를 확인하면 css 문법 중 background 속성의 이미지 경로를 url형태로 불러오는 부분인데&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 &lt;span&gt;url&lt;span&gt;&amp;nbsp;&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 data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;조치&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 부분을 주석 처리하고 해당 페이지를 다시 불러온 결과 정상적으로 페이지를 한 번만 호출하고&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;토큰 값도 정상적으로 한 번만 생성해서 서버에서도 잘 인증되었음.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이미지를 사용하지 않기 위해 사용한 의도라면 아래 속성을 사용을 권함.&lt;/p&gt;
&lt;pre id=&quot;code_1653822728135&quot; class=&quot;css&quot; data-ke-language=&quot;css&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;background-image : none;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>기타</category>
      <category>Background</category>
      <category>css</category>
      <category>html</category>
      <category>jsp</category>
      <category>url</category>
      <category>재호출</category>
      <author>jckim</author>
      <guid isPermaLink="true">https://jckim-dev.tistory.com/34</guid>
      <comments>https://jckim-dev.tistory.com/entry/%EC%9B%B9-%ED%99%94%EB%A9%B4-%EC%A4%91%EB%B3%B5-%ED%98%B8%EC%B6%9C-%EB%90%98%EB%8A%94-%EA%B2%BD%EC%9A%B0-css-background-url#entry34comment</comments>
      <pubDate>Sun, 29 May 2022 20:18:12 +0900</pubDate>
    </item>
    <item>
      <title>Linux 서버 DNS 적용하기 (host.conf, resolv.conf)</title>
      <link>https://jckim-dev.tistory.com/entry/Linux-%EC%84%9C%EB%B2%84-DNS-%EC%A0%81%EC%9A%A9%ED%95%98%EA%B8%B0-hostconf-resolvconf</link>
      <description>&lt;div data-pm-slice=&quot;1 1 []&quot; data-en-clipboard=&quot;true&quot;&gt;운영중인 서버에 DNS 사용 설정이 되어있지 않아&lt;/div&gt;
&lt;div&gt;외부기관의 url을 호출할 때 하당 도메인의 ip를 nslookup으로 확인하여&lt;/div&gt;
&lt;div&gt;hosts 파일에 일일이 등록되고 있는 부분을 확인하였다.&lt;/div&gt;
&lt;div&gt;이러한 작업은 불필요하게 시간과 힘을 들이는 부분이 문제가 된다고 생각하여&lt;/div&gt;
&lt;div&gt;해당 서버에 DNS를 적용해 보기로 하였다.&lt;/div&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;div data-pm-slice=&quot;1 1 []&quot; data-en-clipboard=&quot;true&quot;&gt;&lt;b&gt;작업환경&lt;/b&gt;&lt;/div&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Linux 환경&lt;/li&gt;
&lt;li&gt;별도 DNS 서버 존재&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;div data-pm-slice=&quot;1 1 []&quot; data-en-clipboard=&quot;true&quot;&gt;&lt;b&gt;먼저 host.conf 의 간략한 설명&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;host.conf&lt;/div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1650612024385&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;multi on
order hosts, bind, nis&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 설정대로 라면 hosts, bind, nis 순으로 DNS를 조회하는 의미인데 각 값의 의미는 아래와 같다.&lt;/p&gt;
&lt;/div&gt;
&lt;div&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: 9.30232%;&quot;&gt;multi&lt;/td&gt;
&lt;td style=&quot;width: 90.6978%;&quot; colspan=&quot;2&quot;&gt;/etc/hosts 파일에 여러 url 설정이 가능하다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 9.30232%;&quot; rowspan=&quot;4&quot;&gt;order&lt;/td&gt;
&lt;td style=&quot;width: 90.6978%;&quot; colspan=&quot;2&quot;&gt;도메인을 조회할 방법의 우선순위를 설정&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 14.2443%;&quot;&gt;&lt;span&gt;hosts&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 76.4535%;&quot;&gt;/etc/hosts 파일에 설정한 ip와 도메인을 조회한다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 14.2443%;&quot;&gt;&lt;span&gt;bind&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 76.4535%;&quot;&gt;/etc/resolv.conf 파일에 설정한 nameserver에 도메인 쿼리를 조회한다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 14.2443%;&quot;&gt;&lt;span&gt;nis&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 76.4535%;&quot;&gt;Network Information Service의 약자로 네트워크 정보를 보유하고 제공해주는 서비스, 네트워크 명명 및 관리 시스템으로 주로 소규모 네트워크 구성시 사용된다. nis 서버 구성이 필요하다.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;div&gt;&lt;b&gt;확인한 host.conf 파일에는&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1650612297071&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;multi on&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;div&gt;설정 값만 존재 하였다.&lt;/div&gt;
&lt;div&gt;이러한 경우에 order 값은&lt;/div&gt;
&lt;div&gt;기본 순서인 hosts, bind 순을 따른다.&lt;/div&gt;
&lt;div&gt;&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;&lt;/div&gt;
&lt;div&gt;다음으로 확인할 설정파일은 &lt;b&gt;resolv.conf&lt;/b&gt;로 도메인 쿼리를 조회할 DNS 서버의 IP를 저장한다.&lt;/div&gt;
&lt;div&gt;필자는 해당 파일이 비어있어서 아래와 같이 작성 하였음.&lt;/div&gt;
&lt;div&gt;resolv.conf&lt;/div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1650612356323&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;nameserver x.x.x.x&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;div&gt;&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;&lt;/div&gt;
&lt;div&gt;보통은 여기까지 작업을 하면 정상적으로 DNS가 적용된 것을 확인 할 수 있으나&lt;/div&gt;
&lt;div&gt;필자는 그동안 /etc/hosts 파일에 작성해 놓은 ip와 도메인 주소가 있기 때문에 정리해주었다.&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;만약 방화벽을 관리하고 있다면&lt;/div&gt;
&lt;div&gt;UDP/TCP 53번 port를 오픈해야한다.&lt;/div&gt;
&lt;div&gt;53번 port는 잘 알려진 포트로 DNS용도로 사용한다.&lt;/div&gt;</description>
      <category>server</category>
      <category>dns</category>
      <category>Host</category>
      <category>hosts</category>
      <category>resolv</category>
      <author>jckim</author>
      <guid isPermaLink="true">https://jckim-dev.tistory.com/33</guid>
      <comments>https://jckim-dev.tistory.com/entry/Linux-%EC%84%9C%EB%B2%84-DNS-%EC%A0%81%EC%9A%A9%ED%95%98%EA%B8%B0-hostconf-resolvconf#entry33comment</comments>
      <pubDate>Fri, 22 Apr 2022 18:30:28 +0900</pubDate>
    </item>
    <item>
      <title>jstl 부등호 ge(GreaterThanOrEquals)는 mybatis에서 사용 할 수 없는가</title>
      <link>https://jckim-dev.tistory.com/entry/jstl-%EB%B6%80%EB%93%B1%ED%98%B8-geGreaterThanOrEquals%EB%8A%94-mybatis%EC%97%90%EC%84%9C-%EC%82%AC%EC%9A%A9-%ED%95%A0-%EC%88%98-%EC%97%86%EB%8A%94%EA%B0%80</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;sql&amp;nbsp;querry가&amp;nbsp;들어있는&amp;nbsp;mybatis&amp;nbsp;xml파일&amp;nbsp;내에서&amp;nbsp;부등호를&amp;nbsp;사용할&amp;nbsp;상황은&amp;nbsp;자주&amp;nbsp;등장한다. &lt;br /&gt;그중에서도&amp;nbsp;&quot;크거나&amp;nbsp;같다&quot;,&amp;nbsp;&quot;작거나&amp;nbsp;같다&quot;에&amp;nbsp;대한&amp;nbsp;부등호를&amp;nbsp;처리해야&amp;nbsp;하는&amp;nbsp;경우를&amp;nbsp;정리하였다. &lt;br /&gt;&lt;br /&gt;jsp&amp;nbsp;내에서&amp;nbsp;jstl&amp;nbsp;+&amp;nbsp;EL을&amp;nbsp;경험해본&amp;nbsp;적이&amp;nbsp;있는&amp;nbsp;사용자라면&amp;nbsp;혼란이&amp;nbsp;있을&amp;nbsp;수&amp;nbsp;있기&amp;nbsp;때문이다. &lt;br /&gt;&lt;br /&gt;jstl&amp;nbsp;+&amp;nbsp;EL&amp;nbsp;방식에서&amp;nbsp;&quot;보다&amp;nbsp;크거나&amp;nbsp;같다&quot;,&amp;nbsp;&quot;보다&amp;nbsp;작거나&amp;nbsp;같다&quot;의&amp;nbsp;부등호는 &lt;br /&gt;&amp;amp;ge;&amp;nbsp;&amp;amp;le;로&amp;nbsp;사용을&amp;nbsp;한다. &lt;br /&gt;&lt;br /&gt;이 문법을 그대로 mybatis xml에 사용을 하면 아래와 같이 &lt;br /&gt;&lt;b&gt;mybatis&amp;nbsp;BuilderException&amp;nbsp;The&amp;nbsp;entity&amp;nbsp;&quot;ge&quot;&amp;nbsp;was&amp;nbsp;referenced,&amp;nbsp;but&amp;nbsp;not&amp;nbsp;declared.&lt;/b&gt; &lt;br /&gt;라는&amp;nbsp;에러메시지를&amp;nbsp;확인할&amp;nbsp;수&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;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;jstl&amp;nbsp;분석&lt;/b&gt; &lt;br /&gt;&lt;br /&gt;먼저&amp;nbsp;jstl에서&amp;nbsp;&amp;amp;ge;를&amp;nbsp;사용할&amp;nbsp;수&amp;nbsp;있는&amp;nbsp;이유를&amp;nbsp;알아보았다 &lt;br /&gt;&lt;br /&gt;부등호가&amp;nbsp;일반적으로&amp;nbsp;많이&amp;nbsp;사용되는&amp;nbsp;c:if&amp;nbsp;태그를&amp;nbsp;기준으로&amp;nbsp;진행해보았다. &lt;br /&gt;&lt;br /&gt;jstl을&amp;nbsp;사용하기&amp;nbsp;위해서는&amp;nbsp;standard.jar&amp;nbsp;또는&amp;nbsp;jstl.jar가&amp;nbsp;import&amp;nbsp;되어있을&amp;nbsp;것이다. &lt;br /&gt;&lt;br /&gt;standard.jar&amp;nbsp;파일을&amp;nbsp;디컴파일&amp;nbsp;해보자 &lt;br /&gt;&lt;br /&gt;우선&amp;nbsp;standard.jar&amp;nbsp;파일에&amp;nbsp;META-INF\c.tld로&amp;nbsp;들어가&amp;nbsp;IF&amp;nbsp;태그에&amp;nbsp;대한&amp;nbsp;선언&amp;nbsp;확인(주요 부분만&amp;nbsp;발췌)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1648194713849&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt; &amp;lt;tag&amp;gt;
...
...
...
    &amp;lt;name&amp;gt;if&amp;lt;/name&amp;gt;
    &amp;lt;tag-class&amp;gt;org.apache.taglibs.standard.tag.rt.core.IfTag&amp;lt;/tag-class&amp;gt;
    &amp;lt;body-content&amp;gt;JSP&amp;lt;/body-content&amp;gt;
    &amp;lt;attribute&amp;gt;
        &amp;lt;name&amp;gt;test&amp;lt;/name&amp;gt; -- c:if 태그 사용중 test 속성
        &amp;lt;required&amp;gt;true&amp;lt;/required&amp;gt; --해당 속성 필수 여부
        &amp;lt;rtexprvalue&amp;gt;true&amp;lt;/rtexprvalue&amp;gt; -- el 표현식 사용가능 여부 true
	&amp;lt;type&amp;gt;boolean&amp;lt;/type&amp;gt;
    &amp;lt;/attribute&amp;gt;
...
...
...
  &amp;lt;/tag&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;패키지에&amp;nbsp;class&amp;nbsp;파일을&amp;nbsp;확인&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;org.apache.taglibs.standard.lang.jstl.parser.ELParserTokenManager.class&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래&amp;nbsp;변수값에&amp;nbsp;ge에&amp;nbsp;대하여&amp;nbsp;&quot;&amp;gt;=&quot;가&amp;nbsp;셋팅된&amp;nbsp;부분&amp;nbsp;확인&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1648194746154&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public static final String[] jjstrLiteralImages = { &quot;&quot;, null, &quot;${&quot;, null, null, null, null, null, null, null, null, null, &quot;true&quot;, &quot;false&quot;, &quot;null&quot;, &quot;}&quot;, &quot;.&quot;, &quot;&amp;gt;&quot;, &quot;gt&quot;, &quot;&amp;lt;&quot;, &quot;lt&quot;, &quot;==&quot;, &quot;eq&quot;, &quot;&amp;lt;=&quot;, &quot;le&quot;, &quot;&amp;gt;=&quot;, &quot;ge&quot;, &quot;!=&quot;, &quot;ne&quot;, &quot;(&quot;, &quot;)&quot;, &quot;,&quot;, &quot;:&quot;, &quot;[&quot;, &quot;]&quot;, &quot;+&quot;, &quot;-&quot;, &quot;*&quot;, &quot;/&quot;, &quot;div&quot;, &quot;%&quot;, &quot;mod&quot;, &quot;not&quot;, &quot;!&quot;, &quot;and&quot;, &quot;&amp;amp;&amp;amp;&quot;, &quot;or&quot;, &quot;||&quot;, &quot;empty&quot;, null, null, null, null, null };&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;부등호&amp;nbsp;부분만&amp;nbsp;발췌&lt;/p&gt;
&lt;pre id=&quot;code_1648195176805&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&quot;&amp;gt;&quot;, &quot;gt&quot;, &quot;&amp;lt;&quot;, &quot;lt&quot;, &quot;==&quot;, &quot;eq&quot;, &quot;&amp;lt;=&quot;, &quot;le&quot;, &quot;&amp;gt;=&quot;, &quot;ge&quot;, &quot;!=&quot;, &quot;ne&quot;&lt;/code&gt;&lt;/pre&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;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;mybatis&amp;nbsp;분석&lt;/b&gt;&lt;b&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;mybatis&amp;nbsp;사용하기&amp;nbsp;위해&amp;nbsp;maven에서&amp;nbsp;다운받은&amp;nbsp;mybatis-3.4.1.jar를&amp;nbsp;디컴파일&amp;nbsp;해보았다. &lt;br /&gt;&lt;br /&gt;아래&amp;nbsp;패키지에&amp;nbsp;class&amp;nbsp;파일을&amp;nbsp;확인 &lt;br /&gt;org.apache.ibatis.ognl.OgnlParserTokenManager.class &lt;br /&gt;&lt;br /&gt;아래 변수값에 부등호 부분 확인 &amp;nbsp;&quot;&amp;gt;=&quot;가 셋팅된 부분 확인&lt;/p&gt;
&lt;pre id=&quot;code_1648195247492&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public static final String[] jjstrLiteralImages = { &quot;&quot;, &quot;,&quot;, &quot;=&quot;, &quot;?&quot;, &quot;:&quot;, &quot;||&quot;, &quot;or&quot;, &quot;&amp;amp;&amp;amp;&quot;, &quot;and&quot;, &quot;|&quot;, &quot;bor&quot;, &quot;^&quot;, &quot;xor&quot;, &quot;&amp;amp;&quot;, &quot;band&quot;, &quot;==&quot;, &quot;eq&quot;, &quot;!=&quot;, &quot;neq&quot;, &quot;&amp;lt;&quot;, &quot;lt&quot;, &quot;&amp;gt;&quot;, &quot;gt&quot;, &quot;&amp;lt;=&quot;, &quot;lte&quot;, &quot;&amp;gt;=&quot;, &quot;gte&quot;, &quot;in&quot;, &quot;not&quot;, &quot;&amp;lt;&amp;lt;&quot;, &quot;shl&quot;, &quot;&amp;gt;&amp;gt;&quot;, &quot;shr&quot;, &quot;&amp;gt;&amp;gt;&amp;gt;&quot;, &quot;ushr&quot;, &quot;+&quot;, &quot;-&quot;, &quot;*&quot;, &quot;/&quot;, &quot;%&quot;, &quot;~&quot;, &quot;!&quot;, &quot;instanceof&quot;, &quot;.&quot;, &quot;(&quot;, &quot;)&quot;, &quot;true&quot;, &quot;false&quot;, &quot;null&quot;, &quot;#this&quot;, &quot;#root&quot;, &quot;#&quot;, &quot;[&quot;, &quot;]&quot;, &quot;{&quot;, &quot;}&quot;, &quot;@&quot;, &quot;new&quot;, &quot;$&quot;, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null };&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;부등호&amp;nbsp;부분만&amp;nbsp;발췌&lt;/p&gt;
&lt;pre id=&quot;code_1648195268346&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&quot;==&quot;, &quot;eq&quot;, &quot;!=&quot;, &quot;neq&quot;, &quot;&amp;lt;&quot;, &quot;lt&quot;, &quot;&amp;gt;&quot;, &quot;gt&quot;, &quot;&amp;lt;=&quot;, &quot;lte&quot;, &quot;&amp;gt;=&quot;, &quot;gte&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;따라서&lt;/b&gt; &lt;br /&gt;&lt;br /&gt;mybatis에서&amp;nbsp;&quot;&amp;gt;=&quot;&amp;nbsp;부등호를&amp;nbsp;사용하는&amp;nbsp;방법은&amp;nbsp;아래와&amp;nbsp;같다. &lt;br /&gt;&lt;br /&gt;1. &amp;lt;![CDATA[&amp;gt;=]]&amp;gt;&lt;br /&gt;2. &amp;amp;gt;=&lt;br /&gt;3. &amp;amp;gte; &lt;br /&gt;&lt;br /&gt;&amp;lt;![CDATA[&amp;gt;=]]&amp;gt; &lt;br /&gt;풀네임은&amp;nbsp;Character&amp;nbsp;DATA이고&amp;nbsp;[]&amp;nbsp;기호&amp;nbsp;안에&amp;nbsp;문자는&amp;nbsp;파싱하지&amp;nbsp;않고&amp;nbsp;문자형&amp;nbsp;데이터&amp;nbsp;그대로&amp;nbsp;인식한다. &lt;br /&gt;&lt;br /&gt;&amp;amp;gt;= &lt;br /&gt;문자 형식을&amp;nbsp;보면&amp;nbsp;알&amp;nbsp;수&amp;nbsp;있듯이&amp;nbsp;mybatis에서는&amp;nbsp;&amp;amp;ge;는&amp;nbsp;별도로&amp;nbsp;지원하지&amp;nbsp;않고&amp;nbsp;&amp;amp;gt;&amp;nbsp;문자에&amp;nbsp;&quot;=&quot;를&amp;nbsp;연결하여&amp;nbsp;작성한다. &lt;br /&gt;&lt;br /&gt;&amp;amp;gte; &lt;br /&gt;&quot;&amp;gt;=&quot;&amp;nbsp;부호를&amp;nbsp;나타내며&amp;nbsp;jstl에서&amp;nbsp;&amp;amp;ge;&amp;nbsp;와&amp;nbsp;동일하다.&lt;/p&gt;</description>
      <category>JAVA</category>
      <category>but not declared</category>
      <category>GE</category>
      <category>JSTL</category>
      <category>mybatis</category>
      <category>was referenced</category>
      <category>부등호</category>
      <author>jckim</author>
      <guid isPermaLink="true">https://jckim-dev.tistory.com/32</guid>
      <comments>https://jckim-dev.tistory.com/entry/jstl-%EB%B6%80%EB%93%B1%ED%98%B8-geGreaterThanOrEquals%EB%8A%94-mybatis%EC%97%90%EC%84%9C-%EC%82%AC%EC%9A%A9-%ED%95%A0-%EC%88%98-%EC%97%86%EB%8A%94%EA%B0%80#entry32comment</comments>
      <pubDate>Mon, 28 Mar 2022 06:00:56 +0900</pubDate>
    </item>
    <item>
      <title>jQuery datepicker 날짜 초기화하기</title>
      <link>https://jckim-dev.tistory.com/entry/jQuery-datepicker-%EB%82%A0%EC%A7%9C-%EC%B4%88%EA%B8%B0%ED%99%94%ED%95%98%EA%B8%B0</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;jQuery와&amp;nbsp;날짜&amp;nbsp;관련&amp;nbsp;js라이브러리&amp;nbsp;datepicker를&amp;nbsp;사용&amp;nbsp;중 &lt;br /&gt;시작일자와&amp;nbsp;종료일자가&amp;nbsp;서로&amp;nbsp;침범하지&amp;nbsp;않도록&amp;nbsp;검증을&amp;nbsp;하는&amp;nbsp;기능이&amp;nbsp;존재하여 &lt;br /&gt;날짜를&amp;nbsp;다시&amp;nbsp;선택하고자&amp;nbsp;할&amp;nbsp;때&amp;nbsp;불편함이&amp;nbsp;발생. &lt;br /&gt;입력된&amp;nbsp;날짜를&amp;nbsp;초기화해야 하는&amp;nbsp;기능&amp;nbsp;구현이&amp;nbsp;필요.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;이미지 1.png&quot; data-origin-width=&quot;146&quot; data-origin-height=&quot;51&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dPVu08/btrwUldPF0Y/UpK5R3XFaB8Pg0jxv0CAck/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dPVu08/btrwUldPF0Y/UpK5R3XFaB8Pg0jxv0CAck/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dPVu08/btrwUldPF0Y/UpK5R3XFaB8Pg0jxv0CAck/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdPVu08%2FbtrwUldPF0Y%2FUpK5R3XFaB8Pg0jxv0CAck%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;146&quot; height=&quot;51&quot; data-filename=&quot;이미지 1.png&quot; data-origin-width=&quot;146&quot; data-origin-height=&quot;51&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;b&gt;1. 입력된&amp;nbsp;날짜&amp;nbsp;value&amp;nbsp;값을&amp;nbsp;빈 값으로&amp;nbsp;초기화&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1647938683337&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$('시작날짜선택자').datepicker('setDate', &quot;&quot;);
$('종료날짜선택자').datepicker('setDate', &quot;&quot;);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1번&amp;nbsp;과정만&amp;nbsp;진행하였을&amp;nbsp;때&amp;nbsp;화면상에&amp;nbsp;input&amp;nbsp;box에는&amp;nbsp;아래&amp;nbsp;이미지처럼&amp;nbsp;값이&amp;nbsp;비어있는&amp;nbsp;것으로&amp;nbsp;보이지만 &lt;br /&gt;클릭을&amp;nbsp;하였을&amp;nbsp;때&amp;nbsp;이전에&amp;nbsp;선택하였던&amp;nbsp;날짜가&amp;nbsp;선택되어&amp;nbsp;있어&amp;nbsp;초기화라고&amp;nbsp;할&amp;nbsp;수&amp;nbsp;없음.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;이미지 3.png&quot; data-origin-width=&quot;158&quot; data-origin-height=&quot;52&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/LyGdD/btrwJV9gbiB/XOLgYbZiYriIeeSmMGK6fK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/LyGdD/btrwJV9gbiB/XOLgYbZiYriIeeSmMGK6fK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/LyGdD/btrwJV9gbiB/XOLgYbZiYriIeeSmMGK6fK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FLyGdD%2FbtrwJV9gbiB%2FXOLgYbZiYriIeeSmMGK6fK%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;158&quot; height=&quot;52&quot; data-filename=&quot;이미지 3.png&quot; data-origin-width=&quot;158&quot; data-origin-height=&quot;52&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2. datepicker 기능 해제&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1647938730503&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$('시작날짜선택자').datepicker('destroy');  
$('종료날짜선택자').datepicker('destroy');&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번까지&amp;nbsp;진행&amp;nbsp;후&amp;nbsp;다시&amp;nbsp;달력을&amp;nbsp;클릭&amp;nbsp;하면&amp;nbsp; &lt;br /&gt;콘솔 창에&amp;nbsp;&quot;Cannot&amp;nbsp;read&amp;nbsp;property&amp;nbsp;'settings'&amp;nbsp;of&amp;nbsp;undefined&quot;&amp;nbsp;에러&amp;nbsp;메시지를&amp;nbsp;확인할&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;&lt;b&gt;3. datepicker 재생성&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1647938792655&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$('날짜선택자').datepicker({
	...
})&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;들어올&amp;nbsp;때&amp;nbsp;동작하는&amp;nbsp;datepicker&amp;nbsp;재생성 &lt;br /&gt;환경설정&amp;nbsp;정보&amp;nbsp;동일하게&amp;nbsp;셋팅해줘야&amp;nbsp;동일한&amp;nbsp;달력이&amp;nbsp;표출됨. &lt;br /&gt;&lt;br /&gt;3번&amp;nbsp;부분을&amp;nbsp;함수로&amp;nbsp;만들어서&amp;nbsp;작성하면&amp;nbsp;보기 좋은&amp;nbsp;형식으로&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&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;이미지 2.png&quot; data-origin-width=&quot;269&quot; data-origin-height=&quot;219&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/wDhhw/btrwTb3V2UW/Qvw750H5kilLl0krBywREK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/wDhhw/btrwTb3V2UW/Qvw750H5kilLl0krBywREK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/wDhhw/btrwTb3V2UW/Qvw750H5kilLl0krBywREK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FwDhhw%2FbtrwTb3V2UW%2FQvw750H5kilLl0krBywREK%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;269&quot; height=&quot;219&quot; data-filename=&quot;이미지 2.png&quot; data-origin-width=&quot;269&quot; data-origin-height=&quot;219&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;참고자료 &lt;br /&gt;&lt;a href=&quot;https://api.jqueryui.com/datepicker/#method-destroy&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://api.jqueryui.com/datepicker/#method-destroy&lt;/a&gt;&lt;/p&gt;</description>
      <category>jQuery</category>
      <category>datepicker</category>
      <category>JavaScript</category>
      <category>jQuery</category>
      <category>JS</category>
      <category>날짜</category>
      <category>초기화</category>
      <author>jckim</author>
      <guid isPermaLink="true">https://jckim-dev.tistory.com/31</guid>
      <comments>https://jckim-dev.tistory.com/entry/jQuery-datepicker-%EB%82%A0%EC%A7%9C-%EC%B4%88%EA%B8%B0%ED%99%94%ED%95%98%EA%B8%B0#entry31comment</comments>
      <pubDate>Wed, 23 Mar 2022 06:00:12 +0900</pubDate>
    </item>
    <item>
      <title>Linux 시스템 시간 변경하기(timezone)</title>
      <link>https://jckim-dev.tistory.com/entry/Linux-%EC%8B%9C%EC%8A%A4%ED%85%9C-%EC%8B%9C%EA%B0%84-%EB%B3%80%EA%B2%BD%ED%95%98%EA%B8%B0timezone</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;docker에서&amp;nbsp;특정&amp;nbsp;컨테이너에&amp;nbsp;접속하였을&amp;nbsp;때&amp;nbsp;화면에&amp;nbsp;표출되는&amp;nbsp;시간과&amp;nbsp;PC 시간과&amp;nbsp;맞지&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;WSL2 방식&lt;br /&gt;서버환경은 Ubuntu 18.04&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;먼저&amp;nbsp;현재&amp;nbsp;시스템의&amp;nbsp;날짜 형식을&amp;nbsp;확인&lt;/p&gt;
&lt;pre id=&quot;code_1647931706640&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# date&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;432&quot; data-origin-height=&quot;111&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cp8l5h/btrwT0AxsVr/BGk1w10cvOshNbN0S9Vl91/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cp8l5h/btrwT0AxsVr/BGk1w10cvOshNbN0S9Vl91/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cp8l5h/btrwT0AxsVr/BGk1w10cvOshNbN0S9Vl91/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcp8l5h%2FbtrwT0AxsVr%2FBGk1w10cvOshNbN0S9Vl91%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;432&quot; height=&quot;111&quot; data-origin-width=&quot;432&quot; data-origin-height=&quot;111&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;표출되는&amp;nbsp;시간을&amp;nbsp;보면&amp;nbsp;UTC&amp;nbsp;형태로&amp;nbsp;되어있는&amp;nbsp;것을&amp;nbsp;확인할&amp;nbsp;수&amp;nbsp;있었음, &lt;br /&gt;UTC는&amp;nbsp;영국을&amp;nbsp;기준으로하여&amp;nbsp;각&amp;nbsp;나라의&amp;nbsp;시차를&amp;nbsp;규정한&amp;nbsp;시간인&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;환경에서의&amp;nbsp;시간이&amp;nbsp;어떤&amp;nbsp;기준으로&amp;nbsp;설정된 것인지&amp;nbsp;확인하는&amp;nbsp;명령어는&amp;nbsp;아래와&amp;nbsp;같다.&lt;/p&gt;
&lt;pre id=&quot;code_1647931749786&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# ls -al /etc/localtime&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;620&quot; data-origin-height=&quot;39&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/chASNT/btrwJ9Fn0AB/gp9RJzrY4TNw77VAGD3yF0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/chASNT/btrwJ9Fn0AB/gp9RJzrY4TNw77VAGD3yF0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/chASNT/btrwJ9Fn0AB/gp9RJzrY4TNw77VAGD3yF0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FchASNT%2FbtrwJ9Fn0AB%2Fgp9RJzrY4TNw77VAGD3yF0%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;620&quot; height=&quot;39&quot; data-origin-width=&quot;620&quot; data-origin-height=&quot;39&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;명령어&amp;nbsp;입력&amp;nbsp;결과&amp;nbsp;해당&amp;nbsp;localtime은&amp;nbsp;심볼릭&amp;nbsp;링크로&amp;nbsp;/etc/localtime&amp;nbsp;경로가&amp;nbsp;실제로&amp;nbsp;가리키는&amp;nbsp;경로를&amp;nbsp;알&amp;nbsp;수&amp;nbsp;있다. &lt;br /&gt;처음에&amp;nbsp;날짜를&amp;nbsp;확인한&amp;nbsp;결과처럼&amp;nbsp;UTC를&amp;nbsp;가리키고&amp;nbsp;있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;지역 변경하기&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1647931787815&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# ln -sf /usr/share/zoneinfo/Asia/Seoul /etc/localtime&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&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;되었는지&amp;nbsp;확인&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;444&quot; data-origin-height=&quot;104&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ukq8M/btrwMGJ2IGo/Wn4dhkHJANcaCkyRcS5BP1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ukq8M/btrwMGJ2IGo/Wn4dhkHJANcaCkyRcS5BP1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ukq8M/btrwMGJ2IGo/Wn4dhkHJANcaCkyRcS5BP1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fukq8M%2FbtrwMGJ2IGo%2FWn4dhkHJANcaCkyRcS5BP1%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;444&quot; height=&quot;104&quot; data-origin-width=&quot;444&quot; data-origin-height=&quot;104&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;변경이&amp;nbsp;되었다면&amp;nbsp;다시&amp;nbsp;date&amp;nbsp;명령어로&amp;nbsp;한번&amp;nbsp;더&amp;nbsp;확인&lt;/p&gt;</description>
      <category>server</category>
      <category>Linux</category>
      <category>TimeZone</category>
      <category>시간변경</category>
      <author>jckim</author>
      <guid isPermaLink="true">https://jckim-dev.tistory.com/30</guid>
      <comments>https://jckim-dev.tistory.com/entry/Linux-%EC%8B%9C%EC%8A%A4%ED%85%9C-%EC%8B%9C%EA%B0%84-%EB%B3%80%EA%B2%BD%ED%95%98%EA%B8%B0timezone#entry30comment</comments>
      <pubDate>Tue, 22 Mar 2022 18:15:55 +0900</pubDate>
    </item>
    <item>
      <title>WSL2를 이용하여 Windows에서 Linux 실행하기</title>
      <link>https://jckim-dev.tistory.com/entry/WSL2%EB%A5%BC-%EC%9D%B4%EC%9A%A9%ED%95%98%EC%97%AC-Windows%EC%97%90%EC%84%9C-Linux-%EC%8B%A4%ED%96%89%ED%95%98%EA%B8%B0</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;Windows 환경에서 Linux 운영체제를 사용하고자 하는 경우&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기존에는 VMware와 같은 별도의 가상 머신 프로그램을 이용해야 했었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;VMware를 사용하면 로컬PC가 너무 무거워져서 다른 방법을 확인해보았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;Windows 환경에서 직접 Linux 애플리케이션을 실행할 수 있는 기능을 지원하는데&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 기능이 &lt;b&gt;WSL(Windows-Subsystem-Linux), 즉 &quot;Linux용 Windows 하위 시스템&quot;이다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;WSL은&amp;nbsp;버전 1과&amp;nbsp;버전 2가&amp;nbsp;존재한다. &lt;br /&gt;WSL2는&amp;nbsp;기존&amp;nbsp;버전보다&amp;nbsp;아래와&amp;nbsp;같은&amp;nbsp;이점이&amp;nbsp;있기에&amp;nbsp;업데이트하여&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;파일 시스템 성능 향상 : apt 관련 작업에 대한 속도 향상&lt;/li&gt;
&lt;li&gt;전체 시스템 호출 호환성 지원 : Linux 커널이 포함되어 언제든 업데이트가 가능함.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;WSL2&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;powershell 관리자 권한으로 실행 후 아래 명령어 입력&lt;/p&gt;
&lt;pre id=&quot;code_1647364656615&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#Linux용 Windows 하위 시스템 옵션 기능
dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart

#Virtual Machine 플랫폼 옵션 기능
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;후&amp;nbsp; &lt;br /&gt;&lt;br /&gt;재부팅 후 인터넷 연결이 안 된다면 &lt;a title=&quot;WSL 적용 후 인터넷이 안되는 경우&quot; href=&quot;https://jckim-dev.tistory.com/entry/WSL2-%EC%84%A4%EC%B9%98%ED%95%9C-%ED%9B%84-%EC%9D%B8%ED%84%B0%EB%84%B7-%EC%97%B0%EA%B2%B0%EC%9D%B4-%EC%95%88%EB%90%98%EB%8A%94-%EA%B2%BD%EC%9A%B0&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;여기서 확인&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;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래 사이트로 이동해서 &quot;&lt;span&gt;x64 머신용 최신 WSL2 Linux 커널 업데이트 패키지&quot;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;msi 파일 다운로드&lt;/p&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://docs.microsoft.com/ko-kr/windows/wsl/install-manual#step-4---download-the-linux-kernel-update-package&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://docs.microsoft.com/ko-kr/windows/wsl/install-manual#step-4---download-the-linux-kernel-update-package&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&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;938&quot; data-origin-height=&quot;201&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bBbGL1/btrv4yekzZ9/j1cIpQg3vAO1O82R84k8K1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bBbGL1/btrv4yekzZ9/j1cIpQg3vAO1O82R84k8K1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bBbGL1/btrv4yekzZ9/j1cIpQg3vAO1O82R84k8K1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbBbGL1%2Fbtrv4yekzZ9%2Fj1cIpQg3vAO1O82R84k8K1%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;938&quot; height=&quot;201&quot; data-origin-width=&quot;938&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;다운로드한 msi 설치&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;microsoft&amp;nbsp;store에서&amp;nbsp;사용하고자&amp;nbsp;하는&amp;nbsp;os&amp;nbsp;검색하여&amp;nbsp;설치(필자는&amp;nbsp;Ubuntu-18.04로&amp;nbsp;설치&amp;nbsp;진행)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1189&quot; data-origin-height=&quot;378&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bxfFBP/btrv0Phwr7D/0qGqZQim1fBLyfKS1zLIKk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bxfFBP/btrv0Phwr7D/0qGqZQim1fBLyfKS1zLIKk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bxfFBP/btrv0Phwr7D/0qGqZQim1fBLyfKS1zLIKk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbxfFBP%2Fbtrv0Phwr7D%2F0qGqZQim1fBLyfKS1zLIKk%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;1189&quot; height=&quot;378&quot; data-origin-width=&quot;1189&quot; data-origin-height=&quot;378&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;powershell&amp;nbsp;관리자&amp;nbsp;권한으로&amp;nbsp;실행&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1647364929522&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#현재 wsl 버전 확인 기존적으로 1버전이거나 표출되는게 없을 수 있음
wsl -l -v&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1647364961612&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#wsl 버전 2로 변경
#작성예시 wsl --set-version 하위시스템명
wsl --set-version Ubuntu-18.04 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;정상적으로&amp;nbsp;적용되었다면&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;적용하는데&amp;nbsp;몇 분이&amp;nbsp;걸린다는&amp;nbsp;메시지가&amp;nbsp;표출되고&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;작업이&amp;nbsp;완료되면&amp;nbsp;변경 완료&amp;nbsp;메시지가&amp;nbsp;표출된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1647365014253&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#변경된 버전 확인 wsl 버전 확인
wsl -l -v&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;548&quot; data-origin-height=&quot;77&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cZkZfq/btrv104afLm/0cNnal47Pn7rCwuSI8jKp0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cZkZfq/btrv104afLm/0cNnal47Pn7rCwuSI8jKp0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cZkZfq/btrv104afLm/0cNnal47Pn7rCwuSI8jKp0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcZkZfq%2Fbtrv104afLm%2F0cNnal47Pn7rCwuSI8jKp0%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;548&quot; height=&quot;77&quot; data-origin-width=&quot;548&quot; data-origin-height=&quot;77&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;microsoft&amp;nbsp;store에서&amp;nbsp;설치한&amp;nbsp;Ubuntu-18.04&amp;nbsp;앱에&amp;nbsp;정상적으로&amp;nbsp;접속되는지&amp;nbsp;확인&lt;/p&gt;</description>
      <category>기타</category>
      <category>Linux</category>
      <category>Windows</category>
      <category>WSL</category>
      <author>jckim</author>
      <guid isPermaLink="true">https://jckim-dev.tistory.com/29</guid>
      <comments>https://jckim-dev.tistory.com/entry/WSL2%EB%A5%BC-%EC%9D%B4%EC%9A%A9%ED%95%98%EC%97%AC-Windows%EC%97%90%EC%84%9C-Linux-%EC%8B%A4%ED%96%89%ED%95%98%EA%B8%B0#entry29comment</comments>
      <pubDate>Wed, 16 Mar 2022 02:27:41 +0900</pubDate>
    </item>
    <item>
      <title>WSL2 설치한 후 인터넷 연결이 안되는 경우</title>
      <link>https://jckim-dev.tistory.com/entry/WSL2-%EC%84%A4%EC%B9%98%ED%95%9C-%ED%9B%84-%EC%9D%B8%ED%84%B0%EB%84%B7-%EC%97%B0%EA%B2%B0%EC%9D%B4-%EC%95%88%EB%90%98%EB%8A%94-%EA%B2%BD%EC%9A%B0</link>
      <description>&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;Windows 환경에서 WSL2 사용을 위해 관련 설정을 변경하고 재부팅을 하였는데 &lt;br&gt;기존에 잘 사용하고 있던 LAN 인터넷 연결이 되지 않는 것이 확인이 되었다.&lt;br&gt; &lt;br&gt;자세히 설명하면 제목과는 조금 다르게&lt;br&gt;WSL2를 설치하기 전 설정을 적용하고 연결이 안되었던 것으로 보인다.&lt;br&gt; &lt;br&gt;우선 설정을 변경한 부분은 아래와 같다.&lt;/p&gt;
&lt;pre data-ke-type=&quot;codeblock&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot;&gt;&lt;code&gt;dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart
dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;두 명령어를 진행하였는데 &lt;br&gt;해당 명령어는 &quot;Windows 기능 켜기/끄기&quot; 메뉴 내에&lt;br&gt; &quot;Linux용 Windows 하위 시스템&quot;과 &quot;가상 머신 플랫폼&quot; 기능을 켜는 명령어이다.&lt;br&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: 50%; text-align: justify;&quot;&gt; &lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;479&quot; data-origin-height=&quot;481&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/EE0fM/btru3Mkl1mD/piVaf4krc52c3eXn9mIxok/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/EE0fM/btru3Mkl1mD/piVaf4krc52c3eXn9mIxok/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/EE0fM/btru3Mkl1mD/piVaf4krc52c3eXn9mIxok/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FEE0fM%2Fbtru3Mkl1mD%2FpiVaf4krc52c3eXn9mIxok%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;479&quot; height=&quot;481&quot; data-origin-width=&quot;479&quot; data-origin-height=&quot;481&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/td&gt;
   &lt;td style=&quot;width: 50%; text-align: justify;&quot;&gt; &lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;476&quot; data-origin-height=&quot;481&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/CZT0z/btru8uQPMmH/D3aJVbmkv5klDQPgfVpJPK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/CZT0z/btru8uQPMmH/D3aJVbmkv5klDQPgfVpJPK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/CZT0z/btru8uQPMmH/D3aJVbmkv5klDQPgfVpJPK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FCZT0z%2Fbtru8uQPMmH%2FD3aJVbmkv5klDQPgfVpJPK%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;476&quot; height=&quot;481&quot; data-origin-width=&quot;476&quot; data-origin-height=&quot;481&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/td&gt;
  &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt; &lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot; style=&quot;text-align: left;&quot;&gt;제일 처음 해본 작업은 시스템 복원을 하여 작업 전 상태로 돌아가니 정상적으로 인터넷 연결이 되는 것을 확인하였다. &lt;br&gt;우선 인터넷 연결이 되니 명령어 적용 후 재부팅이 되기 전 해당 이더넷 속성을 확인해보고 비교해보기로 하였다. &lt;br&gt;&lt;br&gt;&lt;b&gt;이더넷 속성 확인 방법&lt;/b&gt;&lt;br&gt;&lt;br&gt;winsows(시작) - 설정 - 네트워크 및 인터넷 - 이더넷 - 어댑터 옵션 변경 - 해당 이더넷 아이콘 우클릭 속성 &lt;br&gt;&lt;br&gt;아래 사진은 재부팅 전 이더넷 속성의 사용 체크된 항목이다.&lt;br&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: 50%; text-align: justify;&quot;&gt; &lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;499&quot; data-origin-height=&quot;449&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cxmjdc/btruWP3um2h/q8aFNP6BYSKKF7g8mXAUE0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cxmjdc/btruWP3um2h/q8aFNP6BYSKKF7g8mXAUE0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cxmjdc/btruWP3um2h/q8aFNP6BYSKKF7g8mXAUE0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcxmjdc%2FbtruWP3um2h%2Fq8aFNP6BYSKKF7g8mXAUE0%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;499&quot; height=&quot;449&quot; data-origin-width=&quot;499&quot; data-origin-height=&quot;449&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/td&gt;
   &lt;td style=&quot;width: 50%; text-align: justify;&quot;&gt; &lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;488&quot; data-origin-height=&quot;509&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/clTTTa/btruVYTXgzO/rmSxmARK5kVl2fT2tciBv1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/clTTTa/btruVYTXgzO/rmSxmARK5kVl2fT2tciBv1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/clTTTa/btruVYTXgzO/rmSxmARK5kVl2fT2tciBv1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FclTTTa%2FbtruVYTXgzO%2FrmSxmARK5kVl2fT2tciBv1%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;488&quot; height=&quot;509&quot; data-origin-width=&quot;488&quot; data-origin-height=&quot;509&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/td&gt;
  &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt; &lt;br&gt;이제 명령어 적용 후 다시 재부팅을 하였을 때 속성을 비교해보자(역시나 인터넷 연결은 안됨.) &lt;br&gt;&lt;br&gt;확인 결과 비교해 볼 것 없이 한눈에 봐도 체크 박스가 대부분 해제되어있는 것을 확인하였다.&lt;br&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: 50%; text-align: justify;&quot;&gt; &lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;477&quot; data-origin-height=&quot;522&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/WpVru/btru3tFECC2/uEsECy77kIl2wEG5nlkoZ1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/WpVru/btru3tFECC2/uEsECy77kIl2wEG5nlkoZ1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/WpVru/btru3tFECC2/uEsECy77kIl2wEG5nlkoZ1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FWpVru%2Fbtru3tFECC2%2FuEsECy77kIl2wEG5nlkoZ1%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;477&quot; height=&quot;522&quot; data-origin-width=&quot;477&quot; data-origin-height=&quot;522&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/td&gt;
   &lt;td style=&quot;width: 50%; text-align: justify;&quot;&gt; &lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;507&quot; data-origin-height=&quot;585&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cHu14t/btru1a0Ygn5/KIBqHFtXVy0E7kXmuhTg31/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cHu14t/btru1a0Ygn5/KIBqHFtXVy0E7kXmuhTg31/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cHu14t/btru1a0Ygn5/KIBqHFtXVy0E7kXmuhTg31/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcHu14t%2Fbtru1a0Ygn5%2FKIBqHFtXVy0E7kXmuhTg31%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;507&quot; height=&quot;585&quot; data-origin-width=&quot;507&quot; data-origin-height=&quot;585&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/td&gt;
  &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&lt;br&gt;&lt;b&gt;재부팅 전에 저장해두었던 항목을 동일하게 체크&lt;/b&gt;하고 적용하고 확인 버튼 클릭하였다.&lt;br&gt; &lt;/p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;254&quot; data-origin-height=&quot;172&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/o5ANe/btru1azOYkk/fv98kJgYV0kQDRO0JQTRDk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/o5ANe/btru1azOYkk/fv98kJgYV0kQDRO0JQTRDk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/o5ANe/btru1azOYkk/fv98kJgYV0kQDRO0JQTRDk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fo5ANe%2Fbtru1azOYkk%2Ffv98kJgYV0kQDRO0JQTRDk%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;254&quot; height=&quot;172&quot; data-origin-width=&quot;254&quot; data-origin-height=&quot;172&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt; &lt;br&gt;인터넷이 정상적으로 연결된 것을 확인하였다.&lt;/p&gt;</description>
      <category>기타</category>
      <category>Internet</category>
      <category>Windows</category>
      <category>WSL2</category>
      <category>네트워크</category>
      <category>연결</category>
      <category>이더넷</category>
      <author>jckim</author>
      <guid isPermaLink="true">https://jckim-dev.tistory.com/28</guid>
      <comments>https://jckim-dev.tistory.com/entry/WSL2-%EC%84%A4%EC%B9%98%ED%95%9C-%ED%9B%84-%EC%9D%B8%ED%84%B0%EB%84%B7-%EC%97%B0%EA%B2%B0%EC%9D%B4-%EC%95%88%EB%90%98%EB%8A%94-%EA%B2%BD%EC%9A%B0#entry28comment</comments>
      <pubDate>Fri, 4 Mar 2022 14:09:19 +0900</pubDate>
    </item>
    <item>
      <title>spring security 스프링시큐리티 주요 설정 분석</title>
      <link>https://jckim-dev.tistory.com/entry/spring-security-%EC%8A%A4%ED%94%84%EB%A7%81%EC%8B%9C%ED%81%90%EB%A6%AC%ED%8B%B0-%EC%A3%BC%EC%9A%94-%EC%84%A4%EC%A0%95-%EB%B6%84%EC%84%9D</link>
      <description>&lt;div data-pm-slice=&quot;0 0 []&quot; data-en-clipboard=&quot;true&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;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;스프링시큐리티에서 가장 많이 언급될 단어로는&lt;/span&gt;&lt;/p&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 data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;아래 개념에서 확실하게 숙지하고 진행하는게 좋다.&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;●&lt;span&gt;&amp;nbsp;&lt;/span&gt;인증과 인가&lt;/b&gt;&lt;/p&gt;
&lt;div&gt;- 인증(Authentication) : 사용자가 맞는지 확인하는 과정&lt;/div&gt;
&lt;div&gt;- 인가(Authorization) : 사용자에게 특정한 권한을 부여하는 과정&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;●&lt;span&gt;&amp;nbsp;&lt;/span&gt;pom.xml 설정(스프링시큐리티 관련)&lt;/b&gt;&lt;/p&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1645963546690&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.boot&amp;lt;/groupId&amp;gt;
	&amp;lt;artifactId&amp;gt;spring-boot-starter-security&amp;lt;/artifactId&amp;gt;
&amp;lt;/dependency&amp;gt;

&amp;lt;dependency&amp;gt;
	&amp;lt;groupId&amp;gt;org.springframework.security&amp;lt;/groupId&amp;gt;
	&amp;lt;artifactId&amp;gt;spring-security-taglibs&amp;lt;/artifactId&amp;gt;
&amp;lt;/dependency&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;●&lt;span&gt;&amp;nbsp;&lt;/span&gt;스프링시큐리티 태그 라이브러리 선언&lt;/b&gt;&lt;/p&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1645963606486&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;%@ taglib prefix=&quot;sec&quot; uri=&quot;http://www.springframework.org/security/tags&quot; %&amp;gt;

&amp;lt;sec:authorize access=&quot;isAuthenticated()&quot;&amp;gt;
&amp;lt;sec:authentication property=&quot;principal&quot; var=&quot;user&quot;/&amp;gt;
	&amp;lt;c:if test=&quot;${user.권한 eq '관리자'}&quot;&amp;gt;
		...인증되고 인가된 사용자에게 표출할 영역
	&amp;lt;/c:if&amp;gt;
&amp;lt;/sec:authorize&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;div&gt;스프링시큐리티에서 제공하는 기능을 jsp에서 태그로 사용할 수 있음.&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;● 스프링시큐리티 설정&lt;/b&gt;&lt;/p&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1645963900586&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter{

@Autowired
UsrService usrService; //회원 관련 로직을 담당하고있는 Service(사용자마다 생성되는 클래스명은 다름)
@Autowired
private DataSource dataSource; //DB관련 설정 (사용자마다 생성되는 클래스명은 다름)
@Bean //비밀번호 암호화 관련
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
   
@Override
protected void configure(HttpSecurity http) throws Exception {
        http
        .authorizeRequests() /*인가 설정*/
        .antMatchers(&quot;/admin/**&quot;).hasAuthority(&quot;ADMIN&quot;)
            .antMatchers(&quot;/&quot;, &quot;/usr/join&quot;, &quot;/resources/**&quot;, &quot;/docs/**&quot;).permitAll() //모든 권한 인가 허용
            .anyRequest().authenticated()
            .and()
        .formLogin()
            .loginPage(&quot;/usr/login&quot;) //로그인 페이지 URL
            .defaultSuccessUrl(&quot;/usr/loginSuccess&quot;)
            .loginProcessingUrl(&quot;/usr/login&quot;)
            .usernameParameter(&quot;usrId&quot;)
            .passwordParameter(&quot;usrPw&quot;)
            .permitAll()
            .and()
        .logout()
        .logoutUrl(&quot;/usr/logout&quot;)
        .logoutSuccessUrl(&quot;/&quot;)
        .invalidateHttpSession(true)
        .permitAll();
       
}
   
    @Override
    public void configure(AuthenticationManagerBuilder auth) throws Exception {
        //인증 시 비밀번호 암호화 설정
    auth.userDetailsService(usrService).passwordEncoder(passwordEncoder());
   
    }   
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;@Configuration &lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #0593d3;&quot;&gt;&lt;b&gt;@EnableWebSecurity&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #ef5369;&quot;&gt;java configuration class&lt;/span&gt;&lt;/b&gt;로 &lt;b&gt;&lt;span style=&quot;color: #0593d3;&quot;&gt;스프링시큐리티 관련 설정&lt;/span&gt;&lt;/b&gt;을 위해&lt;/p&gt;
&lt;div data-pm-slice=&quot;1 1 []&quot; data-en-clipboard=&quot;true&quot;&gt;&lt;b&gt;WebSecurityConfigurerAdapter&lt;/b&gt; 클래스를 상속 받은 후&lt;/div&gt;
&lt;div data-pm-slice=&quot;1 1 []&quot; data-en-clipboard=&quot;true&quot;&gt;필수적인 중요한 설정 두가지를 override를 해야한다.&lt;/div&gt;
&lt;div data-pm-slice=&quot;1 1 []&quot; data-en-clipboard=&quot;true&quot;&gt;eclipse 내에 서는 ctrl + space 를 자동완성 기능이 있기때문에 보다 override 하고자하는&lt;/div&gt;
&lt;div data-pm-slice=&quot;1 1 []&quot; data-en-clipboard=&quot;true&quot;&gt;메소드를 입력하기 편리하다.&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;552&quot; data-origin-height=&quot;197&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bWtuV7/btruwH4GlHd/hyeXIIFi8EUiVGWkS7ry8k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bWtuV7/btruwH4GlHd/hyeXIIFi8EUiVGWkS7ry8k/img.png&quot; data-alt=&quot;자동완성 표출목록&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bWtuV7/btruwH4GlHd/hyeXIIFi8EUiVGWkS7ry8k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbWtuV7%2FbtruwH4GlHd%2FhyeXIIFi8EUiVGWkS7ry8k%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;552&quot; height=&quot;197&quot; data-origin-width=&quot;552&quot; data-origin-height=&quot;197&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;&lt;b&gt;메소드 1. configure(HttpSecurity http)&lt;/b&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;특정 URL(resource 경로)에 대한 접속 허용 여부&lt;/li&gt;
&lt;li&gt;특정 권한에 대한 접속 허용 여부&lt;/li&gt;
&lt;li&gt;로그아웃 URL 설정&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;b&gt;메소드2. configure(AuthenticationManagerBuilder auth)&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;스프링시큐리티 인증 관련 설정을 하는 영역으로&lt;/div&gt;
&lt;div&gt;설정방법에는&lt;/div&gt;
&lt;div&gt;- DB에서 조회하는 방법 (&lt;span style=&quot;background-color: #ffffff; color: #000000;&quot;&gt;jdbcAuthentication)&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;- LDAP 기반 인증 방법 (&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000; letter-spacing: 0px;&quot;&gt;ldapAuthentication)&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;- 직접 설정하는 방법 (&lt;span style=&quot;background-color: #ffffff; color: #000000;&quot;&gt;userDetailsService)&lt;/span&gt;&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000;&quot;&gt;등이 있으나 필자는 &lt;span style=&quot;background-color: #ffffff; color: #000000;&quot;&gt;&lt;b&gt;UserDetailsService 인터페이스를 구현&lt;/b&gt;하여 직접 적용해보았다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;auth.&lt;span style=&quot;background-color: #ffffff; color: #000000;&quot;&gt;userDetailsService()를 사용한다면&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;background-color: #ffffff; color: #000000;&quot;&gt;userDetailsService 인터페이스를 구현한 클래스에&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;loadUserByUsername&lt;/b&gt; 메소드를 override 하여 인증 로직을 작성해 줘야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;필자는 UserService 클래스에 구현하였다.&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;div&gt;&lt;b&gt;●&lt;span&gt;&amp;nbsp;&lt;/span&gt;UserDetailsService 구현&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1645966116655&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;@Service
@Transactional
public class UsrService implements UserDetailsService  {
...
...
	@Override
	public UserDetails loadUserByUsername(String usrId) throws UsernameNotFoundException {
		
        Optional&amp;lt;UsrEntity&amp;gt; userEntityWrapper = usrRepository.findByUsrId(usrId);
        UsrEntity userEntity = userEntityWrapper.get();
        List&amp;lt;GrantedAuthority&amp;gt; authorities = new ArrayList&amp;lt;&amp;gt;();
        RoleUsrEntity roleUsrEntity = userEntity.getRole();
        String authRoleCd = roleUsrEntity.getRoleCd();
        
        if(userEntity.getRole() != null) {
        	authorities.add(new SimpleGrantedAuthority(authRoleCd));
        } else {
        	authorities.add(new SimpleGrantedAuthority(&quot;R01&quot;));
        }
        return new User(userEntity.getUsrId(), userEntity.getUsrPw(), authorities);
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;필자는 회원 가입할 때 회원정보 중 비밀번호를 BCryptPasswordEncoder 암호화하여 저장하였음.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;암호화된 비밀번호는 절대 복호화될 수 없는 점을 숙지.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;loadUserByUsername 메소드에서는 로그인 시도한 사용자의 ID를 조회하여 권한과 비밀번호를 리턴하고&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;passwordEncoder를 이용하여 입력한 비밀번호를 암호화한 값과 조회된 암호화된 비밀번호를&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;비교하여 일치한 경우 인증에 성공시킨다.&lt;/p&gt;</description>
      <category>spring</category>
      <category>Authentication</category>
      <category>Authorization</category>
      <category>loadUserByUsername</category>
      <category>security</category>
      <category>spring</category>
      <category>보안</category>
      <category>인가</category>
      <category>인증</category>
      <author>jckim</author>
      <guid isPermaLink="true">https://jckim-dev.tistory.com/27</guid>
      <comments>https://jckim-dev.tistory.com/entry/spring-security-%EC%8A%A4%ED%94%84%EB%A7%81%EC%8B%9C%ED%81%90%EB%A6%AC%ED%8B%B0-%EC%A3%BC%EC%9A%94-%EC%84%A4%EC%A0%95-%EB%B6%84%EC%84%9D#entry27comment</comments>
      <pubDate>Sun, 27 Feb 2022 22:18:33 +0900</pubDate>
    </item>
    <item>
      <title>oracle 서브쿼리 rownum 조회시 ORA-00904 invalid identifier 원인파악</title>
      <link>https://jckim-dev.tistory.com/entry/oracle-%EC%84%9C%EB%B8%8C%EC%BF%BC%EB%A6%AC-rownum-%EC%A1%B0%ED%9A%8C%EC%8B%9C-ORA-00904-invalid-identifier-%EC%9B%90%EC%9D%B8%ED%8C%8C%EC%95%85</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;oracle&amp;nbsp;DB를&amp;nbsp;사용하여&amp;nbsp;중이며&lt;br /&gt;추가적으로 데이터를 조회해야 하는 작업이었다.&lt;br /&gt;&lt;br /&gt;문제가&amp;nbsp;발생했던&amp;nbsp;쿼리를&amp;nbsp;임의의&amp;nbsp;테이블로&amp;nbsp;재구성&amp;nbsp;해보았고&amp;nbsp;아래와&amp;nbsp;같다. &lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1645604772880&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT 
    (SELECT Z.사용자명
     FROM (SELECT U.사용자명
           FROM 사용자_테이블  U
           WHERE U.사용자_소속 = P.상품_관리자_소속
           order by U.로그인_일자 DESC
           ) Z
    WHERE Z.ROWNUM = 1) 가장 최근에 접속한 사용자
FROM 상품_테이블 P&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;br /&gt;쿼리를&amp;nbsp;간략하게&amp;nbsp;설명하자면 &lt;br /&gt;상품을&amp;nbsp;관리하는&amp;nbsp;사용자의&amp;nbsp;소속에서&amp;nbsp;가장&amp;nbsp;최근에&amp;nbsp;로그인한&amp;nbsp;한 명을&amp;nbsp;추출하는&amp;nbsp;쿼리이다 &lt;br /&gt;&lt;br /&gt;해당&amp;nbsp;쿼리를&amp;nbsp;실행하였을&amp;nbsp;때&amp;nbsp;표출되는&amp;nbsp;메시지는&amp;nbsp;아래와&amp;nbsp;같다. &lt;/p&gt;
&lt;pre id=&quot;code_1645604789511&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;ORA-00904: &quot;P&quot;.&quot;상품_관리자_소속&quot;: invalid identifier&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;br /&gt;메시지를&amp;nbsp;그대로&amp;nbsp;읽으면&amp;nbsp;&quot;P&quot;.&quot;상품_관리자_소속&quot;이&amp;nbsp;부적절한&amp;nbsp;식별자라는&amp;nbsp;것인데 &lt;br /&gt;오타가&amp;nbsp;없으며&amp;nbsp;테이블&amp;nbsp;스키마에도&amp;nbsp;정상적으로&amp;nbsp;생성되어있는&amp;nbsp;컬럼인것을&amp;nbsp;확인하였다. &lt;br /&gt;&lt;br /&gt;확인&amp;nbsp;결과&amp;nbsp;해당&amp;nbsp;쿼리는&amp;nbsp; &lt;br /&gt;제목에는&amp;nbsp;서브쿼리라&amp;nbsp;되어&amp;nbsp;있지만&amp;nbsp;정확하게는 &lt;br /&gt;스칼라&amp;nbsp;서브쿼리&amp;nbsp;안쪽에&amp;nbsp;인라인 뷰&amp;nbsp;내부에서 &lt;br /&gt;가장&amp;nbsp;최상단에&amp;nbsp;있는&amp;nbsp;P&amp;nbsp;테이블의&amp;nbsp;컬럼을&amp;nbsp;호출하였기&amp;nbsp;때문이었다. &lt;br /&gt;&lt;br /&gt;상세하게&amp;nbsp;설명하면&amp;nbsp;인라인뷰의&amp;nbsp;동작&amp;nbsp;방식의&amp;nbsp;특징으로 &lt;br /&gt;인라인 뷰는&amp;nbsp;상관관계 서브 쿼리가&amp;nbsp;아니기&amp;nbsp;때문에&amp;nbsp;독립적으로만&amp;nbsp;사용이&amp;nbsp;가능하여 &lt;br /&gt;스칼라&amp;nbsp;서브쿼리&amp;nbsp;안쪽에&amp;nbsp;인라인 뷰에서는&amp;nbsp;메인 쿼리의&amp;nbsp;컬럼을&amp;nbsp;가져올&amp;nbsp;수가&amp;nbsp;없던&amp;nbsp;것이다. &lt;br /&gt;&lt;br /&gt;조치할&amp;nbsp;수&amp;nbsp;있는&amp;nbsp;방법으로는 &lt;br /&gt;&lt;b&gt;- 오라클의 WITH 함수 &lt;/b&gt;&lt;br /&gt;&lt;b&gt;- 상위 n번째 값을 구하는 다른 방식으로 ORDER BY로 인한 인라인뷰 생성 방지&lt;/b&gt; &lt;br /&gt;가&amp;nbsp;있을&amp;nbsp;것으로&amp;nbsp;보인다. &lt;br /&gt;&lt;br /&gt;후자를&amp;nbsp;선택하여&amp;nbsp;조치를&amp;nbsp;진행하였다. &lt;br /&gt;ROWNUM을&amp;nbsp;구하기위해&amp;nbsp;생성된&amp;nbsp;인라인 뷰&amp;nbsp;영역을 &lt;br /&gt;오라클에서&amp;nbsp;지원하는&amp;nbsp;KEEP&amp;nbsp;(DENSE_RANK...)&amp;nbsp;함수&amp;nbsp;사용 &lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1645604819868&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT 
    (SELECT MAX(U.사용자명) KEEP (DENSE_RANK FIRST ORDER BY U.로그인_일자 DESC NULLS LAST)
           FROM 사용자_테이블  U
           WHERE U.사용자_소속 = P.상품_관리자_소속
           ) 가장 최근에 접속한 사용자
FROM 상품_테이블 P&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>DB</category>
      <category>ORA-00904</category>
      <category>Oracle</category>
      <category>order by</category>
      <category>Rownum</category>
      <category>서브쿼리</category>
      <author>jckim</author>
      <guid isPermaLink="true">https://jckim-dev.tistory.com/26</guid>
      <comments>https://jckim-dev.tistory.com/entry/oracle-%EC%84%9C%EB%B8%8C%EC%BF%BC%EB%A6%AC-rownum-%EC%A1%B0%ED%9A%8C%EC%8B%9C-ORA-00904-invalid-identifier-%EC%9B%90%EC%9D%B8%ED%8C%8C%EC%95%85#entry26comment</comments>
      <pubDate>Thu, 24 Feb 2022 06:00:58 +0900</pubDate>
    </item>
    <item>
      <title>Unexpected character (n) at position 해결하기(JSON)</title>
      <link>https://jckim-dev.tistory.com/entry/Unexpected-character-n-at-position-%ED%95%B4%EA%B2%B0%ED%95%98%EA%B8%B0JSON</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;API를 호출하여 결과를 DB에 수집을 하는데&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;어느 날부터&amp;nbsp;수집이 되지&amp;nbsp;않아&amp;nbsp;확인을&amp;nbsp;해보았음.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;오류파악&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;API를&amp;nbsp;호출하여&amp;nbsp;저장하는&amp;nbsp;WAS의&amp;nbsp;LOG를&amp;nbsp;확인해&amp;nbsp;보았는데&amp;nbsp;해당&amp;nbsp;부분에&amp;nbsp;아래와&amp;nbsp;같은&amp;nbsp;ERROR&amp;nbsp;LOG가&amp;nbsp;확인되었음.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1645517078191&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;Unexpected character (n) at position [nember].&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;관련 LOG는 JSON 파싱 중 문법에 맞지 않은 데이터 형식을 파싱 하려고 할 때 나타나는 에러 메시지로 확인하였고&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;상세하게는 JSON 데이터에서 number 번째에 문자 &quot;n&quot;으로 시작하는 부근에 구문 오류가 있다는 것이다.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;일일이&amp;nbsp;API&amp;nbsp;결과&amp;nbsp;데이터를&amp;nbsp;눈으로&amp;nbsp;보는 건&amp;nbsp;정말&amp;nbsp;비효율적이기&amp;nbsp;때문에&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;해당&amp;nbsp;API를&amp;nbsp;브라우저에서&amp;nbsp;호출하여&amp;nbsp;결괏값을&amp;nbsp;JSON&amp;nbsp;validation&amp;nbsp;사이트를&amp;nbsp;통하여&amp;nbsp;검증을&amp;nbsp;진행하였다.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;다행인 건지 검증 결과에서 바로 발견을 할 수 있었음.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1645517122803&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;{
	&quot;testData&quot;: &quot;&amp;lt;div class= &quot;test&quot;/&amp;gt;&quot;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;603&quot; data-origin-height=&quot;198&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bb2VZY/btrtU9PzkJq/4rflDot6vVPGpAyHSm2xCK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bb2VZY/btrtU9PzkJq/4rflDot6vVPGpAyHSm2xCK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bb2VZY/btrtU9PzkJq/4rflDot6vVPGpAyHSm2xCK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbb2VZY%2FbtrtU9PzkJq%2F4rflDot6vVPGpAyHSm2xCK%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;603&quot; height=&quot;198&quot; data-origin-width=&quot;603&quot; data-origin-height=&quot;198&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;원인은&amp;nbsp;JSON&amp;nbsp;데이터&amp;nbsp;값&amp;nbsp;중에&amp;nbsp;쌍따옴표(&quot;)&amp;nbsp;가&amp;nbsp;포함이&amp;nbsp;되어있어&amp;nbsp;쌍따옴표(&quot;)&amp;nbsp;묶여&amp;nbsp;있는&amp;nbsp;JSON&amp;nbsp;데이터&amp;nbsp;값에&amp;nbsp;올바르지&amp;nbsp;않은&amp;nbsp;문법을&amp;nbsp;나타나게&amp;nbsp;된&amp;nbsp;것이었음.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;조치&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;br /&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;조치방법으로&amp;nbsp;API&amp;nbsp;응답&amp;nbsp;시&amp;nbsp;쌍따옴표(&quot;)와&amp;nbsp;같은&amp;nbsp;JSON&amp;nbsp;파싱에&amp;nbsp;영향을&amp;nbsp;줄&amp;nbsp;수&amp;nbsp;있는&amp;nbsp;문자에&amp;nbsp;대해서&amp;nbsp;이스케이프(\)&amp;nbsp;처리를&amp;nbsp;하도록&amp;nbsp;함.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1645517166440&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;{
	&quot;testData&quot;: &quot;&amp;lt;div class= \&quot;test\&quot;/&amp;gt;&quot;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;186&quot; data-origin-height=&quot;110&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/S9G9J/btrt0NLwSnH/alcG8Euzb1X3yVQLz2ANCk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/S9G9J/btrt0NLwSnH/alcG8Euzb1X3yVQLz2ANCk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/S9G9J/btrt0NLwSnH/alcG8Euzb1X3yVQLz2ANCk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FS9G9J%2Fbtrt0NLwSnH%2FalcG8Euzb1X3yVQLz2ANCk%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;186&quot; height=&quot;110&quot; data-origin-width=&quot;186&quot; data-origin-height=&quot;110&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;개선된&amp;nbsp;JSON&amp;nbsp;데이터&amp;nbsp;검증을&amp;nbsp;완료하고&amp;nbsp;정상적으로&amp;nbsp;적재되는&amp;nbsp;것&amp;nbsp;확인&amp;nbsp;완료.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;기존에&amp;nbsp;잘&amp;nbsp;수집하던&amp;nbsp;데이터가&amp;nbsp;갑자기&amp;nbsp;안 되는&amp;nbsp;원인까지&amp;nbsp;알아보니&amp;nbsp;기존에는&amp;nbsp;이스케이프&amp;nbsp;처리가&amp;nbsp;되어&amp;nbsp;결괏값을&amp;nbsp;응답하였으나&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;최근에&amp;nbsp;API기관의&amp;nbsp;시스템&amp;nbsp;작업&amp;nbsp;이후&amp;nbsp;이스케이프&amp;nbsp;처리가&amp;nbsp;안된&amp;nbsp;데이터가&amp;nbsp;응답되었던&amp;nbsp;것으로&amp;nbsp;확인.&lt;/span&gt;&lt;/p&gt;</description>
      <category>기타</category>
      <category>JSON</category>
      <category>position</category>
      <category>unexpected</category>
      <category>Unexpected character</category>
      <author>jckim</author>
      <guid isPermaLink="true">https://jckim-dev.tistory.com/25</guid>
      <comments>https://jckim-dev.tistory.com/entry/Unexpected-character-n-at-position-%ED%95%B4%EA%B2%B0%ED%95%98%EA%B8%B0JSON#entry25comment</comments>
      <pubDate>Wed, 23 Feb 2022 06:20:13 +0900</pubDate>
    </item>
    <item>
      <title>[GIT] Git에서 SVN의 revert 기능 사용하기(Reset, Revert)</title>
      <link>https://jckim-dev.tistory.com/entry/GIT-git%EC%97%90%EC%84%9C-svn%EC%9D%98-revert-%EA%B8%B0%EB%8A%A5-%EC%82%AC%EC%9A%A9%ED%95%98%EA%B8%B0</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;형상관리 도구로는 평소 자주 사용하였던 SVN 외에도&lt;span style=&quot;background-color: #ffffff; color: #202124;&quot;&gt;Git, SVN, CVN, Perforce, SourceSafe 등이 있으며&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #202124;&quot;&gt;보편적으로 사용하고 있는 SVN과 Git을 우선적으로 사용해 보았다.&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;Subversion(svn)을 사용했던 사용자라면 저장소에서 체크아웃 받은 소스를 작업하다가&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다시 작업하기 전 상태로 되돌리려고 하는 경우&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;revert 기능을 사용하여 간편하게 소스를 되돌렸을 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 Git을 사용하여 작업을 하다가 작업하다가 다시 작업하기 전 상태로 되돌리려고 하는 경우&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;eclipse 내에 형상관리 관련 메뉴에서 revert와 관련 있어 보이는 메뉴로는 &lt;b&gt;Reset과 Revert Commit&lt;/b&gt;이 보인다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;339&quot; data-origin-height=&quot;139&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/emvQfG/btrtLULFdl4/eI9OKxBR9s7tCCXIow7pN1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/emvQfG/btrtLULFdl4/eI9OKxBR9s7tCCXIow7pN1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/emvQfG/btrtLULFdl4/eI9OKxBR9s7tCCXIow7pN1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FemvQfG%2FbtrtLULFdl4%2FeI9OKxBR9s7tCCXIow7pN1%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;339&quot; height=&quot;139&quot; data-origin-width=&quot;339&quot; data-origin-height=&quot;139&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;두 가지 명령에는 차이점이 있다&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;Reset&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;특정 이력으로 돌아가며 그 이후 커밋은 삭제가 되어 깨끗하게 돌아갈 수 있다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;관련 옵션으로는 Soft, Mixed, Hard 세 가지로&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;703&quot; data-origin-height=&quot;281&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cZ3hCP/btrtLWCH5zr/dVykhzpk0Iezip8xnWKWM0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cZ3hCP/btrtLWCH5zr/dVykhzpk0Iezip8xnWKWM0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cZ3hCP/btrtLWCH5zr/dVykhzpk0Iezip8xnWKWM0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcZ3hCP%2FbtrtLWCH5zr%2FdVykhzpk0Iezip8xnWKWM0%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;703&quot; height=&quot;281&quot; data-origin-width=&quot;703&quot; data-origin-height=&quot;281&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;Soft : HEAD 트리만 해당 커밋으로 되돌림.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Mixed : HEAD, Index 트리를 해당 커밋으로 되돌림.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Hard : HEAD, Index, 워킹 디렉터리 트리를 해당 커밋으로 되돌림.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;Revert&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;특정 이력으로 돌아가지만 커밋을 하여 이력이 남게 됨.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다만, 이력이 남기 때문에 다른 사람이 어떤 부분이 변경되었는지 알기 쉽다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;결론&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;commit을 하였으나 이력을 남기지 않고자 할 때 Reset - Hard 옵션을 사용&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;commit을 하였으나 이력을 남겨여 할 때 Rever 옵션 사용&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아직 Commit을 하지 않았다면 해당 파일을 다시 체크아웃Checkout 받으면 이전 상태로 돌아갈 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1646632273893&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;git checkout -- [소스경로]&lt;/code&gt;&lt;/pre&gt;</description>
      <category>형상관리</category>
      <category>Eclipse</category>
      <category>Git</category>
      <category>Reset</category>
      <category>revert</category>
      <category>되돌리기</category>
      <author>jckim</author>
      <guid isPermaLink="true">https://jckim-dev.tistory.com/24</guid>
      <comments>https://jckim-dev.tistory.com/entry/GIT-git%EC%97%90%EC%84%9C-svn%EC%9D%98-revert-%EA%B8%B0%EB%8A%A5-%EC%82%AC%EC%9A%A9%ED%95%98%EA%B8%B0#entry24comment</comments>
      <pubDate>Tue, 22 Feb 2022 07:20:00 +0900</pubDate>
    </item>
    <item>
      <title>DevOps와 SRE 무엇이 다른가?</title>
      <link>https://jckim-dev.tistory.com/entry/DevOps%EC%99%80-SRE-%EB%AC%B4%EC%97%87%EC%9D%B4-%EB%8B%A4%EB%A5%B8%EA%B0%80</link>
      <description>&lt;p data-pm-slice=&quot;1 1 []&quot; data-en-clipboard=&quot;true&quot; data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;결론부터 이야기하자면 SRE(도구)는 DevOps(문화)를 구현하는 역할이다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;1.png&quot; data-origin-width=&quot;654&quot; data-origin-height=&quot;493&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/OfPlk/btrtVpcNT1d/uwTrTwM6kD6dBYHbDskciK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/OfPlk/btrtVpcNT1d/uwTrTwM6kD6dBYHbDskciK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/OfPlk/btrtVpcNT1d/uwTrTwM6kD6dBYHbDskciK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FOfPlk%2FbtrtVpcNT1d%2FuwTrTwM6kD6dBYHbDskciK%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;654&quot; height=&quot;493&quot; data-filename=&quot;1.png&quot; data-origin-width=&quot;654&quot; data-origin-height=&quot;493&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h4 data-pm-slice=&quot;1 1 []&quot; data-en-clipboard=&quot;true&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;DevOps란&lt;/b&gt;&lt;/h4&gt;
&lt;div&gt;Developement 와 Operations의 합성어로&lt;/div&gt;
&lt;div&gt;개발과 운영의 구분없이 모두 수행하는 문화, 원칙을 말한다.&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;실제로 운영팀과 구축(개발)팀의 상황에서만 봐도 각각의 입장 차이가 있어&lt;/div&gt;
&lt;div&gt;서로의 입장차이를 조율하는데 있어서 프로젝트 관리자의 역할이 중요한 상황이 빈번하게 발생한다.&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;때문에 개발, 테스트, 배포, 운영까지 모두 개발팀과 운영팀 구분없이 모든 일을 하나의 조직에서 진행하는 문화, 원칙이 탄생하게 된 것으로 보인다.&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;데브옵스 특징&lt;/b&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;/ul&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;데브옵스 장점&lt;/b&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;하나의 팀에서 개발, 테스트, 배포 등 모두를 담당하기 때문에 개발에서 배포까지의 속도 향상&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;SRE란&lt;/b&gt;&lt;/h4&gt;
&lt;div data-pm-slice=&quot;1 1 []&quot; data-en-clipboard=&quot;true&quot;&gt;SRE(사이트 안정성 엔지니어링)란 조직이 해당 시스템, 서비스 및 제품에서 적절한 수준의 안정성을 달성하도록 지원하는 엔지니어링 분야이다.&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;SRE 역할&lt;/b&gt;&lt;/p&gt;
&lt;div&gt;DevOps 문화를 바탕으로 개발자들이 테스트, 배포, 모니터링 할 수 있는 플랫폼을 개발하는 역할&lt;/div&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;2.png&quot; data-origin-width=&quot;942&quot; data-origin-height=&quot;447&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bqi3J3/btrtNRBF3Wx/6JdrBtMZv8qFDAMDiy76dk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bqi3J3/btrtNRBF3Wx/6JdrBtMZv8qFDAMDiy76dk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bqi3J3/btrtNRBF3Wx/6JdrBtMZv8qFDAMDiy76dk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbqi3J3%2FbtrtNRBF3Wx%2F6JdrBtMZv8qFDAMDiy76dk%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;942&quot; height=&quot;447&quot; data-filename=&quot;2.png&quot; data-origin-width=&quot;942&quot; data-origin-height=&quot;447&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;div data-pm-slice=&quot;1 1 []&quot; data-en-clipboard=&quot;true&quot;&gt;&lt;b&gt;Metrics &amp;amp; Monitoring (장애탐지)&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;&lt;b&gt;모니터링의 지표를 정의&lt;/b&gt;하고, 해당 지표를 모니터링 시스템에서도 적용하여 모니터링 할 수 있게하여&lt;/div&gt;
&lt;div&gt;모든 것은 데이터로 남겨 해당 &lt;b&gt;데이터를 기반으로 의사결정&lt;/b&gt;을 진행.&lt;/div&gt;
&lt;div&gt;&amp;nbsp; &amp;nbsp; - SLI (Service Level Indictor) : &lt;b&gt;서비스 수준을 판단&lt;/b&gt;할 수 있는 몇 가지를 정량적으로 측정할 수 있는 &lt;b&gt;척도&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;&amp;nbsp; &amp;nbsp; - SLO (Service Level Objective) : SLI에 의해 측정된 &lt;b&gt;서비스 수준의 목표 값&lt;/b&gt; 혹은 &lt;b&gt;일정 범위의 값&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;SLI를 먼저 정하고, 각각의 지표에 대한 안정성 목표를 SLO로 설정하여 운영관리&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;&lt;b&gt;Capacity Planning(용량 계획)&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;누적된 데이터를 통해서 시스템 운영에 필요한 충분한 하드웨어 리소스 확보, 설계 및 관리&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;&lt;b&gt;Change Management (장애탐지, 장애복구)&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;배포시 장애가 발생하였을 때 신속하고 정확하게 문제를 찾아낼 수 있도록 해야함&lt;/div&gt;
&lt;div&gt;문제가 발생하였을 때 신속하게 롤백 가능하게 해야함&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;&lt;b&gt;Emergency Response (장애복구, 장애재발방지, 장애예방)&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;장애가 발생하더라도 신속하게 롤백 될 수 있도록 복구 또한 자동화 해야함.&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;&lt;b&gt;Culture&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;장애리뷰, 장애재발방지, 장애예방을 위해 장애경험을 공유하고 누적된 데이터를 기반으로 의견 공유 및 결정을 할 수 있도록 해야함.&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;3.png&quot; data-origin-width=&quot;923&quot; data-origin-height=&quot;366&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/MFib9/btrtTMzkjzn/ScgKjPJi1O4iF8EmCtTSeK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/MFib9/btrtTMzkjzn/ScgKjPJi1O4iF8EmCtTSeK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/MFib9/btrtTMzkjzn/ScgKjPJi1O4iF8EmCtTSeK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FMFib9%2FbtrtTMzkjzn%2FScgKjPJi1O4iF8EmCtTSeK%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;923&quot; height=&quot;366&quot; data-filename=&quot;3.png&quot; data-origin-width=&quot;923&quot; data-origin-height=&quot;366&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-pm-slice=&quot;1 1 []&quot; data-en-clipboard=&quot;true&quot;&gt;조직적인 사일로(silo : 분권) 줄임&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;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;참고자료&lt;/b&gt;&lt;/p&gt;
&lt;div data-pm-slice=&quot;1 1 []&quot; data-en-clipboard=&quot;true&quot;&gt;&lt;a href=&quot;https://drive.google.com/file/d/1iOMaYIwlUBiGoG2mf8MFzl3EHy5xGJpq/view&quot;&gt;https://drive.google.com/file/d/1iOMaYIwlUBiGoG2mf8MFzl3EHy5xGJpq/view&lt;/a&gt;&lt;/div&gt;</description>
      <category>기타</category>
      <category>DevOps</category>
      <category>sre</category>
      <category>데브옵스</category>
      <category>사이트안정성엔지니어</category>
      <author>jckim</author>
      <guid isPermaLink="true">https://jckim-dev.tistory.com/23</guid>
      <comments>https://jckim-dev.tistory.com/entry/DevOps%EC%99%80-SRE-%EB%AC%B4%EC%97%87%EC%9D%B4-%EB%8B%A4%EB%A5%B8%EA%B0%80#entry23comment</comments>
      <pubDate>Mon, 21 Feb 2022 15:06:31 +0900</pubDate>
    </item>
    <item>
      <title>[JPA] JPA 프로젝트 수정 기능 구현 시 null 값으로 저장되는 현상</title>
      <link>https://jckim-dev.tistory.com/entry/JPA-JPA-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%EC%88%98%EC%A0%95-%EA%B8%B0%EB%8A%A5-%EA%B5%AC%ED%98%84-%EC%8B%9C-null-%EA%B0%92%EC%9C%BC%EB%A1%9C-%EC%A0%80%EC%9E%A5%EB%90%98%EB%8A%94-%ED%98%84%EC%83%81</link>
      <description>&lt;h3 style=&quot;text-align: left;&quot; data-ke-size=&quot;size23&quot;&gt;JPA를 사용하여 개인 프로젝트 진행하던 중 게시판 글 수정 기능을 구현하는 과정에서 &lt;br&gt;제목이나 내용을 수정하고 저장을 하면 등록일자 항목의 값이 비어지는 현상이 나타났다.&lt;/h3&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1168&quot; data-origin-height=&quot;267&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b6tUIk/btrqBIgE2Xy/mmkMkURh2GGbHcd4s7YfmK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b6tUIk/btrqBIgE2Xy/mmkMkURh2GGbHcd4s7YfmK/img.png&quot; data-alt=&quot; 21번 게시물에 비어있는 등록일자 &quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b6tUIk/btrqBIgE2Xy/mmkMkURh2GGbHcd4s7YfmK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb6tUIk%2FbtrqBIgE2Xy%2FmmkMkURh2GGbHcd4s7YfmK%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;1168&quot; height=&quot;267&quot; data-origin-width=&quot;1168&quot; data-origin-height=&quot;267&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt; 21번 게시물에 비어있는 등록일자 &lt;/figcaption&gt;
&lt;/figure&gt;

&lt;hr data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot;&gt;
&lt;h3 style=&quot;text-align: left;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;br&gt;우선, 글을 처음 등록할 때 로직을 다시 확인하였다.&lt;br&gt;등록일자 값은 Entity 내에 @PrePersist 어노테이션을 이용하여 Date 객체를 대입하여 값을 등록하였다. &lt;br&gt;@PrePersist 어노테이션은 해당 테이블이 insert를 할 때 동작하는 것으로 수정을 할 때는 해당 어노테이션이 동작하지 않기 때문이다. &lt;/h3&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;299&quot; data-origin-height=&quot;133&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/2CcGg/btrqGc2iAXq/FEdikP7KqtTUwKCvvB5Tn0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/2CcGg/btrqGc2iAXq/FEdikP7KqtTUwKCvvB5Tn0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/2CcGg/btrqGc2iAXq/FEdikP7KqtTUwKCvvB5Tn0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F2CcGg%2FbtrqGc2iAXq%2FFEdikP7KqtTUwKCvvB5Tn0%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;299&quot; height=&quot;133&quot; data-origin-width=&quot;299&quot; data-origin-height=&quot;133&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;hr data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot;&gt;
&lt;h3 style=&quot;text-align: left;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;br&gt;수정 기능은 입력받은 값을 Entity에 저장하고 JPA save() 메소드를 호출하는 방식이다. &lt;/h3&gt;
&lt;h3 style=&quot;text-align: left;&quot; data-ke-size=&quot;size23&quot;&gt; &lt;/h3&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1090&quot; data-origin-height=&quot;203&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bzm1T0/btrqIspzC1i/cEet5hpAkHrOGPkgvHvpHK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bzm1T0/btrqIspzC1i/cEet5hpAkHrOGPkgvHvpHK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bzm1T0/btrqIspzC1i/cEet5hpAkHrOGPkgvHvpHK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbzm1T0%2FbtrqIspzC1i%2FcEet5hpAkHrOGPkgvHvpHK%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;1090&quot; height=&quot;203&quot; data-origin-width=&quot;1090&quot; data-origin-height=&quot;203&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;h3 style=&quot;text-align: left;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;br&gt;해당 로직에서 동작하는 쿼리를 확인하기 위해 로그를 확인해 보았는데 &lt;br&gt;수정화면에서는 제목과 내용의 값만 존재하는데 로그상에 찍힌 update문에는 등록일자 컬럼값까지 update 대상에 포함이 되어있었다. &lt;br&gt;&lt;/h3&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;235&quot; data-origin-height=&quot;268&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bcvDgY/btrqIrYvqaq/FUzd7DRYWab259cUZ6iab1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bcvDgY/btrqIrYvqaq/FUzd7DRYWab259cUZ6iab1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bcvDgY/btrqIrYvqaq/FUzd7DRYWab259cUZ6iab1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbcvDgY%2FbtrqIrYvqaq%2FFUzd7DRYWab259cUZ6iab1%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;235&quot; height=&quot;268&quot; data-origin-width=&quot;235&quot; data-origin-height=&quot;268&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;hr data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot;&gt;
&lt;h3 style=&quot;text-align: left;&quot; data-ke-size=&quot;size23&quot;&gt;원인은 &lt;br&gt;수정 기능이지만 객체에 값을 받아와 해당 데이터에 다시 저장을 하는 방식인데 &lt;br&gt;기존 RDB 사용 방식에 익숙해져 있는 탓에 이부분을 고려하지 못했다. &lt;br&gt;따라서 수정화면에서 입력한 값만 호출한 메소드의 Entity에 셋팅이 되고 update가 진행이 되는 것이었다. &lt;br&gt;&lt;br&gt;조치방법으로는 &lt;br&gt;업데이트를 진행하기 전에 수정하는 게시물의 일련번호를 이용해서 조회한 결과를 &lt;br&gt;동일한 형태의 임시 Entity에 할당하여 기존 값을 유지해야하는 변수에 대입한 후 JPA save() 메소드를 호출하도록 변경하였다.&lt;/h3&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1116&quot; data-origin-height=&quot;280&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lWeaj/btrqAWe7GZR/oB9NhakpyHKBOnCohK4FaK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lWeaj/btrqAWe7GZR/oB9NhakpyHKBOnCohK4FaK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lWeaj/btrqAWe7GZR/oB9NhakpyHKBOnCohK4FaK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FlWeaj%2FbtrqAWe7GZR%2FoB9NhakpyHKBOnCohK4FaK%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;1116&quot; height=&quot;280&quot; data-origin-width=&quot;1116&quot; data-origin-height=&quot;280&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;h3 style=&quot;text-align: left;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;br&gt;&lt;/h3&gt;</description>
      <category>spring</category>
      <category>date</category>
      <category>JPA</category>
      <category>null</category>
      <category>PrePersist</category>
      <category>save</category>
      <category>springdata</category>
      <category>update</category>
      <category>날짜</category>
      <category>빈값</category>
      <category>수정</category>
      <author>jckim</author>
      <guid isPermaLink="true">https://jckim-dev.tistory.com/22</guid>
      <comments>https://jckim-dev.tistory.com/entry/JPA-JPA-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%EC%88%98%EC%A0%95-%EA%B8%B0%EB%8A%A5-%EA%B5%AC%ED%98%84-%EC%8B%9C-null-%EA%B0%92%EC%9C%BC%EB%A1%9C-%EC%A0%80%EC%9E%A5%EB%90%98%EB%8A%94-%ED%98%84%EC%83%81#entry22comment</comments>
      <pubDate>Thu, 13 Jan 2022 23:30:26 +0900</pubDate>
    </item>
    <item>
      <title>다중 서버인 환경에서 DB를 사용한 각 서버 작업 진행</title>
      <link>https://jckim-dev.tistory.com/entry/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D-%EC%A1%B0%EA%B1%B4%EC%9D%98-%EC%A2%85%EB%A5%98main-%EC%8B%9C%EA%B0%84</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;프로그래밍을&amp;nbsp;하다 보면&amp;nbsp;거의&amp;nbsp;대부분&amp;nbsp;사용하게 되는&amp;nbsp;조건문&amp;nbsp;if&amp;nbsp;명령어가&amp;nbsp;있는데 &lt;br /&gt;해당&amp;nbsp;명령어를&amp;nbsp;사용하기&amp;nbsp;위해서&amp;nbsp;중요한&amp;nbsp;부분 중&amp;nbsp;하나인&amp;nbsp;조건에&amp;nbsp;대해서&amp;nbsp;정리를&amp;nbsp;해보았다. &lt;br /&gt;&lt;br /&gt;어떠한 작업, 환경, 데이터 형태 인지에 따라서 사용할 수 있는 조건은 다양하다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;b&gt;조건비교방법&lt;/b&gt; &lt;br /&gt;&amp;nbsp; -일치여부&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; -대소 비교 &lt;br /&gt;&amp;nbsp; -참/거짓 &lt;br /&gt;&lt;br /&gt;&lt;b&gt;조건비교 값&lt;/b&gt; &lt;br /&gt;&amp;nbsp; -상태 &lt;br /&gt;&amp;nbsp; -문자 &lt;br /&gt;&amp;nbsp; -숫자 &lt;br /&gt;&amp;nbsp; -데이터&amp;nbsp;개수 &lt;br /&gt;&amp;nbsp; -시간 &lt;br /&gt;&lt;br /&gt;&lt;b&gt;상태&lt;/b&gt; &lt;br /&gt;API&amp;nbsp;및&amp;nbsp;특정&amp;nbsp;서버에&amp;nbsp;요청을&amp;nbsp;하였을&amp;nbsp;때&amp;nbsp;비정상적인&amp;nbsp;연결&amp;nbsp;또는&amp;nbsp;요청한&amp;nbsp;서버의&amp;nbsp;상태에&amp;nbsp;문제가&amp;nbsp;있는&amp;nbsp;경우&amp;nbsp;결과값을&amp;nbsp;받아&amp;nbsp;다른&amp;nbsp;로직을&amp;nbsp;진행할지에&amp;nbsp;대하여&amp;nbsp;처리를&amp;nbsp;할&amp;nbsp;수&amp;nbsp;있음. &lt;br /&gt;&lt;br /&gt;&lt;b&gt;문자&amp;nbsp;및&amp;nbsp;숫자&lt;/b&gt; &lt;br /&gt;비교할&amp;nbsp;수&amp;nbsp;있는&amp;nbsp;데이터의&amp;nbsp;값이&amp;nbsp;확실하게&amp;nbsp;정해져&amp;nbsp;있거나&amp;nbsp;특정&amp;nbsp;범위를&amp;nbsp;정해놓을&amp;nbsp;수&amp;nbsp;있는&amp;nbsp;경우&amp;nbsp;사용&amp;nbsp;가능. &lt;br /&gt;&lt;br /&gt;&lt;b&gt;데이터의&amp;nbsp;개수&lt;/b&gt; &lt;br /&gt;숫자와&amp;nbsp;비슷하지만&amp;nbsp;조회&amp;nbsp;및&amp;nbsp;수신&amp;nbsp;데이터의&amp;nbsp;개수를&amp;nbsp;먼저&amp;nbsp;확인&amp;nbsp;후&amp;nbsp;세부적인&amp;nbsp;조건을&amp;nbsp;비교할&amp;nbsp;때&amp;nbsp;사용&amp;nbsp;가능. &lt;br /&gt;&lt;br /&gt;&lt;b&gt;시간★&lt;/b&gt;&lt;br /&gt;일정한&amp;nbsp;시간을&amp;nbsp;기준으로&amp;nbsp;동작해야 하는&amp;nbsp;로직을&amp;nbsp;작성할&amp;nbsp;때&amp;nbsp;사용&amp;nbsp;가능. &lt;br /&gt;&lt;br /&gt;사용&amp;nbsp;예시로는&amp;nbsp;2개&amp;nbsp;이상의&amp;nbsp;서버에&amp;nbsp;각각&amp;nbsp;동일한&amp;nbsp;인스턴스를&amp;nbsp;배포해놓은&amp;nbsp;상황에서 &lt;br /&gt;여러&amp;nbsp;서버에&amp;nbsp;동일하게&amp;nbsp;작업을&amp;nbsp;진행해야 하는&amp;nbsp;경우 &lt;br /&gt;하나의&amp;nbsp;서버에서&amp;nbsp;DB의&amp;nbsp;flag&amp;nbsp;값을&amp;nbsp;기준으로&amp;nbsp;로직&amp;nbsp;수행&amp;nbsp;후&amp;nbsp;UPDATE를&amp;nbsp;해버리면&amp;nbsp;아직&amp;nbsp;수행하지&amp;nbsp;못한&amp;nbsp;서버에서는&amp;nbsp;DB&amp;nbsp;flag&amp;nbsp;값을&amp;nbsp;조회하였을&amp;nbsp;때&amp;nbsp;이미&amp;nbsp;완료가&amp;nbsp;된&amp;nbsp;상태이기&amp;nbsp;때문에&amp;nbsp;작업&amp;nbsp;수행을&amp;nbsp;하지&amp;nbsp;않는다.&amp;nbsp; &lt;br /&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&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;KakaoTalk_20220220_234313440.jpg&quot; data-origin-width=&quot;1440&quot; data-origin-height=&quot;900&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/xli6Z/btrtG75SqsI/cS295XDANkevVEcyee7hKk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/xli6Z/btrtG75SqsI/cS295XDANkevVEcyee7hKk/img.jpg&quot; data-alt=&quot;다중 서버에서 DB flag로 작업을 진행하는 경우&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/xli6Z/btrtG75SqsI/cS295XDANkevVEcyee7hKk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fxli6Z%2FbtrtG75SqsI%2FcS295XDANkevVEcyee7hKk%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;1440&quot; height=&quot;900&quot; data-filename=&quot;KakaoTalk_20220220_234313440.jpg&quot; data-origin-width=&quot;1440&quot; data-origin-height=&quot;900&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;다중 서버에서 DB flag로 작업을 진행하는 경우&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;KakaoTalk_20220220_234313739.jpg&quot; data-origin-width=&quot;1440&quot; data-origin-height=&quot;900&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cYmDAw/btrtQpjwyuG/UvuXdsI5QVOY6ZHeFHlpP1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cYmDAw/btrtQpjwyuG/UvuXdsI5QVOY6ZHeFHlpP1/img.jpg&quot; data-alt=&quot;다중서버에서 시간을 기준으로 작업을 진행하는 경우&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cYmDAw/btrtQpjwyuG/UvuXdsI5QVOY6ZHeFHlpP1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcYmDAw%2FbtrtQpjwyuG%2FUvuXdsI5QVOY6ZHeFHlpP1%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;1440&quot; height=&quot;900&quot; data-filename=&quot;KakaoTalk_20220220_234313739.jpg&quot; data-origin-width=&quot;1440&quot; data-origin-height=&quot;900&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;다중서버에서 시간을 기준으로 작업을 진행하는 경우&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>설계</category>
      <category>IF문</category>
      <category>다중서버</category>
      <category>시간</category>
      <category>조건</category>
      <category>조건문</category>
      <category>프로그래밍</category>
      <author>jckim</author>
      <guid isPermaLink="true">https://jckim-dev.tistory.com/21</guid>
      <comments>https://jckim-dev.tistory.com/entry/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D-%EC%A1%B0%EA%B1%B4%EC%9D%98-%EC%A2%85%EB%A5%98main-%EC%8B%9C%EA%B0%84#entry21comment</comments>
      <pubDate>Wed, 29 Dec 2021 00:05:07 +0900</pubDate>
    </item>
    <item>
      <title>[GIT] 초기 연동 시 주요 명령어 정리</title>
      <link>https://jckim-dev.tistory.com/entry/GIT-%EC%A3%BC%EC%9A%94-%EB%AA%85%EB%A0%B9%EC%96%B4-%EC%A0%95%EB%A6%AC</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;VScode IDE에서 작업 시 터미널에서 git 이용 시보다 원활한 작업을 하기 위해 정리.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로젝트 생성 후 git 원격저장소 연동까지 필요한 최소 명령어 우선 정리.&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;p data-ke-size=&quot;size16&quot;&gt;--현재&amp;nbsp;경로를&amp;nbsp;로컬&amp;nbsp;저장소로&amp;nbsp;설정 &lt;br /&gt;git&amp;nbsp;init &lt;br /&gt;&lt;br /&gt;--현재&amp;nbsp;경로의&amp;nbsp;로컬&amp;nbsp;저장소와&amp;nbsp;원격저장소를&amp;nbsp;연결 &lt;br /&gt;git remote add origin [브랜치 master 생략가능] 원격저장소주소 &lt;br /&gt;&lt;br /&gt;--현재&amp;nbsp;경로에&amp;nbsp;원격저장소&amp;nbsp;origin에서&amp;nbsp;master&amp;nbsp;브랜치를&amp;nbsp;가져오기 &lt;br /&gt;git&amp;nbsp;pull&amp;nbsp;origin&amp;nbsp;master &lt;br /&gt;&lt;br /&gt;--현재&amp;nbsp;경로의&amp;nbsp;로컬&amp;nbsp;저장소에&amp;nbsp;스테이징 된&amp;nbsp;항목들을&amp;nbsp;origin&amp;nbsp;원격 저장소의&amp;nbsp;master&amp;nbsp;브랜치에&amp;nbsp;올리기 &lt;br /&gt;git&amp;nbsp;push&amp;nbsp;origin&amp;nbsp;master &lt;br /&gt;&lt;br /&gt;--원격저장소&amp;nbsp;브랜치&amp;nbsp;확인 &lt;br /&gt;git branch -r &lt;br /&gt;&lt;br /&gt;--로컬 저장소&amp;nbsp;브랜치&amp;nbsp;확인 &lt;br /&gt;git branch -a&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;--작업한 파일 index 영역에 올리기&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;git add .&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;--index에 올라간 파일 커밋하기&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;git commin -m &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;--커밋한 작업목록 원격저장소에 push하기 (origin 저장소에 master 브랜치로 푸시)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;git push origin master&lt;/p&gt;</description>
      <category>형상관리</category>
      <category>Git</category>
      <category>Push</category>
      <category>vscode</category>
      <category>명령어</category>
      <category>터미널</category>
      <author>jckim</author>
      <guid isPermaLink="true">https://jckim-dev.tistory.com/20</guid>
      <comments>https://jckim-dev.tistory.com/entry/GIT-%EC%A3%BC%EC%9A%94-%EB%AA%85%EB%A0%B9%EC%96%B4-%EC%A0%95%EB%A6%AC#entry20comment</comments>
      <pubDate>Wed, 11 Aug 2021 23:35:48 +0900</pubDate>
    </item>
    <item>
      <title>[JAVA] javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure (2)</title>
      <link>https://jckim-dev.tistory.com/entry/JAVA-javaxnetsslSSLHandshakeException-Received-fatal-alert-handshakefailure-2</link>
      <description>&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;[관련 시리즈]&lt;/b&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;a href=&quot;https://jckim-dev.tistory.com/14&quot;&gt;API 운영 중 SSLException 조치하기 1편&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://jckim-dev.tistory.com/18&quot;&gt;API 운영 중 SSLException 조치하기 2편&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://jckim-dev.tistory.com/19&quot;&gt;&lt;b&gt;API 운영 중 SSLException 조치하기 3편&lt;/b&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;발단&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이전에 앞서 작성하였던 &lt;a href=&quot;https://jckim-dev.tistory.com/18&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;루트 인증서 관련 SSLHandshakeException을 조치&lt;/a&gt;하였음에도 불구하고 관리하는 API 기관 중 어떤 기관은 앞선 작업으로 인하여 정상적으로 호출하는 것을 확인하였고&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일부 기관은 앞선 작업을 하였지만 이전과 다른 &lt;b&gt;새로운 에러 로그*가&lt;/b&gt; 나타나는 것을 확인하였음.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 서버에서 curl 및 wget 명령어로 API URL을 호출할 때는 정상적인 값을 가져오는 것을 확인.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 WAS단에서 문제가 있는 것으로 판단.&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;b&gt;원인&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래는 *&lt;b&gt;새로운 에러 로그&lt;/b&gt;&lt;/p&gt;
&lt;div class=&quot;colorscripter-code&quot; style=&quot;color: #f0f0f0; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace !important; position: relative !important; overflow: auto;&quot;&gt;
&lt;table class=&quot;colorscripter-code-table&quot; style=&quot;margin: 0px; padding: 0px; border: none; background-color: #272727; border-radius: 4px; height: 891px;&quot; width=&quot;1260&quot; cellspacing=&quot;0&quot; cellpadding=&quot;0&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;padding: 6px; border-right: 2px solid #4f4f4f; width: 16.5px;&quot;&gt;
&lt;div style=&quot;margin: 0; padding: 0; word-break: normal; text-align: right; color: #aaa; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace !important; line-height: 130%;&quot;&gt;
&lt;div style=&quot;line-height: 130%;&quot;&gt;1&lt;/div&gt;
&lt;div style=&quot;line-height: 130%;&quot;&gt;2&lt;/div&gt;
&lt;div style=&quot;line-height: 130%;&quot;&gt;3&lt;/div&gt;
&lt;div style=&quot;line-height: 130%;&quot;&gt;4&lt;/div&gt;
&lt;div style=&quot;line-height: 130%;&quot;&gt;5&lt;/div&gt;
&lt;div style=&quot;line-height: 130%;&quot;&gt;6&lt;/div&gt;
&lt;div style=&quot;line-height: 130%;&quot;&gt;7&lt;/div&gt;
&lt;div style=&quot;line-height: 130%;&quot;&gt;8&lt;/div&gt;
&lt;div style=&quot;line-height: 130%;&quot;&gt;9&lt;/div&gt;
&lt;div style=&quot;line-height: 130%;&quot;&gt;10&lt;/div&gt;
&lt;div style=&quot;line-height: 130%;&quot;&gt;11&lt;/div&gt;
&lt;div style=&quot;line-height: 130%;&quot;&gt;12&lt;/div&gt;
&lt;div style=&quot;line-height: 130%;&quot;&gt;13&lt;/div&gt;
&lt;div style=&quot;line-height: 130%;&quot;&gt;14&lt;/div&gt;
&lt;div style=&quot;line-height: 130%;&quot;&gt;15&lt;/div&gt;
&lt;div style=&quot;line-height: 130%;&quot;&gt;16&lt;/div&gt;
&lt;div style=&quot;line-height: 130%;&quot;&gt;17&lt;/div&gt;
&lt;div style=&quot;line-height: 130%;&quot;&gt;18&lt;/div&gt;
&lt;div style=&quot;line-height: 130%;&quot;&gt;19&lt;/div&gt;
&lt;div style=&quot;line-height: 130%;&quot;&gt;20&lt;/div&gt;
&lt;div style=&quot;line-height: 130%;&quot;&gt;21&lt;/div&gt;
&lt;div style=&quot;line-height: 130%;&quot;&gt;22&lt;/div&gt;
&lt;div style=&quot;line-height: 130%;&quot;&gt;23&lt;/div&gt;
&lt;div style=&quot;line-height: 130%;&quot;&gt;24&lt;/div&gt;
&lt;div style=&quot;line-height: 130%;&quot;&gt;25&lt;/div&gt;
&lt;div style=&quot;line-height: 130%;&quot;&gt;26&lt;/div&gt;
&lt;div style=&quot;line-height: 130%;&quot;&gt;27&lt;/div&gt;
&lt;div style=&quot;line-height: 130%;&quot;&gt;28&lt;/div&gt;
&lt;div style=&quot;line-height: 130%;&quot;&gt;29&lt;/div&gt;
&lt;div style=&quot;line-height: 130%;&quot;&gt;30&lt;/div&gt;
&lt;div style=&quot;line-height: 130%;&quot;&gt;31&lt;/div&gt;
&lt;div style=&quot;line-height: 130%;&quot;&gt;32&lt;/div&gt;
&lt;div style=&quot;line-height: 130%;&quot;&gt;33&lt;/div&gt;
&lt;div style=&quot;line-height: 130%;&quot;&gt;34&lt;/div&gt;
&lt;div style=&quot;line-height: 130%;&quot;&gt;35&lt;/div&gt;
&lt;div style=&quot;line-height: 130%;&quot;&gt;36&lt;/div&gt;
&lt;div style=&quot;line-height: 130%;&quot;&gt;37&lt;/div&gt;
&lt;div style=&quot;line-height: 130%;&quot;&gt;38&lt;/div&gt;
&lt;div style=&quot;line-height: 130%;&quot;&gt;39&lt;/div&gt;
&lt;div style=&quot;line-height: 130%;&quot;&gt;40&lt;/div&gt;
&lt;div style=&quot;line-height: 130%;&quot;&gt;41&lt;/div&gt;
&lt;div style=&quot;line-height: 130%;&quot;&gt;42&lt;/div&gt;
&lt;div style=&quot;line-height: 130%;&quot;&gt;43&lt;/div&gt;
&lt;div style=&quot;line-height: 130%;&quot;&gt;44&lt;/div&gt;
&lt;div style=&quot;line-height: 130%;&quot;&gt;45&lt;/div&gt;
&lt;div style=&quot;line-height: 130%;&quot;&gt;46&lt;/div&gt;
&lt;div style=&quot;line-height: 130%;&quot;&gt;47&lt;/div&gt;
&lt;div style=&quot;line-height: 130%;&quot;&gt;48&lt;/div&gt;
&lt;div style=&quot;line-height: 130%;&quot;&gt;49&lt;/div&gt;
&lt;div style=&quot;line-height: 130%;&quot;&gt;50&lt;/div&gt;
&lt;div style=&quot;line-height: 130%;&quot;&gt;51&lt;/div&gt;
&lt;div style=&quot;line-height: 130%;&quot;&gt;52&lt;/div&gt;
&lt;div style=&quot;line-height: 130%;&quot;&gt;53&lt;/div&gt;
&lt;/div&gt;
&lt;/td&gt;
&lt;td style=&quot;padding: 6px 0px; text-align: left; width: 1232.58px;&quot;&gt;
&lt;div style=&quot;margin: 0; padding: 0; color: #f0f0f0; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace !important; line-height: 130%;&quot;&gt;
&lt;div style=&quot;padding: 0 6px; white-space: pre; line-height: 130%;&quot;&gt;javax.net.ssl.SSLHandshakeException:&amp;nbsp;Received&amp;nbsp;fatal&amp;nbsp;alert:&amp;nbsp;handshake_failure&lt;/div&gt;
&lt;div style=&quot;padding: 0 6px; white-space: pre; line-height: 130%;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;at&amp;nbsp;sun.security.ssl.Alerts.getSSLException(Alerts.java:&lt;span style=&quot;color: #c10aff;&quot;&gt;192&lt;/span&gt;)&lt;/div&gt;
&lt;div style=&quot;padding: 0 6px; white-space: pre; line-height: 130%;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;at&amp;nbsp;sun.security.ssl.Alerts.getSSLException(Alerts.java:&lt;span style=&quot;color: #c10aff;&quot;&gt;154&lt;/span&gt;)&lt;/div&gt;
&lt;div style=&quot;padding: 0 6px; white-space: pre; line-height: 130%;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;at&amp;nbsp;sun.security.ssl.SSLSocketImpl.recvAlert(SSLSocketImpl.java:&lt;span style=&quot;color: #c10aff;&quot;&gt;1959&lt;/span&gt;)&lt;/div&gt;
&lt;div style=&quot;padding: 0 6px; white-space: pre; line-height: 130%;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;at&amp;nbsp;sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:&lt;span style=&quot;color: #c10aff;&quot;&gt;1077&lt;/span&gt;)&lt;/div&gt;
&lt;div style=&quot;padding: 0 6px; white-space: pre; line-height: 130%;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;at&amp;nbsp;sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:&lt;span style=&quot;color: #c10aff;&quot;&gt;1312&lt;/span&gt;)&lt;/div&gt;
&lt;div style=&quot;padding: 0 6px; white-space: pre; line-height: 130%;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;at&amp;nbsp;sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:&lt;span style=&quot;color: #c10aff;&quot;&gt;1339&lt;/span&gt;)&lt;/div&gt;
&lt;div style=&quot;padding: 0 6px; white-space: pre; line-height: 130%;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;at&amp;nbsp;sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:&lt;span style=&quot;color: #c10aff;&quot;&gt;1323&lt;/span&gt;)&lt;/div&gt;
&lt;div style=&quot;padding: 0 6px; white-space: pre; line-height: 130%;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;at&amp;nbsp;sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:&lt;span style=&quot;color: #c10aff;&quot;&gt;563&lt;/span&gt;)&lt;/div&gt;
&lt;div style=&quot;padding: 0 6px; white-space: pre; line-height: 130%;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;at&amp;nbsp;sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:&lt;span style=&quot;color: #c10aff;&quot;&gt;185&lt;/span&gt;)&lt;/div&gt;
&lt;div style=&quot;padding: 0 6px; white-space: pre; line-height: 130%;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;at&amp;nbsp;sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:&lt;span style=&quot;color: #c10aff;&quot;&gt;1300&lt;/span&gt;)&lt;/div&gt;
&lt;div style=&quot;padding: 0 6px; white-space: pre; line-height: 130%;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;at&amp;nbsp;sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:&lt;span style=&quot;color: #c10aff;&quot;&gt;254&lt;/span&gt;)&lt;/div&gt;
&lt;div style=&quot;padding: 0 6px; white-space: pre; line-height: 130%;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;at&amp;nbsp;com.jc.pj.HomeController.testPost(HomeController.java:&lt;span style=&quot;color: #c10aff;&quot;&gt;114&lt;/span&gt;)&lt;/div&gt;
&lt;div style=&quot;padding: 0 6px; white-space: pre; line-height: 130%;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;at&amp;nbsp;com.jc.pj.HomeController$$FastClassByCGLIB$$57a84547.invoke(&lt;span style=&quot;color: #0086b3;&quot;&gt;&lt;/span&gt;&lt;span style=&quot;color: #ff3399;&quot;&gt;&amp;lt;&lt;/span&gt;generated&lt;span style=&quot;color: #0086b3;&quot;&gt;&lt;/span&gt;&lt;span style=&quot;color: #ff3399;&quot;&gt;&amp;gt;&lt;/span&gt;)&lt;/div&gt;
&lt;div style=&quot;padding: 0 6px; white-space: pre; line-height: 130%;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;at&amp;nbsp;net.sf.cglib.proxy.MethodProxy.invoke(MethodProxy.java:&lt;span style=&quot;color: #c10aff;&quot;&gt;191&lt;/span&gt;)&lt;/div&gt;
&lt;div style=&quot;padding: 0 6px; white-space: pre; line-height: 130%;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;at&amp;nbsp;org.springframework.aop.framework.Cglib2AopProxy$DynamicAdvisedInterceptor.intercept(Cglib2AopProxy.java:&lt;span style=&quot;color: #c10aff;&quot;&gt;618&lt;/span&gt;)&lt;/div&gt;
&lt;div style=&quot;padding: 0 6px; white-space: pre; line-height: 130%;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;at&amp;nbsp;com.jc.pj.HomeController$$EnhancerByCGLIB$$f98447e3.testPost(&lt;span style=&quot;color: #0086b3;&quot;&gt;&lt;/span&gt;&lt;span style=&quot;color: #ff3399;&quot;&gt;&amp;lt;&lt;/span&gt;generated&lt;span style=&quot;color: #0086b3;&quot;&gt;&lt;/span&gt;&lt;span style=&quot;color: #ff3399;&quot;&gt;&amp;gt;&lt;/span&gt;)&lt;/div&gt;
&lt;div style=&quot;padding: 0 6px; white-space: pre; line-height: 130%;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;at&amp;nbsp;sun.reflect.NativeMethodAccessorImpl.invoke0(Native&amp;nbsp;Method)&lt;/div&gt;
&lt;div style=&quot;padding: 0 6px; white-space: pre; line-height: 130%;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;at&amp;nbsp;sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:&lt;span style=&quot;color: #c10aff;&quot;&gt;57&lt;/span&gt;)&lt;/div&gt;
&lt;div style=&quot;padding: 0 6px; white-space: pre; line-height: 130%;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;at&amp;nbsp;sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:&lt;span style=&quot;color: #c10aff;&quot;&gt;43&lt;/span&gt;)&lt;/div&gt;
&lt;div style=&quot;padding: 0 6px; white-space: pre; line-height: 130%;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;at&amp;nbsp;java.lang.reflect.Method.invoke(Method.java:&lt;span style=&quot;color: #c10aff;&quot;&gt;606&lt;/span&gt;)&lt;/div&gt;
&lt;div style=&quot;padding: 0 6px; white-space: pre; line-height: 130%;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;at&amp;nbsp;org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:&lt;span style=&quot;color: #c10aff;&quot;&gt;213&lt;/span&gt;)&lt;/div&gt;
&lt;div style=&quot;padding: 0 6px; white-space: pre; line-height: 130%;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;at&amp;nbsp;org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:&lt;span style=&quot;color: #c10aff;&quot;&gt;126&lt;/span&gt;)&lt;/div&gt;
&lt;div style=&quot;padding: 0 6px; white-space: pre; line-height: 130%;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;at&amp;nbsp;org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:&lt;span style=&quot;color: #c10aff;&quot;&gt;96&lt;/span&gt;)&lt;/div&gt;
&lt;div style=&quot;padding: 0 6px; white-space: pre; line-height: 130%;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;at&amp;nbsp;org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:&lt;span style=&quot;color: #c10aff;&quot;&gt;617&lt;/span&gt;)&lt;/div&gt;
&lt;div style=&quot;padding: 0 6px; white-space: pre; line-height: 130%;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;at&amp;nbsp;org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:&lt;span style=&quot;color: #c10aff;&quot;&gt;578&lt;/span&gt;)&lt;/div&gt;
&lt;div style=&quot;padding: 0 6px; white-space: pre; line-height: 130%;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;at&amp;nbsp;org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:&lt;span style=&quot;color: #c10aff;&quot;&gt;80&lt;/span&gt;)&lt;/div&gt;
&lt;div style=&quot;padding: 0 6px; white-space: pre; line-height: 130%;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;at&amp;nbsp;org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:&lt;span style=&quot;color: #c10aff;&quot;&gt;923&lt;/span&gt;)&lt;/div&gt;
&lt;div style=&quot;padding: 0 6px; white-space: pre; line-height: 130%;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;at&amp;nbsp;org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:&lt;span style=&quot;color: #c10aff;&quot;&gt;852&lt;/span&gt;)&lt;/div&gt;
&lt;div style=&quot;padding: 0 6px; white-space: pre; line-height: 130%;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;at&amp;nbsp;org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:&lt;span style=&quot;color: #c10aff;&quot;&gt;882&lt;/span&gt;)&lt;/div&gt;
&lt;div style=&quot;padding: 0 6px; white-space: pre; line-height: 130%;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;at&amp;nbsp;org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:&lt;span style=&quot;color: #c10aff;&quot;&gt;778&lt;/span&gt;)&lt;/div&gt;
&lt;div style=&quot;padding: 0 6px; white-space: pre; line-height: 130%;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;at&amp;nbsp;javax.servlet.http.HttpServlet.service(HttpServlet.java:&lt;span style=&quot;color: #c10aff;&quot;&gt;624&lt;/span&gt;)&lt;/div&gt;
&lt;div style=&quot;padding: 0 6px; white-space: pre; line-height: 130%;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;at&amp;nbsp;javax.servlet.http.HttpServlet.service(HttpServlet.java:&lt;span style=&quot;color: #c10aff;&quot;&gt;731&lt;/span&gt;)&lt;/div&gt;
&lt;div style=&quot;padding: 0 6px; white-space: pre; line-height: 130%;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;at&amp;nbsp;org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:&lt;span style=&quot;color: #c10aff;&quot;&gt;303&lt;/span&gt;)&lt;/div&gt;
&lt;div style=&quot;padding: 0 6px; white-space: pre; line-height: 130%;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;at&amp;nbsp;org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:&lt;span style=&quot;color: #c10aff;&quot;&gt;208&lt;/span&gt;)&lt;/div&gt;
&lt;div style=&quot;padding: 0 6px; white-space: pre; line-height: 130%;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;at&amp;nbsp;org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:&lt;span style=&quot;color: #c10aff;&quot;&gt;52&lt;/span&gt;)&lt;/div&gt;
&lt;div style=&quot;padding: 0 6px; white-space: pre; line-height: 130%;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;at&amp;nbsp;org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:&lt;span style=&quot;color: #c10aff;&quot;&gt;241&lt;/span&gt;)&lt;/div&gt;
&lt;div style=&quot;padding: 0 6px; white-space: pre; line-height: 130%;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;at&amp;nbsp;org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:&lt;span style=&quot;color: #c10aff;&quot;&gt;208&lt;/span&gt;)&lt;/div&gt;
&lt;div style=&quot;padding: 0 6px; white-space: pre; line-height: 130%;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;at&amp;nbsp;org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:&lt;span style=&quot;color: #c10aff;&quot;&gt;219&lt;/span&gt;)&lt;/div&gt;
&lt;div style=&quot;padding: 0 6px; white-space: pre; line-height: 130%;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;at&amp;nbsp;org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:&lt;span style=&quot;color: #c10aff;&quot;&gt;110&lt;/span&gt;)&lt;/div&gt;
&lt;div style=&quot;padding: 0 6px; white-space: pre; line-height: 130%;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;at&amp;nbsp;org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:&lt;span style=&quot;color: #c10aff;&quot;&gt;506&lt;/span&gt;)&lt;/div&gt;
&lt;div style=&quot;padding: 0 6px; white-space: pre; line-height: 130%;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;at&amp;nbsp;org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:&lt;span style=&quot;color: #c10aff;&quot;&gt;169&lt;/span&gt;)&lt;/div&gt;
&lt;div style=&quot;padding: 0 6px; white-space: pre; line-height: 130%;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;at&amp;nbsp;org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:&lt;span style=&quot;color: #c10aff;&quot;&gt;103&lt;/span&gt;)&lt;/div&gt;
&lt;div style=&quot;padding: 0 6px; white-space: pre; line-height: 130%;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;at&amp;nbsp;org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:&lt;span style=&quot;color: #c10aff;&quot;&gt;962&lt;/span&gt;)&lt;/div&gt;
&lt;div style=&quot;padding: 0 6px; white-space: pre; line-height: 130%;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;at&amp;nbsp;org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:&lt;span style=&quot;color: #c10aff;&quot;&gt;116&lt;/span&gt;)&lt;/div&gt;
&lt;div style=&quot;padding: 0 6px; white-space: pre; line-height: 130%;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;at&amp;nbsp;org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:&lt;span style=&quot;color: #c10aff;&quot;&gt;445&lt;/span&gt;)&lt;/div&gt;
&lt;div style=&quot;padding: 0 6px; white-space: pre; line-height: 130%;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;at&amp;nbsp;org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:&lt;span style=&quot;color: #c10aff;&quot;&gt;1115&lt;/span&gt;)&lt;/div&gt;
&lt;div style=&quot;padding: 0 6px; white-space: pre; line-height: 130%;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;at&amp;nbsp;org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:&lt;span style=&quot;color: #c10aff;&quot;&gt;637&lt;/span&gt;)&lt;/div&gt;
&lt;div style=&quot;padding: 0 6px; white-space: pre; line-height: 130%;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;at&amp;nbsp;org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:&lt;span style=&quot;color: #c10aff;&quot;&gt;318&lt;/span&gt;)&lt;/div&gt;
&lt;div style=&quot;padding: 0 6px; white-space: pre; line-height: 130%;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;at&amp;nbsp;java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:&lt;span style=&quot;color: #c10aff;&quot;&gt;1145&lt;/span&gt;)&lt;/div&gt;
&lt;div style=&quot;padding: 0 6px; white-space: pre; line-height: 130%;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;at&amp;nbsp;java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:&lt;span style=&quot;color: #c10aff;&quot;&gt;615&lt;/span&gt;)&lt;/div&gt;
&lt;div style=&quot;padding: 0 6px; white-space: pre; line-height: 130%;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;at&amp;nbsp;org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:&lt;span style=&quot;color: #c10aff;&quot;&gt;61&lt;/span&gt;)&lt;/div&gt;
&lt;div style=&quot;padding: 0 6px; white-space: pre; line-height: 130%;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;at&amp;nbsp;java.lang.Thread.run(Thread.java:&lt;span style=&quot;color: #c10aff;&quot;&gt;744&lt;/span&gt;)&lt;/div&gt;
&lt;/div&gt;
&lt;div style=&quot;text-align: right; margin-top: -13px; margin-right: 5px; font-size: 9px; font-style: italic;&quot;&gt;&lt;a style=&quot;color: #4f4f4ftext-decoration:none;&quot; href=&quot;http://colorscripter.com/info#e&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Colored by Color Scripter&lt;/a&gt;&lt;/div&gt;
&lt;/td&gt;
&lt;td style=&quot;vertical-align: bottom; padding: 0px 2px 4px 0px; width: 13px;&quot;&gt;&lt;a style=&quot;text-decoration: none; color: white;&quot; href=&quot;http://colorscripter.com/info#e&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;&lt;span style=&quot;font-size: 9px; word-break: normal; background-color: #4f4f4f; color: white; border-radius: 10px; padding: 1px;&quot;&gt;cs&lt;/span&gt;&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 로그 중 눈에 새롭게 들어오는 부분은 &lt;span style=&quot;background-color: #272727; color: #f0f0f0;&quot;&gt;&amp;nbsp;sun.security.ssl~&lt;/span&gt;부분이다 관련 에러 로그로 확인을 좀 더 확인해 보니&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;JAVA 보안 메커니즘의 문제로 확인이 되었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ssl handshake 중 상대기관에서 보내온 응답에 대한 암호화 방식에 대하여&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;운영 중인 현재 서버의 java 암호화 방식이 지원되지 않는 것으로 판단.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;각 기관의 jdk 버전 확인&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;상대기관 jdk 1.8&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;운영서버 jdk 1.7.0_45&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;TLS1.2v 사용한다면&amp;nbsp; 보다 강력한 &lt;span style=&quot;color: #212529;&quot;&gt;암호화 방식으로 256비트 키를 이용하여 암호화하여 보안 소켓 통신.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 현재 상황에 경우 경우 운영서버의 jdk1.7의 보안 패키지인 &lt;span style=&quot;background-color: #e8e8e8; color: #000000;&quot;&gt;Java Cryptography Extension(JCE)&lt;/span&gt;의 경우 기본적으로&amp;nbsp; 128비트 키를 이용하여 암호화를 지원을 하기 때문에 &lt;span style=&quot;color: #212529;&quot;&gt;무제한 강도의 JCE 정책지원 버전으로 &lt;/span&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;b&gt;조치&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;oracle 홈페이지에서 jdk7전용&amp;nbsp; &lt;span style=&quot;color: #212529;&quot;&gt;무제한 강도의 &lt;/span&gt;JCE 패키지 다운로드&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.oracle.com/java/technologies/javase-jce7-downloads.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.oracle.com/java/technologies/javase-jce7-downloads.html&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;운영서버의 JCE 패키지 교체&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(보안상 윈도우즈 PC 기준으로 경로 작성)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래 경로에 jar파일 2개를 다운로드한 jar 파일로 교체&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;C:\Program Files\Java\jdk1.7.0_45\jre\lib\security&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;US_export_policy.jar&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;local_policy.jar&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;비교해보면 교체 전과 후의 파일 사이즈도 다른 것 확인 가능.&lt;/p&gt;
&lt;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: 50%;&quot;&gt;교체 전&lt;/td&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;교체 후&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;348&quot; data-origin-height=&quot;82&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/nL3tG/btq9bkB5xfI/jMuzMdxtvgWuckQ2zyzo0K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/nL3tG/btq9bkB5xfI/jMuzMdxtvgWuckQ2zyzo0K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/nL3tG/btq9bkB5xfI/jMuzMdxtvgWuckQ2zyzo0K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FnL3tG%2Fbtq9bkB5xfI%2FjMuzMdxtvgWuckQ2zyzo0K%2Fimg.png&quot; data-origin-width=&quot;348&quot; data-origin-height=&quot;82&quot; data-ke-mobilestyle=&quot;widthOrigin&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/td&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;343&quot; data-origin-height=&quot;44&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/WeJlW/btq89EgTVAM/g0w5jTjaD73OoR6KRPSuM1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/WeJlW/btq89EgTVAM/g0w5jTjaD73OoR6KRPSuM1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/WeJlW/btq89EgTVAM/g0w5jTjaD73OoR6KRPSuM1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FWeJlW%2Fbtq89EgTVAM%2Fg0w5jTjaD73OoR6KRPSuM1%2Fimg.png&quot; data-origin-width=&quot;343&quot; data-origin-height=&quot;44&quot; data-ke-mobilestyle=&quot;widthOrigin&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;/&gt;&lt;/span&gt;&lt;/figure&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>JAVA</category>
      <author>jckim</author>
      <guid isPermaLink="true">https://jckim-dev.tistory.com/19</guid>
      <comments>https://jckim-dev.tistory.com/entry/JAVA-javaxnetsslSSLHandshakeException-Received-fatal-alert-handshakefailure-2#entry19comment</comments>
      <pubDate>Thu, 8 Jul 2021 22:43:23 +0900</pubDate>
    </item>
    <item>
      <title>[java] &amp;nbsp;javax.net.ssl.SSLHandshakeException : Received fatal alert : handshake_failure</title>
      <link>https://jckim-dev.tistory.com/entry/java-%C2%A0javaxnetsslSSLHandshakeException-Received-fatal-alert-handshakefailure</link>
      <description>&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;[관련 시리즈]&lt;/b&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;a href=&quot;https://jckim-dev.tistory.com/14&quot;&gt;API 운영 중 SSLException 조치하기 1편&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://jckim-dev.tistory.com/18&quot;&gt;&lt;b&gt;API 운영 중 SSLException 조치하기 2편&lt;/b&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://jckim-dev.tistory.com/19&quot;&gt;API 운영 중 SSLException 조치하기 3편&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;발단&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;API를 통하여 타 기관의 데이터를 가져오는 서비스를 관리하는 중 상대 기관에서 기존에 제공하던 API url 변경 및 https 적용 작업이 있다하여 작업을 준비 하였음.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 기관 말고도 다른 API에서도 https로 변경하였기 때문에 비슷한 작업이라고 추정하였음.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이전에 SSL 관련하여 비슷한 작업 &lt;b&gt;(이하 이전 ssl 작업)&lt;/b&gt; (&lt;a href=&quot;https://jckim-dev.tistory.com/14&quot;&gt;https://jckim-dev.tistory.com/14&lt;/a&gt;)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 작업 후 신규 url 호출 시 아래와 같은 에러문구가 확인됨.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;javax.net.ssl.SSLHandshakeException : Received fatal alert : handshake_failure&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&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;image.png&quot; data-origin-width=&quot;536&quot; data-origin-height=&quot;132&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Ij66g/btq6JlYYEuA/CWoZDlU9UkhTu4KdDX8mt0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Ij66g/btq6JlYYEuA/CWoZDlU9UkhTu4KdDX8mt0/img.png&quot; data-alt=&quot;java 버전별 기본TLS 버전과 지원버전에 대한 표&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Ij66g/btq6JlYYEuA/CWoZDlU9UkhTu4KdDX8mt0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FIj66g%2Fbtq6JlYYEuA%2FCWoZDlU9UkhTu4KdDX8mt0%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;536&quot; height=&quot;132&quot; data-filename=&quot;image.png&quot; data-origin-width=&quot;536&quot; data-origin-height=&quot;132&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;java 버전별 기본TLS 버전과 지원버전에 대한 표&lt;/figcaption&gt;
&lt;/figure&gt;
&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;java 버전(1.7) - TLSv1.0&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;-해당기관 서버 설정 확인&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;java 버전(1.8)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;TLS 설정(TLSv1.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;1. 클라이언트에서 TLSv1.0으로 서버에 요청을 하기 떄문에 서버에서는 허용되지 않은 TLS 버전.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 서버(API제공기관)과 클라이언트(운영중인 서버)간에 TLS 버전이 호환이 되지 않기 때문.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;3. java keyStore에 해당 기관의 인증서가 없을 수 있음.&lt;/b&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;원인에 1번과 2번에 대해서는 &lt;b&gt;[이전 ssl관련 작업]&lt;/b&gt;에서 진행하였기 때문에 &lt;b&gt;3번 항목에 대한 조치&lt;/b&gt;를 진행하였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 인증서를 받기 전에 인증서 유효성 없이 정상 호출이 되는지 확인 후 정상적인 호출을 확인하여 해당 해당 발급기관의 루트인증서를 java keyStore에 저장 하였음.&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;1. 인증서 유효성 없이 정상 호출이 되는지 확인하기&lt;/p&gt;
&lt;div class=&quot;colorscripter-code&quot; style=&quot;color: #f0f0f0; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace !important; position: relative !important; overflow: auto;&quot;&gt;
&lt;table class=&quot;colorscripter-code-table&quot; style=&quot;margin: 0; padding: 0; border: none; background-color: #272727; border-radius: 4px;&quot; cellspacing=&quot;0&quot; cellpadding=&quot;0&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;padding: 6px; border-right: 2px solid #4f4f4f;&quot;&gt;
&lt;div style=&quot;margin: 0; padding: 0; word-break: normal; text-align: right; color: #aaa; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace !important; line-height: 130%;&quot;&gt;
&lt;div style=&quot;line-height: 130%;&quot;&gt;1&lt;/div&gt;
&lt;div style=&quot;line-height: 130%;&quot;&gt;2&lt;/div&gt;
&lt;div style=&quot;line-height: 130%;&quot;&gt;3&lt;/div&gt;
&lt;div style=&quot;line-height: 130%;&quot;&gt;4&lt;/div&gt;
&lt;div style=&quot;line-height: 130%;&quot;&gt;5&lt;/div&gt;
&lt;div style=&quot;line-height: 130%;&quot;&gt;6&lt;/div&gt;
&lt;div style=&quot;line-height: 130%;&quot;&gt;7&lt;/div&gt;
&lt;div style=&quot;line-height: 130%;&quot;&gt;8&lt;/div&gt;
&lt;div style=&quot;line-height: 130%;&quot;&gt;9&lt;/div&gt;
&lt;div style=&quot;line-height: 130%;&quot;&gt;10&lt;/div&gt;
&lt;div style=&quot;line-height: 130%;&quot;&gt;11&lt;/div&gt;
&lt;div style=&quot;line-height: 130%;&quot;&gt;12&lt;/div&gt;
&lt;div style=&quot;line-height: 130%;&quot;&gt;13&lt;/div&gt;
&lt;div style=&quot;line-height: 130%;&quot;&gt;14&lt;/div&gt;
&lt;div style=&quot;line-height: 130%;&quot;&gt;15&lt;/div&gt;
&lt;div style=&quot;line-height: 130%;&quot;&gt;16&lt;/div&gt;
&lt;div style=&quot;line-height: 130%;&quot;&gt;17&lt;/div&gt;
&lt;div style=&quot;line-height: 130%;&quot;&gt;18&lt;/div&gt;
&lt;div style=&quot;line-height: 130%;&quot;&gt;19&lt;/div&gt;
&lt;div style=&quot;line-height: 130%;&quot;&gt;20&lt;/div&gt;
&lt;div style=&quot;line-height: 130%;&quot;&gt;21&lt;/div&gt;
&lt;/div&gt;
&lt;/td&gt;
&lt;td style=&quot;padding: 6px 0; text-align: left;&quot;&gt;
&lt;div style=&quot;margin: 0; padding: 0; color: #f0f0f0; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace !important; line-height: 130%;&quot;&gt;
&lt;div style=&quot;padding: 0 6px; white-space: pre; line-height: 130%;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;TrustManager[]&amp;nbsp;trustCerts&amp;nbsp;&lt;span style=&quot;color: #0086b3;&quot;&gt;&lt;/span&gt;&lt;span style=&quot;color: #ff3399;&quot;&gt;=&lt;/span&gt;&amp;nbsp;&lt;span style=&quot;color: #ff3399;&quot;&gt;new&lt;/span&gt;&amp;nbsp;TrustManager[]{&lt;/div&gt;
&lt;div style=&quot;padding: 0 6px; white-space: pre; line-height: 130%;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style=&quot;color: #ff3399;&quot;&gt;new&lt;/span&gt;&amp;nbsp;X509TrustManager()&amp;nbsp;{&lt;/div&gt;
&lt;div style=&quot;padding: 0 6px; white-space: pre; line-height: 130%;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style=&quot;color: #ff3399;&quot;&gt;public&lt;/span&gt;&amp;nbsp;java.security.cert.X509Certificate[]&amp;nbsp;getAcceptedIssuers()&amp;nbsp;{&lt;/div&gt;
&lt;div style=&quot;padding: 0 6px; white-space: pre; line-height: 130%;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style=&quot;color: #ff3399;&quot;&gt;return&lt;/span&gt;&amp;nbsp;&lt;span style=&quot;color: #4be6fa;&quot;&gt;null&lt;/span&gt;;&lt;/div&gt;
&lt;div style=&quot;padding: 0 6px; white-space: pre; line-height: 130%;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/div&gt;
&lt;div style=&quot;padding: 0 6px; white-space: pre; line-height: 130%;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style=&quot;color: #ff3399;&quot;&gt;public&lt;/span&gt;&amp;nbsp;&lt;span style=&quot;color: #ff3399;&quot;&gt;void&lt;/span&gt;&amp;nbsp;checkClientTrusted(&lt;/div&gt;
&lt;div style=&quot;padding: 0 6px; white-space: pre; line-height: 130%;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;java.security.cert.X509Certificate[]&amp;nbsp;certs,&amp;nbsp;&lt;span style=&quot;color: #4be6fa;&quot;&gt;String&lt;/span&gt;&amp;nbsp;authType)&amp;nbsp;{&lt;/div&gt;
&lt;div style=&quot;padding: 0 6px; white-space: pre; line-height: 130%;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/div&gt;
&lt;div style=&quot;padding: 0 6px; white-space: pre; line-height: 130%;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style=&quot;color: #ff3399;&quot;&gt;public&lt;/span&gt;&amp;nbsp;&lt;span style=&quot;color: #ff3399;&quot;&gt;void&lt;/span&gt;&amp;nbsp;checkServerTrusted(&lt;/div&gt;
&lt;div style=&quot;padding: 0 6px; white-space: pre; line-height: 130%;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;java.security.cert.X509Certificate[]&amp;nbsp;certs,&amp;nbsp;&lt;span style=&quot;color: #4be6fa;&quot;&gt;String&lt;/span&gt;&amp;nbsp;authType)&amp;nbsp;{&lt;/div&gt;
&lt;div style=&quot;padding: 0 6px; white-space: pre; line-height: 130%;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/div&gt;
&lt;div style=&quot;padding: 0 6px; white-space: pre; line-height: 130%;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/div&gt;
&lt;div style=&quot;padding: 0 6px; white-space: pre; line-height: 130%;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;};&lt;/div&gt;
&lt;div style=&quot;padding: 0 6px; white-space: pre; line-height: 130%;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;padding: 0 6px; white-space: pre; line-height: 130%;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;SSLContext&amp;nbsp;sc&amp;nbsp;&lt;span style=&quot;color: #0086b3;&quot;&gt;&lt;/span&gt;&lt;span style=&quot;color: #ff3399;&quot;&gt;=&lt;/span&gt;&amp;nbsp;SSLContext.getInstance(&lt;span style=&quot;color: #ffd500;&quot;&gt;&quot;TLSv1.2&quot;&lt;/span&gt;);&lt;/div&gt;
&lt;div style=&quot;padding: 0 6px; white-space: pre; line-height: 130%;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;sc.init(&lt;span style=&quot;color: #4be6fa;&quot;&gt;null&lt;/span&gt;,&amp;nbsp;trustCerts,&amp;nbsp;&lt;span style=&quot;color: #ff3399;&quot;&gt;new&lt;/span&gt;&amp;nbsp;java.security.SecureRandom());&lt;/div&gt;
&lt;div style=&quot;padding: 0 6px; white-space: pre; line-height: 130%;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;padding: 0 6px; white-space: pre; line-height: 130%;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;URL&amp;nbsp;url&amp;nbsp;&lt;span style=&quot;color: #0086b3;&quot;&gt;&lt;/span&gt;&lt;span style=&quot;color: #ff3399;&quot;&gt;=&lt;/span&gt;&amp;nbsp;&lt;span style=&quot;color: #ff3399;&quot;&gt;new&lt;/span&gt;&amp;nbsp;URL(&lt;span style=&quot;color: #ffd500;&quot;&gt;&quot;https://호출&amp;nbsp;url&quot;&lt;/span&gt;);&lt;/div&gt;
&lt;div style=&quot;padding: 0 6px; white-space: pre; line-height: 130%;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;padding: 0 6px; white-space: pre; line-height: 130%;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;HttpsURLConnection&amp;nbsp;conn&amp;nbsp;&lt;span style=&quot;color: #0086b3;&quot;&gt;&lt;/span&gt;&lt;span style=&quot;color: #ff3399;&quot;&gt;=&lt;/span&gt;&amp;nbsp;(HttpsURLConnection)url.openConnection();&lt;/div&gt;
&lt;div style=&quot;padding: 0 6px; white-space: pre; line-height: 130%;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;conn.setSSLSocketFactory(sc.getSocketFactory());&lt;/div&gt;
&lt;/div&gt;
&lt;/td&gt;
&lt;td style=&quot;vertical-align: bottom; padding: 0 2px 4px 0;&quot;&gt;&lt;a style=&quot;text-decoration: none; color: white;&quot; href=&quot;http://colorscripter.com/info#e&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;&lt;span style=&quot;font-size: 9px; word-break: normal; background-color: #4f4f4f; color: white; border-radius: 10px; padding: 1px;&quot;&gt;cs&lt;/span&gt;&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 해당 발급기관의 루트인증서를 java keyStore에 저장&lt;/p&gt;
&lt;div class=&quot;colorscripter-code&quot; style=&quot;color: #f0f0f0; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace !important; position: relative !important; overflow: auto;&quot;&gt;
&lt;table class=&quot;colorscripter-code-table&quot; style=&quot;margin: 0px; padding: 0px; border: none; background-color: #272727; border-radius: 4px; height: 83px;&quot; cellspacing=&quot;0&quot; cellpadding=&quot;0&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 83px;&quot;&gt;
&lt;td style=&quot;padding: 6px; border-right: 2px solid #4f4f4f; height: 83px; width: 8.25px;&quot;&gt;
&lt;div style=&quot;margin: 0; padding: 0; word-break: normal; text-align: right; color: #aaa; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace !important; line-height: 130%;&quot;&gt;
&lt;div style=&quot;line-height: 130%;&quot;&gt;1&lt;/div&gt;
&lt;div style=&quot;line-height: 130%;&quot;&gt;2&lt;/div&gt;
&lt;div style=&quot;line-height: 130%;&quot;&gt;3&lt;/div&gt;
&lt;div style=&quot;line-height: 130%;&quot;&gt;4&lt;/div&gt;
&lt;/div&gt;
&lt;/td&gt;
&lt;td style=&quot;padding: 6px 0px; text-align: left; height: 83px; width: 960.328px;&quot;&gt;
&lt;div style=&quot;margin: 0; padding: 0; color: #f0f0f0; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace !important; line-height: 130%;&quot;&gt;
&lt;div style=&quot;padding: 0 6px; white-space: pre; line-height: 130%;&quot;&gt;keytool&amp;nbsp;&lt;span style=&quot;color: #0086b3;&quot;&gt;&lt;/span&gt;&lt;span style=&quot;color: #ff3399;&quot;&gt;-&lt;/span&gt;importcert&amp;nbsp;&lt;span style=&quot;color: #0086b3;&quot;&gt;&lt;/span&gt;&lt;span style=&quot;color: #ff3399;&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color: #4be6fa;&quot;&gt;alias&lt;/span&gt;&amp;nbsp;등록할&amp;nbsp;인증서&amp;nbsp;별칭&amp;nbsp;&lt;span style=&quot;color: #0086b3;&quot;&gt;&lt;/span&gt;&lt;span style=&quot;color: #ff3399;&quot;&gt;-&lt;/span&gt;keystore JAVA_HOME/&lt;span style=&quot;color: #ff3399;&quot;&gt;jre/lib/security&lt;/span&gt;&lt;span style=&quot;color: #ff3399;&quot;&gt;/&lt;/span&gt;cacerts&amp;nbsp;&lt;span style=&quot;color: #0086b3;&quot;&gt;&lt;/span&gt;&lt;span style=&quot;color: #ff3399;&quot;&gt;-&lt;/span&gt;file&amp;nbsp;다운받은&amp;nbsp;루트인증서&lt;/div&gt;
&lt;div style=&quot;padding: 0 6px; white-space: pre; line-height: 130%;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;padding: 0 6px; white-space: pre; line-height: 130%;&quot;&gt;cacerts에&amp;nbsp;설정된&amp;nbsp;기본&amp;nbsp;비밀번호&amp;nbsp;:&amp;nbsp;changeit&lt;/div&gt;
&lt;div style=&quot;padding: 0 6px; white-space: pre; line-height: 130%;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div style=&quot;text-align: right; margin-top: -13px; margin-right: 5px; font-size: 9px; font-style: italic;&quot;&gt;&lt;a style=&quot;color: #4f4f4ftext-decoration:none;&quot; href=&quot;http://colorscripter.com/info#e&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Colored by Color Scripter&lt;/a&gt;&lt;/div&gt;
&lt;/td&gt;
&lt;td style=&quot;vertical-align: bottom; padding: 0px 2px 4px 0px; height: 83px; width: 13px;&quot;&gt;&lt;a style=&quot;text-decoration: none; color: white;&quot; href=&quot;http://colorscripter.com/info#e&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;&lt;span style=&quot;font-size: 9px; word-break: normal; background-color: #4f4f4f; color: white; border-radius: 10px; padding: 1px;&quot;&gt;cs&lt;/span&gt;&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;참고자료&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;java 버전별 지원 TLS 버전 &lt;span style=&quot;color: #777777;&quot;&gt;&lt;/span&gt;&lt;a href=&quot;https://www.ateam-oracle.com/tls-and-java&quot;&gt;https://www.ateam-oracle.com/tls-and-java&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Windows에서 CA 인증서 가져오기 &lt;a href=&quot;https://docs.vmware.com/kr/VMware-Horizon-7/7.13/horizon-console-administration/GUID-43F2DA27-2FDF-4425-BC99-ABA84F4F493F.html&quot;&gt;https://docs.vmware.com/kr/VMware-Horizon-7/7.13/horizon-console-administration/GUID-43F2DA27-2FDF-4425-BC99-ABA84F4F493F.html&lt;/a&gt;&lt;/p&gt;</description>
      <category>JAVA</category>
      <category>Ca</category>
      <category>handshake_failure</category>
      <category>SSL</category>
      <category>TLS</category>
      <category>TrustManager</category>
      <author>jckim</author>
      <guid isPermaLink="true">https://jckim-dev.tistory.com/18</guid>
      <comments>https://jckim-dev.tistory.com/entry/java-%C2%A0javaxnetsslSSLHandshakeException-Received-fatal-alert-handshakefailure#entry18comment</comments>
      <pubDate>Tue, 8 Jun 2021 00:15:12 +0900</pubDate>
    </item>
    <item>
      <title>[oracle 설정] UNDO tablespace 사용량 급증 현상 해결</title>
      <link>https://jckim-dev.tistory.com/entry/oracle-%EC%84%A4%EC%A0%95-UNDO-tablespace-%EC%82%AC%EC%9A%A9%EB%9F%89-%EA%B8%89%EC%A6%9D-%ED%98%84%EC%83%81-%ED%95%B4%EA%B2%B0</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;발단&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;oracle DB 환경을 관리하던 중 DB서버 이동을 하게 되었음.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;신규 서버에 oracle DB가 다시 세팅되고 며칠간 모니터링 수행 중 &lt;span style=&quot;color: #000000;&quot;&gt;Tablespace&lt;/span&gt; 중 UNDOTBS 사용량이 아주 빠른 속도로 증가되는 것을 발견.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;원인 파악을 하여 바로 조치하는 것이 제일 베스트이지만 당장의 서비스 운영을 위해서 임시조치로 해당 테이블스페이스를 증설한 상태에서 원인 파악에 들어갔음.&lt;/span&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;사전조사 및 참고자료&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;UNDOTBS(Undo Tablespace)란?&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;읽기 일관성을 유지하기 위해 사용되는 Tablespace로 &lt;/span&gt;데이터베이스 운영 중 많은 사용자들에게서 DML 작업이 이루어지는데 이때 Rollback하게 되는 경우를 대비하여 DML 작업이 발생했을 때 삭제 및 수정 이전의 값에 대한 정보를 UNDO Segment에 저장합니다. 이러한&amp;nbsp;&lt;span style=&quot;color: #000000;&quot;&gt;Undo Segment에 대한 관리 공간으로 Undo Tablespace를 사용합니다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;AUM(Automatic Undo Management)이란?&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000; font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;oracle 9i 부터 제공하는 undo 관리 기능이며 오라클 서버가 자동적으로 undo Data 및 &lt;span style=&quot;color: #000000;&quot;&gt;Tablespace&lt;/span&gt;를 관리한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000; font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;반대로 MUM 방식은 DBA의 설정 및 작업으로 수동적으로 관리되는 방식.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;755&quot; height=&quot;489&quot; data-origin-width=&quot;755&quot; data-origin-height=&quot;489&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/pjPHi/btqQ0PVvMCH/bXb7xIQ0evBYC8ry3yKva1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/pjPHi/btqQ0PVvMCH/bXb7xIQ0evBYC8ry3yKva1/img.jpg&quot; data-alt=&quot;MUM/AUM 비교&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/pjPHi/btqQ0PVvMCH/bXb7xIQ0evBYC8ry3yKva1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FpjPHi%2FbtqQ0PVvMCH%2FbXb7xIQ0evBYC8ry3yKva1%2Fimg.jpg&quot; width=&quot;755&quot; height=&quot;489&quot; data-origin-width=&quot;755&quot; data-origin-height=&quot;489&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;figcaption&gt;MUM/AUM 비교&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;AUM 사용 여부 확인&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;[확인 1] &lt;b&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;AUM 사용 여부 확인 SQL&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;div class=&quot;colorscripter-code&quot; style=&quot;color: #f0f0f0; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace !important; position: relative !important; overflow: auto;&quot;&gt;
&lt;table class=&quot;colorscripter-code-table&quot; style=&quot;margin: 0; padding: 0; border: none; background-color: #272727; border-radius: 4px;&quot; cellspacing=&quot;0&quot; cellpadding=&quot;0&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;padding: 6px; border-right: 2px solid #4f4f4f;&quot;&gt;
&lt;div style=&quot;margin: 0; padding: 0; word-break: normal; text-align: right; color: #aaa; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace !important; line-height: 130%;&quot;&gt;
&lt;div style=&quot;line-height: 130%;&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;1&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/td&gt;
&lt;td style=&quot;padding: 6px 0; text-align: left;&quot;&gt;
&lt;div style=&quot;margin: 0; padding: 0; color: #f0f0f0; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace !important; line-height: 130%;&quot;&gt;
&lt;div style=&quot;padding: 0 6px; white-space: pre; line-height: 130%;&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #ff3399;&quot;&gt;show&lt;/span&gt;&amp;nbsp;parameter&amp;nbsp;undo;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/td&gt;
&lt;td style=&quot;vertical-align: bottom; padding: 0 2px 4px 0;&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;&lt;a style=&quot;text-decoration: none; color: white;&quot; href=&quot;http://colorscripter.com/info#e&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;&lt;span style=&quot;font-size: 9px; word-break: normal; background-color: #4f4f4f; color: white; border-radius: 10px; padding: 1px;&quot;&gt;cs&lt;/span&gt;&lt;/a&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;span style=&quot;color: #333333; font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;조회 쿼리 이며 아래는 조회 결과다.&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;colorscripter-code&quot; style=&quot;color: #f0f0f0; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace !important; position: relative !important; overflow: auto;&quot;&gt;
&lt;table style=&quot;border-collapse: collapse; width: 826px; height: 358px;&quot; border=&quot;1&quot; data-ke-style=&quot;style12&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 189px; height: 20px; text-align: center;&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;NAME&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 167.606px; height: 20px; text-align: center;&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;TYPE&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 185.737px; height: 20px; text-align: center;&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;VALUE&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 213.75px; height: 20px; text-align: center;&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;설명&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 189px; height: 20px; text-align: center;&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #333333;&quot;&gt;undo_management&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 167.606px; height: 20px; text-align: center;&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #333333;&quot;&gt;string&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 185.737px; height: 20px; text-align: center;&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #333333;&quot;&gt;AUTO&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 213.75px; height: 20px; text-align: center;&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #333333;&quot;&gt;undo 관리 방식 (AUTO/MANUAL)&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 189px; height: 20px; text-align: center;&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #333333;&quot;&gt;undo_retention&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 167.606px; height: 20px; text-align: center;&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #333333;&quot;&gt;integer&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 185.737px; height: 20px; text-align: center;&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;900&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 213.75px; height: 20px; text-align: center;&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #333333;&quot;&gt;undo 데이터 유지시간(default:900)&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 189px; height: 20px; text-align: center;&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #333333;&quot;&gt;undo_tablespace&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 167.606px; height: 20px; text-align: center;&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #333333;&quot;&gt;string&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 185.737px; height: 20px; text-align: center;&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #333333;&quot;&gt;UNDOTBS1&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 213.75px; height: 20px; text-align: center;&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #333333;&quot;&gt;관리 대상 undo &lt;span style=&quot;color: #000000;&quot;&gt;Tablespace Name&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333; font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif; letter-spacing: 0px;&quot;&gt; &lt;span style=&quot;color: #333333;&quot;&gt;undo_management의 값이 AUTO 이기 때문에 현재 DB는 AUM 방식을 사용하는 것을 확인 가능하다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;UNDO_EXTENTS 상태 조회 및 상태 설명&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;[확인2]UNDO_EXTENTS 상태 조회 SQL&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;div class=&quot;colorscripter-code&quot; style=&quot;color: #f0f0f0; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace !important; position: relative !important; overflow: auto;&quot;&gt;
&lt;table class=&quot;colorscripter-code-table&quot; style=&quot;margin: 0; padding: 0; border: none; background-color: #272727; border-radius: 4px;&quot; cellspacing=&quot;0&quot; cellpadding=&quot;0&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;padding: 6px; border-right: 2px solid #4f4f4f;&quot;&gt;
&lt;div style=&quot;margin: 0; padding: 0; word-break: normal; text-align: right; color: #aaa; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace !important; line-height: 130%;&quot;&gt;
&lt;div style=&quot;line-height: 130%;&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;1&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/td&gt;
&lt;td style=&quot;padding: 6px 0; text-align: left;&quot;&gt;
&lt;div style=&quot;margin: 0; padding: 0; color: #f0f0f0; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace !important; line-height: 130%;&quot;&gt;
&lt;div style=&quot;padding: 0 6px; white-space: pre; line-height: 130%;&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #ff3399;&quot;&gt;SELECT&lt;/span&gt;&amp;nbsp;DISTINCT&amp;nbsp;STATUS,&amp;nbsp;SUM(BYTES)&lt;span style=&quot;color: #f0f0f0;&quot;&gt;&lt;/span&gt;&lt;span style=&quot;color: #4be6fa;&quot;&gt;/&lt;/span&gt;(&lt;span style=&quot;color: #c10aff;&quot;&gt;1024&lt;/span&gt;&lt;span style=&quot;color: #4be6fa;&quot;&gt;*&lt;/span&gt;&lt;span style=&quot;color: #c10aff;&quot;&gt;1024&lt;/span&gt;)&amp;nbsp;MB,&amp;nbsp;COUNT(&lt;span style=&quot;color: #f0f0f0;&quot;&gt;&lt;/span&gt;&lt;span style=&quot;color: #4be6fa;&quot;&gt;*&lt;/span&gt;)&amp;nbsp;&lt;span style=&quot;color: #ff3399;&quot;&gt;FROM&lt;/span&gt;&amp;nbsp;DBA_UNDO_EXTENTS&amp;nbsp;GROUP&amp;nbsp;&lt;span style=&quot;color: #ff3399;&quot;&gt;BY&lt;/span&gt;&amp;nbsp;STATUS;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/td&gt;
&lt;td style=&quot;vertical-align: bottom; padding: 0 2px 4px 0;&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;&lt;a style=&quot;text-decoration: none; color: white;&quot; href=&quot;http://colorscripter.com/info#e&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;&lt;span style=&quot;font-size: 9px; word-break: normal; background-color: #4f4f4f; color: white; border-radius: 10px; padding: 1px;&quot;&gt;cs&lt;/span&gt;&lt;/a&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 60px;&quot; border=&quot;1&quot; data-ke-style=&quot;style8&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 20px;&quot;&gt;&lt;span&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;STATUS&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 20px;&quot;&gt;&lt;span&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;MB&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 20px;&quot;&gt;&lt;span&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;COUNT(*)&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 20px;&quot;&gt;&lt;span&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;UNEXPIRED&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 20px;&quot;&gt;&lt;span&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;50&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 20px;&quot;&gt;&lt;span&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;51&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 20px;&quot;&gt;&lt;span&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;EXPIRED&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 20px;&quot;&gt;&lt;span&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;150&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 20px;&quot;&gt;&lt;span&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;99&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;U&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;NDO_EXTENTS 상태 &lt;/span&gt;조회 결과이며 각 상태에 대해서 설명은 아래와 같다.&lt;/span&gt;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-style=&quot;style12&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 21.9768%;&quot;&gt;&lt;span&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;EXTENT STATUS&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 78.0232%;&quot;&gt;&lt;span&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;설명&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 21.9768%;&quot;&gt;&lt;span&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;EXPIRED EXTENT&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 78.0232%;&quot;&gt;&lt;span&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;undo_retention 시간을 초과한 Extent. 사용&amp;nbsp;중인&amp;nbsp;트랜잭션이&amp;nbsp;없고&amp;nbsp;undo&amp;nbsp;retention&amp;nbsp;도&amp;nbsp;완료되어서&amp;nbsp;언제든지&amp;nbsp;트랜잭션에&amp;nbsp;할당될&amp;nbsp;수&amp;nbsp;있는&amp;nbsp;상태&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 21.9768%;&quot;&gt;&lt;span&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #333333;&quot;&gt;UNEXPIRED EXTENT&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 78.0232%;&quot;&gt;&lt;span&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;undo_retention&amp;nbsp;시간을&amp;nbsp;초과하지&amp;nbsp;않은&amp;nbsp;Extent.&amp;nbsp;사용&amp;nbsp;중인&amp;nbsp;트랜잭션이&amp;nbsp;없으나,&amp;nbsp;언두&amp;nbsp;유지&amp;nbsp;시간이&amp;nbsp;완료되지&amp;nbsp;않아서&amp;nbsp;트랜잭션에&amp;nbsp;할당되지&amp;nbsp;않고&amp;nbsp;보존되어&amp;nbsp;있는&amp;nbsp;상태&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 21.9768%;&quot;&gt;&lt;span&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;ACTIVE EXTENT&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 78.0232%;&quot;&gt;&lt;span&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;트랜잭션에&amp;nbsp;할당되어&amp;nbsp;언두&amp;nbsp;데이터를&amp;nbsp;기록하고&amp;nbsp;있는&amp;nbsp;상태&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 21.9768%;&quot;&gt;&lt;span&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;FREE EXTENT&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 78.0232%;&quot;&gt;&lt;span&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;생성&amp;nbsp;이후&amp;nbsp;트랜잭션에&amp;nbsp;한&amp;nbsp;번도&amp;nbsp;할당되지&amp;nbsp;않았거나,&amp;nbsp;SMON에&amp;nbsp;의한&amp;nbsp;주기적&amp;nbsp;정리가&amp;nbsp;완료되어&amp;nbsp;있는&amp;nbsp;상태&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;Extent Stealing&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000; font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;트랜잭션이 끝났지만 언두유지시간에 의하여 유지되고 있는 언두 익스텐트를 재사용하는 기능&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;Extent&amp;nbsp; 할당 순서&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #333333; font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;1. 자기 자신의 Extent의 프리 블록을 찾는다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #333333; font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;2. 다음 Extent가 만료된 Extent인지 확인한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #333333; font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;3. 언두 테이블스페이스에서 새로운 Extent를 할당한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #333333; font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;4. 오프라인 트랜잭션 테이블에서 expired Extent를 가져온다(steal).&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #333333; font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;5. 온라인 트랜잭션 테이블에서 expired Extent를 가져온다(steal).&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #333333; font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;6. autoextend가 가능하다면 파일을 확장하여 Extent를 할당한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #333333; font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;7. 자신의 트랜잭션 테이블에서 unexpired Extent를 재사용한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #333333; font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;8. 오프라인 트랜잭션 테이블에서 unexpired Extent를 가져온다(steal).&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #333333; font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;9. 에러(ORA-30036)를 발생한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;RETENTION 상태 확인&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;[확인3] &lt;b&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;RETENTION 상태 확인 SQL&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;div class=&quot;colorscripter-code&quot; style=&quot;color: #f0f0f0; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace !important; position: relative !important; overflow: auto;&quot;&gt;
&lt;table class=&quot;colorscripter-code-table&quot; style=&quot;margin: 0; padding: 0; border: none; background-color: #272727; border-radius: 4px;&quot; cellspacing=&quot;0&quot; cellpadding=&quot;0&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;padding: 6px; border-right: 2px solid #4f4f4f;&quot;&gt;
&lt;div style=&quot;margin: 0; padding: 0; word-break: normal; text-align: right; color: #aaa; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace !important; line-height: 130%;&quot;&gt;
&lt;div style=&quot;line-height: 130%;&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;1&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/td&gt;
&lt;td style=&quot;padding: 6px 0; text-align: left;&quot;&gt;
&lt;div style=&quot;margin: 0; padding: 0; color: #f0f0f0; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace !important; line-height: 130%;&quot;&gt;
&lt;div style=&quot;padding: 0 6px; white-space: pre; line-height: 130%;&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #ff3399;&quot;&gt;select&lt;/span&gt;&amp;nbsp;RETENTION&amp;nbsp;&lt;span style=&quot;color: #ff3399;&quot;&gt;from&lt;/span&gt;&amp;nbsp;DBA_TABLESPACES&amp;nbsp;&lt;span style=&quot;color: #ff3399;&quot;&gt;where&lt;/span&gt;&amp;nbsp;tablespace_name&amp;nbsp;&lt;span style=&quot;color: #f0f0f0;&quot;&gt;&lt;/span&gt;&lt;span style=&quot;color: #4be6fa;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #ffd500;&quot;&gt;'UNDOTBS1'&lt;/span&gt;;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/td&gt;
&lt;td style=&quot;vertical-align: bottom; padding: 0 2px 4px 0;&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;&lt;a style=&quot;text-decoration: none; color: white;&quot; href=&quot;http://colorscripter.com/info#e&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;&lt;span style=&quot;font-size: 9px; word-break: normal; background-color: #4f4f4f; color: white; border-radius: 10px; padding: 1px;&quot;&gt;cs&lt;/span&gt;&lt;/a&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #333333; font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;조회 결과는 아래 두 값 중 하나&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #333333; font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;guarantee&amp;nbsp; : 언두 유지 시간 엄격히 적용&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;noguarantee : 언두 유지 시간을 엄격하게 적용하지 않고 테이블 스페이스 크기와 연관하여 관리&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif; color: #000000;&quot;&gt;&lt;b&gt;Tablespace 확장성 사용 여부 확인&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif; color: #000000;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;[확인 4] Tablespace 확장성 사용 여부 확인&lt;/b&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;div class=&quot;colorscripter-code&quot; style=&quot;color: #f0f0f0; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace !important; position: relative !important; overflow: auto;&quot;&gt;
&lt;table class=&quot;colorscripter-code-table&quot; style=&quot;margin: 0; padding: 0; border: none; background-color: #272727; border-radius: 4px;&quot; cellspacing=&quot;0&quot; cellpadding=&quot;0&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;padding: 6px; border-right: 2px solid #4f4f4f;&quot;&gt;
&lt;div style=&quot;margin: 0; padding: 0; word-break: normal; text-align: right; color: #aaa; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace !important; line-height: 130%;&quot;&gt;
&lt;div style=&quot;line-height: 130%;&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;1&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/td&gt;
&lt;td style=&quot;padding: 6px 0; text-align: left;&quot;&gt;
&lt;div style=&quot;margin: 0; padding: 0; color: #f0f0f0; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace !important; line-height: 130%;&quot;&gt;
&lt;div style=&quot;padding: 0 6px; white-space: pre; line-height: 130%;&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #ff3399;&quot;&gt;select&lt;/span&gt;&amp;nbsp;autoextensible&amp;nbsp;&lt;span style=&quot;color: #ff3399;&quot;&gt;from&lt;/span&gt;&amp;nbsp;DBA_DATA_FILES&amp;nbsp;&lt;span style=&quot;color: #ff3399;&quot;&gt;where&lt;/span&gt;&amp;nbsp;tablespace_name&amp;nbsp;&lt;span style=&quot;color: #f0f0f0;&quot;&gt;&lt;/span&gt;&lt;span style=&quot;color: #4be6fa;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #ffd500;&quot;&gt;'UNDOTBS1'&lt;/span&gt;;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/td&gt;
&lt;td style=&quot;vertical-align: bottom; padding: 0 2px 4px 0;&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;&lt;a style=&quot;text-decoration: none; color: white;&quot; href=&quot;http://colorscripter.com/info#e&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;&lt;span style=&quot;font-size: 9px; word-break: normal; background-color: #4f4f4f; color: white; border-radius: 10px; padding: 1px;&quot;&gt;cs&lt;/span&gt;&lt;/a&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #333333; font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;조회 결과는 아래 두 값 중 하나&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;on(yes) : 테이블스페이스 공간이 부족할 시 자동적으로 확장 가능하게 하는 옵션&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;off(no)&amp;nbsp; : 테이블스페이스 공간이 부족할 시 자동적인 확장을 제한하는 옵션&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif; color: #000000;&quot;&gt;&lt;b&gt;Automatic Undo Retention 적용 조건 표&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;525&quot; height=&quot;375&quot; data-origin-width=&quot;525&quot; data-origin-height=&quot;375&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bjng8Y/btqQ7TP6tqh/q0B44Kj2mf4B9CWhYzMdEk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bjng8Y/btqQ7TP6tqh/q0B44Kj2mf4B9CWhYzMdEk/img.png&quot; data-alt=&quot;Automatic Undo Retention &amp;amp;amp;nbsp;적용 조건&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bjng8Y/btqQ7TP6tqh/q0B44Kj2mf4B9CWhYzMdEk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbjng8Y%2FbtqQ7TP6tqh%2Fq0B44Kj2mf4B9CWhYzMdEk%2Fimg.png&quot; width=&quot;525&quot; height=&quot;375&quot; data-origin-width=&quot;525&quot; data-origin-height=&quot;375&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;figcaption&gt;Automatic Undo Retention &amp;nbsp;적용 조건&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;u&gt;&lt;b&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif; color: #ee2323;&quot;&gt;해당 표가 이번 이슈해결에 가장 큰 도움을 받은 자료이다.&lt;/span&gt;&lt;/b&gt;&lt;/u&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;원인 분석&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;상단에 UNDO 관리에 대한 참고자료 항목에 정리해 보았다 관련 자료를 참고하여 현재 문제가 발생한 DB에서 각각의 설정을 확인하였다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #333333; font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;b&gt;[확인 1]&lt;/b&gt; AUM 사용 여부 조회 (확인 결과 AUTO 값 확인)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #333333; font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;[확인 2]&lt;/b&gt;UNDO_EXTENTS 결과를 확인하였을 때 UNEXPIRED EXTENT값이 줄어들지 않는 것을 확인&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;b&gt;[확인 3]&lt;/b&gt;RETENTION &lt;/span&gt;상태 조회 (&lt;span style=&quot;color: #333333;&quot;&gt;noguarantee 값 확인&lt;/span&gt;)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;[확인 4]&lt;/b&gt;TABLESPACE autoextensible 값 확인 (off 값 확인)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;위에 상태 확인 결과를 토대로 &quot;&lt;span style=&quot;color: #000000;&quot;&gt;Automatic Undo Retention&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&amp;nbsp;적용 조건 표&quot;에 대입해 보았다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;현재 상태는 GUARANTEE : NO / AUTOEXTEND : NO에 해당하며 이 경우 언두 유지시간은 345,600초와 UNDO_RETENTION(900초) 설정 값 중 큰 값을 따르기 때문에 큰 값인 345,600초 즉 4일이라는 기간 동안 언두를 유지하도록 되어 있던 것이었다. 현재 시스템상 매분마다 들어오는 데이터가 많고 매분마다 반복해서 작업이 있기 때문에 undo Tablespace 사용량이 증가하는 것을 쉽게 확인할 수 있었던 것이다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;552&quot; data-origin-height=&quot;105&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/yRWJR/btqQZxnfMNt/Lznt485ORG6gmX8DXLh5wK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/yRWJR/btqQZxnfMNt/Lznt485ORG6gmX8DXLh5wK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/yRWJR/btqQZxnfMNt/Lznt485ORG6gmX8DXLh5wK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FyRWJR%2FbtqQZxnfMNt%2FLznt485ORG6gmX8DXLh5wK%2Fimg.png&quot; data-origin-width=&quot;552&quot; data-origin-height=&quot;105&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif; color: #000000;&quot;&gt;&lt;b&gt;조치방법&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;undo &lt;span style=&quot;color: #333333;&quot;&gt;Tablespace &lt;/span&gt;autoextensible 옵션 yes로 적용하고 maxsize는 현재 생성된 dbf 파일 사이즈만큼 설정하면 해당 dbf 파일이 이전 이슈가 발생하였을 때 무분별하게 확장하지 않도록 방지할 수 있게 설정할 수 있고 이에 따라 참고자료 항목에 &lt;span style=&quot;color: #000000;&quot;&gt;Automatic Undo Retention&lt;/span&gt; 적용 조건 표 두 번째 조건 &lt;span style=&quot;color: #333333;&quot;&gt;GUARANTEE : NO / AUTOEXTEND : YES에&lt;/span&gt; 맞추어 관리하도록 변경 후 언두 유지시간은 MAXQURTLEN + 300초와 &lt;span style=&quot;color: #333333;&quot;&gt;UNDO_RETENTION(900초) 중 큰 값을 따르게 되는 것을 볼 수 있으며&amp;nbsp;&lt;/span&gt;모니터링 진행 결과 정상적으로 UNDO Tablespace가 관리되는 모습을 볼 수 있었다.&lt;/span&gt;&lt;/p&gt;
&lt;div class=&quot;colorscripter-code&quot; style=&quot;color: #f0f0f0; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace !important; position: relative !important; overflow: auto;&quot;&gt;
&lt;table class=&quot;colorscripter-code-table&quot; style=&quot;margin: 0; padding: 0; border: none; background-color: #272727; border-radius: 4px;&quot; cellspacing=&quot;0&quot; cellpadding=&quot;0&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;padding: 6px; border-right: 2px solid #4f4f4f;&quot;&gt;
&lt;div style=&quot;margin: 0; padding: 0; word-break: normal; text-align: right; color: #aaa; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace !important; line-height: 130%;&quot;&gt;
&lt;div style=&quot;line-height: 130%;&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;1&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/td&gt;
&lt;td style=&quot;padding: 6px 0; text-align: left;&quot;&gt;
&lt;div style=&quot;margin: 0; padding: 0; color: #f0f0f0; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace !important; line-height: 130%;&quot;&gt;
&lt;div style=&quot;padding: 0 6px; white-space: pre; line-height: 130%;&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #ff3399;&quot;&gt;ALTER&lt;/span&gt;&amp;nbsp;DATABASE&amp;nbsp;DATAFILE&amp;nbsp;&lt;span style=&quot;color: #ffd500;&quot;&gt;'C:\ORACLE\ORADATA\undo01.dbf'&lt;/span&gt;&amp;nbsp;AUTOEXTEND&amp;nbsp;&lt;span style=&quot;color: #ff3399;&quot;&gt;ON&lt;/span&gt;&amp;nbsp;MAXSIZE&amp;nbsp;1024M;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/td&gt;
&lt;td style=&quot;vertical-align: bottom; padding: 0 2px 4px 0;&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;&lt;a style=&quot;text-decoration: none; color: white;&quot; href=&quot;http://colorscripter.com/info#e&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;&lt;span style=&quot;font-size: 9px; word-break: normal; background-color: #4f4f4f; color: white; border-radius: 10px; padding: 1px;&quot;&gt;cs&lt;/span&gt;&lt;/a&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;523&quot; data-origin-height=&quot;190&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cY2L67/btqQUZq1AHL/fkRic2NkOvm8lNi7VVevTk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cY2L67/btqQUZq1AHL/fkRic2NkOvm8lNi7VVevTk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cY2L67/btqQUZq1AHL/fkRic2NkOvm8lNi7VVevTk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcY2L67%2FbtqQUZq1AHL%2FfkRic2NkOvm8lNi7VVevTk%2Fimg.png&quot; data-origin-width=&quot;523&quot; data-origin-height=&quot;190&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-type=&quot;image&quot; data-ke-size=&quot;size18&quot;&gt;참고사이트 출처&lt;/p&gt;
&lt;p data-ke-type=&quot;image&quot; data-ke-size=&quot;size18&quot;&gt;&lt;a href=&quot;http://wiki.gurubee.net/display/CORE/3.2+AUM+vs.+MUM&quot;&gt;http://wiki.gurubee.net/display/CORE/3.2+AUM+vs.+MUM&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;http://wiki.gurubee.net/pages/viewpage.action?pageId=26742857&quot;&gt;http://wiki.gurubee.net/pages/viewpage.action?pageId=26742857&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://sarc.io/index.php/oracledatabase/145-2014-04-23-05-17-38&quot;&gt;https://sarc.io/index.php/oracledatabase/145-2014-04-23-05-17-38&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>DB</category>
      <category>aum</category>
      <category>Expired</category>
      <category>Oracle</category>
      <category>Retention</category>
      <category>tablespace</category>
      <category>undo</category>
      <category>사용량</category>
      <category>증가</category>
      <author>jckim</author>
      <guid isPermaLink="true">https://jckim-dev.tistory.com/17</guid>
      <comments>https://jckim-dev.tistory.com/entry/oracle-%EC%84%A4%EC%A0%95-UNDO-tablespace-%EC%82%AC%EC%9A%A9%EB%9F%89-%EA%B8%89%EC%A6%9D-%ED%98%84%EC%83%81-%ED%95%B4%EA%B2%B0#entry17comment</comments>
      <pubDate>Tue, 22 Dec 2020 23:17:57 +0900</pubDate>
    </item>
    <item>
      <title>[java] API 호출 안되는 현상 해결 (301 응답코드)</title>
      <link>https://jckim-dev.tistory.com/entry/java-API-%ED%98%B8%EC%B6%9C-%EC%95%88%EB%90%98%EB%8A%94-%ED%98%84%EC%83%81-%ED%95%B4%EA%B2%B0-301-%EC%9D%91%EB%8B%B5%EC%BD%94%EB%93%9C</link>
      <description>&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;*발단&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;특정 기관의 api를 호출한 결과 데이터를 DB에 삽입하여 관리하고 있으나 특정 시점부터 데이터가 들어오지 않는 현상이 발생.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;*원인 파악&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;exception을 제대로 걸지 않은 것인지 log레벨에 맞지 않은 것인지 log 파일에서는 관련된 부분을 확인할 수 없었음.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;아래 소스와 같이 로컬상에 api 끌어오는 부분을 구현하여 결과값을 output 하는 것으로 결정.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;[호출 테스트]&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1645487594410&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;//예시용도 호출 api url
String fullUrl = &quot;http://jckim-dev.tistory.com/apiTest&quot;;
        
HttpURLConnection conn = (HttpURLConnection)url.openConnection();
 
BufferedReader tempBufferedReader = null;
BufferedReader bufferedReader = null;
InputStream inputStream = null;
 
conn.setDoOutput(true);
conn.setRequestMethod(&quot;GET&quot;);
 
tempBufferedReader = new BufferedReader(new InputStreamReader(conn.getInputStream(), &quot;euc-kr&quot;));
String tempStr = &quot;&quot;;
StringBuilder bufferedStr = new StringBuilder();
 
while ((tempStr = tempBufferedReader.readLine()) != null) {
  bufferedStr.append(tempStr).append(&quot;\n&quot;);
}
 
inputStream = new ByteArrayInputStream(bufferedStr.toString().getBytes());
bufferedReader = new BufferedReader(new InputStreamReader(inputStream, &quot;UTF-8&quot;));
 
System.out.println(&quot;===============================&quot;);
System.out.println(bufferedStr.toString());&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;[조치 전 호출 결과]&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1645487630803&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;!DOCTYPE HTML PUBLIC &quot;-//IETF//DTD HTML 2.0//EN&quot;&amp;gt;
&amp;lt;html&amp;gt;
&amp;lt;head&amp;gt;
    &amp;lt;title&amp;gt;301 Moved Permanently&amp;lt;/title&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
    &amp;lt;h1&amp;gt;Moved Permanently&amp;lt;/h1&amp;gt;
    &amp;lt;p&amp;gt;The document has moved &amp;lt;a href=&quot;https://jckim-dev.tistory.com/apiTest&quot;&amp;gt;here&amp;lt;/a&amp;gt;.&amp;lt;/p&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;div class=&quot;colorscripter-code&quot; style=&quot;color: #f0f0f0; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace !important; position: relative !important; overflow: auto;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;문제가 되었던 api를 호출하였을 때 &lt;b&gt;301 응답 코드가&lt;/b&gt; 발생한 것을 확인하였고 친절하게 어떠한 URL로 변경되었다고 메시지까지 확인할 수 있었음.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;메시지는 기존 url의 콘텐츠는 새로운 url로 옮겨졌으니 해당 url로 호출하라는 내용이었음.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;˚&lt;/span&gt;http 응답 코드 301 (영구 이동): 요청한 페이지를 새 위치로 영구적으로 이동했다. GET 또는 HEAD 요청에 대한 응답으로 이 응답을 표시하면 요청자가 자동으로 새 위치로 전달된다. &lt;a href=&quot;https://ko.wikipedia.org/wiki/HTTP_%EC%83%81%ED%83%9C_%EC%BD%94%EB%93%9C&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;참조자료&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;*조치&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;해당 기관이 http에서 https로 제공하도록 변경된 것으로 확인.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;api를 호출하는 로직에서는 해당 결과를 확인할 수 없었기 때문에 원인 파악에 어려움이 있었음.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;api url을 기존 http에서 https로 호출.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;추가적으로 방화벽을 관리하고 있다면 &lt;span style=&quot;color: #333333;&quot;&gt;https로 호출 시 &lt;/span&gt;443 포트가 열려있는지 확인 필요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;[조치 후 결과]&lt;/b&gt;&lt;/p&gt;
&lt;p class=&quot;colorscripter-code&quot; style=&quot;color: #f0f0f0; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace !important; position: relative !important; overflow: auto;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1645488098697&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;document&amp;gt;
    &amp;lt;root&amp;gt;
        &amp;lt;result&amp;gt;        
            ...
            ...
            ...
        &amp;lt;/result&amp;gt;
    &amp;lt;/root&amp;gt;
&amp;lt;/document&amp;gt;&lt;/code&gt;&lt;/pre&gt;</description>
      <category>JAVA</category>
      <category>301</category>
      <category>API</category>
      <category>HTTPS</category>
      <category>Moved Permanently</category>
      <category>응답코드</category>
      <category>호출</category>
      <author>jckim</author>
      <guid isPermaLink="true">https://jckim-dev.tistory.com/16</guid>
      <comments>https://jckim-dev.tistory.com/entry/java-API-%ED%98%B8%EC%B6%9C-%EC%95%88%EB%90%98%EB%8A%94-%ED%98%84%EC%83%81-%ED%95%B4%EA%B2%B0-301-%EC%9D%91%EB%8B%B5%EC%BD%94%EB%93%9C#entry16comment</comments>
      <pubDate>Mon, 7 Dec 2020 23:19:48 +0900</pubDate>
    </item>
    <item>
      <title>[JPA] 메서드명으로 쿼리 생성 원리</title>
      <link>https://jckim-dev.tistory.com/entry/JPA-%EB%A9%94%EC%84%9C%EB%93%9C%EB%AA%85%EC%9C%BC%EB%A1%9C-%EC%BF%BC%EB%A6%AC-%EC%83%9D%EC%84%B1-%EC%9B%90%EB%A6%AC</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;발단&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;Spring Data JPA 학습을 하는 도중 메서드명으로 쿼리를 생성하는 부분에 궁금증이 생김.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;필요한 Entitiy를 선언하고 메소드를 작성하던 중 동일한 키워드가 하나의 메소드에 여러 개가 선언되었는데 해당 경우에도 정상적으로 원하는 쿼리가 동작을 하는 것을 확인하였음.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;내가 작성하였을 때만 어색하게 보일 뿐이지 내부적으로 어떠한 원리로 메소드명에서 정보를 추출하여 쿼리를 생성하는지 찾아봄.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;학습환경 (발단의 원인)&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;회원정보인 Usr Entity에 권한을 뜻하는 Role Entity가 존재(&lt;span style=&quot;color: #333333;&quot;&gt;One&lt;/span&gt;ToOne Join).&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;Entitiy &lt;/span&gt;정보는 아래와 같음.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div class=&quot;colorscripter-code&quot; style=&quot;color: #f0f0f0; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace !important; position: relative !important; overflow: auto;&quot;&gt;
&lt;table class=&quot;colorscripter-code-table&quot; style=&quot;margin: 0px; padding: 0px; border: none; background-color: #272727; border-radius: 4px; height: 206px; width: 584px;&quot; cellspacing=&quot;0&quot; cellpadding=&quot;0&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 206px;&quot;&gt;
&lt;td style=&quot;padding: 6px; border-right: 2px solid #4f4f4f; height: 206px; width: 16.0243px;&quot;&gt;
&lt;div style=&quot;margin: 0; padding: 0; word-break: normal; text-align: right; color: #aaa; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace !important; line-height: 130%;&quot;&gt;
&lt;div style=&quot;line-height: 130%;&quot;&gt;1&lt;/div&gt;
&lt;div style=&quot;line-height: 130%;&quot;&gt;2&lt;/div&gt;
&lt;div style=&quot;line-height: 130%;&quot;&gt;3&lt;/div&gt;
&lt;div style=&quot;line-height: 130%;&quot;&gt;4&lt;/div&gt;
&lt;div style=&quot;line-height: 130%;&quot;&gt;5&lt;/div&gt;
&lt;div style=&quot;line-height: 130%;&quot;&gt;6&lt;/div&gt;
&lt;div style=&quot;line-height: 130%;&quot;&gt;7&lt;/div&gt;
&lt;div style=&quot;line-height: 130%;&quot;&gt;8&lt;/div&gt;
&lt;div style=&quot;line-height: 130%;&quot;&gt;9&lt;/div&gt;
&lt;div style=&quot;line-height: 130%;&quot;&gt;10&lt;/div&gt;
&lt;div style=&quot;line-height: 130%;&quot;&gt;11&lt;/div&gt;
&lt;/div&gt;
&lt;/td&gt;
&lt;td style=&quot;padding: 6px 0px; text-align: left; height: 206px; width: 555.556px;&quot;&gt;
&lt;div style=&quot;margin: 0; padding: 0; color: #f0f0f0; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace !important; line-height: 130%;&quot;&gt;
&lt;div style=&quot;padding: 0 6px; white-space: pre; line-height: 130%;&quot;&gt;&lt;span style=&quot;color: #999999;&quot;&gt;//회원정보&amp;nbsp;엔티티&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;padding: 0 6px; white-space: pre; line-height: 130%;&quot;&gt;&lt;span style=&quot;color: #ff3399;&quot;&gt;public&lt;/span&gt;&amp;nbsp;&lt;span style=&quot;color: #ff3399;&quot;&gt;class&lt;/span&gt;&amp;nbsp;UsrEntity&amp;nbsp;{&lt;/div&gt;
&lt;div style=&quot;padding: 0 6px; white-space: pre; line-height: 130%;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;@OneToOne&lt;/div&gt;
&lt;div style=&quot;padding: 0 6px; white-space: pre; line-height: 130%;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;@JoinColumn(name&amp;nbsp;&lt;span style=&quot;color: #0086b3;&quot;&gt;&lt;/span&gt;&lt;span style=&quot;color: #ff3399;&quot;&gt;=&lt;/span&gt;&amp;nbsp;&lt;span style=&quot;color: #ffd500;&quot;&gt;&quot;usr_id&quot;&lt;/span&gt;,&amp;nbsp;referencedColumnName&amp;nbsp;&lt;span style=&quot;color: #0086b3;&quot;&gt;&lt;/span&gt;&lt;span style=&quot;color: #ff3399;&quot;&gt;=&lt;/span&gt;&amp;nbsp;&lt;span style=&quot;color: #ffd500;&quot;&gt;&quot;usr_id&quot;&lt;/span&gt;)&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;padding: 0 6px; white-space: pre; line-height: 130%;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style=&quot;color: #ff3399;&quot;&gt;private&lt;/span&gt;&amp;nbsp;RoleUsrEntity&amp;nbsp;role;&lt;/div&gt;
&lt;div style=&quot;padding: 0 6px; white-space: pre; line-height: 130%;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;padding: 0 6px; white-space: pre; line-height: 130%;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style=&quot;color: #ff3399;&quot;&gt;public&lt;/span&gt;&amp;nbsp;&lt;span style=&quot;color: #ff3399;&quot;&gt;void&lt;/span&gt;&amp;nbsp;setRole(RoleUsrEntity&amp;nbsp;role)&amp;nbsp;{&lt;/div&gt;
&lt;div style=&quot;padding: 0 6px; white-space: pre; line-height: 130%;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style=&quot;color: #ff3399;&quot;&gt;this&lt;/span&gt;.role&amp;nbsp;&lt;span style=&quot;color: #0086b3;&quot;&gt;&lt;/span&gt;&lt;span style=&quot;color: #ff3399;&quot;&gt;=&lt;/span&gt;&amp;nbsp;role;&lt;/div&gt;
&lt;div style=&quot;padding: 0 6px; white-space: pre; line-height: 130%;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/div&gt;
&lt;div style=&quot;padding: 0 6px; white-space: pre; line-height: 130%;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;...&amp;nbsp;생략&lt;/div&gt;
&lt;div style=&quot;padding: 0 6px; white-space: pre; line-height: 130%;&quot;&gt;}&lt;/div&gt;
&lt;/div&gt;
&lt;div style=&quot;text-align: right; margin-top: -13px; margin-right: 5px; font-size: 9px; font-style: italic;&quot;&gt;&lt;a style=&quot;color: #4f4f4ftext-decoration:none;&quot; href=&quot;http://colorscripter.com/info#e&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Colored by Color Scripter&lt;/a&gt;&lt;/div&gt;
&lt;/td&gt;
&lt;td style=&quot;vertical-align: bottom; padding: 0px 2px 4px 0px; height: 206px; width: 10.2257px;&quot;&gt;&lt;a style=&quot;text-decoration: none; color: white;&quot; href=&quot;http://colorscripter.com/info#e&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;&lt;span style=&quot;font-size: 9px; word-break: normal; background-color: #4f4f4f; color: white; border-radius: 10px; padding: 1px;&quot;&gt;cs&lt;/span&gt;&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;colorscripter-code&quot; style=&quot;color: #f0f0f0; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace !important; position: relative !important; overflow: auto;&quot;&gt;
&lt;table class=&quot;colorscripter-code-table&quot; style=&quot;margin: 0; padding: 0; border: none; background-color: #272727; border-radius: 4px;&quot; cellspacing=&quot;0&quot; cellpadding=&quot;0&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;padding: 6px; border-right: 2px solid #4f4f4f;&quot;&gt;
&lt;div style=&quot;margin: 0; padding: 0; word-break: normal; text-align: right; color: #aaa; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace !important; line-height: 130%;&quot;&gt;
&lt;div style=&quot;line-height: 130%;&quot;&gt;1&lt;/div&gt;
&lt;div style=&quot;line-height: 130%;&quot;&gt;2&lt;/div&gt;
&lt;div style=&quot;line-height: 130%;&quot;&gt;3&lt;/div&gt;
&lt;div style=&quot;line-height: 130%;&quot;&gt;4&lt;/div&gt;
&lt;div style=&quot;line-height: 130%;&quot;&gt;5&lt;/div&gt;
&lt;div style=&quot;line-height: 130%;&quot;&gt;6&lt;/div&gt;
&lt;div style=&quot;line-height: 130%;&quot;&gt;7&lt;/div&gt;
&lt;div style=&quot;line-height: 130%;&quot;&gt;8&lt;/div&gt;
&lt;div style=&quot;line-height: 130%;&quot;&gt;9&lt;/div&gt;
&lt;div style=&quot;line-height: 130%;&quot;&gt;10&lt;/div&gt;
&lt;div style=&quot;line-height: 130%;&quot;&gt;11&lt;/div&gt;
&lt;/div&gt;
&lt;/td&gt;
&lt;td style=&quot;padding: 6px 0; text-align: left;&quot;&gt;
&lt;div style=&quot;margin: 0; padding: 0; color: #f0f0f0; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace !important; line-height: 130%;&quot;&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;div style=&quot;padding: 0 6px; white-space: pre; line-height: 130%;&quot;&gt;&lt;span style=&quot;color: #999999;&quot;&gt;//권한엔티티&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;padding: 0 6px; white-space: pre; line-height: 130%;&quot;&gt;&lt;span style=&quot;color: #ff3399;&quot;&gt;public&lt;/span&gt;&amp;nbsp;&lt;span style=&quot;color: #ff3399;&quot;&gt;class&lt;/span&gt;&amp;nbsp;RoleUsrEntity&amp;nbsp;{&lt;/div&gt;
&lt;div style=&quot;padding: 0 6px; white-space: pre; line-height: 130%;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;padding: 0 6px; white-space: pre; line-height: 130%;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;@Id&lt;/div&gt;
&lt;div style=&quot;padding: 0 6px; white-space: pre; line-height: 130%;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;@Column(nullable&amp;nbsp;&lt;span style=&quot;color: #0086b3;&quot;&gt;&lt;/span&gt;&lt;span style=&quot;color: #ff3399;&quot;&gt;=&lt;/span&gt;&amp;nbsp;&lt;span style=&quot;color: #c10aff;&quot;&gt;false&lt;/span&gt;)&lt;/div&gt;
&lt;div style=&quot;padding: 0 6px; white-space: pre; line-height: 130%;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style=&quot;color: #ff3399;&quot;&gt;private&lt;/span&gt;&amp;nbsp;&lt;span style=&quot;color: #4be6fa;&quot;&gt;String&lt;/span&gt;&amp;nbsp;usrId;&lt;/div&gt;
&lt;div style=&quot;padding: 0 6px; white-space: pre; line-height: 130%;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;padding: 0 6px; white-space: pre; line-height: 130%;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;@Column(nullable&amp;nbsp;&lt;span style=&quot;color: #0086b3;&quot;&gt;&lt;/span&gt;&lt;span style=&quot;color: #ff3399;&quot;&gt;=&lt;/span&gt;&amp;nbsp;&lt;span style=&quot;color: #c10aff;&quot;&gt;false&lt;/span&gt;)&lt;/div&gt;
&lt;div style=&quot;padding: 0 6px; white-space: pre; line-height: 130%;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style=&quot;color: #ff3399;&quot;&gt;private&lt;/span&gt;&amp;nbsp;&lt;span style=&quot;color: #4be6fa;&quot;&gt;String&lt;/span&gt;&amp;nbsp;roleCd;&lt;/div&gt;
&lt;div style=&quot;padding: 0 6px; white-space: pre; line-height: 130%;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;padding: 0 6px; white-space: pre; line-height: 130%;&quot;&gt;}&lt;/div&gt;
&lt;/div&gt;
&lt;/td&gt;
&lt;td style=&quot;vertical-align: bottom; padding: 0 2px 4px 0;&quot;&gt;&lt;a style=&quot;text-decoration: none; color: white;&quot; href=&quot;http://colorscripter.com/info#e&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;&lt;span style=&quot;font-size: 9px; word-break: normal; background-color: #4f4f4f; color: white; border-radius: 10px; padding: 1px;&quot;&gt;cs&lt;/span&gt;&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #333333; font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif; letter-spacing: 0px;&quot;&gt;권한코드를 기준으로 회원 목록을 검색하려는 메소드를 작성하였을 때 아래와 같이 RoleRoleCd이라고 작성하였음.&lt;/span&gt;&lt;span style=&quot;color: #333333; font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif; letter-spacing: 0px;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div class=&quot;colorscripter-code&quot; style=&quot;color: #f0f0f0; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace !important; position: relative !important; overflow: auto;&quot;&gt;
&lt;table class=&quot;colorscripter-code-table&quot; style=&quot;margin: 0; padding: 0; border: none; background-color: #272727; border-radius: 4px;&quot; cellspacing=&quot;0&quot; cellpadding=&quot;0&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;padding: 6px; border-right: 2px solid #4f4f4f;&quot;&gt;
&lt;div style=&quot;margin: 0; padding: 0; word-break: normal; text-align: right; color: #aaa; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace !important; line-height: 130%;&quot;&gt;
&lt;div style=&quot;line-height: 130%;&quot;&gt;1&lt;/div&gt;
&lt;/div&gt;
&lt;/td&gt;
&lt;td style=&quot;padding: 6px 0; text-align: left;&quot;&gt;
&lt;div style=&quot;margin: 0; padding: 0; color: #f0f0f0; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace !important; line-height: 130%;&quot;&gt;
&lt;div style=&quot;padding: 0 6px; white-space: pre; line-height: 130%;&quot;&gt;List&lt;span style=&quot;color: #0086b3;&quot;&gt;&lt;/span&gt;&lt;span style=&quot;color: #ff3399;&quot;&gt;&amp;lt;&lt;/span&gt;UsrEntity&lt;span style=&quot;color: #0086b3;&quot;&gt;&lt;/span&gt;&lt;span style=&quot;color: #ff3399;&quot;&gt;&amp;gt;&lt;/span&gt;&amp;nbsp;findByRoleRoleCd(&lt;span style=&quot;color: #4be6fa;&quot;&gt;String&lt;/span&gt;&amp;nbsp;roleCd);&lt;/div&gt;
&lt;/div&gt;
&lt;/td&gt;
&lt;td style=&quot;vertical-align: bottom; padding: 0 2px 4px 0;&quot;&gt;&lt;a style=&quot;text-decoration: none; color: white;&quot; href=&quot;http://colorscripter.com/info#e&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;&lt;span style=&quot;font-size: 9px; word-break: normal; background-color: #4f4f4f; color: white; border-radius: 10px; padding: 1px;&quot;&gt;cs&lt;/span&gt;&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;/div&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;b&gt;확인결과&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;JPA 프로젝트에서 repository에 메소드명을 정의하는 경우 spring data jpa 명세에 따라서 메소드명과 Entity를 이용하여 쿼리를 추출하게 됨.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;JPA&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;관련 다양한 구현체가 존재하나 학습 중 이용하였던 JpaRepository를 기준으로 확인.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;아래는 메소드명에서 쿼리 속성을 찾아가는 과정을 붉은색으로 표시한 것임.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-style=&quot;style13&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 6.12406%; text-align: center;&quot;&gt;&lt;b&gt;순서&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 20.7751%; text-align: center;&quot;&gt;&lt;b&gt;메서드&lt;/b&gt;&lt;br /&gt;&lt;b&gt;(&lt;span style=&quot;color: #ee2323;&quot;&gt;확인중인 엔티티 속성&lt;/span&gt;)&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 73.1007%; text-align: center;&quot;&gt;&lt;b&gt;설명&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 6.12406%; text-align: center;&quot;&gt;1&lt;/td&gt;
&lt;td style=&quot;width: 20.7751%; text-align: center;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;findBy&lt;/span&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;RoleRoleCd&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 73.1007%;&quot;&gt;가장 처음 확인하는 경우 By 이후의 전체 단어를 엔티티에 속성에 존재하는지 확인&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 6.12406%; text-align: center;&quot;&gt;2&lt;/td&gt;
&lt;td style=&quot;width: 20.7751%; text-align: center;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;findByRoleRole&lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;Cd&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 73.1007%;&quot;&gt;1번에서 속성을 찾지 못한 경우 오른쪽 끝에서부터 CamelCase 기준으로 왼쪽으로 이동하여 해당 단어가&amp;nbsp;&lt;span style=&quot;color: #333333;&quot;&gt;엔티티에 속성에 존재하는지 확인&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 6.12406%; text-align: center;&quot;&gt;3&lt;/td&gt;
&lt;td style=&quot;width: 20.7751%; text-align: center;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;findByRole&lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;RoleCd&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 73.1007%;&quot;&gt;2번에서 속성을 찾지 못한 경우 2번 단어 에서 다시 CamelCase 기준으로 왼쪽으로 이동하여 해당 단어가 엔티티 속성에 존재하는지 확인&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;즉, 제일 처음 확인하는 경우에는 By 이후 전체 단어를 Entity 속성에서 확인하고 확인에 실패한 경우에는 가장 오른쪽부터 CamelCase 기준으로 나누어 엔티티 속성에 존재하는지 확인하며 다시 확인에 실패하는 경우에는 해당 위치에서 &lt;span style=&quot;color: #333333;&quot;&gt;CamelCase 기준&lt;/span&gt; 왼쪽으로 이동하며 &lt;span style=&quot;color: #333333;&quot;&gt;엔티티 속성에 존재하는지 확인하는 &lt;/span&gt;과정이 존재하는 것임.&lt;/p&gt;
&lt;p&gt;확인해보니 이러한 경우는 &lt;b&gt;T&lt;span style=&quot;color: #000000;&quot;&gt;raversal(순회) &lt;/span&gt;속성&lt;/b&gt;이라고 함.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;이러한 모호성을 구분할 수 있는 방법&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;수동으로 순회 지점을 (_) 밑줄을 이용하여 선언할 수 있음.&lt;/p&gt;
&lt;div class=&quot;colorscripter-code&quot; style=&quot;color: #f0f0f0; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace !important; position: relative !important; overflow: auto;&quot;&gt;
&lt;table class=&quot;colorscripter-code-table&quot; style=&quot;margin: 0; padding: 0; border: none; background-color: #272727; border-radius: 4px;&quot; cellspacing=&quot;0&quot; cellpadding=&quot;0&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;padding: 6px; border-right: 2px solid #4f4f4f;&quot;&gt;
&lt;div style=&quot;margin: 0; padding: 0; word-break: normal; text-align: right; color: #aaa; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace !important; line-height: 130%;&quot;&gt;
&lt;div style=&quot;line-height: 130%;&quot;&gt;1&lt;/div&gt;
&lt;/div&gt;
&lt;/td&gt;
&lt;td style=&quot;padding: 6px 0; text-align: left;&quot;&gt;
&lt;div style=&quot;margin: 0; padding: 0; color: #f0f0f0; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace !important; line-height: 130%;&quot;&gt;
&lt;div style=&quot;padding: 0 6px; white-space: pre; line-height: 130%;&quot;&gt;List&lt;span style=&quot;color: #0086b3;&quot;&gt;&lt;/span&gt;&lt;span style=&quot;color: #ff3399;&quot;&gt;&amp;lt;&lt;/span&gt;UsrEntity&lt;span style=&quot;color: #0086b3;&quot;&gt;&lt;/span&gt;&lt;span style=&quot;color: #ff3399;&quot;&gt;&amp;gt;&lt;/span&gt;&amp;nbsp;findByRole_RoleCd(&lt;span style=&quot;color: #4be6fa;&quot;&gt;String&lt;/span&gt;&amp;nbsp;roleCd);&lt;/div&gt;
&lt;/div&gt;
&lt;/td&gt;
&lt;td style=&quot;vertical-align: bottom; padding: 0 2px 4px 0;&quot;&gt;&lt;a style=&quot;text-decoration: none; color: white;&quot; href=&quot;http://colorscripter.com/info#e&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;&lt;span style=&quot;font-size: 9px; word-break: normal; background-color: #4f4f4f; color: white; border-radius: 10px; padding: 1px;&quot;&gt;cs&lt;/span&gt;&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;</description>
      <category>spring</category>
      <category>Java</category>
      <category>JPA</category>
      <category>spring</category>
      <category>traversal</category>
      <author>jckim</author>
      <guid isPermaLink="true">https://jckim-dev.tistory.com/15</guid>
      <comments>https://jckim-dev.tistory.com/entry/JPA-%EB%A9%94%EC%84%9C%EB%93%9C%EB%AA%85%EC%9C%BC%EB%A1%9C-%EC%BF%BC%EB%A6%AC-%EC%83%9D%EC%84%B1-%EC%9B%90%EB%A6%AC#entry15comment</comments>
      <pubDate>Tue, 6 Oct 2020 00:30:57 +0900</pubDate>
    </item>
    <item>
      <title>[java] SSLException: Received fatal alert: protocol_version 에러 해결</title>
      <link>https://jckim-dev.tistory.com/entry/java-SSLException-Received-fatal-alert-protocolversion-%EC%97%90%EB%9F%AC-%ED%95%B4%EA%B2%B0</link>
      <description>&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;[관련 시리즈]&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;&lt;a href=&quot;https://jckim-dev.tistory.com/14&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;API 운영 중 SSLException 조치하기 1편&lt;/a&gt;&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://jckim-dev.tistory.com/18&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;API 운영 중 SSLException 조치하기 2편&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://jckim-dev.tistory.com/19&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;API 운영 중 SSLException 조치하기 3편&lt;/a&gt;&lt;/li&gt;
&lt;/ul&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;size18&quot;&gt;운영중인 서버에서 타 기관의 API를 호출하여 데이터를 통신하는 부분이 있음.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;여러 기관중 특정 기관에서만 데이터가 들어오지 않는 현상 발생.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;원인분석&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;처음에는 요청하는 기관의 &lt;b&gt;ip 및 port가 열려있는지 여부를 의심&lt;/b&gt;하였지만 확인결과 정상적으로 열려있음을 확인.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;어떤 LOG가 찍히는지 상세하게 확인하기 위해&lt;b&gt; LOG 추가 후 모니터링&lt;/b&gt; 해 본 결과 아래와 같은 에러 메시지가 확인.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;javax.net.ssl.SSLException: Received fatal alert: protocol_version&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;해당 메시지 확인 결과 ssl관련 프로토콜 버전으로 인해 발생한것으로 보임.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;해당기관은 https://로 API를 제공하고 있었음.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;하지만 다른 기관의 https://로 API를 제공하고 있는 데이터는 정상적으로 데이터 수신 확인.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;API를 요청하는 WAS 인스턴스의 JVM https관련 옵션을 확인하였으나 별다른 설정이 선언되어 있지 않았음.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;운영환경은 java7 사용 중이었으며 java7에서는 기본 설정으로 TLSv1.0을 지원.(TLS.v1.1, TLSv1.2, SSLv3.0 까지 지원 가능)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;해당 기관에서는 TLSv1.0 이상의 버전을 사용하는 것으로 판단.&lt;/b&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;해결&amp;nbsp;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;WAS 인스턴스 구동시 JVM 옵션에 아래와 같은 옵션을 추가 설정&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; &amp;nbsp;&lt;b&gt; -Dhttps.protocols=TLSv1,TLSv1.1,TLSv1.2&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;데이터가 정상적으로 수신되는 것 확인.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;JVM 설정 외에도 소스단에서 설정해 주는 방법&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; &amp;nbsp; &lt;b&gt;System.setProperty(&quot;https.protocols&quot;, &quot;TLSv1,TLSv1.1,TLSv1.2&quot;);&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;있지만 사용하는 작업영역이 세분화 되어있기때문에 미적용.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>JAVA</category>
      <category>protocol_version</category>
      <category>SSL</category>
      <category>SSLException</category>
      <category>TLS</category>
      <author>jckim</author>
      <guid isPermaLink="true">https://jckim-dev.tistory.com/14</guid>
      <comments>https://jckim-dev.tistory.com/entry/java-SSLException-Received-fatal-alert-protocolversion-%EC%97%90%EB%9F%AC-%ED%95%B4%EA%B2%B0#entry14comment</comments>
      <pubDate>Sat, 15 Aug 2020 17:19:15 +0900</pubDate>
    </item>
  </channel>
</rss>