<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>bluepaper14_.log</title>
        <link>https://velog.io/</link>
        <description>가시방석 개발생활</description>
        <lastBuildDate>Sun, 05 Apr 2026 15:51:38 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>bluepaper14_.log</title>
            <url>https://velog.velcdn.com/images/bluepaper14_/profile/fbdfc988-efbc-4f60-96c5-f247066f4aff/image.png</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. bluepaper14_.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/bluepaper14_" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[[Spring Boot]API 방식]]></title>
            <link>https://velog.io/@bluepaper14_/Spring-BootAPI-%EB%B0%A9%EC%8B%9D</link>
            <guid>https://velog.io/@bluepaper14_/Spring-BootAPI-%EB%B0%A9%EC%8B%9D</guid>
            <pubDate>Sun, 05 Apr 2026 15:51:38 GMT</pubDate>
            <description><![CDATA[<h3 id="api">API</h3>
<blockquote>
<p><strong>API:</strong> 서로 다른 소프트웨어가 기능이나 데이터를 주고받을 수 있도록 정해놓은 인터페이스</p>
</blockquote>
<p>바로 코드를 확인해보자.</p>
<h3 id="예제">예제</h3>
<pre><code class="language-java">package hello.hello_spring.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
public class HelloController {

    @GetMapping(&quot;hello-api&quot;)
    @ResponseBody 
    public Hello helloApi(@RequestParam(&quot;name&quot;) String name) {
        Hello hello = new Hello();
        hello.setName(name); 
        return hello; 
    }

    static class Hello {
        private String name;
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
    }
}</code></pre>
<blockquote>
<p>@GetMapping :웹 브라우저에서 &#39;/hello-api&#39;요청이 들어오면 메서드 실행</p>
</blockquote>
<pre><code class="language-java">@GetMapping(&quot;hello-api&quot;)</code></pre>
<blockquote>
<p>@ResponseBody : HTTP의 BODY에 이 데이터를 직접 넣겠다는 선언</p>
</blockquote>
<pre><code class="language-java">@ResponseBody</code></pre>
<blockquote>
<p>?name=spring이라고 입력하면, Spring이 URL을 확인하고 spring이라는 글자를 추출해서 name이라는 변수에 넣는다. 데이터를 담을 Hello 객체를 하나 만듭니다. 그리고 아까 받은 name(&quot;spring&quot;)을 상자 안에 예쁘게 넣습니다(setName). 이를 리턴한다.</p>
</blockquote>
<pre><code class="language-java">public Hello helloApi(@RequestParam(&quot;name&quot;) String name) {
        Hello hello = new Hello();
        hello.setName(name); 
        return hello; 
    }</code></pre>
<p>** 1. HTTP 요청 **
웹 브라우저나 클라이언트가 URL을 통해 서버에 요청을 보낸다.</p>
<p>예시: /hello-api?name=spring -&gt; 데이터가 전달</p>
<p><strong>2. 컨트롤러 매핑 및 파라미터 바인딩</strong>
해당 URL을 처리할 컨트롤러(HelloController)를 찾는다. -&gt; controll 먼저</p>
<p><strong>@RequestParam</strong>(&quot;name&quot;)에 의해 URL의 spring이라는 문자열이 자바 변수 String name에 할당</p>
<p><strong>3. @ResponseBody와 컨버터 작동</strong>
메서드가 hello 객체를 리턴하면, Spring은 @ResponseBody 어노테이션을 확인</p>
<p>ViewResolver 대신 <strong>HttpMessageConverter가 선택</strong></p>
<p>리턴 타입이 객체이므로, <strong>JSON 변환기인 MappingJackson2HttpMessageConverter</strong>가 동작</p>
<p>*<em>5. JSON 응답 *</em>
변환기가 자바 객체를 JSON 문자열로 바꾼 뒤, HTTP 응답 바디에 담아 클라이언트에 보냄</p>
<p>최종 결과값: {&quot;name&quot;:&quot;spring&quot;}</p>
<h3 id="gettersetter">Getter/Setter</h3>
<p>private String name;만 쓰는것이 아니다. 왜냐하면 데이터를 넣고 뺄 수 있는 공식적인 통로가 필요하다.API 방식(JSON 변환)이 작동하려면 이 구조가 필수다.</p>
<pre><code class="language-java">static class Hello {
        private String name;
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
    }</code></pre>
<p>스프링이 객체를 JSON으로 바꿀 때 쓰는 도구다. 객체의 변수(name)를 직접 보는 게 아니라, getName()이라는 메서드 이름을 보고 &quot;아, 이 객체에는 name이라는 데이터가 있구나!&quot;라고 판단한다</p>
<pre><code class="language-java">@Controller // 스프링이 시작될 때 이 클래스를 &#39;컨트롤러(서버 입구)&#39;로 자동 등록합니다.
public class HelloController {

    @GetMapping(&quot;hello-api&quot;) // 사용자가 주소창에 /hello-api 라고 치고 들어오면 아래 메서드를 실행합니다.
    @ResponseBody // 중요! 이 메서드의 결과물을 HTML 파일에서 찾는 게 아니라, HTTP 응답의 바디(Body)에 직접 넣어서 보내겠다는 뜻입니다.
    public Hello helloApi(@RequestParam(&quot;name&quot;) String name) { 
        // @RequestParam(&quot;name&quot;): 주소창의 ?name=spring 부분에서 &#39;spring&#39;을 꺼내서 자바 변수 &#39;name&#39;에 저장합니다.
        // Hello helloApi(...): 이 메서드는 최종적으로 &#39;Hello&#39;라는 객체(데이터 상자)를 밖으로 내보냅니다.

        Hello hello = new Hello(); // 데이터를 담기 위해 위에서 정의한 &#39;Hello&#39;라는 이름의 빈 상자(객체)를 하나 새로 만듭니다.
        hello.setName(name); // 사용자가 보내준 &#39;spring&#39;이라는 이름을 그 상자 안에 집어넣습니다.

        return hello; // 상자(객체)를 그대로 반환합니다. @ResponseBody가 붙어있으므로, 스프링이 이 상자를 JSON(문자 데이터)으로 자동 변환해서 사용자에게 쏩니다.
    }

    // 데이터를 담는 전용 상자의 설계도입니다.
    static class Hello {
        private String name; // 이름 데이터를 저장할 공간입니다. &#39;private&#39;은 외부에서 이 변수를 직접 만지지 못하게 잠가둔 것입니다.

        // 상자 안의 이름을 밖으로 꺼내주는 통로(Getter)입니다. 스프링(Jackson 라이브러리)이 이 메서드를 호출해서 JSON을 만듭니다.
        public String getName() {
            return name;
        }

        // 상자 안에 이름을 새로 저장하거나 바꿀 때 쓰는 통로(Setter)입니다.
        public void setName(String name) {
            this.name = name; // 여기서 &#39;this.name&#39;은 위에서 선언한 변수이고, &#39;name&#39;은 밖에서 전달받은 새로운 이름입니다.
        }
    }
}</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Spring Boot]MVC]]></title>
            <link>https://velog.io/@bluepaper14_/Spring-BootMVC</link>
            <guid>https://velog.io/@bluepaper14_/Spring-BootMVC</guid>
            <pubDate>Fri, 03 Apr 2026 07:41:08 GMT</pubDate>
            <description><![CDATA[<h3 id="mvc">MVC</h3>
<blockquote>
<p><strong>MVC</strong>(Model, View, Controller) : 데이터, 화면, 제어 로직을 분리하여 각자의 역할에만 집중하게 만드는 소프트웨어 설계 방식</p>
</blockquote>
<p>바로 코드로 확인해보자.</p>
<h3 id="예제코드">예제코드</h3>
<p>초기 설정으로는 현재 controller패키지 안에 HelloController 그리고 templates내부에 hello.html이 존재한다. </p>
<pre><code class="language-java">package hello.hello_spring.controller;

import org.springframework.ui.Model;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;

@Controller
public class HelloController {
    @GetMapping(&quot;hello&quot;)
    public String hello(Model model) {
        model.addAttribute(&quot;data&quot;, &quot;spring!!&quot;);
        return &quot;hello&quot;;
    }
}</code></pre>
<blockquote>
<p>@Controller: 이 클래스가 스프링 MVC의 컨트롤러임을 선언하고 있다. 스프링 컨테이너가 실행될 때 이 애노테이션(라벨)을 보고 객체를 생성하여 관리한다.</p>
</blockquote>
<pre><code class="language-java">@Controller</code></pre>
<blockquote>
<p>@GetMapping : 웹 브라우저에서 &#39;/hello&#39;라는 경로로 <em>GET</em> 방식의 요청이 들어오면 이 메서드를 실행합니다.</p>
</blockquote>
<pre><code class="language-java">@GetMapping(&quot;hello&quot;)</code></pre>
<p>GET은 서버로부터 정보를 조회하기 위한 요청 방식이다. POST는 서버의 리소스를 생성하거나 데이터를 제출하기 위한 방식이다.</p>
<p>정리하면 서버는 주소창에 hello라고 치고 들어온 GET요청은 이 메서드에서 처리하자! 라는 의미.</p>
<blockquote>
<p>Model 객체 : 데이터를 담아서 뷰로 전달하는 바구니 역할이다.
key는 data value는 spring!!으로 설정하여 모델에 담았다.
View Resolver : 컨트롤러에서 문자열을 반환하면 뷰 리졸버가 해당 이름의 파일을 찼는다. 기본적으로 &#39;resources/templates/hello.html&#39; 파일을 찾아 렌더링한다.</p>
</blockquote>
<pre><code class="language-java">public String hello(Model model) {
        model.addAttribute(&quot;data&quot;, &quot;spring!!&quot;);
        return &quot;hello&quot;;
    }</code></pre>
<pre><code class="language-html">&lt;!DOCTYPE HTML&gt;
&lt;html xmlns:th=&quot;http://www.thymeleaf.org&quot;&gt;
&lt;head&gt;
    &lt;title&gt;Hello&lt;/title&gt;
    &lt;meta http-equiv=&quot;Content-Type&quot; content=&quot;text/html; charset=UTF-8&quot; /&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;p th:text=&quot;&#39;안녕하세요. &#39; + ${data}&quot; &gt;안녕하세요. 손님&lt;/p&gt;
&lt;/body&gt;
&lt;/html&gt;</code></pre>
<p>정리하면 프로그램 순서는 이러하다.</p>
<ol>
<li>사용자 요청(localhost:8080/hello)</li>
<li>Controller Mapping(GET요청 인식하고 메서드 실행)</li>
<li>Model 준비(Model 객체에 값 담아 준비)</li>
<li>View 찾기(파일 찾아 랜더링 할준비함)</li>
<li>응답(${data}부분을 추적하여 값으로 치환)</li>
</ol>
]]></description>
        </item>
        <item>
            <title><![CDATA[깃허브 프로젝트 기초]]></title>
            <link>https://velog.io/@bluepaper14_/%EA%B9%83%ED%97%88%EB%B8%8C-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%EA%B4%80%EB%A6%AC%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@bluepaper14_/%EA%B9%83%ED%97%88%EB%B8%8C-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%EA%B4%80%EB%A6%AC%ED%95%98%EA%B8%B0</guid>
            <pubDate>Tue, 16 Dec 2025 07:58:06 GMT</pubDate>
            <description><![CDATA[<h3 id="들어가기-전">들어가기 전..</h3>
<p>GitHub를 주제로 어떻게 글을 쓸지 고민이 많았다. GitHub를 제대로 이해하려면 Git에 대한 기본 개념이 선행되어야 하는데 그렇다고 설치 과정이나 환경 설정까지 구구절절 다루는 것이 맞나 싶다.</p>
<p>이번 글은 세부적인 설정이나 복잡한 명령어보다는 프로젝트를 시작하는 시점에서 GitHub를 활용해 어떻게 기초적인 관리를 할 수 있는지를 중심으로 정리하려고 한다. 프로젝트를 생성하고 변경 사항을 관리하며 작업이 어떤 흐름으로 이어지는지 그 전반적인 맥락을 이해하는 데 초점을 맞췄다. 이 정도 흐름만 파악해도 활용하는 데 큰 무리는 없을 것이다.</p>
<p><img src="https://velog.velcdn.com/images/bluepaper14_/post/1bdace25-b730-4043-9f5f-ffd2f65b2399/image.png" alt=""></p>
<h3 id="git-그리고-github">Git 그리고 Github</h3>
<p>GitHub를 사용하려면 먼저 Git이 있어야 한다. 비유하자면 인스타그램에 사진을 올리려면 먼저 사진을 찍는 도구(카메라)가 필요한데 이 촬영 도구가 바로 Git이다.</p>
<blockquote>
<p>Git으로 관리한 코드를 업로드해 저장하는 있는 장소가 Github</p>
</blockquote>
<p>이게 끝이다. 굳이 이렇게 나누어 사용하는 이유는 코드의 과거 시점으로 되돌리기가 편하고 여러 명이 동시에 작업할 때 이점이 많다. 그럼 바로 Git을 사용해 보자.</p>
<blockquote>
<p><a href="https://git-scm.com/book/ko/v2">https://git-scm.com/book/ko/v2</a> (Git 공식문서 참조)</p>
</blockquote>
<h3 id="git-init">Git init</h3>
<p>Git 최초 설정은 생략하고 빠르게 vsCode에서 Github에 소스를 업로드해보자.</p>
<pre><code>git init</code></pre><p>프로젝트 폴더에서 해당 명령어를 입력한다. git init은 일반 디렉토리를 Git이 관리하는 로컬 저장소로 변환해 준다. 이제부터 이 폴더 안의 모든 변경 사항을 Git이 추적하겠다고 선언하는 것이다.</p>
<p><img src="https://velog.velcdn.com/images/bluepaper14_/post/91090e30-0c88-4cf8-a1f5-5fee198647a6/image.png" alt=""></p>
<p>명령어를 실행하면 위와 같이 폴더가 Git으로 관리되기 시작한다. 이제 버전 관리가 가능하다는 뜻이다. 만약 이런 메시지가 출력되지 않는다면 Git 설치가 제대로 되었는지 확인해 봐야 한다.</p>
<h3 id="git-status">Git status</h3>
<p>파일을 새로 생성했다면 에디터에 색깔이 변하는 등 신호가 올 것이다. Git이 새로운 파일을 감지했다는 뜻이다. </p>
<pre><code>git status</code></pre><p>위 명령어는 Git에서 현재 상태를 알 수 있다. 확인해보자. </p>
<p><img src="https://velog.velcdn.com/images/bluepaper14_/post/c0c66b96-8d96-48c3-8f6e-51f39d769d03/image.png" alt=""></p>
<pre><code class="language-cmd">test&gt;git status On branch master

No commits yet

Untracked files: 
    (use &quot;git add &lt;file&gt;...&quot; to include in what will be committed)
          test.md

nothing added to commit but untracked files present (use &quot;git add&quot; to track)</code></pre>
<p>출력 내용을 보면 현재 브랜치이름이 master임을 알 수 있고 아직 커밋(저장)이 하나도 없다고 나온다. 중요한 점은 test.md 파일이 Untracked files(추적되지 않음) 목록에 있다는 것이다. Git이 이 파일을 관리하게 하려면 <u><strong>스테이징(Staging)</strong>이라는 단계</u>가 필요하다.</p>
<h3 id="스테이징이-뭘까요">스테이징이 뭘까요?</h3>
<p>스테이징이라는 개념을 명확히 알아야만 기초적인 프로젝트 관리를 할 수 있다. Git에서 파일은 세 가지 상태가 존재하는데 Commited modified Staged이다. </p>
<table>
<thead>
<tr>
<th>상태</th>
<th>의미</th>
<th>위치/단계</th>
</tr>
</thead>
<tbody><tr>
<td><strong>Committed</strong></td>
<td>파일이 로컬 데이터베이스(Git 디렉토리)에 안전하게 저장됨</td>
<td>Git 디렉토리</td>
</tr>
<tr>
<td><strong>Modified</strong></td>
<td>워킹 트리에서 파일을 수정했지만 아직 커밋하지 않음</td>
<td>워킹 트리</td>
</tr>
<tr>
<td><strong>Staged</strong></td>
<td>수정한 파일을 곧 커밋할 것으로 표시</td>
<td>Staging Area (Index)</td>
</tr>
</tbody></table>
<p><img src="https://velog.velcdn.com/images/bluepaper14_/post/64dff1cd-5844-4d5d-abd0-2fe293483bfa/image.jpeg" alt=""></p>
<p>수정(Modified) -&gt; 스테이징(Staged) -&gt; 커밋(Committed) 순서로 파일을 업로드하게 된다. 굳이 스테이징 단계가 필요한 이유는 <strong>&#39;부분 커밋&#39;</strong>이 가능하기 때문이다. 내가 수정한 파일이 10개라도, 이번에는 3개만 골라서 기록하고 싶을 때 유용하다. 이제 파일을 스테이징 해보자.</p>
<h3 id="git-add">Git add</h3>
<p><img src="https://velog.velcdn.com/images/bluepaper14_/post/f7dec78b-5c4f-4d64-8200-fb415ad63ea0/image.png" alt=""></p>
<pre><code class="language-cmd">test&gt;git add test.md

test&gt;git status
On branch master

No commits yet

Changes to be committed:
  (use &quot;git rm --cached &lt;file&gt;...&quot; to unstage)
        new file:   test.md
test&gt;</code></pre>
<p>git add 파일명을 입력하여 test.md를 Staging Area에 올렸다. 상태를 확인해 보면 Changes to be committed(커밋 될 변경 사항) 목록에 파일이 들어온 것을 볼 수 있다. 물론 아직 저장이 완료된 것은 아니다.</p>
<p>만약 모든 파일을 한 번에 스테이징하거나, 스테이징을 취소하고 싶다면 아래 명령어들을 참고하자.</p>
<pre><code>git add .               # 변경된 모든 파일 스테이징
git rm --cached test.md # 특정 파일 스테이징 취소
git reset               # 모든 스테이징 취소</code></pre><p>이렇게 입력해주면 다시 돌아간다. 바로 커밋해보자. </p>
<h3 id="git-commit">Git commit</h3>
<p><img src="https://velog.velcdn.com/images/bluepaper14_/post/5d2c6a0e-3468-455a-b939-180e4b20226d/image.png" alt=""></p>
<pre><code class="language-cmd">test&gt;git commit -m &quot;First test code&quot; 
[master (root-commit) a8480e7] First test code
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 test.md

test&gt;git status
On branch master
nothing to commit, working tree clean

test&gt;</code></pre>
<p>-m 옵션 뒤에 큰따옴표로 감싸서 커밋 메시지를 작성하면 된다. 이 메시지는 히스토리에 남으므로 명확하게 적는 습관을 들이는 것이 좋다.(보통 짧게 적는편)이후 git status로 확인해 보면 &quot;working tree clean&quot;, 즉 더 이상 저장할 변경 사항 없이 깨끗한 상태임을 알 수 있다.</p>
<h3 id="github-원격-저장소-만들기">Github 원격 저장소 만들기</h3>
<p>GitHub 웹사이트에서 New Repository를 클릭해 저장소를 만들면 원격 저장소 URL을 확인할 수 있다. 이를 내 컴퓨터(로컬)의 Git과 연결해 보자.</p>
<pre><code>git remote add origin https://github.com/당신깃헙닉네임/TEST-code.git</code></pre><p>이런식으로 등록하게되면 아래와 같은 출력이다.</p>
<p><img src="https://velog.velcdn.com/images/bluepaper14_/post/dbff9244-875b-4da0-b700-bd66ad07f003/image.png" alt=""></p>
<p>origin은 원격 저장소의 기본 별칭(Alias)이다. fetch는 데이터를 가져올 때, push는 데이터를 보낼 때 사용하는 주소인데 보통 동일하다. 이제 내 컴퓨터의 작업물을 GitHub로 쏘아 올릴 차례다.</p>
<p>최종적으로 master 브랜치 커밋을 원격 저장소에 업로드하자. </p>
<h3 id="git-push">Git push</h3>
<p><img src="https://velog.velcdn.com/images/bluepaper14_/post/e46e42db-a100-488d-9cf2-cf83751fb04b/image.png" alt=""></p>
<pre><code>git push -u origin master</code></pre><p>master 브랜치의 커밋 내역을 원격 저장소(origin)에 업로드하는 명령어다. 이 과정이 끝나면 GitHub 새로고침 시 내 코드가 올라와 있는 것을 확인할 수 있다.</p>
<p>기초적인 프로젝트 관리이다. 요즘은 GUI 도구(SourceTree, GitKraken)나 VS Code 확장 프로그램 덕분에 클릭 한 번이면 해결되는 세상이다. 하지만 무언가 꼬였을 때 터미널에서 직접 상태를 확인하고 명령어를 치는 것이 가장 확실한 해결책이 되기도 한다. 그러니 한 번쯤은 직접 타이핑해 보며 흐름을 익혀두길 바란다.</p>
<p>다음 글에서는 브랜치(Branch)를 활용하고, 실제로 PR(Pull Request)을 날려 이슈를 관리하는 협업 과정을 다뤄볼 예정이다.</p>
]]></description>
        </item>
    </channel>
</rss>