<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>blcoding_2023.log</title>
        <link>https://velog.io/</link>
        <description>콜라맘 코딩일기</description>
        <lastBuildDate>Mon, 16 Oct 2023 05:55:33 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>blcoding_2023.log</title>
            <url>https://velog.velcdn.com/images/blcoding_2023/profile/735984f4-50ac-4e6e-8996-571800675983/image.jpg</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. blcoding_2023.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/blcoding_2023" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[컴퓨터의 4가지 핵심 부품]]></title>
            <link>https://velog.io/@blcoding_2023/%ED%98%BC%EA%B3%B5%EC%BB%B4%EC%9A%B4%EC%BB%B4%ED%93%A8%ED%84%B0%EC%9D%98-4%EA%B0%80%EC%A7%80-%ED%95%B5%EC%8B%AC-%EB%B6%80%ED%92%88</link>
            <guid>https://velog.io/@blcoding_2023/%ED%98%BC%EA%B3%B5%EC%BB%B4%EC%9A%B4%EC%BB%B4%ED%93%A8%ED%84%B0%EC%9D%98-4%EA%B0%80%EC%A7%80-%ED%95%B5%EC%8B%AC-%EB%B6%80%ED%92%88</guid>
            <pubDate>Mon, 16 Oct 2023 05:55:33 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/blcoding_2023/post/29abf5e6-eeed-42a3-ab5f-392233e09095/image.png" alt=""></p>
<h1 id="✅-메인보드">✅ 메인보드</h1>
<ul>
<li><strong>현재 실행되는 프로그램</strong>의 명령어와 데이터를 저장하는 부품</li>
<li><strong>프로그램이 실행되기 위해서는 반드시 메모리에 저장되어 있어야 한다</strong></li>
<li>메모리는 현재 실행되는 프로그램의 명령어와 데이터를 저장한다</li>
<li>메모리에 저장된 값의 위치는 <strong>주소</strong>로 알 수 있다</li>
</ul>
<h1 id="✅-cpu">✅ CPU</h1>
<ul>
<li>컴퓨터의 두뇌</li>
<li>메모리에 저장된  명령어를 읽고, 해석하고, 실행하는 부품</li>
<li>산술논리연산장치(ALU), 레지스터, 제어장치로 구성되어 있다</li>
</ul>
<h3 id="🔹-산술논리연산장치alu">🔹 산술논리연산장치(ALU)</h3>
<ul>
<li>계산만을 위해 존재하는 부품</li>
<li>컴퓨터 내부에서 수행되는 대부분의 계산은 ALU가 도맡아 처리한다</li>
</ul>
<h3 id="🔹-레지스터">🔹 레지스터</h3>
<ul>
<li>CPU 내부의 임시저장장치</li>
<li>가격이 비싸고 저장용량이 작다</li>
<li><strong>전원이 꺼지면 저장된 내용을 잃는다</strong></li>
</ul>
<h3 id="🔹-제어장치">🔹 제어장치</h3>
<ul>
<li>제어신호라는 전기신호를 내보내고 명령어를 해석하는 장치</li>
</ul>
<h1 id="✅-보조기억장치">✅ 보조기억장치</h1>
<ul>
<li>전원이 꺼져도 보관될 프로그램을 저장하는 부품</li>
<li>하드디스크, SSD, USB메모리, DVD, CD-ROM 등</li>
<li>보조기억장치는 관점에 따라 입출력장치의 일종으로 볼 수 있다 =&gt; <strong>주변장치</strong>라고 통칭하기도 한다</li>
</ul>
<h1 id="✅-입출력장치">✅ 입출력장치</h1>
<ul>
<li>컴퓨터 외부에 연결되어 컴퓨터 내부와 정보를 교환할 수 있는 부품</li>
<li>마이크, 마우스, 키보드, 프린터 등</li>
</ul>
<h1 id="✅-메인보드마더보드">✅ 메인보드(마더보드)</h1>
<ul>
<li>컴퓨터의 핵심 부품들을 모아 연결하는 판</li>
</ul>
<h1 id="✅-시스템버스">✅ 시스템버스</h1>
<ul>
<li>메인보드에 연결된 네가지 핵심 부품이 서로 정보를 주고받는 통로</li>
<li>주소버스, 데이터버스, 제어버스로 구성되어 있다</li>
<li>주소버스 : 주소를 주고 받는 통로</li>
<li>데이터버스 : 명령어와 데이터를 주고 받는 통로</li>
<li>제어버스 : 제어신호를 주고 받는 통로</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[AJAX]]></title>
            <link>https://velog.io/@blcoding_2023/AJAX</link>
            <guid>https://velog.io/@blcoding_2023/AJAX</guid>
            <pubDate>Tue, 11 Jul 2023 10:26:02 GMT</pubDate>
            <description><![CDATA[<h1 id="🍀-ajaxasync-javascript-and-xml">🍀 AJAX(Async JavaScript and XML)</h1>
<ul>
<li>비동기 자바스크립트와 XML(요즘엔 JSON을 많이 사용)</li>
<li>해당 웹 페이지를 새로고침하지 않고 요청을 보내 응답 받은 내용을 현재 페이지에 반영할 수 있는 문법</li>
<li>웹페이지 전체를 다시 로딩하지 않고도 웹페이지의 일부분만을 갱신할 수 있고 백그라운드 영역에서 서버와 통신하여 그 결과를 웹페이지의 일부분에만 표시할 수 있다</li>
<li>주로 @RestController에 요청을 보내 데이터만 가져와서 활용하는 방식으로 사용한다</li>
<li>서버로부터 데이터를 응답받을 때 마다 이벤트가 발생하고 해당 이벤트를 처리하여 사용한다</li>
</ul>
<hr>
<h1 id="🍀-xmlhttprequest">🍀 XMLHttpRequest</h1>
<ul>
<li>자바스크립트의 <strong>비동기 통신 요청 객체(AJAX 요청 객체)</strong></li>
<li>요청을 보내도 페이지가 새로고침되지 않는다</li>
<li>인스턴스를 생성한 후 해당 인스턴스에 여러 설정을 한 뒤 요청을 보낸다</li>
<li>웹 브라우저가 서버와 데이터를 교환할 때 사용한다(웹 브라우저가 백그라운드에서 서버와 계속 통신할 수 있는 이유)</li>
</ul>
<hr>
<h1 id="🍀-서버에-요청request하기">🍀 서버에 요청(request)하기</h1>
<h2 id="🌼-openmethod-url-메소드">🌼 open(method, url) 메소드</h2>
<ul>
<li>서버로 보낼 ajax 요청의 형식을 설정</li>
<li>첫 번째 파라미터에는 요청 방식을 설정(GET, POST 방식 중 하나 선택, 이외의 메서드(PUT, DELETE)는 xhttp로만 보낼 수 있다(form으로는 못보냄))</li>
<li>두 번째 파라미터에는 요청 URL을 설정한다</li>
</ul>
<h2 id="🌼-send-메소드">🌼 send() 메소드</h2>
<ul>
<li>작성된 ajax 요청을 서버로 전달한다</li>
<li>전달방식에 따라 인수를 가질수도, 안가질수도 있다(GET방식의 경우는 url로 파라미터를 넘겨주지만 POST인 경우에는 send()에 파라미터를 실어서 넘겨줘야 한다)</li>
</ul>
<p><em>※ AJAX에서는 주로 GET방식 보다는 POST방식을 사용하여 요청을 전송한다</em></p>
<hr>
<h1 id="🍀-서버에-응답response하기">🍀 서버에 응답(response)하기</h1>
<h2 id="🌼-readystate">🌼 readyState</h2>
<ul>
<li>XMLHttpRequest 객체의 현재 상태를 나타낸다</li>
<li>객체의 현재 상태에 따라 값이 변화한다</li>
</ul>
<blockquote>
<pre><code>    1. UNSENT(숫자 0) : XMLHttpRequest 객체가 생성됨
    2. OPENED(숫자 1) : open()메서드가 성공적으로 실행됨
    3. HEADERS_RECEIVED(숫자 2) : 모든 요청에 대한 응답이 도착
    4. LOADING(숫자 3) : 요청한 데이터를 처리중
    5. DONE(숫자 4) : 요청한 데이터의 처리가 완료되어 응답할 준비가 완료됨</code></pre></blockquote>
<h2 id="🌼-status">🌼 status</h2>
<ul>
<li>서버의 문서상태를 나타낸다(HTTP 상태코드)</li>
</ul>
<blockquote>
<pre><code></code></pre></blockquote>
<ul>
<li>1xx : 조건부 응답</li>
<li>2xx : 성공(서버에 문서가 존재함)</li>
<li>3xx : 리다이렉션 완료</li>
<li>4xx : 요청 오류 (404- 서버에 문서가 존재하지 않음)</li>
<li>5xx : 서버 오류</li>
</ul>
<h2 id="🌼-onreadystatechange">🌼 onreadystatechange</h2>
<ul>
<li><p>XMLHttpRequest 객체의 readyState 프로퍼티 값이 변할 때 마다 호출되는 이벤트</p>
</li>
<li><p>서버에서 응답이 도착할 때까지 readyState프로퍼티 값의 변화에 따라 총 5번 호출된다</p>
</li>
<li><p>이 프로퍼티를 이용하면 서버에 요청한 데이터가 존재하고, 서버로부터 응답이 도착하는 순간을 특정할 수 있다</p>
</li>
<li><p><strong>readyState 0</strong> : XMLHttpRequest 객체가 생성되었을 때</p>
</li>
<li><p><strong>readyState 1</strong> : open()이 성공했을 때 (send()하기 전)</p>
</li>
<li><p><strong>readyState 2</strong> : 요청에 대한 응답이 도착했을 때</p>
</li>
<li><p><strong>readyState 3</strong> : 응답에 대한 처리를 시작했을 때</p>
</li>
<li><p><strong>readyState 4</strong> : 응답에 대한 처리가 모두 끝났을 때</p>
</li>
</ul>
<h1 id="🍀-서버로부터의-응답-데이터-확인하기">🍀 서버로부터의 응답 데이터 확인하기</h1>
<h2 id="🌼-responsetext">🌼 responseText</h2>
<ul>
<li>서버에 요청하여 응답받은 데이터를 문자열로 반환한다</li>
<li>서버로부터 텍스트파일을 응답받은 경우에는 responseText를 사용하여 받은 데이터를 문자열로 반환한 후 사용할 수 있다</li>
</ul>
<h2 id="🌼-responsexml">🌼 responseXML</h2>
<ul>
<li>서버에 요청하여 응답받은 데이터를 XML DOM 객체로 반환한다</li>
<li>이방법은 잘 안쓴다 ,,, (귀찮음)</li>
</ul>
<hr>
<h1 id="🍀-httpheader">🍀 HttpHeader</h1>
<ul>
<li>클라이언트와 서버 사이의 통신시 서로에게 전달해야 할 여러 데이터를 포함한다</li>
<li>AJAX를 사용하여 Http요청 헤더를 직접 설정하거나 Http응답 헤더의 내용을 직접 확인할 수도 있다</li>
<li>요청을 보내기 전에 setRequestHeader()메서드를 사용하여 Http요청 헤더를 작성할 수 있다</li>
</ul>
<h2 id="🌼-httprequestheadername-value">🌼 HttpRequestHeader(name, value)</h2>
<ul>
<li>요청을 보내기 전에 setRequestHeader()메서드를 사용하여 Http요청 헤더를 작성할 수 있다</li>
<li>name은 Http요청 헤더에 포함하고자 하는 헤더의 이름이며, 값도 함께 전달한다<h2 id="🌼-httpresponseheader">🌼 HttpResponseHeader</h2>
</li>
<li>서버로 부터 전달받은 Http응답 헤더 내용을 메서드를 이용하여 확인할 수 있다 </li>
<li><strong>getAllResponseHeaders()</strong> : Http응답 헤더의 모든 헤더를 문자열로 반환한다 </li>
<li><strong>getResponseHeader()</strong> : Http응답 헤더 중 인수로 전달받은 이름과 일치하는 헤더의 값을 문자열로 반환한다</li>
</ul>
<h2 id="🌼-content-type">🌼 Content-Type</h2>
<ul>
<li>요청 또는 응답의 데이터가 어떤 형식인지 판단</li>
<li>자원의 형식(Media Type)을 명시하기 위해 헤더에 실려서 전송된다</li>
<li>기본값은 html문서의 MIME타입인 &quot;text/html&quot;이다 </li>
</ul>
<hr>
<h4 id="📚-참고자료">📚 참고자료</h4>
<p>✅ <a href="https://velog.io/@startin1229/Ajax-%EC%82%AC%EC%9A%A9%EB%B2%95">Ajax_사용법</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[에러 페이지 처리하기]]></title>
            <link>https://velog.io/@blcoding_2023/%EC%97%90%EB%9F%AC-%ED%8E%98%EC%9D%B4%EC%A7%80-%EC%B2%98%EB%A6%AC%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@blcoding_2023/%EC%97%90%EB%9F%AC-%ED%8E%98%EC%9D%B4%EC%A7%80-%EC%B2%98%EB%A6%AC%ED%95%98%EA%B8%B0</guid>
            <pubDate>Tue, 11 Jul 2023 01:25:56 GMT</pubDate>
            <description><![CDATA[<h1 id="webxml에-다음과-같이-에러페이지를-등록할-수-있다">web.xml에 다음과 같이 에러페이지를 등록할 수 있다</h1>
<ul>
<li>해당 에러코드 발생시 포워드가 아니라 리다이렉트 처리이므로 컨트롤러에서 별도 처리가 필요하다<blockquote>
<pre><code></code></pre></blockquote>
<!-- 404 에러에 대한 처리 등록 -->
<error-page>
  <error-code>404</error-code>
  <location>/error/notfound</location>
</error-page>

</li>
</ul>
<h1 id="에러-처리-컨트롤러">에러 처리 컨트롤러</h1>
<p>```java
 @RequestMapping(&quot;/error&quot;)
@Controller
public class ErrorController {</p>
<pre><code>@GetMapping(&quot;/notfound&quot;)
void notFound() {

}</code></pre><p>}</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[REST API]]></title>
            <link>https://velog.io/@blcoding_2023/REST-API</link>
            <guid>https://velog.io/@blcoding_2023/REST-API</guid>
            <pubDate>Mon, 10 Jul 2023 03:42:13 GMT</pubDate>
            <description><![CDATA[<h1 id="🍀-rest">🍀 REST</h1>
<ul>
<li>HTTP URI로 해당 자원을 식별하고 HTTP method로 해당 자원에 대한 CRUD를 구분하여 자원만 응답하는 방식</li>
<li>HTML 뷰 페이지가 아닌 자원만 응답하기 때문에 웹 브라우저가 아닌 프로그램에서도 서버를 활용할 수 있다는 장점이 있다</li>
<li><strong>Create, Insert(POST method)</strong>     POST:/employee - 새 사원을 추가한다</li>
<li><strong>Read, Select(GET method)</strong>        GET:/employee/105 - 105번 사원을 조회한다</li>
<li>*<em>Update (PUT method)    *</em>        PUT:/employee/183 - 183번 사원을 수정한다</li>
<li><strong>Delete (DELETE method)</strong>        DELETE:/employee/170 - 170번 사원을 삭제한다</li>
</ul>
<hr>
<h1 id="🍀-spring-rest">🍀 Spring REST</h1>
<ul>
<li><strong>@RestController</strong> : 해당 클래스가 RestController임을 표시</li>
<li><strong>@ResponseBody</strong> : 해당 메서드가 뷰 페이지 대신 데이터를 응답한다는 것을 표시</li>
<li><strong>@RequestBody</strong> : 요청에 실려온 데이터를 바인딩해주는 어노테이션</li>
<li><strong>@PathVariable</strong> : 요청 URI의 일부분을 변수의 값으로 활용할 수 있다(일반 컨트롤러에서도 사용 가능)</li>
</ul>
<hr>
<h1 id="🍀-restcontroller">🍀 @RestController</h1>
<ul>
<li>일반 컨트롤러와 다르게 다음 뷰를 가리키는 대신 데이터를 응답한다</li>
<li>컨트롤러 내부 메서드의 리턴타입은 뷰를 찾아가는 방식이 아니라 사용자에게 응답할 데이터의 타입을 의미한다</li>
<li>주로 JSON방식 또는 XML형식으로 응답하게 된다</li>
</ul>
<hr>
<h1 id="🍀-jackson-databind와-jackson-dataformat-xml">🍀 jackson-databind와 jackson-dataformat-xml</h1>
<ul>
<li>@RestController에서 자바빈 객체를 리턴하면 알아서 JSON(또는 XML)형식으로 변환해 응답해주는 라이브러리</li>
<li><a href="https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind/2.15.2">jackson-databind</a>와 <a href="https://mvnrepository.com/artifact/com.fasterxml.jackson.dataformat/jackson-dataformat-xml/2.15.2">jackson-dataformat-xml</a>의 Maven을 복사하여 pom.xml에 붙여넣기(아래 내용 복사해도 됨)</li>
</ul>
<blockquote>
<pre><code>&lt;dependency&gt;
    &lt;groupId&gt;com.fasterxml.jackson.core&lt;/groupId&gt;
    &lt;artifactId&gt;jackson-databind&lt;/artifactId&gt;
    &lt;version&gt;2.15.2&lt;/version&gt;
&lt;/dependency&gt;
&lt;dependency&gt;
    &lt;groupId&gt;com.fasterxml.jackson.dataformat&lt;/groupId&gt;
    &lt;artifactId&gt;jackson-dataformat-xml&lt;/artifactId&gt;
    &lt;version&gt;2.15.2&lt;/version&gt;
&lt;/dependency&gt;</code></pre></blockquote>
<hr>
<h2 id="🌼-restcontroller에서-사용하기">🌼 RestController에서 사용하기</h2>
<h3 id="🌱-json형식으로-변환하기">🌱 json형식으로 변환하기</h3>
<pre><code class="language-java">@RequestMapping(&quot;/restful&quot;)
@Log4j
@RestController
public class RestSampleController {
    @GetMapping(value=&quot;/employee/json&quot;, produces = MediaType.APPLICATION_JSON_VALUE)
    public Employee emp1() {
        Employee e = new Employee();
        e.setFirst_name(&quot;철수&quot;);
        e.setLast_name(&quot;김&quot;);
        e.setSalary(5000);
        return e;
    }
}</code></pre>
<p>** 📺 출력 결과 &gt;&gt; **
<img src="https://velog.velcdn.com/images/blcoding_2023/post/286cfe68-6253-40d6-a380-01b5ccc8d6ad/image.png" alt=""></p>
<h3 id="🌱-xml형식으로-변환하기">🌱 xml형식으로 변환하기</h3>
<pre><code class="language-java">@RequestMapping(&quot;/restful&quot;)
@Log4j
@RestController
public class RestSampleController {
    @GetMapping(value=&quot;/employee/xml&quot;, produces = MediaType.APPLICATION_XML_VALUE)
    public Employee emp2() {
        Employee e = new Employee();
        e.setFirst_name(&quot;철수&quot;);
        e.setLast_name(&quot;김&quot;);
        e.setSalary(5000);
        return e;
    }
}
</code></pre>
<p>** 📺 출력 결과 &gt;&gt; **
<img src="https://velog.velcdn.com/images/blcoding_2023/post/70888e13-3884-4225-9845-14dc82e5d4c2/image.png" alt=""></p>
<hr>
<h4 id="📚-참고자료">📚 참고자료</h4>
<p><a href="https://velog.io/@dnjscksdn98/REST-REST-API-RESTful%EC%97%90-%EB%8C%80%ED%95%98%EC%97%AC">restful api</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[JSON]]></title>
            <link>https://velog.io/@blcoding_2023/JSON</link>
            <guid>https://velog.io/@blcoding_2023/JSON</guid>
            <pubDate>Mon, 10 Jul 2023 03:41:38 GMT</pubDate>
            <description><![CDATA[<h1 id="🍀-json">🍀 JSON</h1>
<ul>
<li>JavaScript Object Notation</li>
<li>언제든지 자바스크립트 오브젝트로 변환할 수 있는 문자열 형식</li>
<li>다양한 언어들의 객체로 변환하기에도 편리하기 때문에 객체들의 공용어로 활용되고 있다</li>
<li>속성-값 쌍으로 구성되어있다</li>
<li>특정 언어에 종속되어있지 않은 공통 규격</li>
</ul>
<h2 id="🌼-jsonobject">🌼 JSONObject</h2>
<ul>
<li>자바의 Map처럼 사용할 수 있는 객체</li>
<li>해당 객체에 값들을 추가 한 후에 toJSONString()을 호출하여 JSON 형식의 문자열을 얻을 수 있다</li>
<li>자바의 기본 배열은 값으로 사용할 수 없다</li>
<li>배열을 값으로 추가할 때는 List(또는 JSONArray)로 추가하면 된다</li>
<li>객체를 값으로 추가할 때는 Map(또는 JSONObject)으로 추가할 수 있다</li>
</ul>
<h2 id="🌼-jsonparser">🌼 JSONParser</h2>
<ul>
<li>JSON 형식 문자열을 JSONObject로 변환하는 기능을 가진 클래스</li>
<li>문자열로 전달하거나 Reader를 전달하여 사용할 수 있다</li>
</ul>
<hr>
<h1 id="🍀-자바에서-json을-사용하기">🍀 자바에서 JSON을 사용하기</h1>
<ol>
<li>의존성 주입</li>
</ol>
<ul>
<li><a href="https://mvnrepository.com/artifact/com.googlecode.json-simple/json-simple/1.1.1">json-simple</a>에서 maven을 복사해서 pom.xml에 붙여넣기(아래내용을 붙여넣어도 됨)<blockquote>
<pre><code>&lt;dependency&gt;
      &lt;groupId&gt;com.googlecode.json-simple&lt;/groupId&gt;
      &lt;artifactId&gt;json-simple&lt;/artifactId&gt;
      &lt;version&gt;1.1.1&lt;/version&gt;
&lt;/dependency&gt;</code></pre></blockquote>
</li>
</ul>
<ol start="2">
<li>JSON 객체를 생성하여 사용하기</li>
</ol>
<ul>
<li><p>자바의 Map을 바로 JSON 형태 문자열로 변환해준다</p>
</li>
<li><p>자바스크립트에 배열로 전달하고 싶을 때는 List를 사용한다</p>
</li>
<li><p>객체 내부에 객체를 넣을 수 있다</p>
<pre><code class="language-java">public class SimpleJsonTest {
  public static void main(String[] args) {
      //JSON객체 생성
      JSONObject obj = new JSONObject();

      obj.put(&quot;name&quot;, &quot;홍길동&quot;);
      obj.put(&quot;age&quot;, 40);
      // JSON으로 생성한 객체 출력
      System.out.println(obj);

      Map&lt;String, Object&gt; map = new HashMap&lt;&gt;();
      List&lt;String&gt; hobbies = new ArrayList&lt;&gt;();
      Map&lt;String, Object&gt; car = new HashMap&lt;&gt;();

      car.put(&quot;carName&quot;, &quot;스포티지&quot;);
      car.put(&quot;carNumber&quot;, &quot;12가3456&quot;);
      car.put(&quot;carAge&quot;, 8);

      hobbies.add(&quot;농구&quot;);
      hobbies.add(&quot;야구&quot;);
      hobbies.add(&quot;발야구&quot;);

      map.put(&quot;name&quot;, &quot;임꺽정&quot;);
      map.put(&quot;phone&quot;, &quot;123-1234-1234&quot;);
      map.put(&quot;age&quot;, 33);
      map.put(&quot;hobby&quot;, hobbies);
      map.put(&quot;car&quot;, car);

      // map을 JSON으로 변환하여 출력
      System.out.println(new JSONObject(map));
  }
</code></pre>
</li>
</ul>
<p>}</p>
<pre><code>** 📺 출력 결과 &gt;&gt; ** 
![](https://velog.velcdn.com/images/blcoding_2023/post/92087335-8ec7-4e99-aac3-bfb6c6fdc43c/image.png)

---
# 🍀 자바스크립트에서 JSON 사용하기
## 🌼 JSON.stringify()
&gt;```js
JSON.stringify(value);

+ 인수로 전달받은 자바스크립트 객체를 문자열로 변환하여 반환한다
+ value에는 변환할 자바스크립트 객체를 전달한다
+ 이 메서드는 UTF-16으로 인코딩된 JSON형식의 문자열을 반환한다

## 🌼 JSON.parse()
&gt;```js
JSON.parse(text);

+ 인수로 전달받은 문자열을 자바스크립트 객체로 변환하여 반환한다
+ text에는 변환할 문자열을 전달한다(text는 유효한 JSON형식의 문자열이여야 함)

---
# 🍀 JSON과 JavaScript Object의 차이점
- JavaScript Object는 문자열 값 또는 key에 &quot;&quot;를 생략할 수 있지만 JSON은 반드시 써야한다
- JavaScript Object는 문자열 값 또는 key에 &#39;&#39;를 쓸 수 있지만 JSON은 &quot;&quot;만 써야한다
- JSON은 문자열 형식의 이름이고 JavaScript Object는 자바스크립트의 인스턴스이다 
---

# 🍀 JSON의 활용
- RestController에서 데이터 application/json 형식으로 응답할 때 사용한다
- JSON 형식의 문자열을 받은 웹 페이지에서 해당 값을 JavaScript Object로 변환하여 페이지 구성에 활용할 수 있다
- 요청시 JSON 형식으로 데이터를 보내 DB에 반영하는 것도 가능하다 (자주 쓰는 방법은 아님)

## 🌼 Parsing 
+ JSON 형식 문자열 -&gt; JSONObject로 만들기

```java
public class SimpleJsonTest {

    public static void main(String[] args) {
        JSONParser parser = new JSONParser();

        try {
            JSONObject parsed = (JSONObject)parser.parse(
                    &quot;{\&quot;fruit\&quot;:\&quot;apple\&quot;,\&quot;drink\&quot;:\&quot;ade\&quot;&quot;
                    + &quot;\&quot;flavor\&quot;:[3,5,6,11]}&quot;);

            System.out.println(&quot;JSON 문자열로 객체 만들어서 자바에서 활용하기&quot;);
            System.out.println(parsed.get(&quot;fruit&quot;));
            System.out.println(parsed.get(&quot;drink&quot;));

            List&lt;Integer&gt; flavorNums = (List&lt;Integer&gt;)parsed.get(&quot;flavor&quot;);

            for(int i = 0; i &lt; flavorNums.size(); i++) {
                System.out.println(&quot;flavor[&quot;+i+&quot;] : &quot; + flavorNums.get(i));

            }
        } catch (ParseException e) {
            e.printStackTrace();
        }
    }
}</code></pre><p>** 📺 출력 결과 &gt;&gt; ** 
<img src="https://velog.velcdn.com/images/blcoding_2023/post/742c2a02-ce49-4609-aacf-3e25c32f0154/image.png" alt=""></p>
<hr>
<h4 id="📚-참고자료">📚 참고자료</h4>
<ul>
<li>✅ <a href="https://developer.mozilla.org/ko/docs/Learn/JavaScript/Objects/JSON">mdn공식문서</a></li>
<li>✅ <a href="http://www.tcpschool.com/json/intro">JSON</a></li>
<li>✅ <a href="https://cheershennah.tistory.com/179">RequestBody란?</a></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[프로젝트 계층 분리]]></title>
            <link>https://velog.io/@blcoding_2023/%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%EA%B3%84%EC%B8%B5-%EB%B6%84%EB%A6%AC</link>
            <guid>https://velog.io/@blcoding_2023/%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%EA%B3%84%EC%B8%B5-%EB%B6%84%EB%A6%AC</guid>
            <pubDate>Fri, 07 Jul 2023 04:42:20 GMT</pubDate>
            <description><![CDATA[<h1 id="🍀-프로젝트-계층">🍀 프로젝트 계층</h1>
<ul>
<li>프로젝트를 구성하는 소스코드들을 계층별로 분리한 것</li>
<li>화면 계층(Presentation Layer)</li>
<li>비즈니스 계층(Business Layer)</li>
<li>영속 계층(Persistence Layer)</li>
</ul>
<h2 id="🌼-화면-계층">🌼 화면 계층</h2>
<ul>
<li>화면에 보이는 코드를 작성하는 계층</li>
<li>하나의 요청이 여러개의 비즈니스 로직을 요구하거나 하나의 비즈니스 로직이 여러 요청에서 사용되는 경우가 있기 때문에 
계층의 분리가 필요하다</li>
</ul>
<h2 id="🌼-영속-계층">🌼 영속 계층</h2>
<ul>
<li>저장되어 있는 데이터를 꺼내오는 작업을 구현하는 계층</li>
<li>하나의 비즈니스 로직이 데이터에 여러번 접근해야 하는 경우와 하나의 데이터가 여러 비즈니스로직에 사용되는 경우가 있기 때문에
계층의 분리가 필요하다</li>
</ul>
<hr>
<h1 id="🍀-스프링-웹-프로젝트에서-각-계층에-대한-클래스-이름-규칙">🍀 스프링 웹 프로젝트에서 각 계층에 대한 클래스 이름 규칙</h1>
<ul>
<li><strong>비즈니스 로직</strong>: xxxService(인터페이스), xxxServiceImpl(인터페이스 구현)</li>
<li><strong>영속 계층</strong> : xxxMapper(Mybatis), xxxDao, xxxRepository(저장소, DB에 데이터를 저장하거나 꺼내는 역할을 하는 클래스들)</li>
<li><strong>데이터 클래스</strong> : xxxVO(Getter만 붙은 읽기 전용(느낌) xxxDTO(Getter/Setter 보유) </li>
</ul>
<hr>
<h1 id="🍀-웹-프로젝트에서-패키지를-나누는-방식">🍀 웹 프로젝트에서 패키지를 나누는 방식</h1>
<h2 id="🌼-프로젝트-규모가-작은-경우">🌼 프로젝트 규모가 작은 경우</h2>
<ul>
<li>컨트롤러, 비즈니스 계층, 영속 계층, DTO를 구분할 수 있도록 패키지를 작성한다<blockquote>
<pre><code>ex&gt; com.company.bookstore.controller.BookListController
 com.company.bookstore.controller.PurchaseController
 com.company.bookstore.service.BookListService
 com.company.bookstore.service.PurchaseService
 com.company.bookstore.mapper.BookListMapper
 com.company.bookstore.dto.BookDTO</code></pre></blockquote>
</li>
</ul>
<h2 id="🌼-프로젝트-규모가-큰-경우">🌼 프로젝트 규모가 큰 경우</h2>
<ul>
<li>우선 비즈니스 단위별로 패키지 구분을 한 뒤 다시 내부에서 각 계층을 구분한다<blockquote>
<p>```
ex&gt; com.company.bookstore.booklist.controller.IndexController
  com.company.bookstore.booklist.controller.BookDetailController
  com.company.bookstore.booklist.service.IndexService
  com.company.bookstore.membership.controller.RegisterController
  com.company.bookstore.membership.controller.MypageController</p>
</blockquote>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[Log4jdbc]]></title>
            <link>https://velog.io/@blcoding_2023/Log4jdbc</link>
            <guid>https://velog.io/@blcoding_2023/Log4jdbc</guid>
            <pubDate>Fri, 07 Jul 2023 04:38:46 GMT</pubDate>
            <description><![CDATA[<h1 id="🍀-log4jdbc">🍀 Log4jdbc</h1>
<ul>
<li>JDBC에서 발생하는 작업들을 로그로 찍어주는 라이브러리</li>
<li>디버깅이 매우 수월해진다</li>
</ul>
<h2 id="🌼-적용순서">🌼 적용순서</h2>
<h3 id="1-pomxml에-등록">1. pom.xml에 등록</h3>
<ul>
<li><a href="https://mvnrepository.com/artifact/org.bgee.log4jdbc-log4j2/log4jdbc-log4j2-jdbc4.1/1.16">log4jdbc</a>에서 Maven을 복사해도 됨</li>
<li>아래 내용을 복봍해도 됨</li>
</ul>
<blockquote>
<pre><code>&lt;dependency&gt;</code></pre></blockquote>
<!-- https://mvnrepository.com/artifact/org.bgee.log4jdbc-log4j2/log4jdbc-log4j2-jdbc4.1 -->
<pre><code>&lt;groupId&gt;org.bgee.log4jdbc-log4j2&lt;/groupId&gt;
&lt;artifactId&gt;log4jdbc-log4j2-jdbc4.1&lt;/artifactId&gt;
&lt;version&gt;1.16&lt;/version&gt;</code></pre></dependency>


<h3 id="2-root-context에-jdbcurl-driverclassname-변경">2. root-context에 jdbcUrl, driverClassName 변경</h3>
<blockquote>
<pre><code>&lt;property name=&quot;driverClassName&quot; value=&quot;net.sf.log4jdbc.sql.jdbcapi.DriverSpy&quot;/&gt;
&lt;property name=&quot;jdbcUrl&quot; value=&quot;jdbc:log4jdbc:oracle:thin:@localhost:1521:XE&quot;/&gt;</code></pre></blockquote>
<pre><code>
### 3. resources에 log4jdbc.log4j2.properties 파일 추가
&gt;```
파일명 : log4jdbc.log4j2.properties
파일내용 : log4jdbc.spylogdelegator.name=net.sf.log4jdbc.log.slf4j.Slf4jSpyLogDelegator</code></pre><h3 id="4-log4jxml에-logger-추가">4. log4j.xml에 logger 추가</h3>
<blockquote>
<pre><code></code></pre></blockquote>
<!-- Log4jdbc Loggers -->
<logger name="jdbc.sqltiming">
    <level value="info" />
</logger>
<logger name="jdbc.resultsettable">
    <level value="info" />
</logger>
```

<ul>
<li><strong>jdbc.sqlonly</strong>     : 실행하는 SQL문을 출력한다</li>
<li><strong>jdbc.sqltiming</strong>    : 실행하는 SQL문과 실행하는데 걸린 시간을 출력한다</li>
<li><strong>jdbc.audit</strong>        : ResultSet을 제외한 모든 JDBC 실행 과정을 출력한다</li>
<li><strong>jdbc.resultset</strong>    : 모든 ResultSet의 실행 과정을 출력한다</li>
<li><strong>jdbc.resultsettable</strong> : 쿼리 실행 결과를 표로 출력해준다, 로깅 레벨을 debug로 설정하면 읽히지 않았던 값들도 모두 출력해준다</li>
<li><strong>jdbc.connection</strong>    : jdbc connetion을 생성하고 닫는 과정을 출력한다, 메모리 누수(close를 하지 않아서 발생하는 문제)를 해결할 때 사용한다</li>
</ul>
<hr>
<p>🚀 <a href="https://log4jdbc.brunorozendo.com/">log4jdbc 공식 페이지로 바로가기</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[MyBatis]]></title>
            <link>https://velog.io/@blcoding_2023/MyBatis</link>
            <guid>https://velog.io/@blcoding_2023/MyBatis</guid>
            <pubDate>Thu, 06 Jul 2023 00:59:09 GMT</pubDate>
            <description><![CDATA[<h1 id="🍀-mybatis">🍀 Mybatis</h1>
<ul>
<li>쿼리문만 적으면 알아서 DB에서 데이터를 꺼내오는 프레임워크</li>
<li>거의 모든 jdbc관련 코드를 자동으로 생성해준다</li>
<li>개발자는 사용할 쿼리문과 종류만 선택하면 된다</li>
</ul>
<h2 id="🌼-필요한-의존성들">🌼 필요한 의존성들</h2>
<ul>
<li>mybatis</li>
<li>mybatis-spring</li>
<li>spring-jdbc</li>
</ul>
<h2 id="🌼-의존성-주입하기">🌼 의존성 주입하기</h2>
<ul>
<li><p><a href="https://mvnrepository.com/artifact/org.mybatis/mybatis/3.5.13">mybatis</a></p>
</li>
<li><p><a href="https://mvnrepository.com/artifact/org.mybatis/mybatis-spring/2.0.7">mybatis_spring</a></p>
</li>
<li><p><a href="https://mvnrepository.com/artifact/org.springframework/spring-jdbc/5.2.24.RELEASE">spring_jdbc</a> (스프링과 같은 버전 가져오기)</p>
</li>
<li><p>위 링크에서 Maven을 복사하여 pom.xml에 붙여 넣기
<img src="https://velog.velcdn.com/images/blcoding_2023/post/9433cb3f-3897-438c-b219-2c858f97dd53/image.png" alt=""></p>
</li>
</ul>
<h2 id="🌼-적용-순서">🌼 적용 순서</h2>
<ol>
<li><p>DBCP로 DataSource 객체를 생성한다 (HikariDataSource)</p>
</li>
<li><p>생성한 DataSource 객체를 전달해 SqlSessionFactoryBean 객체를 생성한다
(컨텍스트 상에 생성한 sqlSessionFactory가 있으면 mybatis가 알아서 필요할 때 가져다 사용한다)</p>
<pre><code> &lt;bean id=&quot;hikariDataSource&quot; class=&quot;com.zaxxer.hikari.HikariDataSource&quot;&gt;
     &lt;constructor-arg ref=&quot;hikariConfig&quot;&gt;&lt;/constructor-arg&gt;
 &lt;/bean&gt;</code></pre></li>
<li><p>root-context의 Namespace에서 mybatis 체크(여기서 체크하면 임포트하는것과 같은 효과가 있다, 직접 임포트해도되고 여기서 체크해도됨)
<img src="https://velog.velcdn.com/images/blcoding_2023/post/8471744f-c641-4ccf-b20e-8bc98c58da63/image.png" alt=""></p>
</li>
<li><p>mybatis-spring:scan 기능을 통해 패키지의 위치를 지정한다</p>
<pre><code> &lt;mybatis-spring:scan base-package=&quot;com.ezen.springdatabase.mapper&quot;/&gt;</code></pre></li>
</ol>
<hr>
<h1 id="🍀-mapper">🍀 Mapper</h1>
<ul>
<li>Mybatis에 Mapper 인터페이스를 등록하면 해당 Mapper의 정보를 통해 자동으로 메서드를 생성해준다 (내가 설정해야하는 것 : 리턴 타입, 쿼리문, 쿼리문 타입) </li>
<li>어노테이션 방식의 Mapper와 XML방식의 Mapper가 있다</li>
</ul>
<hr>
<h2 id="🌼-어노테이션-방식-mapper">🌼 어노테이션 방식 Mapper</h2>
<h3 id="🌱-어노테이션-종류">🌱 어노테이션 종류</h3>
<ul>
<li>@Select(query)</li>
<li>@Insert(query)</li>
<li>@Delete(query)</li>
<li>@Update(query)</li>
</ul>
<h3 id="🌱-사용방법">🌱 사용방법</h3>
<ul>
<li>@Select로 조회하는 데이터가 여러 행인경우 List 타입으로 리턴해준다</li>
<li>@Select로 조회하는 데이터가 한 행인 경우 해당 DTO 타입으로 리턴해준다</li>
<li>쿼리문에 파라미터가 필요한 경우 #{name}로 사용하고 @Param(&quot;name&quot;)으로 지정해준다</li>
<li>@Insert, @Update, @Delete는 업데이트 된 행을 리턴하므로 정수 타입으로 리턴해준다</li>
<li>@Insert, @Update시에 파라미터를 자바빈 데이터 클래스 형식(DTO)으로 넘기면 파라미터에 #{property}를 사용할 수 있다</li>
</ul>
<hr>
<h1 id="🍀-xml-방식-mapper">🍀 XML 방식 Mapper</h1>
<h2 id="🌼-사용방법">🌼 사용방법</h2>
<ol>
<li>Mapper Interface를 생성한다(메서드만 정의하고 어노테이션은 사용하지 않는다) </li>
<li>resources 밑에 해당 Mapper가 속한 패키지의 경로대로 폴더를 생성한다(폴더를 하나씩 생성하는 것이 좋다)</li>
<li>해당 폴더에 같은 이름의 Mapper.xml을 생성한다</li>
<li>xml의 형식은 <a href="https://mybatis.org/mybatis-3/getting-started.html">mybatis의 공식 페이지</a>를 참조한다</li>
</ol>
<hr>
<p><strong><a href="https://mybatis.org/mybatis-3/">🚀 mybatis_공식페이지 바로가기</a></strong></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Controller]]></title>
            <link>https://velog.io/@blcoding_2023/Controller</link>
            <guid>https://velog.io/@blcoding_2023/Controller</guid>
            <pubDate>Tue, 04 Jul 2023 05:57:43 GMT</pubDate>
            <description><![CDATA[<h1 id="🍀-mvc-디자인-패턴">🍀 MVC 디자인 패턴</h1>
<ul>
<li>프로그램을 효율적으로 개발하기 위해서 각 코드를 3가지로 구분하여 개발을 진행하고자 하는 디자인 패턴</li>
<li>프로그램의 비즈니스 로직과 화면을 구분하는데에 초점을 맞춘 디자인 패턴</li>
<li><strong>Model, View, Controller</strong> 세 가지로 나뉜다</li>
<li><strong>Model</strong> : 데이터의 형태를 표현하기 위한 용도의 코드</li>
<li><strong>View</strong> : 사용자에게 보여지는 화면을 꾸미기 위한 용도의 코드(Swing, html, css, js, jsp, ...)</li>
<li><strong>Controller</strong> : 요청을 받으면 어떤 서비스를 거쳐(비즈니스로직) 어떤 뷰로 가야할지를 결정하는 코드</li>
</ul>
<h1 id="🍀-controller">🍀 @Controller</h1>
<ul>
<li>해당 클래스가 MVC패턴 중 Controller임을 표시하는 어노테이션</li>
<li>spring-context가 자동으로 수거해 알아서 사용한다</li>
<li>어떤 요청 uri + method로 어떤 처리를 하고 어떤 뷰로 가야하는지를 정의하는 곳이다</li>
<li>다른 uri에서 같은 처리를 진행할 수도 있으므로 컨트롤러에서 비즈니스 로직을 구현하는 것은 바람직하지 않다</li>
</ul>
<hr>
<h2 id="🌼-컨트롤러에서-자동으로-받을-수-있는-인자값들">🌼 컨트롤러에서 자동으로 받을 수 있는 인자값들</h2>
<p><strong>1. HttpServletRequest</strong></p>
<ul>
<li>컨트롤러에서 JSP의 request객체를 받아서 사용할 수 있다</li>
</ul>
<p><strong>2. HttpServletResoponse</strong></p>
<ul>
<li>컨트롤러에서 JSP의 response 객체를 받아서 사용할 수 있다</li>
</ul>
<p><strong>3. 자바빈 형태의 모델 객체</strong></p>
<ul>
<li>파라미터의 이름과 모델 객체의 필드명이 동일하다면 값을 바인딩해준다</li>
<li>심지어, 데이터 타입도 알아서 변환해준다 (파라미터는 원래 String이였지만 age를 Integer로 변환하여 넣어준다)</li>
<li>만약 바인딩이 성공했다면 view에서 사용할 수 있도록 자동으로 어트리뷰트에 추가해준다</li>
</ul>
<p><strong>4. 전달받는 파라미터의 name과 같은 이름의 변수</strong></p>
<ul>
<li>파라미터와 같은 이름의 매개변수를 선언해두면 값이 알아서 바인딩된다</li>
<li>타입도 알아서 변환해준다</li>
<li>기본적으로 어트리뷰트에 자동으로 추가되지는 않는다</li>
<li>매개변수 앞에 @ModelAttribute(&quot;name&quot;)를 사용하는 경우 어트리뷰트에도 추가된다 </li>
</ul>
<p><strong>5. HttpSession</strong></p>
<ul>
<li>세션 객체를 꺼내 활용할 수 있다</li>
</ul>
<p><strong>6. Model</strong></p>
<ul>
<li>어트리뷰트와 같은 역할</li>
</ul>
<hr>
<h2 id="🌼-컨트롤러의-리턴-타입">🌼 컨트롤러의 리턴 타입</h2>
<p>** 1. 다음 view 페이지를 찾는 타입 **</p>
<ul>
<li>*<em>String *</em><ul>
<li>리턴하는 문자열의 앞에 /WEB-INF/views/를 더하고 뒤에는 .jsp를 더해 다음 view페이지를 찾아 포워드한다<ul>
<li>리턴하는 문자열 앞에 redirect:를 붙이면 리다이렉트를 응답한다 </li>
</ul>
</li>
</ul>
</li>
<li>*<em>void *</em><ul>
<li>컨트롤러로 접속할 때 사용했던 URI를 그대로 사용해 다음 view를 찾는다</li>
</ul>
</li>
<li>*<em>ModelAndView *</em><ul>
<li>모델과 뷰를 모두 한번에 설정할 수 있는 객체</li>
</ul>
</li>
</ul>
<p>** 2. view를 찾지 않는 타입**</p>
<ul>
<li><strong>자바빈 객체 타입으로 리턴</strong><ul>
<li>웹 페이지 코드 대신 데이터를 바로 응답한다</li>
</ul>
</li>
<li><strong>ResponseEntity</strong>
직접 원하는 응답을 생성하여 응답한다 (직접 커스텀)</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[Lombok]]></title>
            <link>https://velog.io/@blcoding_2023/Lombok</link>
            <guid>https://velog.io/@blcoding_2023/Lombok</guid>
            <pubDate>Tue, 04 Jul 2023 02:14:59 GMT</pubDate>
            <description><![CDATA[<h1 id="🍀-lombok">🍀 Lombok</h1>
<ul>
<li>간단한 어노테이션 추가로 자바빈 스타일의 객체를 자동으로 완성해주는 라이브러리</li>
</ul>
<h2 id="🌼-lombok-설치하기">🌼 Lombok 설치하기</h2>
<ol>
<li><a href="https://projectlombok.org/download">롬복 다운로드</a>에서 다운로드 후 실행</li>
<li>sts.exe의 경로를 찾아서 지정(IDE 설정하기)</li>
<li>sts 재시작</li>
<li><a href="https://mvnrepository.com/artifact/org.projectlombok/lombok/1.18.28">maven repository</a>에서 같은 버전의 maven을 복사</li>
<li>pom.xml의 dependencies에 붙여넣기</li>
<li>프로젝트 우클릭 -&gt; maven -&gt; update project ... 실행</li>
<li>Package Explorer의 Maven Dependencies에서 해당 버전의 lombok이 잘 설치되었는지 확인</li>
</ol>
<h2 id="🌼-lombok의-어노테이션들">🌼 Lombok의 어노테이션들</h2>
<ul>
<li><p><strong>@Getter</strong></p>
<ul>
<li>클래스 위에 붙이면 해당 클래스의 모든 필드에 대한 Getter를 생성한다</li>
<li>필드 위에 붙이면 해당 필드에만 Getter를 생성한다 </li>
</ul>
</li>
<li><p><strong>@Setter</strong></p>
<ul>
<li>클래스 위에 붙이면 해당 클래스의 모든 필드에 대한 Setter를 생성한다</li>
<li>필드 위에 붙이면 해당 필드에만 Setter를 생성한다 </li>
</ul>
</li>
<li><p><strong>@ToString</strong></p>
<ul>
<li>해당 클래스의 toString()을 알아서 적당히 구현해준다</li>
</ul>
</li>
<li><p><strong>@NoArgsConstructor</strong></p>
<ul>
<li>기본 생성자를 생성한다</li>
</ul>
</li>
<li><p><strong>@AllArgsConstructor</strong></p>
<ul>
<li>모든 필드값을 초기화해야 하는 생성자를 생성한다</li>
</ul>
</li>
<li><p><strong>@RequiredArgsConstructor</strong></p>
<ul>
<li>필수로 채워야하는 필드만 초기화하는 생성자를 생성한다</li>
<li>@NonNull이 붙어있는 필드를 필수로 채워야 하는 필드로 간주한다</li>
</ul>
</li>
<li><p><strong>@EqualsAndHashCode</strong></p>
<ul>
<li>해당 클래스의 equals()와 hashCode()를 적절하게 오버라이딩 한다</li>
<li>equals()는 모든 필드의 값이 일치하면 같은 객체로 인정한다</li>
<li>hashCode()는 모든 필드의 값이 일치하면 같은 값을 생성한다</li>
</ul>
</li>
<li><p><strong>@Data</strong></p>
<ul>
<li>@Getter</li>
<li>@Setter</li>
<li>@ToString</li>
<li>@EqualsAndHashCode</li>
<li>@RequiredArgsConstructor를 모두 합친 어노테이션</li>
<li>자주 쓰는 조합 .. ?</li>
</ul>
</li>
</ul>
<h2 id="🌼-lombok-사용하기">🌼 Lombok 사용하기</h2>
<pre><code class="language-java">@Data
public class EmployeeDTO {
    String first_name;
    String last_name;
    Date hire_date;
    Integer salary;
}</code></pre>
<ol>
<li>클래스 생성 후 멤버변수를 추가한다</li>
<li>클래스에 @Data 어노테이션을 추가한다</li>
<li>Lombok이 Getter, Setter, 생성자, toString등을 모두 자동으로 생성해준다
<img src="https://velog.velcdn.com/images/blcoding_2023/post/d7e6e90d-9b41-4c75-96ea-8c8d9df0c375/image.png" alt=""></li>
</ol>
]]></description>
        </item>
        <item>
            <title><![CDATA[Log4j]]></title>
            <link>https://velog.io/@blcoding_2023/Log4j</link>
            <guid>https://velog.io/@blcoding_2023/Log4j</guid>
            <pubDate>Mon, 03 Jul 2023 08:22:49 GMT</pubDate>
            <description><![CDATA[<h1 id="🍀-log4j">🍀 Log4j</h1>
<ul>
<li>로그를 효율적으로 남길 수 있는 기능들이 구현되어있는 라이브러리</li>
<li>각 로그마다 등급을 설정하고 일정 등급 이상의 로그만 보이도록 설정할 수 있다</li>
<li>프로젝트 폴더의 src/main/resources -&gt; log4j.xml 내용을 확인할 수 있다(직접 수정도 가능)</li>
</ul>
<h1 id="🍀-logger">🍀 Logger</h1>
<ul>
<li>각 클래스에 장착하면 해당 클래스에서 발생하는 로그를 수집하는 객체</li>
<li>발생하는 로그들을 등급별로 수집하여 Appender로 전송하는 역할을 한다</li>
<li>어떤 클래스를 감시해야하는지 클래스의 이름을 전달한다(클래스이름.class)
<img src="https://velog.velcdn.com/images/blcoding_2023/post/7bc6c8f6-46a6-40b2-b63e-81ad5cdebbac/image.png" alt=""></li>
</ul>
<h1 id="🍀-appender">🍀 Appender</h1>
<ul>
<li>수집된 로그들을 출력하는 장소</li>
<li>파일, 콘솔, DB, 웹 등으로 발생한 로그들을 출력할 수 있다</li>
</ul>
<h2 id="🌼-file을-append-하는-방법">🌼 File을 Append 하는 방법</h2>
<ul>
<li><p>log4j.xml에 appender와 appender-ref를 추가</p>
<pre><code class="language-java">&lt;!-- Appenders --&gt;
&lt;appender name=&quot;myfile&quot; class=&quot;org.apache.log4j.FileAppender&quot;&gt;
      &lt;param name=&quot;file&quot; value=&quot;/log/mylog.txt&quot;/&gt;
      &lt;layout class=&quot;org.apache.log4j.PatternLayout&quot;&gt;    
          &lt;param name=&quot;ConversionPattern&quot; value=&quot;%-5p: %c - %m[%d{HH:mm:ss}]%n&quot; /&gt;
      &lt;/layout&gt;
  &lt;/appender&gt;
  &lt;appender name=&quot;myfile2&quot; class=&quot;org.apache.log4j.FileAppender&quot;&gt;
      &lt;param name=&quot;file&quot; value=&quot;/log/mylog2.html&quot;/&gt;
      &lt;layout class=&quot;org.apache.log4j.HTMLLayout&quot;/&gt;    
  &lt;/appender&gt;

&lt;!-- Root Logger --&gt;
  &lt;root&gt;
      &lt;priority value=&quot;warn&quot; /&gt;
      &lt;appender-ref ref=&quot;console&quot; /&gt;
      &lt;appender-ref ref=&quot;myfile&quot; /&gt;
      &lt;appender-ref ref=&quot;myfile2&quot; /&gt;
  &lt;/root&gt;</code></pre>
</li>
<li><ul>
<li>실행 결과 &gt;&gt; **
param의 value에 설정한 경로에 해당 로그 파일이 추가된다
<img src="https://velog.velcdn.com/images/blcoding_2023/post/b8d060ba-2d79-4d49-a320-f0568af4115e/image.png" alt=""></li>
</ul>
</li>
</ul>
<h1 id="🍀-layout">🍀 Layout</h1>
<ul>
<li>로그를 출력하는 모양을 설정할 수 있다</li>
<li><a href="https://everlikemorning.tistory.com/entry/Log4J-%EA%B0%84%EB%8B%A8-%EC%82%AC%EC%9A%A9%EB%B2%95">Log</a></li>
<li>layout class의 param value에서 출력되는 형태를 직접 설정할 수 있다
<img src="https://velog.velcdn.com/images/blcoding_2023/post/85e8a17c-0241-4e01-b13a-6812d9f3d1ba/image.png" alt=""></li>
<li>설정한 모양대로 콘솔에 출력된다
<img src="https://velog.velcdn.com/images/blcoding_2023/post/49fc7a47-d94c-4aaf-a766-e40f7fb46a5b/image.png" alt=""></li>
</ul>
<h2 id="🌼-log4j-업데이트하기">🌼 Log4j 업데이트하기</h2>
<ol>
<li><a href="https://mvnrepository.com/artifact/log4j/log4j/1.2.17">Log4j</a>에서 Maven 복사</li>
<li>pom.xml에서 log4j를 해당 내용으로 변경 후 저장</li>
<li>Package Explorer의 Maven Dependencies에서 log4j가 선택한 버전으로 변경되었는지 확인</li>
</ol>
<h2 id="🌼-loging-level">🌼 Loging level</h2>
<ul>
<li><strong>OFF</strong> : 모든 등급의 로그를 끔</li>
<li><strong>FATAL</strong> : 아주 심각한 로그를 작성할 때 사용하는 등급(FATAL만 출력됨)</li>
<li><strong>ERROR</strong> : 에러 발생 로그를 작성할 때 사용되는 등급 (ERROR보다 심각한 로그만 출력됨 / 빨간줄 등급)</li>
<li><strong>WARN</strong> : 경고 로그를 작성할 때 사용하는 등급 (WARN보다 심각한 로그만 출력됨 / 노란줄등급)</li>
<li><strong>INFO</strong> : 일반적인 정보 로그를 작성할 때 사용하는 등급 (INFO보다 심각한 로그만 출력됨/운영단계)</li>
<li><strong>DEBUG</strong> : 디버깅 용도로 로그를 작성할 때 사용하는 등급 (DEBUG보다 심각한 로그만 출력됨/개발단계)</li>
<li><strong>TRACE</strong> : 에러를 추적하기 위한 정밀한 로그를 작성할 때 사용하는 등급 (모든 로그가 출력됨/개발단계)</li>
<li><strong>ALL</strong> : 모든 로그를 출력함(TRACE와 같다)</li>
<li>로깅 레벨은 log4j.xml에서 각 로거의 레벨(value)에서 설정할 수 있다
<img src="https://velog.velcdn.com/images/blcoding_2023/post/7851916d-49d1-4209-88e0-296b4fc21a32/image.png" alt=""></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[의존성 주입(Dependency Injection, DI)]]></title>
            <link>https://velog.io/@blcoding_2023/%EC%9D%98%EC%A1%B4%EC%84%B1-%EC%A3%BC%EC%9E%85Dependency-Injection-DI</link>
            <guid>https://velog.io/@blcoding_2023/%EC%9D%98%EC%A1%B4%EC%84%B1-%EC%A3%BC%EC%9E%85Dependency-Injection-DI</guid>
            <pubDate>Mon, 03 Jul 2023 06:11:37 GMT</pubDate>
            <description><![CDATA[<h1 id="🍀-dependency-injection">🍀 Dependency Injection</h1>
<ul>
<li>외부에서 두 객체간의 관계를 결정해주는 디자인 패턴</li>
<li>인터페이스를 사이에 두어 클래스 레벨에서는 의존관계가 고정되지 않도록 하고 런타임시에 관계를 동적으로 주입하여 <strong>유연성을 확보하고 결합도를 낮출 수 있도록 한다</strong></li>
<li>유지보수성이 좋아진다는 장점이 있다</li>
</ul>
<h2 id="🌼-스프링이-자동으로-컨텍스트에-등록하는-어노테이션들">🌼 스프링이 자동으로 컨텍스트에 등록하는 어노테이션들</h2>
<ul>
<li><strong>@Component</strong> : 컨텍스트 로드시에 스프링이 자동으로 수거해가는 대상이 된다, 컴포넌트 스캔을 통해 특정 패키지의 컴포넌트들을 수거할 수 있다</li>
<li><strong>@Controller</strong> : MVC패턴에서 컨트롤러 역할을 하는 컴포넌트들을 표시해놓는 어노테이션</li>
<li><strong>@Repository</strong> : MVC패턴에서 모델 역할을 하는 컴포넌트들을 표시해놓는 어노테이션</li>
<li><strong>@Service</strong> : MVC패턴에서 비즈니스 로직을 수행하는 컴포넌트들을 표시해놓는 어노테이션</li>
</ul>
<h2 id="🌼-autowired를-통한-의존성-주입">🌼 @Autowired를 통한 의존성 주입</h2>
<ul>
<li>@Autowired가 적용되어 있는 자원은 컨텍스트 영역에 등록된 컴포넌트들 중 알맞은 컴포넌트를 자동으로 찾아 인스턴스를 주입해준다</li>
<li>생성자를 사용하지 않아도 스프링이 대신 인스턴스를 생성하여 주입해주기 때문에 클래스 간의 결합도가 낮아져 유지보수성이 올라가는 효과가 있다 </li>
</ul>
<hr>
<h2 id="🌼-java-bean-object자바빈-객체">🌼 Java Bean Object(자바빈 객체)</h2>
<ul>
<li>데이터 클래스를 만들 때 자주 사용하던 클래스의 형태를 자바빈 객체라고 한다</li>
<li>필드값(속성)의 <strong>접근 제어자는 private</strong>이어야 한다 (protected도 됨)</li>
<li><strong>필드값에 대한 접근은 Getter/Setter를 통해</strong> 이루어져야 한다</li>
<li>기본 생성자가 반드시 존재해야 한다(다른 생성자를 쓰고 싶다면 기본 생성자를 반드시 명시해줘야 한다)</li>
<li>자바빈 스타일의 객체는 다양한 프레임워크, API, 라이브러리 등에서 기본 형태로 생각하기 때문에 반드시 지켜야한다</li>
</ul>
<hr>
<h2 id="🌼-의존성-주입-방법">🌼 의존성 주입 방법</h2>
<p><strong>1. 자바빈 객체 생성</strong> 
** ✔ Student.java &gt;&gt; **</p>
<pre><code class="language-java">import org.springframework.stereotype.Component;
@Component
public class Student {
    private String name;
    private String grade;
    public Student(){
        name = &quot;기본 이름&quot;;
        grade = &quot;기본 등급&quot;;    
    }
    public Student(String name, String grade) {
        this.name = name;
        this.grade = grade;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getGrade() {
        return grade;
    }
    public void setGrade(String grade) {
        this.grade = grade;
    }
    @Override
    public String toString() {
        return String.format(&quot;%s[%s]&quot;, name, grade);
    }
}</code></pre>
<p>** 2. 컨트롤러에 Autowired 어노테이션 추가**
** ✔ HomeController.java &gt;&gt; ** </p>
<pre><code class="language-java">@Controller
public class HomeController {
    private static final Logger logger = LoggerFactory.getLogger(HomeController.class);

    @Autowired
    Student student;

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

        System.out.println(&quot;stu : &quot; + student);
        return &quot;home&quot;;
    }
}</code></pre>
<hr>
<p>** 📺 출력 결과 &gt;&gt; **
<img src="https://velog.velcdn.com/images/blcoding_2023/post/2bc03492-908e-4485-b8c5-a2c88958c3f9/image.png" alt=""></p>
<p> -&gt; Student를 직접 생성하지 않아도 Autowired으로 자동으로 생성됨을 확인할 수 있다</p>
<hr>
<h1 id="🍀-컨텍스트에-빈bean-등록하기">🍀 컨텍스트에 빈(Bean) 등록하기</h1>
<ul>
<li>&lt;bean&gt;을 사용해 직접 등록하거나 컴포넌트 스캔을 통해 등록할 수 있다</li>
<li>컨텍스트에 등록된 자바 객체를 빈(bean)이라고 부른다</li>
<li>컨텍스트에 등록된 객체들은 알아서 적재적소에 사용된다</li>
<li>컨텍스트에 등록되는 객체들은 싱글톤 패턴으로 등록된다</li>
</ul>
<h2 id="🌼-servlet-context의-bean-graph">🌼 servlet-context의 Bean Graph</h2>
<p><img src="https://velog.velcdn.com/images/blcoding_2023/post/dadbf579-6950-4ddd-bb65-4eff3a6f0484/image.png" alt=""></p>
<ul>
<li>내가 생성한 클래스들이 Bean으로 자동 등록된다</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[JUnit]]></title>
            <link>https://velog.io/@blcoding_2023/JUnit</link>
            <guid>https://velog.io/@blcoding_2023/JUnit</guid>
            <pubDate>Mon, 03 Jul 2023 05:59:50 GMT</pubDate>
            <description><![CDATA[<h1 id="🍀-junit">🍀 JUnit</h1>
<ul>
<li>자바의 단위테스트용 라이브러리</li>
<li>스프링 프로젝트 배포시 작성되어있는 모든 단위 테스트를 통과해야 배포를 진행할 수 있다</li>
<li>기본 버전은 너무 옛날 것이므로 pom.xml에서 버던을 수정한 후 사용</li>
</ul>
<hr>
<h2 id="🌼-junit-버전-업데이트-하기">🌼 JUnit 버전 업데이트 하기</h2>
<ol>
<li><a href="https://mvnrepository.com/artifact/junit/junit/4.13.2">JUnit 버전 업데이트</a> 클릭 후 Maven에 있는 값 복사</li>
<li>pom.xml의 dependendy에서 junit찾기</li>
<li>해당 부분에 복사한 내용 붙여넣기
<img src="https://velog.velcdn.com/images/blcoding_2023/post/7f33967d-3c5e-4859-bc0d-2cb9883df1e3/image.png" alt=""></li>
</ol>
<hr>
<h2 id="🌼-junit의-어노테이션들">🌼 JUnit의 어노테이션들</h2>
<ul>
<li><strong>@Test</strong> : 해당 메서드가 단위 테스트임을 표시하는 어노테이션</li>
<li><strong>@Ignore</strong> : 해당 테스트를 무시한다</li>
<li><strong>@Before</strong> : 테스트 시작 전 실행하는 메서드, 테스트 전에 초기화등의 작업을 먼저 수행하는 역할을 한다</li>
<li><strong>@After</strong> : 테스트 종료 후 실행하는 메서드, close()등의 작업을 수행할 때 사용한다</li>
</ul>
<hr>
<h2 id="🌼-junit-asserts">🌼 JUnit Asserts</h2>
<ul>
<li>기대하던 결과가 나오면 테스트를 통과하고, 기대하던 값과 결과가 다르면 테스트에 실패한다</li>
<li><strong>assertEquals(expect, test)</strong> : 기대하던 값과 결과가 일치하면 테스트 통과</li>
<li><strong>assertTrue(test)</strong> : 결과가 true면 테스트 통과</li>
<li><strong>assertFalse(test)</strong> : 결과가 false면 테스트 통과</li>
<li><strong>assertNull(test)</strong> : 결과가 null이면 테스트 통과</li>
<li><strong>assertNotNull(test)</strong> : 결과가 null이 아니면 테스트 통과</li>
<li><strong>assertThrows(expect, test)</strong> : 실행 도중 원하는 예외가 발생하면 테스트 통과</li>
<li><strong>fail()</strong> : fail()을 만나면 테스트 실패 (테스트 내부에서 return 같은 역할을 한다)</li>
</ul>
<hr>
<h3 id="싱글톤singleton-패턴">싱글톤(Singleton) 패턴</h3>
<ul>
<li>객체 내에서 단 하나의 인스턴스만 가지고 있는 것이 보장되는 디자인 패턴</li>
<li>주로 프로그램 내에서 하나로 공유를 해야하는 객체가 존재할 때 해당 객체를 싱글톤으로 구현하여 모든 유저 또는 프로그램들이 해당 객체를 공유하며 사용하도록 할때 사용한다</li>
</ul>
<hr>
<h1 id="🍀-단위-테스트-unit-test">🍀 단위 테스트 (Unit test)</h1>
<ul>
<li>어떤 기능을 구현한 후 해당 기능이 원하는 대로 동작하는지 보기 위해 작성하는 프로그램</li>
<li>테스트 중 가장 작은 단위의 테스트에 속한다</li>
<li>어떤 메서드를 실행했을 때 기대하는 값이 잘 나오는지 체크하는 방식으로 진행</li>
</ul>
<hr>
<h1 id="🍀-tddtest-driven-development-테스트-주도-개발">🍀 TDD(Test Driven Development, 테스트 주도 개발)</h1>
<ul>
<li>조건을 만족하는 테스트 프로그램을 먼저 작성한 후 해당 테스트를 통과하는 기능을 구현하는 방식의 개발(테스트 케이스와 테스트 코드를 먼저 작성)</li>
<li>테스트 단위로 기능이 구현되기 때문에 더욱 객체지향적인 개발이 가능해진다</li>
<li>유지보수(리팩토링)이 용이해진다</li>
<li>익숙하지 않으면 시간이 너무 오래 걸리기 때문에 생산성이 저하된다 (생산 비용 증가)</li>
</ul>
<hr>
<h1 id="🍀-jnuit-단위테스트-방법">🍀 Jnuit 단위테스트 방법</h1>
<ol>
<li>src/main/java 폴더에 패키지와 클래스를 만든다</li>
<li>클래스 안에 만들고 싶은 기능을 작성한다</li>
<li>src/test/java 폴더에 같은 이름의 패키지를 만든 후 우클릭하여 JUnit Test Case 생성</li>
<li>test 메서드 안에 assertEquals(기대하는 값, 내가 생성한 클래스.메서드(매개값) 전달</li>
<li>우클릭 -&gt; Run As -&gt; JUnit Test 실행</li>
</ol>
<p><img src="https://velog.velcdn.com/images/blcoding_2023/post/e27c0ddb-32f1-4eed-b387-0f161d952131/image.png" alt=""></p>
<h2 id="🌼-단위-테스트-실행">🌼 단위 테스트 실행</h2>
<p>** ✔ MyStringBuilder.java **</p>
<pre><code class="language-java">package com.ezen.springmvc.common;

public class MyStringBuilder {
    public static String reverse(String str) {
        str = new StringBuilder(str).reverse().toString();
        return str;
    }
}</code></pre>
<p>** ✔ MyTest.java **</p>
<pre><code class="language-java">package com.ezen.springmvc.common;
public class MyTest {
    @Test
    public void test1() {
        assertEquals(&quot;elppa&quot;, MyStringBuilder.reverse(&quot;apple&quot;)); // 다른 폴더에 있지만 같은 패키지이기 때문에 import가 필요없다
        // 기대하는 값을 쓰고 테스트 할 유닛을 전달
    }
}</code></pre>
<p>** 📺 실행 결과 &gt;&gt; **
<img src="https://velog.velcdn.com/images/blcoding_2023/post/3d9037fc-4834-47ad-8b6a-6a1dcad0138c/image.png" alt=""></p>
<hr>
<h1 id="🍀-단위-테스트에서-autowired-사용하기">🍀 단위 테스트에서 Autowired 사용하기</h1>
<ul>
<li>Autowired는 서버가 켜질 때 실행되기 때문에 서버를 통하지 않는 단위테스트에서는 사용이 불가하다</li>
<li>단위테스트에서 Autowired를 사용하기 위해서는 spring context와 spring testContext의 버전을 업데이트 해야한다</li>
</ul>
<p>와 <a href="https://mvnrepository.com/artifact/org.springframework/spring-test/5.2.24.RELEASE">spring test context</a>를 release버전으로 업데이트 하고 다음 내용을 추가
<code>@RunWith(SpringRunner.class)
@ContextConfiguration(&quot;file:src/main/webapp/WEB-INF/spring/appServlet/servlet-context.xml&quot;)</code></p>
<ul>
<li>테스트 케이스에 테스트 할 클래스를 선언한 뒤 @Autowired를 붙이면 @Component 어노테이션을 붙인 유닛을 찾아서 알아서 실행해준다</li>
</ul>
<hr>
<h2 id="🌼-pomxml에서-스프링-프레임워크-버전-업데이트-하기">🌼 pom.xml에서 스프링 프레임워크 버전 업데이트 하기</h2>
<ul>
<li><a href="https://mvnrepository.com/artifact/org.springframework/spring-context/5.2.24.RELEASE">spring context</a>에서 Maven을 복사한 후 &lt;dependencies&gt;의 &lt;dependency&gt;에 붙여넣기</li>
<li>spring context와 같은 버전의 <a href="https://mvnrepository.com/artifact/org.springframework/spring-test/5.2.24.RELEASE">spring test context</a>를 복사하여 &lt;dependencies&gt;에 추가</li>
<li>&lt;properties&gt;의 &lt;java-version&gt;을 1.8로 변경 후 &lt;configuration&gt;의 &lt;source&gt;와 &lt;target&gt;을 앞에서 설정한 변수명(${java-version}으로 변경)</li>
<li>해당 프로젝트 우클릭 -&gt; Maven -&gt; Update Project ... 실행</li>
</ul>
<hr>
<p>** MyReducer.java (인터페이스) **</p>
<pre><code class="language-java">@RunWith(SpringRunner.class)
@ContextConfiguration(&quot;file:src/main/webapp/WEB-INF/spring/appServlet/servlet-context.xml&quot;)</code></pre>
<p>** MyReducer_Impl.java (구현체) **</p>
<pre><code class="language-java">@Component
public class MyReducer_Impl implements MyReducer {
    @Override
    public Integer reduce(Integer[] arr) {
        int sum = 0;
        for(Integer i : arr) {
            sum += i == null ? 0 : 1;
        }
        return sum;
    }
}</code></pre>
<p>** MyReducerTest.java (테스트케이스) **</p>
<pre><code class="language-java">@RunWith(SpringRunner.class)
@ContextConfiguration(&quot;file:src/main/webapp/WEB-INF/spring/appServlet/servlet-context.xml&quot;)
public class MyReducerTest {
    @Autowired
    MyReducer reducer;

    @Before
    public void test0() {
        System.out.println(reducer);
    }
    @Test
    public void test1() {
        assertEquals(Integer.valueOf(150), reducer.reduce(new Integer[] {10,20,30,40,50}));
    }
    @Test
    public void test2() {
        assertEquals(Integer.valueOf(120), reducer.reduce(new Integer[] {10,20,null,40,50}));
    }
    @Test
    public void test3() {
        assertEquals(Integer.valueOf(0), reducer.reduce(new Integer[] {null, null, null}));
    }
}</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[Maven]]></title>
            <link>https://velog.io/@blcoding_2023/Maven</link>
            <guid>https://velog.io/@blcoding_2023/Maven</guid>
            <pubDate>Mon, 03 Jul 2023 05:01:22 GMT</pubDate>
            <description><![CDATA[<h1 id="🍀-maven">🍀 Maven</h1>
<ul>
<li>Maven은 자바 프로젝트의 빌드(build)를 자동화 해주는 빌드 툴(build tool)</li>
<li>프로젝트를 진행하면서 필연적으로 발생하는 다양한 작업들을 편리하게 관리할 수 있는 빌드 자동화 도구
<code>ex: 라이브러리 관리(JSTL 다운받고 등록하고 .. )
  라이브러리 버전 관리(다른버전으로 다시 다운받고 .. 다시 등록하고 .. )
  프로젝트 버전 관리(프로젝트 업데이트하면 이름 바꿔주고 .. 관리하고..)
  프로젝트 배포 관리(프로젝트의 배포판 생성하기)</code></li>
<li>프로젝트 내부의 pom.xml을 통해 전체 프로젝트를 관리할 수 있는 프로그램이다</li>
</ul>
<hr>
<h2 id="🌼-pomproject-object-model">🌼 POM(Project Object Model)</h2>
<ul>
<li>프로젝트 객체 모델</li>
<li>해당 프로젝트에 대한 여러가지 설정 및 의존성등의 정보들을 담고 있다</li>
<li>프로젝트 전체에 대한 명세서</li>
</ul>
<hr>
<h2 id="🌼-pomxml">🌼 pom.xml</h2>
<ul>
<li><strong>&lt;groupId&gt;</strong> : 이 프로젝트의 그룹 아이디 (패키지 이름에 사용했던 회사 이름)</li>
<li><strong>&lt;artifactId&gt;</strong> : 이 프로젝트의 프로젝트명(패키지에서 쓸 이름)</li>
<li><strong>&lt;name&gt;</strong> : 이 프로젝트의 프로젝트 이름(대소문자 버전)</li>
<li><strong>&lt;packaging&gt;</strong> : 이 프로젝트의 빌드 결과가 무엇일지 설정</li>
<li><strong>&lt;version&gt;</strong> : 이 프로젝트의 현재 버전</li>
<li><strong>&lt;properties&gt;</strong> : pom.xml 내부에서 사용할 변수 등록</li>
<li><strong>&lt;dependencies&gt;</strong> : 이 프로젝트를 구성하는 데에 필요한 다른 프로젝트들(이 프로젝트가 의존하는 다른 프로젝트들)<pre><code>             여기에 등록한 프로젝트들은 메이븐이 자동으로 다운로드하여 관리해준다
             프로젝트 빌드(BuildPath)에도 자동으로 포함시킨다</code></pre></li>
<li><strong>&lt;dependency&gt;</strong> : 의존하는 프로젝트의 pom 정보를 적어 등록하는 곳 <pre><code>           해당 프로젝트의 &amp;lt;groupId&gt;, &amp;lt;artifactId&gt;, &amp;lt;version&gt;등을 적어 이 프로젝트에 포함시킨다
           &amp;lt;scope&gt;를 설정하여 이 프로젝트에서 어느정도 범위까지 필요한지 설정할 수 있다</code></pre></li>
</ul>
<hr>
<h2 id="🌼-scope의-종류">🌼 &lt;scope&gt;의 종류</h2>
<ul>
<li><strong>compile</strong> : 프로젝트를 컴파일 할 때 필요한 의존성, 컴파일 당시에도 사용되고, 프로젝트 배포시에도 포함된다(기본값)</li>
<li><strong>runtime</strong> : 컴파일할 때는 필요 없지만 해당 프로젝트를 실행할 때는 필요한 의존성, 프로젝트 배포시에 포함된다</li>
<li><strong>provided</strong> : 컴파일 할 때는 필요하지만 실행할 때는 필요없는 의존성(JSP 등), 프로젝트 배포시에는 포함되지 않는다</li>
<li><strong>test</strong> : 테스트 단계에서만 필요한 의존성, 컴파일 및 배포에 모두 포함되지 않는다</li>
</ul>
<hr>
<h2 id="🌼-maven의-원격-레포지토리와-로컬-레포지토리">🌼 Maven의 원격 레포지토리와 로컬 레포지토리</h2>
<ul>
<li>Maven &lt;dependencies&gt;에 등록한 모든 프로젝트들을 중앙 원격 레포지토리에서 다운받는다</li>
<li>다운받은 프로젝트들은 user/.m2/repository/groupId/artifactId/...폴더에 버전별로 보관된다(로컬 레포지토리)</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[Spring]]></title>
            <link>https://velog.io/@blcoding_2023/Spring</link>
            <guid>https://velog.io/@blcoding_2023/Spring</guid>
            <pubDate>Mon, 03 Jul 2023 02:21:00 GMT</pubDate>
            <description><![CDATA[<h1 id="🍀-스프링-설치하기">🍀 스프링 설치하기</h1>
<ol>
<li>JDK11을 다운로드(충돌 방지) 후 설치
<a href="https://www.oracle.com/kr/java/technologies/javase/jdk11-archive-downloads.html">JDK11 다운로드</a></li>
<li>Spring 다운로드 후 설치
<a href="https://spring.io/tools">spring 다운로드</a></li>
<li>spring-workspace 폴더 만들어 workspace폴더 지정</li>
<li>기본 설치된 서버 지우고 apache tomcat으로 재설정</li>
<li>프로그램 종료 후 스프링 폴더의 STS.ini 파일에 아래 내용 추가
<code>-vm
C:\Program Files\Java\jdk-11\bin\javaw.exe(jvm경로를 넣는다)</code></li>
<li>window -&gt; preference에서 encoding 검색 후 모든 인코딩 설정을 &#39;UTF-8&#39;로 변경</li>
<li>File -&gt; new -&gt; SpringLagacyProject 선택</li>
<li>SpringMVCProject 선택 후 next화면에서 아래처럼 com.mycompany.myapp 형태로 작성
<img src="https://velog.velcdn.com/images/blcoding_2023/post/27d06899-9d30-4b5e-b728-61953c94cff1/image.png" alt=""></li>
<li>프로젝트 폴더에 빨간 엑스 나올 때 : 프로젝트 우클릭 -&gt; Maven -&gt; update project 실행</li>
</ol>
<hr>
<h1 id="🍀-스프링-프레임워크">🍀 스프링 프레임워크</h1>
<ul>
<li>자바를 이용해 웹 애플리케이션 서버 개발을 효율적으로 진행하기 위한 프레임워크</li>
<li>다양한 디자인 패턴 및 기능들이 미리 구현되어 있기 때문에 효율적으로 개발을 진행할 수 있다</li>
</ul>
<h2 id="🌼-프레임워크framework">🌼 프레임워크(Framework)</h2>
<ul>
<li>프로젝트 개발에 효율적인 구조를 미리 만들어 놓은 것(PPT 템플릿 같은 것)</li>
<li>개발자는 이미 완성된 구조에 빈칸을 채우는 느낌으로 프로젝트를 진행할 수 있다</li>
<li>전체적인 구조(디자인 패턴 등)에 대한 지식이 없는 초보 개발자들도 프로젝트에 투입할 수 있다는 장점이 있다</li>
<li>일정 수준 이상의 품질이 항상 보장된다</li>
<li>개발 비용이 많이 절감된다</li>
</ul>
<h2 id="🌼-스프링의-특징">🌼 스프링의 특징</h2>
<h3 id="1-pojo-plain-old-java-object">1. POJO (Plain Old Java Object)</h3>
<ul>
<li>JSP처럼 새로운 공부가 필요한 문법들의 사용을 지양한다</li>
<li>백엔드에 JSP 코드가 섞이는 것은 바람직하지 않으며 순수 JAVA코드로 작성되어야 한다</li>
<li>익숙치 않은 별도의 API를 최대한 배제하여 개발자의 혼란을 최소화 한다</li>
</ul>
<h3 id="2-제어의-역전ioc--inversion-of-controll">2. 제어의 역전(IoC,  Inversion of Controll)</h3>
<ul>
<li>개발자가 객체를 생성하는 것이 아니라 스프링이 객체를 만들고 메서드를 호출한다</li>
<li>객체의 생성과 관리를 개발자가 하는 것이 아니라 스프링 프레임워크가 대신한다</li>
</ul>
<h3 id="3-의존성-주입di-dependency-injection">3. 의존성 주입(DI, Dependency Injection)</h3>
<ul>
<li>외부에서 객체를 주입받아 사용하는 것</li>
<li>생성자를 아예 사용하지 말자 (생성자로 인해 유지보수 비용이 증가)</li>
<li>프로젝트 내부의 생성자 사용을 모두 제거하여 객체간의 결합도를 낮출 수 있다</li>
</ul>
<p><em>※ 결합도가 높다 -&gt; 하나 수정하면 빨간 줄이 100개 뜬다
※ 결합도가 낮다 -&gt; 객체 하나 수정해도 거의 문제가 안생긴다</em></p>
<h2 id="🌼-스프링-프로젝트의-기본-구조">🌼 스프링 프로젝트의 기본 구조</h2>
<ul>
<li><strong>src/main/java</strong> : 자바 코드를 작성하는 곳</li>
<li><strong>src/main/resources</strong> : 자바 코드를 실행할 때 필요한 자원들을 저장하는 곳</li>
<li><strong>src/test/java</strong> : 작성한 자바 코드에 대한 테스트 코드를 작성하는 곳</li>
<li><strong>src/test/resources</strong> : 테스트 코드를 실행할 때 필요한 자원들을 저장하는 곳</li>
<li><strong>Maven Dependencies</strong> : 이 프로젝트가 의존하고 있는 다른 프로젝트들 목록</li>
<li><strong>webapp/resources</strong> : 웹 정적 자원들을 보관하는 곳</li>
<li><strong>webapp/WEB-INF/spring/appServlet/servlet-context.xml</strong> : appServlet(디스패처 서블릿)의 초기화 파라미터들을 정의하는 곳(지역 초기화 파라미터, ServletConfig)</li>
<li><strong>webapp/WEB-INF/spring/root-context.xml</strong> : 전역 초기화 파라미터들을 정의하는 곳(전체 초기화 파라미터, ServletContext)</li>
<li><strong>webapp/WEB-INF/views</strong> : 뷰 페이지(.jsp)들을 보관하는 곳</li>
<li><strong>webapp/WEB-INF/web.xml</strong> : 서버 설정 파일</li>
<li><strong>pom.xml</strong> : 메이븐 프로잭트에서 사용하는 설정 파일</li>
</ul>
<hr>
<h1 id="🍀-스프링-인코딩설정">🍀 스프링 인코딩설정</h1>
<ul>
<li>web.xml에 다음 내용을 추가 후 서버 재시작<pre><code>&lt;filter&gt;
      &lt;filter-name&gt;encodingFilter&lt;/filter-name&gt;
      &lt;filter-class&gt;org.springframework.web.filter.CharacterEncodingFilter&lt;/filter-class&gt;
      &lt;init-param&gt;
          &lt;param-name&gt;encoding&lt;/param-name&gt;
          &lt;param-value&gt;UTF-8&lt;/param-value&gt;
      &lt;/init-param&gt;
      &lt;init-param&gt;
      &lt;!-- 설정된 인코딩이 있더라도 내가 등록한 것으로 강제로 인코딩 하게 설정 --&gt;
          &lt;param-name&gt;forceEncoding&lt;/param-name&gt;
          &lt;param-value&gt;true&lt;/param-value&gt;
      &lt;/init-param&gt;
  &lt;/filter&gt;
  &lt;filter-mapping&gt;
      &lt;filter-name&gt;encodingFilter&lt;/filter-name&gt;
      &lt;servlet-name&gt;appServlet&lt;/servlet-name&gt;
  &lt;/filter-mapping&gt;</code></pre></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[Popup]]></title>
            <link>https://velog.io/@blcoding_2023/Popup</link>
            <guid>https://velog.io/@blcoding_2023/Popup</guid>
            <pubDate>Tue, 27 Jun 2023 08:24:03 GMT</pubDate>
            <description><![CDATA[<h1 id="🏁-popup-새창에서-열기">🏁 Popup (새창에서 열기)</h1>
<p>** ✔ index.jsp &gt;&gt; **</p>
<pre><code class="language-html">&lt;%@ page language=&quot;java&quot; contentType=&quot;text/html; charset=EUC-KR&quot;
    pageEncoding=&quot;EUC-KR&quot;%&gt;
&lt;%@ taglib prefix=&quot;c&quot; uri=&quot;http://java.sun.com/jsp/jstl/core&quot; %&gt;
&lt;c:url value=&quot;/resources/js/popup/index.js&quot; var=&quot;js1&quot;/&gt;
&lt;!DOCTYPE html&gt;
&lt;html&gt;
&lt;head&gt;
&lt;meta charset=&quot;EUC-KR&quot;&gt;
&lt;title&gt;팝업창 열기&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
    &lt;input id=&quot;addr&quot; type=&quot;text&quot; /&gt;
    &lt;button id=&quot;btn1&quot;&gt;팝업 열기&lt;/button&gt;

&lt;!-- c:url에서 설정한 var 값을 주면됨 --&gt;
    &lt;script src=&quot;${js1}&quot;&gt;&lt;/script&gt;

&lt;/body&gt;
&lt;/html&gt;</code></pre>
<p>** ✔ popup.jsp &gt;&gt; **</p>
<pre><code class="language-html">&lt;%@ page language=&quot;java&quot; contentType=&quot;text/html; charset=EUC-KR&quot;
    pageEncoding=&quot;EUC-KR&quot;%&gt;
&lt;!DOCTYPE html&gt;
&lt;html&gt;
&lt;head&gt;
&lt;meta charset=&quot;EUC-KR&quot;&gt;
&lt;title&gt;버튼을 누르면 새창에서 열리는 팝업창입니다&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
    새 창에서 열릴 내용입니다 ... &lt;br&gt;
    &lt;br&gt;
    이 팝업창을 연 부모창은 opener라는 객체로 접근할 수 있다. &lt;br&gt;
    &lt;script src=&quot;&lt;%=request.getContextPath() %&gt;/resources/js/popup/popup.js&quot;&gt;&lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;
</code></pre>
<p>** ✔ index.js &gt;&gt; ** </p>
<pre><code class="language-js">const btn1 = document.getElementById(&#39;btn1&#39;);
btn1.addEventListener(&#39;click&#39;,(e)=&gt; {
    window.open(&#39;./popup.jsp&#39;,&#39;_blank&#39;,
    &#39;width=500, height=500, top=100, left=100&#39;); // 새 창을 열어주는 자바스크립트 함수
});</code></pre>
<p>** ✔ popup.js &gt;&gt; **</p>
<pre><code class="language-js">//opener : 이 창을 연 부모 객체 window
console.log(opener);
console.log(opener.document.getElementById(&#39;addr&#39;));
opener.document.getElementById(&#39;addr&#39;).value=&#39;apple&#39;;
opener.document.body.style.backgroundColor=&#39;green&#39;;</code></pre>
<p>** 📺 화면 출력 &gt;&gt; ** </p>
<p><img src="https://velog.velcdn.com/images/blcoding_2023/post/defbeacb-60c7-485e-8bb8-a5c0a0463b02/image.png" alt=""></p>
<p><strong>팝업열기 버튼을 눌렀을 때 &gt;&gt;</strong>
팝업 &gt;&gt; 
<img src="https://velog.velcdn.com/images/blcoding_2023/post/79a92754-f0ee-4836-a596-23233cce0094/image.png" alt=""></p>
<p>index.jsp 화면 &gt;&gt; 
<img src="https://velog.velcdn.com/images/blcoding_2023/post/f7f19b41-b34d-41e9-ac3d-7aa9d6e592f6/image.png" alt=""></p>
<p><a href="https://offbyone.tistory.com/312">팝업 옵션 참고</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Http Cookie]]></title>
            <link>https://velog.io/@blcoding_2023/Http-Cookie</link>
            <guid>https://velog.io/@blcoding_2023/Http-Cookie</guid>
            <pubDate>Tue, 27 Jun 2023 08:13:03 GMT</pubDate>
            <description><![CDATA[<h1 id="🏁-http-cookie">🏁 Http Cookie</h1>
<ul>
<li>key와 value로 된 값</li>
<li>서버에서 생성한 쿠키를 응답에 실어보내면 클라이언트의 웹 브라우저에 보관한다</li>
<li>웹 브라우저는 해당 서버로 요청을 보낼 때 마다 보관하고 있던 쿠키를 요청에 함께 실어 전달한다</li>
<li>쿠키에 저장되는 값은** 클라이언트 측에서 언제든지 위/변조가 가능하다는 것**을 감안하고 사용해야 한다(보안이 없다)</li>
<li>쿠키는 서버에서 클라이언트의 웹 브라우저에 name/value를 추가하는 것이고 로컬/세션 스토리지는 클라이언트 측의 자바스크립트에서 추가된다는 차이가 있다</li>
</ul>
<hr>
<h1 id="🏁-cookie의-설정값들">🏁 Cookie의 설정값들</h1>
<h2 id="🤺-maxage">🤺 maxAge</h2>
<ul>
<li>쿠키의 수명을 설정할 수 있다 (초 단위)</li>
<li>기본값은 -1이 된다</li>
<li>0은 삭제 / -1은 세션을 의미한다</li>
</ul>
<h2 id="🤺-path">🤺 path</h2>
<ul>
<li>쿠키가 어떤 URI 범위에서 사용될지를 설정할 수 있다</li>
<li>기본값은 현재 경로가 된다</li>
</ul>
<hr>
<h1 id="🏁-쿠키-추가삭제하기">🏁 쿠키 추가/삭제하기</h1>
<p><strong>※ 어떤 쿠키의 값 또는 수명을 수정하려고 할 때 name 뿐만 아니라 path까지 정확하게 일치해야 해당 쿠키를 수정할 수 있다</strong></p>
<h2 id="🤺-쿠키-추가하기">🤺 쿠키 추가하기</h2>
<p>** ✔ list.jsp &gt;&gt; **</p>
<pre><code class="language-html">&lt;%
    // 모든 요청은 클라이언트에 보관된 쿠키를 함께 가져온다
    Cookie[] cookies = request.getCookies();
    for(Cookie cookie : cookies){
        System.out.println(cookie.getName()+ &quot; = &quot; + cookie.getValue());
    }
%&gt;</code></pre>
<p>** 📺 화면 출력(콘솔) &gt;&gt; **</p>
<p><img src="https://velog.velcdn.com/images/blcoding_2023/post/b0456a23-75dc-4682-8452-c42c5b3b4427/image.png" alt=""></p>
<hr>
<h2 id="🤺-쿠키-삭제하기">🤺 쿠키 삭제하기</h2>
<p>** ✔ list.jsp &gt;&gt; **</p>
<pre><code class="language-html">&lt;%@ page language=&quot;java&quot; contentType=&quot;text/html; charset=EUC-KR&quot;
    pageEncoding=&quot;EUC-KR&quot;%&gt;
&lt;%@ taglib prefix=&quot;c&quot; uri=&quot;http://java.sun.com/jsp/jstl/core&quot; %&gt;    
&lt;%
    // 모든 요청은 클라이언트에 보관된 쿠키를 함께 가져온다
    Cookie[] cookies = request.getCookies();
    // EL / JSTL의 반복문을 활용하기 위해 어트리뷰트에 등록
    pageContext.setAttribute(&quot;cookies&quot;, cookies);
    for(Cookie cookie : cookies){
        System.out.println(cookie.getName()+ &quot; = &quot; + cookie.getValue());
    }
%&gt;
&lt;!DOCTYPE html&gt;
&lt;html&gt;
&lt;head&gt;
&lt;meta charset=&quot;EUC-KR&quot;&gt;
&lt;title&gt;Cookie List&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
    &lt;div style=&quot;display:grid; grid-template-columns:1fr 100px;&quot;&gt;
    &lt;!-- c:forEach는 Getter가 달린 Object 라면 무조건 활용할 수 있다는 장점이 있다 --&gt;
        &lt;c:forEach items=&quot;${cookies }&quot; var=&quot;cook&quot;&gt;
            &lt;div&gt;
            ${cook.name }=${cook.value} 
            &lt;/div&gt;
            &lt;div&gt;
            &lt;a href=&quot;./delete.jsp?name=${cook.name }&quot;&gt;[삭제]&lt;/a&gt;
            &lt;/div&gt;
        &lt;/c:forEach&gt;
    &lt;/div&gt;
&lt;/body&gt;
&lt;/html&gt;</code></pre>
<p>** ✔ delete.jsp &gt;&gt; **</p>
<pre><code class="language-html">&lt;%@ page language=&quot;java&quot; contentType=&quot;text/html; charset=EUC-KR&quot;
    pageEncoding=&quot;EUC-KR&quot;%&gt;
&lt;% 
    String cookie_name = request.getParameter(&quot;name&quot;);
    // 쿠키의 수명을 0으로 변경하면 쿠키가 삭제된다
    // 쿠키는 하나만 꺼내는 메서드가 존재하지 않아서 번거롭다
    Cookie[] cookies = request.getCookies();
    if(cookies != null){
        for(Cookie cookie : cookies){
            if(cookie.getName().equals(cookie_name)){
                cookie.setMaxAge(0); //쿠키의 수명을 0으로 변경하여 삭제 
                response.addCookie(cookie);
            }
        }
    }
    response.sendRedirect(&quot;./list.jsp&quot;);
%&gt;</code></pre>
<hr>
]]></description>
        </item>
        <item>
            <title><![CDATA[Include]]></title>
            <link>https://velog.io/@blcoding_2023/Include</link>
            <guid>https://velog.io/@blcoding_2023/Include</guid>
            <pubDate>Tue, 27 Jun 2023 08:11:16 GMT</pubDate>
            <description><![CDATA[<h1 id="🏁-jsp-include">🏁 JSP include</h1>
<ul>
<li>포워드처럼 request와 response를 다른 jsp로 보냈다가 다시 돌아오는 기능</li>
<li>다른 페이지로 잠깐 갔다 돌아오는 기능이기 때문에 page scope의 값을 사용할 수는 없다</li>
</ul>
<h1 id="🏁-file-include">🏁 File include</h1>
<ul>
<li>해당 파일 내용을 읽어서 현재 jsp 내부에 포함시키는 기능</li>
<li>컴파일 이전에 파일 내용을 포함시킨 후 컴파일을 진행하게 된다</li>
<li>page scope의 값을 사용할 수 있다</li>
</ul>
<hr>
<h2 id="🤺-jsp-include-사용해보기">🤺 JSP include 사용해보기</h2>
<p>** ✔ main.jsp &gt;&gt; **</p>
<pre><code class="language-html">&lt;%@ page language=&quot;java&quot; contentType=&quot;text/html; charset=EUC-KR&quot;
    pageEncoding=&quot;EUC-KR&quot;%&gt;
&lt;!-- 여기는...Servlet extends HttpServlet 이 생략되어 있음 --&gt;    
&lt;jsp:include page=&quot;/include/top.jsp&quot;&gt;&lt;/jsp:include&gt; 
&lt;h1&gt;제목&lt;/h1&gt;
&lt;p&gt;Lorem ipsum dolor sit amet, consectetur adipisicing elit.
 Quod ullam placeat cum pariatur at nulla eum iure neque rerum 
 corrupti veritatis fuga doloremque esse explicabo ut quia aspernatur numquam enim.
 Lorem ipsum dolor sit amet, consectetur adipisicing elit. Voluptatum dignissimos 
 molestias aspernatur voluptatem iure officia cumque fugit neque sint excepturi ut 
 eaque facilis rem illo at nostrum qui odit ab!&lt;/p&gt;
 &lt;!-- contextpath는 생략 가능 / webapp 아래의 경로를 줘야함 --&gt;
 &lt;jsp:include page=&quot;/include/bottom.jsp&quot;&gt;&lt;/jsp:include&gt;</code></pre>
<p>** ✔ top.jsp &gt;&gt; **</p>
<pre><code class="language-html">&lt;%@ page language=&quot;java&quot; contentType=&quot;text/html; charset=EUC-KR&quot;
    pageEncoding=&quot;EUC-KR&quot;%&gt;
&lt;!DOCTYPE html&gt;
&lt;html&gt;
&lt;head&gt;
&lt;meta charset=&quot;EUC-KR&quot;&gt;
&lt;title&gt;Top.jsp에서 정한 제목&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;table border=&quot;1&quot;&gt;
    &lt;tr&gt;
        &lt;th&gt;메뉴소개&lt;/th&gt;
        &lt;th&gt;찾아오시는 길&lt;/th&gt;
        &lt;th&gt;체인점&lt;/th&gt;
        &lt;th&gt;사이트맵&lt;/th&gt;
        &lt;th&gt;고객센터&lt;/th&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
        &lt;th&gt;
            &lt;ul&gt;
                &lt;li&gt;Side menu1&lt;/li&gt;
                &lt;li&gt;Side menu2&lt;/li&gt;
                &lt;li&gt;Side menu3&lt;/li&gt;
                &lt;li&gt;Side menu4&lt;/li&gt;
                &lt;li&gt;Side menu5&lt;/li&gt;
            &lt;/ul&gt;        
        &lt;/th&gt;
        &lt;td colspan=&quot;4&quot;&gt;
&lt;!-- 여기는 top.jsp이기 때문에 이하는 지워도된다 --&gt;</code></pre>
<p>** ✔ bottom.jsp &gt;&gt; **</p>
<pre><code class="language-html">&lt;%@ page language=&quot;java&quot; contentType=&quot;text/html; charset=EUC-KR&quot;
    pageEncoding=&quot;EUC-KR&quot;%&gt;
        &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
        &lt;th colspan=&quot;5&quot;&gt;
            전화번호 : 123-1234-1234 | 사업자등록번호 : 123-123-123
            | FAX : 1234-123-1234 ...
        &lt;/th&gt;
    &lt;/tr&gt;
&lt;/table&gt;
&lt;/body&gt;
&lt;/html&gt;</code></pre>
<p>** 📺 main.jsp 실행 결과 &gt;&gt; **
<img src="https://velog.velcdn.com/images/blcoding_2023/post/ee88e39c-48e8-4ee7-8e44-e01ebb2567fe/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Filter]]></title>
            <link>https://velog.io/@blcoding_2023/Filter</link>
            <guid>https://velog.io/@blcoding_2023/Filter</guid>
            <pubDate>Tue, 27 Jun 2023 07:58:30 GMT</pubDate>
            <description><![CDATA[<h1 id="🏁-filter">🏁 Filter</h1>
<ul>
<li>특정 주소로 접속할 때 이 필터를 거쳐서 지나가도록 만들 수 있다</li>
<li>web.xml에서 필터 등록을 한 후 특정 URL에 대한 매핑을 해놓을 수 있다</li>
<li>chain으로 다음 필터를 호출하면 </li>
<li>javax.servlet.Filter를 import 해야한다</li>
</ul>
<h2 id="🤺-filter-구현하기">🤺 Filter 구현하기</h2>
<pre><code class="language-java">public class MyFilter1 implements Filter {
    @Override
        public void init(FilterConfig filterConfig) throws ServletException {
            // 필터를 초기화하는 곳
        }    
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        // 필터 기능 수행 ... 
        chain.doFilter(request, response);// chain으로 다음 필터로 쿼리 전달
    }    
}</code></pre>
<ul>
<li>doFilter 메서드는 요청이 있을 때 마다 매번 실행된다
<a href="https://scshim.tistory.com/398">참고</a></li>
</ul>
<h2 id="🤺-filter-설정하기">🤺 Filter 설정하기</h2>
<ul>
<li>web.xml에서 모든 경로로 들어오는 요청에 대해(*/) 인코딩필터를 지나가도록 설정한다 </li>
<li>인코딩 필터를 지나가는 모든 request는 characterEncoding을 EUC-KR로 세팅하도록 설정한다</li>
</ul>
<p>** ✔ web.xml &gt;&gt; **</p>
<pre><code class="language-html">  &lt;filter&gt;
      &lt;filter-name&gt;characterEncodingFilter&lt;/filter-name&gt;
      &lt;filter-class&gt;chap10.filter.CharacterEncodingFilter&lt;/filter-class&gt;
  &lt;/filter&gt;

  &lt;filter-mapping&gt;
      &lt;filter-name&gt;characterEncodingFilter&lt;/filter-name&gt;
    &lt;!-- 모든 요청에 대해 인코딩을 수행 --&gt;
      &lt;servlet-name&gt;/*&lt;/servlet-name&gt; 
  &lt;/filter-mapping&gt;</code></pre>
<p>** ✔ CharacterEncodingFilter.java &gt;&gt; **</p>
<pre><code class="language-java">public class CharacterEncodingFilter implements Filter {
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        System.out.println(&quot;인코딩 필터를 지나감&quot;);

        // 모든 요청에 대한 인코딩 처리를 미리 진행할 수 있다
        request.setCharacterEncoding(&quot;EUC-KR&quot;);
        response.setCharacterEncoding(&quot;EUC-KR&quot;);

        chain.doFilter(request, response);
    }
}
</code></pre>
<hr>
<h1 id="🏁-listener">🏁 Listener</h1>
<ul>
<li>특정 이벤트(특정 사건)가 발생하기를 기다리다가 실행되는 컴포넌트(메서드나 함수)</li>
<li>ContextLoaderListener : Context 내부의 내용에 뭔가 변화가 있는 경우 ReLoad할 때 호출되는 이벤트리스너</li>
</ul>
<h2 id="🤺-리스너-등록하기">🤺 리스너 등록하기</h2>
<p>** ✔ web.xml &gt;&gt; **</p>
<pre><code class="language-html"> &lt;listener&gt;
      &lt;listener-class&gt;chap10.listener.MyServletRequestProcess&lt;/listener-class&gt;
 &lt;/listener&gt;
 &lt;listener&gt;
      &lt;listener-class&gt;chap10.listener.ContextLoaderListener&lt;/listener-class&gt;
  &lt;/listener&gt;</code></pre>
<p>** ✔ MyServletRequestProcess.java &gt;&gt; **</p>
<pre><code class="language-java">public class MyServletRequestProcess implements ServletRequestListener {
    @Override
    public void requestInitialized(ServletRequestEvent sre) {
        // 요청 초기화 시점
        //요청 시작 부분에 이벤트 처리 하고 싶은 내용을 적는다

        // sre 객체에 ServletRequest와 ServletContext가 모두 들어있다
        System.out.println(&quot;파라미터 : &quot; + sre.getServletRequest().getParameter(&quot;flavor&quot;));
        // 파라미터 꺼내서 찍어보기
    }    
    @Override
    public void requestDestroyed(ServletRequestEvent sre) {        
        //요청 마무리 부분에 이벤트 처리 하고 싶은 내용을 적는다
    }
}</code></pre>
<p>** ✔ ContextLoaderListener.java &gt;&gt; **</p>
<pre><code class="language-java">public class ContextLoaderListener implements ServletContextListener{
    @Override
    public void contextInitialized(ServletContextEvent sce) {
        System.out.println(&quot;ContextLoaderListener : 컨텍스트 내부에 뭔가 변화가 있습니다 ...&quot;);
        System.out.println(&quot;ContextLoaderListener : 다시 초기화합니다&quot;);
    }
        @Override
    public void contextDestroyed(ServletContextEvent sce) {
        System.out.println(&quot;ContextLoaderListener : ServletContext Destroyed ... &quot;);
    }
}</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[DispatcherServlet]]></title>
            <link>https://velog.io/@blcoding_2023/DispatcherServlet</link>
            <guid>https://velog.io/@blcoding_2023/DispatcherServlet</guid>
            <pubDate>Tue, 27 Jun 2023 04:38:27 GMT</pubDate>
            <description><![CDATA[<h1 id="🏁-dispatcherservlet">🏁 DispatcherServlet</h1>
<ul>
<li>HTTP 프로토콜로 들어오는 모든 요청을 가장 먼저 받아 적합한 컨트롤러에 위임해주는 프론트 컨트롤러(Front Controller)</li>
<li>쇼핑몰의 인포 데스크처럼 입구에서 기다리고 있다가 요청에 따라 길을 안내해주는 역할</li>
</ul>
<h2 id="🤺-dispatcherservlet-작성-순서">🤺 DispatcherServlet 작성 순서</h2>
<ol>
<li>디스패쳐 서블릿을 만들고 HttpServlet을 상속받고 init과 service를 오버라이드 해서 사용한다</li>
</ol>
<p>** ✔ DispatcherServlet.java (예시) &gt;&gt; **</p>
<pre><code class="language-java">public class DispatcherServlet extends HttpServlet{
    private Map&lt;String, RequestProcess&gt; processMapping = new HashMap&lt;&gt;();

    @Override
    public void init(ServletConfig config) throws ServletException {
        // config에서 application scope를 꺼내 contextPath를 꺼냄
        String contextPath = config.getServletContext().getContextPath();
        // 어떤 주소 + 어떤 요청 방식으로 접속했을 때 어떤 처리를 할 것인지 등록
        processMapping.put(contextPath + &quot;/hello::GET&quot;, new HelloProcess());
    }
    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        // 1. 사용자의 요청을 받는다
        System.out.println(&quot;사용자가 요청한 URL : &quot; + request.getRequestURL());
        System.out.println(&quot;사용자가 요청한 URI : &quot; + request.getRequestURI());
        System.out.println(&quot;요청 방식 : &quot; + request.getMethod());

        try {
            // 2. 요청한 URI와 Method에 맞는 처리를 진행한다 (객체지향화)
            //         -&gt; uri와 method로 알맞은 RequestProcess를 골라 process()를 실행시킨다
            String nextPage = processMapping.get(request.getRequestURI() + &quot;::&quot; + request.getMethod()).process(request, response);

            // 3. 처리 후 알맞은 view 페이지로 포워드 하거나 redirect한다
            if(nextPage.startsWith(&quot;redirect:&quot;)) {
                response.sendRedirect(nextPage.substring(&quot;redirect:&quot;.length()));
            }else {
            request.getRequestDispatcher(&quot;/WEB-INF/views&quot; + nextPage + &quot;.jsp&quot;).forward(request, response);
            }
        }catch(NullPointerException e) {
            response.getWriter().append(&quot;&lt;html&gt;&lt;script&gt;history.back();&lt;/script&gt;&lt;/html&gt;&quot;);
        }
    }
}</code></pre>
<ol start="2">
<li>web.xml에서 servlet, servlet-mapping 작성<pre><code class="language-html">&lt;servlet&gt;
   &lt;servlet-name&gt;appServlet&lt;/servlet-name&gt;
   &lt;servlet-class&gt;servlet.DispatcherServlet&lt;/servlet-class&gt;
&lt;/servlet&gt;
&lt;servlet-mapping&gt;
</code></pre>
</li>
</ol>
<!--이 경로로 들어오는 모든 요청에 대해 DispatcherServlet으로 가장먼저 들어오도록 한다-->
<p>  <servlet-name>appServlet</servlet-name>
  <url-pattern>/</url-pattern>
 </servlet-mapping></p>
<pre><code></code></pre>]]></description>
        </item>
    </channel>
</rss>