<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Spring on j2234's log</title><link>https://log.j2234.cc/tags/spring/</link><description>Recent content in Spring on j2234's log</description><generator>Hugo -- gohugo.io</generator><language>en</language><copyright>© 2026</copyright><lastBuildDate>Tue, 07 Apr 2026 15:25:58 +0000</lastBuildDate><atom:link href="https://log.j2234.cc/tags/spring/index.xml" rel="self" type="application/rss+xml"/><item><title>RabbitMQ 기초</title><link>https://log.j2234.cc/posts/velog/003-rabbitmq-%EA%B8%B0%EC%B4%88/</link><pubDate>Sun, 27 Apr 2025 21:22:54 +0000</pubDate><guid>https://log.j2234.cc/posts/velog/003-rabbitmq-%EA%B8%B0%EC%B4%88/</guid><description>&lt;figure&gt;&lt;img
 class="my-0 rounded-md"
 loading="lazy"
 decoding="async"
 fetchpriority="auto"
 alt=""
 width="500"
 height="500"
 src="https://log.j2234.cc/posts/velog/003-rabbitmq-%EA%B8%B0%EC%B4%88/img/image-01.webp"
 srcset="https://log.j2234.cc/posts/velog/003-rabbitmq-%EA%B8%B0%EC%B4%88/img/image-01.webp 800w, https://log.j2234.cc/posts/velog/003-rabbitmq-%EA%B8%B0%EC%B4%88/img/image-01.webp 1280w"
 sizes="(min-width: 768px) 50vw, 65vw"
 data-zoom-src="https://log.j2234.cc/posts/velog/003-rabbitmq-%EA%B8%B0%EC%B4%88/img/image-01.webp"&gt;&lt;/figure&gt;
&lt;blockquote&gt;&lt;p&gt;이 글은 RabbitMQ의 기본적인 개념과 spring에서 연동 방법을 기초 수준에서 설명한다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 class="relative group"&gt;RabbitMQ란?
 &lt;div id="rabbitmq란" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#rabbitmq%eb%9e%80" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;플랫폼 중립적인 메시징 및 스트리밍 브로커로,&lt;a href="https://www.rabbitmq.com/docs/protocols" target="_blank" rel="noreferrer"&gt;AMQP,MQTT 등의 여러 개방형 표준 프로토콜&lt;/a&gt;을 지원해 다양한 언어와 플랫폼 간 메시지 송수신을 처리한다.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/rabbitmq" target="_blank" rel="noreferrer"&gt;오픈소스&lt;/a&gt;이며 MPL2.0 라이센스를 따른다.&lt;/p&gt;

&lt;h2 class="relative group"&gt;설치
 &lt;div id="설치" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#%ec%84%a4%ec%b9%98" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;다음 &lt;code&gt;docker-compose.yml&lt;/code&gt; 파일로 연습용 RabbitMQ 서버를 간단히 띄울 수 있다. &lt;em&gt;클러스터 구성 등의 정보도 구글링하면 쉽게찾을 수 있음!!&lt;/em&gt;&lt;/p&gt;</description><media:content xmlns:media="http://search.yahoo.com/mrss/" url="https://log.j2234.cc/posts/velog/003-rabbitmq-%EA%B8%B0%EC%B4%88/featured.webp"/></item><item><title>OIDC 구현(GOOGLE)</title><link>https://log.j2234.cc/posts/velog/004-oidc-%EA%B5%AC%ED%98%84google/</link><pubDate>Sat, 19 Apr 2025 00:01:19 +0000</pubDate><guid>https://log.j2234.cc/posts/velog/004-oidc-%EA%B5%AC%ED%98%84google/</guid><description>&lt;p&gt;이 글에 등장하는 전체 코드는 &lt;a href="https://github.com/jiheon2234-s-lab/spring_oidc" target="_blank" rel="noreferrer"&gt;깃허브 저장소&lt;/a&gt;에서 확인할 수 있다.&lt;/p&gt;
&lt;p&gt;OIDC는 OAuth2에 인증 기능을 추가한 확장 프로토콜이므로, 구현 과정은 &lt;a href="https://velog.io/@jiheon2234/OAuth2%EC%99%80-OIDC-%EA%B5%AC%ED%98%84" target="_blank" rel="noreferrer"&gt;이전 글&lt;/a&gt;과 거의 동일하지만&amp;hellip;
제공자가 OIDC를 지원해야만 이 방식으로 구현이 가능하다.&lt;/p&gt;

&lt;h3 class="relative group"&gt;사용자 로그인 진입점
 &lt;div id="사용자-로그인-진입점" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#%ec%82%ac%ec%9a%a9%ec%9e%90-%eb%a1%9c%ea%b7%b8%ec%9d%b8-%ec%a7%84%ec%9e%85%ec%a0%90" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h3&gt;
&lt;p&gt;OIDC에서는 로그인 페이지로 진입할 때,&lt;br&gt;
OAuth2에서 전달하는 기본 파라미터(&lt;code&gt;client_id&lt;/code&gt;, &lt;code&gt;response_type&lt;/code&gt;, &lt;code&gt;redirect_uri&lt;/code&gt;)에 &lt;strong&gt;&lt;code&gt;scope&lt;/code&gt;파라미터가 필수로 포함된다.&lt;/strong&gt; 이 &lt;code&gt;scope&lt;/code&gt;에는 반드시 &lt;code&gt;openid&lt;/code&gt;가 포함되어야 하며, 필요한 사용자 정보 항목을 추가로 명시할 수 있다.&lt;/p&gt;</description></item><item><title>OAuth2 구현(naver)</title><link>https://log.j2234.cc/posts/velog/005-oauth2-%EA%B5%AC%ED%98%84naver/</link><pubDate>Fri, 18 Apr 2025 22:01:25 +0000</pubDate><guid>https://log.j2234.cc/posts/velog/005-oauth2-%EA%B5%AC%ED%98%84naver/</guid><description>&lt;p&gt;이 글에 등장하는 전체 코드는 &lt;a href="https://github.com/jiheon2234-s-lab/spring_oidc" target="_blank" rel="noreferrer"&gt;깃허브 저장소&lt;/a&gt;에서 확인할 수 있다.&lt;/p&gt;

&lt;h3 class="relative group"&gt;사용자 로그인 진입점
 &lt;div id="사용자-로그인-진입점" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#%ec%82%ac%ec%9a%a9%ec%9e%90-%eb%a1%9c%ea%b7%b8%ec%9d%b8-%ec%a7%84%ec%9e%85%ec%a0%90" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;index.html&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;사용자가 네이버 로그인 버튼을 클릭하면, 다음과 같은 URL로 이동한다:
&lt;code&gt;https://nid.naver.com/oauth2.0/authorize?&lt;/code&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;client_id={내 네이버 클라이언트 ID}&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;response_type=code&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;redirect_uri={네이버 개발자센터에 등록된 내 서버 URI}&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;해당 화면에서 사용자는 네이버 계정으로 인증을 진행하게 된다.&lt;/p&gt;

&lt;h3 class="relative group"&gt;리다이렉트
 &lt;div id="리다이렉트" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#%eb%a6%ac%eb%8b%a4%ec%9d%b4%eb%a0%89%ed%8a%b8" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h3&gt;
&lt;p&gt;인증이 성공하면, 사용자는 &lt;code&gt;redirect_uri&lt;/code&gt;로 이동한다.&lt;/p&gt;</description></item><item><title>OAuth2와 OIDC</title><link>https://log.j2234.cc/posts/velog/006-oauth2%EC%99%80-oidc/</link><pubDate>Fri, 18 Apr 2025 14:49:50 +0000</pubDate><guid>https://log.j2234.cc/posts/velog/006-oauth2%EC%99%80-oidc/</guid><description>&lt;p&gt;어떤 멘토 분이 이런 말을 하셨다.&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;&amp;ldquo;요즘은 Spring Security에 OAuth2 라이브러리 하나만 추가해놓고&lt;br&gt;
소셜 로그인 인증을 구현했다고 한다.&lt;br&gt;
과연 이렇게 구현한 사람들이 OAuth2에 대해 안다고 할 수 있을까?&lt;br&gt;
OIDC가 뭔지는 알기나 할까?&amp;rdquo;&lt;/p&gt;
&lt;/blockquote&gt;&lt;p&gt;이 말을 듣고 찔려서 공부해보겠다.&lt;/p&gt;

&lt;h2 class="relative group"&gt;OAuth2는 인증 프로토콜이 아니라 &amp;ldquo;인가&amp;rdquo; 프로토콜이다.
 &lt;div id="oauth2는-인증-프로토콜이-아니라-인가-프로토콜이다" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#oauth2%eb%8a%94-%ec%9d%b8%ec%a6%9d-%ed%94%84%eb%a1%9c%ed%86%a0%ec%bd%9c%ec%9d%b4-%ec%95%84%eb%8b%88%eb%9d%bc-%ec%9d%b8%ea%b0%80-%ed%94%84%eb%a1%9c%ed%86%a0%ec%bd%9c%ec%9d%b4%eb%8b%a4" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;&lt;del&gt;Authentication&lt;/del&gt; &lt;strong&gt;Authorization&lt;/strong&gt;
많은 글들이 OAuth2예시를 설명하면서, 이를 구분하지 않는다. 거의 &lt;code&gt;소셜 로그인 == OAuth2 로그인&lt;/code&gt; 정도로 취급되지만, OAuth2의 목적은 인증이 아닌 &lt;strong&gt;인가&lt;/strong&gt;이다.&lt;/p&gt;</description></item><item><title>3. 도메인 개발</title><link>https://log.j2234.cc/posts/velog/032-3.-%EB%8F%84%EB%A9%94%EC%9D%B8-%EA%B0%9C%EB%B0%9C/</link><pubDate>Fri, 29 Sep 2023 22:26:02 +0000</pubDate><guid>https://log.j2234.cc/posts/velog/032-3.-%EB%8F%84%EB%A9%94%EC%9D%B8-%EA%B0%9C%EB%B0%9C/</guid><description>&lt;p&gt;이 강의에서는 따로 적을게 별로없다. &lt;del&gt;그냥 개발하는 내용이 다임&lt;/del&gt;&lt;/p&gt;

&lt;h2 class="relative group"&gt;테스트 환경설정
 &lt;div id="테스트-환경설정" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#%ed%85%8c%ec%8a%a4%ed%8a%b8-%ed%99%98%ea%b2%bd%ec%84%a4%ec%a0%95" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;blockquote&gt;&lt;p&gt;테스트를 할때, 기본적으로 &lt;code&gt;/test/resources/application.yml&lt;/code&gt;에 있는 설정 파일을 먼져 읽는다. (없으면 기본 파일읽음)
따라서, 이곳에 테스트에서의 설정을 생성할 수 있다.&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;또한, 스프링부트는 아무 설정이 안되어있는 경우, 기본적으로 메모리DB(H2)로 설정을 한다.
따라서, 빈 application.yml을 만들기만 하면, 기본적으로 메모리DB가 설정된다.&lt;/p&gt;
&lt;/blockquote&gt;&lt;/blockquote&gt;
&lt;h2 class="relative group"&gt;동적쿼리
 &lt;div id="동적쿼리" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#%eb%8f%99%ec%a0%81%ec%bf%bc%eb%a6%ac" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;blockquote&gt;&lt;p&gt;JPA에서 기본적인 동적쿼리는 지원하지만, 코드가 진짜 끔찍해진다.
따라서 QueryDsl과의 동작이 잘 어울린다.&lt;/p&gt;</description></item><item><title>빈 스코프</title><link>https://log.j2234.cc/posts/velog/041-%EB%B9%88-%EC%8A%A4%EC%BD%94%ED%94%84/</link><pubDate>Sun, 12 Mar 2023 19:48:49 +0000</pubDate><guid>https://log.j2234.cc/posts/velog/041-%EB%B9%88-%EC%8A%A4%EC%BD%94%ED%94%84/</guid><description>&lt;h2 class="relative group"&gt;빈 스코프란?
 &lt;div id="빈-스코프란" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#%eb%b9%88-%ec%8a%a4%ec%bd%94%ed%94%84%eb%9e%80" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;blockquote&gt;&lt;p&gt;빈이 존재할 수 있는 범위&lt;/p&gt;
&lt;/blockquote&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;싱글톤&lt;/strong&gt; : 기본 스코프, 스프링 컨테이너의 시작~종료&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;프로토타입&lt;/strong&gt; : 스프링 컨테이너는 프로토타입 빈의 생성과 의존관계 주입까지만 관여&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;웹 관련 스코프&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;request&lt;/strong&gt; : 웹 요청이 들어오고 나갈때까지&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;session&lt;/strong&gt; : 웹 세션이 생성되고 종료될때까지&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;application&lt;/strong&gt; : 웹의 서블릿 컨텍스트와 같은 범위로 유지&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;

&lt;h2 class="relative group"&gt;프로토타입 스코프
 &lt;div id="프로토타입-스코프" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#%ed%94%84%eb%a1%9c%ed%86%a0%ed%83%80%ec%9e%85-%ec%8a%a4%ec%bd%94%ed%94%84" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;blockquote&gt;&lt;p&gt;싱글톤 스코프의 빈을 조회하면, 항상 같은 인스턴스의 스프링 빈을 반환&lt;/p&gt;</description><media:content xmlns:media="http://search.yahoo.com/mrss/" url="https://log.j2234.cc/posts/velog/041-%EB%B9%88-%EC%8A%A4%EC%BD%94%ED%94%84/featured.webp"/></item><item><title>빈 생명주기 콜백</title><link>https://log.j2234.cc/posts/velog/042-%EB%B9%88-%EC%83%9D%EB%AA%85%EC%A3%BC%EA%B8%B0-%EC%BD%9C%EB%B0%B1/</link><pubDate>Sun, 12 Mar 2023 16:41:49 +0000</pubDate><guid>https://log.j2234.cc/posts/velog/042-%EB%B9%88-%EC%83%9D%EB%AA%85%EC%A3%BC%EA%B8%B0-%EC%BD%9C%EB%B0%B1/</guid><description>&lt;h2 class="relative group"&gt;빈 생명주기 콜백이란?
 &lt;div id="빈-생명주기-콜백이란" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#%eb%b9%88-%ec%83%9d%eb%aa%85%ec%a3%bc%ea%b8%b0-%ec%bd%9c%eb%b0%b1%ec%9d%b4%eb%9e%80" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;blockquote&gt;&lt;p&gt;db커넥션 풀이나, 네트워크 소캣처럼 연결을 미리 해두고, 어플리케이션 종료 시점에 연결을 모두 종료하라면 객체의 초기화와 종료 작업이 필요&lt;/p&gt;
&lt;/blockquote&gt;&lt;ul&gt;
&lt;li&gt;스프링은 의존관계 주입이 완료되면, &lt;strong&gt;스프링 빈에게 콜백 메서드를 통해서&lt;/strong&gt; 초기화 시점을 알려줌&lt;/li&gt;
&lt;li&gt;또한, 스프링 컨테이너가 종료되기 직전에 &lt;strong&gt;소멸 콜백&lt;/strong&gt;을 줌&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;빈 생명주기 콜백 지원 3가지 방법&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;인터페이스(InitializingBean, DisposableBean)&lt;/li&gt;
&lt;li&gt;설정 정보에 초기화 메서드, 종료 메서드 지정&lt;/li&gt;
&lt;li&gt;@PostConstruct, @PreDestroy&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;

&lt;h2 class="relative group"&gt;인터페이스
 &lt;div id="인터페이스" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#%ec%9d%b8%ed%84%b0%ed%8e%98%ec%9d%b4%ec%8a%a4" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;&lt;em&gt;초창기에 나온 방법으로, 거의 사용안함&lt;/em&gt;&lt;/p&gt;</description></item><item><title>의존관계 자동 주입</title><link>https://log.j2234.cc/posts/velog/043-%EC%9D%98%EC%A1%B4%EA%B4%80%EA%B3%84-%EC%9E%90%EB%8F%99-%EC%A3%BC%EC%9E%85/</link><pubDate>Mon, 06 Mar 2023 22:37:41 +0000</pubDate><guid>https://log.j2234.cc/posts/velog/043-%EC%9D%98%EC%A1%B4%EA%B4%80%EA%B3%84-%EC%9E%90%EB%8F%99-%EC%A3%BC%EC%9E%85/</guid><description>&lt;h2 class="relative group"&gt;의존관계 주입 방법
 &lt;div id="의존관계-주입-방법" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#%ec%9d%98%ec%a1%b4%ea%b4%80%ea%b3%84-%ec%a3%bc%ec%9e%85-%eb%b0%a9%eb%b2%95" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;blockquote&gt;&lt;p&gt;생성자, 수정자, 필드 ,메서드 4가지&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 class="relative group"&gt;생성자 주입
 &lt;div id="생성자-주입" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#%ec%83%9d%ec%84%b1%ec%9e%90-%ec%a3%bc%ec%9e%85" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;생성자를 통해 주입받는 방법&lt;/li&gt;
&lt;li&gt;생성자 호출시점에 단 한번만 (불변, 필수)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;em&gt;생성자가 딱 1개만 있으면 @Autowired를 생략해도 자동 주입&lt;/em&gt;&lt;/p&gt;

&lt;h3 class="relative group"&gt;수정자 주입
 &lt;div id="수정자-주입" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#%ec%88%98%ec%a0%95%ec%9e%90-%ec%a3%bc%ec%9e%85" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;setter&lt;/code&gt;을 통해 의존관계 주입&lt;/li&gt;
&lt;li&gt;&lt;code&gt;선택, 변경&lt;/code&gt; 가능성이 있는 의존관계에 사용 (거의 사용할일 없음)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 class="relative group"&gt;필드 주입
 &lt;div id="필드-주입" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#%ed%95%84%eb%93%9c-%ec%a3%bc%ec%9e%85" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;필드에 바로 주입하는 방식&lt;/li&gt;
&lt;li&gt;코드가 간결하지만, 외부에서 변경 불가 =&amp;gt; 테스트하기 어려움&lt;/li&gt;
&lt;li&gt;DI 프레임워크가 없으면 암것도 못함&lt;/li&gt;
&lt;li&gt;&lt;code&gt;@Configuration&lt;/code&gt; 같은 곳에서만 특별한 용도로 사용
웬만하면 사용하지 말자!!
&lt;del&gt;실무에서 많이씀&lt;/del&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 class="relative group"&gt;일반 메서드 주입
 &lt;div id="일반-메서드-주입" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#%ec%9d%bc%eb%b0%98-%eb%a9%94%ec%84%9c%eb%93%9c-%ec%a3%bc%ec%9e%85" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;일반적인 메서드를 통한 주입&lt;/li&gt;
&lt;li&gt;안씀&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;

&lt;h2 class="relative group"&gt;옵션 처리
 &lt;div id="옵션-처리" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#%ec%98%b5%ec%85%98-%ec%b2%98%eb%a6%ac" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;blockquote&gt;&lt;p&gt;주입할 스프링 빈이 없어도 동작해야 될 때&lt;/p&gt;</description></item><item><title>컴포넌트 스캔</title><link>https://log.j2234.cc/posts/velog/044-%EC%BB%B4%ED%8F%AC%EB%84%8C%ED%8A%B8-%EC%8A%A4%EC%BA%94/</link><pubDate>Sun, 05 Mar 2023 20:56:21 +0000</pubDate><guid>https://log.j2234.cc/posts/velog/044-%EC%BB%B4%ED%8F%AC%EB%84%8C%ED%8A%B8-%EC%8A%A4%EC%BA%94/</guid><description>&lt;h2 class="relative group"&gt;컴포넌트 스캔
 &lt;div id="컴포넌트-스캔" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#%ec%bb%b4%ed%8f%ac%eb%84%8c%ed%8a%b8-%ec%8a%a4%ec%ba%94" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;blockquote&gt;&lt;p&gt;이전 강의들에서는 &lt;code&gt;@Bean&lt;/code&gt; 등을 통해서 직접 스프링 빈을 등록함 (귀찮음)&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;설정 정보가 없어도 자동으로 스프링 빈을 등록하는 컴포넌트 스캔
설정 정보에 &lt;code&gt;@ComponentScan&lt;/code&gt;을 붙여주기만 하면 됨&lt;/p&gt;
&lt;/blockquote&gt;&lt;/blockquote&gt;&lt;p&gt;컴포넌트 스캔은 이름 그대로 &lt;code&gt;@Component&lt;/code&gt; 어노테이션이 붙은 클래스들을 스캔해서 스프링 빈으로 등록&lt;/p&gt;
&lt;p&gt;&lt;code&gt;@Autowired&lt;/code&gt;를 사용하면, 생성자에서 여러 의존관계도 한번에 주입 가능&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;순서&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;@ComponentScan
&lt;figure&gt;&lt;img
 class="my-0 rounded-md"
 loading="lazy"
 decoding="async"
 fetchpriority="auto"
 alt=""
 width="800"
 height="358"
 src="https://log.j2234.cc/posts/velog/044-%EC%BB%B4%ED%8F%AC%EB%84%8C%ED%8A%B8-%EC%8A%A4%EC%BA%94/img/image-01.webp"
 srcset="https://log.j2234.cc/posts/velog/044-%EC%BB%B4%ED%8F%AC%EB%84%8C%ED%8A%B8-%EC%8A%A4%EC%BA%94/img/image-01.webp 800w, https://log.j2234.cc/posts/velog/044-%EC%BB%B4%ED%8F%AC%EB%84%8C%ED%8A%B8-%EC%8A%A4%EC%BA%94/img/image-01.webp 1280w"
 sizes="(min-width: 768px) 50vw, 65vw"
 data-zoom-src="https://log.j2234.cc/posts/velog/044-%EC%BB%B4%ED%8F%AC%EB%84%8C%ED%8A%B8-%EC%8A%A4%EC%BA%94/img/image-01.webp"&gt;&lt;/figure&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;@ComponentScan&lt;/code&gt;은 &lt;code&gt;@Component&lt;/code&gt;가 붙은 모든 클래스를 스프링 빈으로
&lt;ul&gt;
&lt;li&gt;빈 이름 기본 : 앞글자만 대문자로
MemberServiceImpl =&amp;gt; memberServiceImpl&lt;/li&gt;
&lt;li&gt;&lt;code&gt;@Component(&amp;quot;name&amp;quot;)&lt;/code&gt; 으로 직접 이름 지정도 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ol start="2"&gt;
&lt;li&gt;의존관계 자동 주입
&lt;figure&gt;&lt;img
 class="my-0 rounded-md"
 loading="lazy"
 decoding="async"
 fetchpriority="auto"
 alt=""
 width="804"
 height="348"
 src="https://log.j2234.cc/posts/velog/044-%EC%BB%B4%ED%8F%AC%EB%84%8C%ED%8A%B8-%EC%8A%A4%EC%BA%94/img/image-02_hu_53becf381c0c0e4d.webp"
 srcset="https://log.j2234.cc/posts/velog/044-%EC%BB%B4%ED%8F%AC%EB%84%8C%ED%8A%B8-%EC%8A%A4%EC%BA%94/img/image-02_hu_53becf381c0c0e4d.webp 800w, https://log.j2234.cc/posts/velog/044-%EC%BB%B4%ED%8F%AC%EB%84%8C%ED%8A%B8-%EC%8A%A4%EC%BA%94/img/image-02.webp 1280w"
 sizes="(min-width: 768px) 50vw, 65vw"
 data-zoom-src="https://log.j2234.cc/posts/velog/044-%EC%BB%B4%ED%8F%AC%EB%84%8C%ED%8A%B8-%EC%8A%A4%EC%BA%94/img/image-02.webp"&gt;&lt;/figure&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;생성자에 &lt;code&gt;@Autowired&lt;/code&gt; 를 지정하면, 스프링 컨테이너가 자동으로 해당 스프링 빈을 찾아서 주입&lt;/li&gt;
&lt;li&gt;파라미터가 많아도 다 찾아서 주입해줌&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;

&lt;h2 class="relative group"&gt;탐색 위치, 기본 스캔 대상
 &lt;div id="탐색-위치-기본-스캔-대상" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#%ed%83%90%ec%83%89-%ec%9c%84%ec%b9%98-%ea%b8%b0%eb%b3%b8-%ec%8a%a4%ec%ba%94-%eb%8c%80%ec%83%81" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;탐색 위치 지정&lt;/strong&gt;&lt;/p&gt;</description><media:content xmlns:media="http://search.yahoo.com/mrss/" url="https://log.j2234.cc/posts/velog/044-%EC%BB%B4%ED%8F%AC%EB%84%8C%ED%8A%B8-%EC%8A%A4%EC%BA%94/featured.webp"/></item><item><title>싱글톤 컨테이너</title><link>https://log.j2234.cc/posts/velog/045-%EC%8B%B1%EA%B8%80%ED%86%A4-%EC%BB%A8%ED%85%8C%EC%9D%B4%EB%84%88/</link><pubDate>Sun, 05 Mar 2023 10:53:26 +0000</pubDate><guid>https://log.j2234.cc/posts/velog/045-%EC%8B%B1%EA%B8%80%ED%86%A4-%EC%BB%A8%ED%85%8C%EC%9D%B4%EB%84%88/</guid><description>&lt;h2 class="relative group"&gt;싱글톤
 &lt;div id="싱글톤" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#%ec%8b%b1%ea%b8%80%ed%86%a4" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;blockquote&gt;&lt;p&gt;웹 어플리케이션 특성상, 굉장히 많은 요청이 들어옴
이 때마다 객체가 생성되고 소멸되면, 이는 엄청난 메모리 낭비임&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;해결책 : 해당 객체가 딱 1개만 생성되고, 공유하도록 설계 =&amp;gt; 싱글톤&lt;/p&gt;
&lt;/blockquote&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;strong&gt;singleton 예제&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight-wrapper"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;private&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;static&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;final&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;SingletonService&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;instance&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;SingletonService&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;static&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;SingletonService&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;getInstance&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;instance&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;private&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;SingletonService&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;em&gt;싱글톤 패턴은 여러가지 문제점을 가지고 있다.&lt;/em&gt;&lt;/p&gt;</description></item><item><title>스프링 컨테이너와 스프링 빈</title><link>https://log.j2234.cc/posts/velog/046-%EC%8A%A4%ED%94%84%EB%A7%81-%EC%BB%A8%ED%85%8C%EC%9D%B4%EB%84%88%EC%99%80-%EC%8A%A4%ED%94%84%EB%A7%81-%EB%B9%88/</link><pubDate>Thu, 02 Mar 2023 21:12:46 +0000</pubDate><guid>https://log.j2234.cc/posts/velog/046-%EC%8A%A4%ED%94%84%EB%A7%81-%EC%BB%A8%ED%85%8C%EC%9D%B4%EB%84%88%EC%99%80-%EC%8A%A4%ED%94%84%EB%A7%81-%EB%B9%88/</guid><description>&lt;h2 class="relative group"&gt;컨테이너 생성
 &lt;div id="컨테이너-생성" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#%ec%bb%a8%ed%85%8c%ec%9d%b4%eb%84%88-%ec%83%9d%ec%84%b1" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;div class="highlight-wrapper"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;ApplicationContext&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;applicationContext&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;	&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;AnnotationConfigApplicationContext&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;AppConfig&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 class="relative group"&gt;1. 스프링 컨테이너 생성
 &lt;div id="1-스프링-컨테이너-생성" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#1-%ec%8a%a4%ed%94%84%eb%a7%81-%ec%bb%a8%ed%85%8c%ec%9d%b4%eb%84%88-%ec%83%9d%ec%84%b1" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h3&gt;
&lt;figure&gt;&lt;img
 class="my-0 rounded-md"
 loading="lazy"
 decoding="async"
 fetchpriority="auto"
 alt=""
 width="809"
 height="381"
 src="https://log.j2234.cc/posts/velog/046-%EC%8A%A4%ED%94%84%EB%A7%81-%EC%BB%A8%ED%85%8C%EC%9D%B4%EB%84%88%EC%99%80-%EC%8A%A4%ED%94%84%EB%A7%81-%EB%B9%88/img/image-01_hu_4113b8bdf8138fe5.webp"
 srcset="https://log.j2234.cc/posts/velog/046-%EC%8A%A4%ED%94%84%EB%A7%81-%EC%BB%A8%ED%85%8C%EC%9D%B4%EB%84%88%EC%99%80-%EC%8A%A4%ED%94%84%EB%A7%81-%EB%B9%88/img/image-01_hu_4113b8bdf8138fe5.webp 800w, https://log.j2234.cc/posts/velog/046-%EC%8A%A4%ED%94%84%EB%A7%81-%EC%BB%A8%ED%85%8C%EC%9D%B4%EB%84%88%EC%99%80-%EC%8A%A4%ED%94%84%EB%A7%81-%EB%B9%88/img/image-01.webp 1280w"
 sizes="(min-width: 768px) 50vw, 65vw"
 data-zoom-src="https://log.j2234.cc/posts/velog/046-%EC%8A%A4%ED%94%84%EB%A7%81-%EC%BB%A8%ED%85%8C%EC%9D%B4%EB%84%88%EC%99%80-%EC%8A%A4%ED%94%84%EB%A7%81-%EB%B9%88/img/image-01.webp"&gt;&lt;/figure&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt; new AnnotationConfigApplicationContext(AppConfig.class)&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 class="relative group"&gt;2. 스프링 빈 등록
 &lt;div id="2-스프링-빈-등록" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#2-%ec%8a%a4%ed%94%84%eb%a7%81-%eb%b9%88-%eb%93%b1%eb%a1%9d" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h3&gt;
&lt;figure&gt;&lt;img
 class="my-0 rounded-md"
 loading="lazy"
 decoding="async"
 fetchpriority="auto"
 alt=""
 width="806"
 height="363"
 src="https://log.j2234.cc/posts/velog/046-%EC%8A%A4%ED%94%84%EB%A7%81-%EC%BB%A8%ED%85%8C%EC%9D%B4%EB%84%88%EC%99%80-%EC%8A%A4%ED%94%84%EB%A7%81-%EB%B9%88/img/image-02_hu_3e456ce632684ec.webp"
 srcset="https://log.j2234.cc/posts/velog/046-%EC%8A%A4%ED%94%84%EB%A7%81-%EC%BB%A8%ED%85%8C%EC%9D%B4%EB%84%88%EC%99%80-%EC%8A%A4%ED%94%84%EB%A7%81-%EB%B9%88/img/image-02_hu_3e456ce632684ec.webp 800w, https://log.j2234.cc/posts/velog/046-%EC%8A%A4%ED%94%84%EB%A7%81-%EC%BB%A8%ED%85%8C%EC%9D%B4%EB%84%88%EC%99%80-%EC%8A%A4%ED%94%84%EB%A7%81-%EB%B9%88/img/image-02.webp 1280w"
 sizes="(min-width: 768px) 50vw, 65vw"
 data-zoom-src="https://log.j2234.cc/posts/velog/046-%EC%8A%A4%ED%94%84%EB%A7%81-%EC%BB%A8%ED%85%8C%EC%9D%B4%EB%84%88%EC%99%80-%EC%8A%A4%ED%94%84%EB%A7%81-%EB%B9%88/img/image-02.webp"&gt;&lt;/figure&gt;
&lt;ul&gt;
&lt;li&gt;파라미터로 넘어온 설정 클래스 정보를 사용해서 스프링 빈 등록&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;** 빈 이름 **&lt;/p&gt;</description><media:content xmlns:media="http://search.yahoo.com/mrss/" url="https://log.j2234.cc/posts/velog/046-%EC%8A%A4%ED%94%84%EB%A7%81-%EC%BB%A8%ED%85%8C%EC%9D%B4%EB%84%88%EC%99%80-%EC%8A%A4%ED%94%84%EB%A7%81-%EB%B9%88/featured.webp"/></item><item><title>스프링 객체지향원리 적용</title><link>https://log.j2234.cc/posts/velog/047-%EC%8A%A4%ED%94%84%EB%A7%81-%EA%B0%9D%EC%B2%B4%EC%A7%80%ED%96%A5%EC%9B%90%EB%A6%AC-%EC%A0%81%EC%9A%A9/</link><pubDate>Wed, 01 Mar 2023 17:38:36 +0000</pubDate><guid>https://log.j2234.cc/posts/velog/047-%EC%8A%A4%ED%94%84%EB%A7%81-%EA%B0%9D%EC%B2%B4%EC%A7%80%ED%96%A5%EC%9B%90%EB%A6%AC-%EC%A0%81%EC%9A%A9/</guid><description>&lt;blockquote&gt;&lt;p&gt;&lt;a href="https://velog.io/@jiheon2234/%EA%B0%9D%EC%B2%B4-%EC%A7%80%ED%96%A5-%EC%84%A4%EA%B3%84%EC%99%80-%EC%8A%A4%ED%94%84%EB%A7%81" target="_blank" rel="noreferrer"&gt;이전 글&lt;/a&gt;에서 언급되었던 &lt;strong&gt;OCP&lt;/strong&gt;,&lt;strong&gt;DIP&lt;/strong&gt; 의 문제점을 스프링에서 해결하는 방법
&lt;em&gt;클라이언트 코드를 변경하지 않고, 새로운 구현체로 갈아끼우려면??&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;&lt;hr&gt;

&lt;h2 class="relative group"&gt;관심사의 분리
 &lt;div id="관심사의-분리" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#%ea%b4%80%ec%8b%ac%ec%82%ac%ec%9d%98-%eb%b6%84%eb%a6%ac" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;blockquote&gt;&lt;p&gt;어플리케이션의 전체 동작 방식을 구성(config) 하기 위해서, &lt;strong&gt;구현 객체를 생성&lt;/strong&gt; 하고, &lt;strong&gt;연결&lt;/strong&gt; 하는 책임을 가지는 별도의 생성 클래스&lt;/p&gt;
&lt;/blockquote&gt;&lt;ul&gt;
&lt;li&gt;어플리케이션의 실제 동작에 필요한 &lt;strong&gt;구현 객체를 생성&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;생성한 객체 인스턴스의 참조(rference)를 &lt;strong&gt;생성자를 통해서 주입&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;즉, 생성자를 통해 어떤 구현체가 들어올지는 오직 외부에서 결정됨
=&amp;gt; &lt;strong&gt;의존관계에 대한 고민은 외부에 맡기고, 실행에만 집중&lt;/strong&gt;
&lt;em&gt;클라이언트 코드는 절대 변경되지 않음&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;

&lt;h2 class="relative group"&gt;IOD, DI, 컨테이너
 &lt;div id="iod-di-컨테이너" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#iod-di-%ec%bb%a8%ed%85%8c%ec%9d%b4%eb%84%88" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;

&lt;h3 class="relative group"&gt;IOC (제어의 역전)
 &lt;div id="ioc-제어의-역전" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#ioc-%ec%a0%9c%ec%96%b4%ec%9d%98-%ec%97%ad%ec%a0%84" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h3&gt;
&lt;p&gt;&lt;em&gt;Inversion of Control&lt;/em&gt;&lt;/p&gt;</description></item><item><title>객체 지향 설계</title><link>https://log.j2234.cc/posts/velog/048-%EA%B0%9D%EC%B2%B4-%EC%A7%80%ED%96%A5-%EC%84%A4%EA%B3%84/</link><pubDate>Mon, 27 Feb 2023 21:27:34 +0000</pubDate><guid>https://log.j2234.cc/posts/velog/048-%EA%B0%9D%EC%B2%B4-%EC%A7%80%ED%96%A5-%EC%84%A4%EA%B3%84/</guid><description>&lt;h2 class="relative group"&gt;SQLID (좋은 객체 지향 설계의 5원칙)
 &lt;div id="sqlid-좋은-객체-지향-설계의-5원칙" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#sqlid-%ec%a2%8b%ec%9d%80-%ea%b0%9d%ec%b2%b4-%ec%a7%80%ed%96%a5-%ec%84%a4%ea%b3%84%ec%9d%98-5%ec%9b%90%ec%b9%99" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;

&lt;h3 class="relative group"&gt;SRP (단일책임)
 &lt;div id="srp-단일책임" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#srp-%eb%8b%a8%ec%9d%bc%ec%b1%85%ec%9e%84" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h3&gt;
&lt;p&gt;*Single Responsibility priniple *&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;한 클래스는 하나의 책임만
&lt;ul&gt;
&lt;li&gt;하나의 책임이란? 문맥과 상황에 라 다름&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;중요한 기준은 변경&lt;/strong&gt; =&amp;gt; 변경이 있을 때 파급 효과가 적으면 👍&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 class="relative group"&gt;OCP (개방-폐쇄)❗️
 &lt;div id="ocp-개방-폐쇄" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#ocp-%ea%b0%9c%eb%b0%a9-%ed%8f%90%ec%87%84" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h3&gt;
&lt;p&gt;&lt;em&gt;Open/closed principle&lt;/em&gt;&lt;/p&gt;</description></item><item><title>파일 업로드</title><link>https://log.j2234.cc/posts/velog/049-%ED%8C%8C%EC%9D%BC-%EC%97%85%EB%A1%9C%EB%93%9C/</link><pubDate>Sat, 25 Feb 2023 19:27:09 +0000</pubDate><guid>https://log.j2234.cc/posts/velog/049-%ED%8C%8C%EC%9D%BC-%EC%97%85%EB%A1%9C%EB%93%9C/</guid><description>&lt;h2 class="relative group"&gt;전송방식
 &lt;div id="전송방식" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#%ec%a0%84%ec%86%a1%eb%b0%a9%ec%8b%9d" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;폼을 전송하는 두 방법&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;application/x-www-form-urlencoded&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;multipart/form-data&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;파일을 전송할 땐, 이진 데이터를 전송해야 되므로, 이 방식 사용 불가
또한, 보통 폼과 파일을 같이 전송하므로, &lt;strong&gt;문자와 바이너리를 동시에 전송&lt;/strong&gt;해야 함&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;이 문제를 해결하기 위해서, HTTP는 &lt;code&gt;multipart/form-data&lt;/code&gt; 방식 제공!&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 class="relative group"&gt;&lt;code&gt;multipart/form-data&lt;/code&gt;
 &lt;div id="multipartform-data" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#multipartform-data" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h3&gt;
&lt;p&gt;&lt;em&gt;다른 종류의 여러 파일과 폼의 내용을 함께 전송하는 방식&lt;/em&gt;
&lt;figure&gt;&lt;img
 class="my-0 rounded-md"
 loading="lazy"
 decoding="async"
 fetchpriority="auto"
 alt=""
 width="801"
 height="393"
 src="https://log.j2234.cc/posts/velog/049-%ED%8C%8C%EC%9D%BC-%EC%97%85%EB%A1%9C%EB%93%9C/img/image-01_hu_34dc54dd473e5235.webp"
 srcset="https://log.j2234.cc/posts/velog/049-%ED%8C%8C%EC%9D%BC-%EC%97%85%EB%A1%9C%EB%93%9C/img/image-01_hu_34dc54dd473e5235.webp 800w, https://log.j2234.cc/posts/velog/049-%ED%8C%8C%EC%9D%BC-%EC%97%85%EB%A1%9C%EB%93%9C/img/image-01.webp 1280w"
 sizes="(min-width: 768px) 50vw, 65vw"
 data-zoom-src="https://log.j2234.cc/posts/velog/049-%ED%8C%8C%EC%9D%BC-%EC%97%85%EB%A1%9C%EB%93%9C/img/image-01.webp"&gt;&lt;/figure&gt;
&lt;/p&gt;</description><media:content xmlns:media="http://search.yahoo.com/mrss/" url="https://log.j2234.cc/posts/velog/049-%ED%8C%8C%EC%9D%BC-%EC%97%85%EB%A1%9C%EB%93%9C/featured.webp"/></item><item><title>스프링 타입 컨버터</title><link>https://log.j2234.cc/posts/velog/050-%EC%8A%A4%ED%94%84%EB%A7%81-%ED%83%80%EC%9E%85-%EC%BB%A8%EB%B2%84%ED%84%B0/</link><pubDate>Tue, 21 Feb 2023 20:11:01 +0000</pubDate><guid>https://log.j2234.cc/posts/velog/050-%EC%8A%A4%ED%94%84%EB%A7%81-%ED%83%80%EC%9E%85-%EC%BB%A8%EB%B2%84%ED%84%B0/</guid><description>&lt;h2 class="relative group"&gt;타입 컨버터란?
 &lt;div id="타입-컨버터란" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#%ed%83%80%ec%9e%85-%ec%bb%a8%eb%b2%84%ed%84%b0%eb%9e%80" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;HTTP 요청 파라미터는 모두 문자로 처리함
&lt;code&gt;Integer intvalue = Integer.valueOf(data)&lt;/code&gt;로 숫자로 변환해야됨&lt;/p&gt;
&lt;p&gt;스프링의 &lt;code&gt;RequestParam&lt;/code&gt;을 사용하면 쉽게 타입을 변환해서 받을 수 있음
&lt;code&gt;(@RequestParam Integer data)&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;스프링은 &lt;strong&gt;컨버터 인터페이스&lt;/strong&gt; 를 사용해서 이를 가능하게 한다.
&lt;code&gt;org.springframework.core.convert.converter.Converter&lt;/code&gt;를 구현해서 사용가능&lt;/p&gt;
&lt;hr&gt;

&lt;h2 class="relative group"&gt;컨버전 서비스
 &lt;div id="컨버전-서비스" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#%ec%bb%a8%eb%b2%84%ec%a0%84-%ec%84%9c%eb%b9%84%ec%8a%a4" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;blockquote&gt;&lt;p&gt;스프링이 제공하는, 개별 컨버터를 모아두고 묶어서 사용하는 기능&lt;/p&gt;</description></item><item><title>API 예외 처리</title><link>https://log.j2234.cc/posts/velog/051-api-%EC%98%88%EC%99%B8-%EC%B2%98%EB%A6%AC/</link><pubDate>Mon, 13 Feb 2023 21:15:08 +0000</pubDate><guid>https://log.j2234.cc/posts/velog/051-api-%EC%98%88%EC%99%B8-%EC%B2%98%EB%A6%AC/</guid><description>&lt;h2 class="relative group"&gt;시작
 &lt;div id="시작" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#%ec%8b%9c%ec%9e%91" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;HTML은, 오류가 나면 4xx,5xx 오류 페이지만 있으면 된다.
근데, API의 경우에는 각 오류 상황에 맞는 응답 스펙을 정하고, json으로 줘야됨&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;ex)&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight-wrapper"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nd"&gt;@RequestMapping&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;/error-page/500&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;produces&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;MediaType&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;APPLICATION_JSON_VALUE&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ResponseEntity&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Map&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Object&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;errorPage500Api&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;HttpServletRequest&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;HttpServletResponse&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Map&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Object&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;HashMap&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Exception&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ex&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Exception&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getAttribute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;RequestDispatcher&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;ERROR_EXCEPTION&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;put&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;status&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getAttribute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;RequestDispatcher&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;ERROR_STATUS_CODE&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;put&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;message&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ex&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getMessage&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Integer&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;statusCode&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Integer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getAttribute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;RequestDispatcher&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;ERROR_STATUS_CODE&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ResponseEntity&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;HttpStatus&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;valueOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;statusCode&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;요청의 &lt;code&gt;Accept&lt;/code&gt;가 &lt;code&gt;application/json&lt;/code&gt;인 경우를 처리
&lt;code&gt;HttpRequest&lt;/code&gt;의 정보를 토대로 json 생성 후 반환
&lt;a href="https://velog.io/@jiheon2234/%EC%98%88%EC%99%B8-%EC%B2%98%EB%A6%AC%EC%98%A4%EB%A5%98#%EC%84%9C%EB%B8%94%EB%A6%BF-%EC%98%88%EC%99%B8-%EC%B2%98%EB%A6%AC" target="_blank" rel="noreferrer"&gt;이전글 참고&lt;/a&gt;&lt;/p&gt;</description><media:content xmlns:media="http://search.yahoo.com/mrss/" url="https://log.j2234.cc/posts/velog/051-api-%EC%98%88%EC%99%B8-%EC%B2%98%EB%A6%AC/featured.webp"/></item><item><title>예외 처리,오류</title><link>https://log.j2234.cc/posts/velog/052-%EC%98%88%EC%99%B8-%EC%B2%98%EB%A6%AC%EC%98%A4%EB%A5%98/</link><pubDate>Sat, 11 Feb 2023 19:41:43 +0000</pubDate><guid>https://log.j2234.cc/posts/velog/052-%EC%98%88%EC%99%B8-%EC%B2%98%EB%A6%AC%EC%98%A4%EB%A5%98/</guid><description>&lt;h2 class="relative group"&gt;프로젝트 생성
 &lt;div id="프로젝트-생성" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#%ed%94%84%eb%a1%9c%ec%a0%9d%ed%8a%b8-%ec%83%9d%ec%84%b1" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;figure&gt;&lt;img
 class="my-0 rounded-md"
 loading="lazy"
 decoding="async"
 fetchpriority="auto"
 alt=""
 width="1302"
 height="595"
 src="https://log.j2234.cc/posts/velog/052-%EC%98%88%EC%99%B8-%EC%B2%98%EB%A6%AC%EC%98%A4%EB%A5%98/img/image-01_hu_4065ef16aad6e324.webp"
 srcset="https://log.j2234.cc/posts/velog/052-%EC%98%88%EC%99%B8-%EC%B2%98%EB%A6%AC%EC%98%A4%EB%A5%98/img/image-01_hu_4065ef16aad6e324.webp 800w, https://log.j2234.cc/posts/velog/052-%EC%98%88%EC%99%B8-%EC%B2%98%EB%A6%AC%EC%98%A4%EB%A5%98/img/image-01_hu_34e75541f48e389b.webp 1280w"
 sizes="(min-width: 768px) 50vw, 65vw"
 data-zoom-src="https://log.j2234.cc/posts/velog/052-%EC%98%88%EC%99%B8-%EC%B2%98%EB%A6%AC%EC%98%A4%EB%A5%98/img/image-01.webp"&gt;&lt;/figure&gt;
&lt;hr&gt;

&lt;h2 class="relative group"&gt;서블릿 예외 처리
 &lt;div id="서블릿-예외-처리" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#%ec%84%9c%eb%b8%94%eb%a6%bf-%ec%98%88%ec%99%b8-%ec%b2%98%eb%a6%ac" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;순수 서블릿 컨테이너가 에러를 처리하는 방법&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Exception&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;response.sendError&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;자바를 직접 실행할때, main()에서 에러를 던지면 해당 쓰레드는 종료됨
웹 어플리케이션은 Was 까지 던져지고, 해당 화면을 보게됨&lt;/p&gt;
&lt;figure&gt;&lt;img
 class="my-0 rounded-md"
 loading="lazy"
 decoding="async"
 fetchpriority="auto"
 alt=""
 width="1830"
 height="242"
 src="https://log.j2234.cc/posts/velog/052-%EC%98%88%EC%99%B8-%EC%B2%98%EB%A6%AC%EC%98%A4%EB%A5%98/img/image-02_hu_23236eb065b9626b.webp"
 srcset="https://log.j2234.cc/posts/velog/052-%EC%98%88%EC%99%B8-%EC%B2%98%EB%A6%AC%EC%98%A4%EB%A5%98/img/image-02_hu_23236eb065b9626b.webp 800w, https://log.j2234.cc/posts/velog/052-%EC%98%88%EC%99%B8-%EC%B2%98%EB%A6%AC%EC%98%A4%EB%A5%98/img/image-02_hu_92a7883603fcfdbd.webp 1280w"
 sizes="(min-width: 768px) 50vw, 65vw"
 data-zoom-src="https://log.j2234.cc/posts/velog/052-%EC%98%88%EC%99%B8-%EC%B2%98%EB%A6%AC%EC%98%A4%EB%A5%98/img/image-02.webp"&gt;&lt;/figure&gt;
&lt;p&gt;서블릿은 &lt;code&gt;Exception&lt;/code&gt;이 서블릿 밖으로 전달되거나, &lt;code&gt;response.sendError()&lt;/code&gt;가 호출 되었을 때 상황에 맞게 오류 처리 기능을 제공&lt;/p&gt;</description><media:content xmlns:media="http://search.yahoo.com/mrss/" url="https://log.j2234.cc/posts/velog/052-%EC%98%88%EC%99%B8-%EC%B2%98%EB%A6%AC%EC%98%A4%EB%A5%98/featured.webp"/></item><item><title>로그인2 (필터,인터셉터)</title><link>https://log.j2234.cc/posts/velog/053-%EB%A1%9C%EA%B7%B8%EC%9D%B82-%ED%95%84%ED%84%B0%EC%9D%B8%ED%84%B0%EC%85%89%ED%84%B0/</link><pubDate>Mon, 06 Feb 2023 20:52:07 +0000</pubDate><guid>https://log.j2234.cc/posts/velog/053-%EB%A1%9C%EA%B7%B8%EC%9D%B82-%ED%95%84%ED%84%B0%EC%9D%B8%ED%84%B0%EC%85%89%ED%84%B0/</guid><description>&lt;h2 class="relative group"&gt;서블릿 필터
 &lt;div id="서블릿-필터" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#%ec%84%9c%eb%b8%94%eb%a6%bf-%ed%95%84%ed%84%b0" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;&lt;em&gt;서블릿이 지원하는 수문장&lt;/em&gt;&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;필터 흐름&lt;/strong&gt;
HTTP 요청 -&amp;gt; WAS -&amp;gt; 필터(들) -&amp;gt; 서블릿 -&amp;gt; 컨트롤러&lt;/p&gt;
&lt;/blockquote&gt;&lt;p&gt;필터에서 막히면 끝낼수 있음 (로그인에 딱임)&lt;/p&gt;
&lt;p&gt;**필터 인터페이스 (javax.servlet.Filter) **&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;init()&lt;/code&gt; : 컨테이너가 생성될때 호출&lt;/li&gt;
&lt;li&gt;&lt;code&gt;doFilter()&lt;/code&gt; : 로직&lt;/li&gt;
&lt;li&gt;&lt;code&gt;destroy()&lt;/code&gt; : 컨테이너가 종료될 때 호출&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;em&gt;스프링시큐리티 등은 필터로 구현되어있음&lt;/em&gt;&lt;/p&gt;
&lt;hr&gt;

&lt;h2 class="relative group"&gt;인터셉터
 &lt;div id="인터셉터" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#%ec%9d%b8%ed%84%b0%ec%85%89%ed%84%b0" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;스프링 MVC가 제공하는 기술로, 필터와 비슷하지만 &lt;strong&gt;순서,범위,사용방법이 다름&lt;/strong&gt;&lt;/p&gt;</description><media:content xmlns:media="http://search.yahoo.com/mrss/" url="https://log.j2234.cc/posts/velog/053-%EB%A1%9C%EA%B7%B8%EC%9D%B82-%ED%95%84%ED%84%B0%EC%9D%B8%ED%84%B0%EC%85%89%ED%84%B0/featured.webp"/></item><item><title>로그인1(쿠키,세션)</title><link>https://log.j2234.cc/posts/velog/054-%EB%A1%9C%EA%B7%B8%EC%9D%B81%EC%BF%A0%ED%82%A4%EC%84%B8%EC%85%98/</link><pubDate>Sun, 29 Jan 2023 12:38:30 +0000</pubDate><guid>https://log.j2234.cc/posts/velog/054-%EB%A1%9C%EA%B7%B8%EC%9D%B81%EC%BF%A0%ED%82%A4%EC%84%B8%EC%85%98/</guid><description>&lt;h2 class="relative group"&gt;쿠키를 사용한 로그인
 &lt;div id="쿠키를-사용한-로그인" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#%ec%bf%a0%ed%82%a4%eb%a5%bc-%ec%82%ac%ec%9a%a9%ed%95%9c-%eb%a1%9c%ea%b7%b8%ec%9d%b8" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;로그인 상태 유지하기&lt;/strong&gt;
로그인에 성공하면, 쿠키를 생성하고 &lt;code&gt;HttpServletResponse&lt;/code&gt;에 담는다.
웹 브라우저는, 세션이 끊기기 전까지 쿠키를 서버에 계속 보내줌&lt;/p&gt;
&lt;p&gt;로그아웃시에는, 똑같은 이름의 새 쿠키를 생성하고,&lt;code&gt;.setMaxAge(0)&lt;/code&gt;으로 지속시간을 없애고, &lt;code&gt;HttpServletResponse&lt;/code&gt; 에 담아주면 된다.&lt;/p&gt;

&lt;h3 class="relative group"&gt;보안문제
 &lt;div id="보안문제" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#%eb%b3%b4%ec%95%88%eb%ac%b8%ec%a0%9c" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h3&gt;
&lt;p&gt;쿠키값은 임의로 바뀔 수도 있고, 웹 브라우저에 보관되기 때문에 누군가 정보를 훔처갈 수도 있음
&lt;em&gt;해커가 한번 쿠키를 가져가면 평생 사용 가능&lt;/em&gt;&lt;/p&gt;</description><media:content xmlns:media="http://search.yahoo.com/mrss/" url="https://log.j2234.cc/posts/velog/054-%EB%A1%9C%EA%B7%B8%EC%9D%B81%EC%BF%A0%ED%82%A4%EC%84%B8%EC%85%98/featured.webp"/></item><item><title>검증2 - Bean Validation</title><link>https://log.j2234.cc/posts/velog/055-%EA%B2%80%EC%A6%9D2-bean-validation/</link><pubDate>Thu, 26 Jan 2023 14:34:50 +0000</pubDate><guid>https://log.j2234.cc/posts/velog/055-%EA%B2%80%EC%A6%9D2-bean-validation/</guid><description>&lt;h2 class="relative group"&gt;Bean Validation이란?
 &lt;div id="bean-validation이란" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#bean-validation%ec%9d%b4%eb%9e%80" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;검증 어노테이션과 여러 인터페이스의 모음
일반적으로 하이버네이트 Validator를 구현체로 사용
&lt;a href="https://docs.jboss.org/hibernate/validator/6.2/reference/en-US/html_single/#validator-defineconstraints-spec" target="_blank" rel="noreferrer"&gt;공식 문서&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;build.gradle&lt;/code&gt;에 의존관계추가&lt;/p&gt;
&lt;div class="highlight-wrapper"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; implementation &amp;#39;org.springframework.boot:spring-boot-starter-validation&amp;#39;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;em&gt;스프링에선 빈 검증기를 완전히 통합해뒀음&lt;/em&gt;&lt;/p&gt;
&lt;hr&gt;

&lt;h2 class="relative group"&gt;스프링 적용
 &lt;div id="스프링-적용" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#%ec%8a%a4%ed%94%84%eb%a7%81-%ec%a0%81%ec%9a%a9" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;	implementation 'org.springframework.boot:spring-boot-starter-validation'&lt;/code&gt;이 있으면, 자동으로 통합&lt;/p&gt;
&lt;p&gt;글로벌 Validator를 등록하기 때문에, &lt;code&gt;@Validated&lt;/code&gt;만 적용하면 됨
오류가 나면, &lt;code&gt;filedError&lt;/code&gt;,&lt;code&gt;ObjectError&lt;/code&gt;를 생성해서 &lt;code&gt;BindingResult&lt;/code&gt;에 담아줌&lt;/p&gt;</description></item><item><title>검증1 -Validation</title><link>https://log.j2234.cc/posts/velog/056-%EA%B2%80%EC%A6%9D1-validation/</link><pubDate>Wed, 25 Jan 2023 15:38:21 +0000</pubDate><guid>https://log.j2234.cc/posts/velog/056-%EA%B2%80%EC%A6%9D1-validation/</guid><description>&lt;h2 class="relative group"&gt;검증 요구사항
 &lt;div id="검증-요구사항" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#%ea%b2%80%ec%a6%9d-%ec%9a%94%ea%b5%ac%ec%82%ac%ed%95%ad" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;웹 서비스는 폼 입력시 오류가 발생하면, 데이터를 유지한 상태로 오류를 사용자에게 알려주어야 한다.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;컨트롤러의 중요한 역활 중 하나는, HTTP 요청이 정상인지 검증하는 것이다&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;클라이언트 검증(js)은 보안에 취약&lt;/li&gt;
&lt;li&gt;서버만으로 검증하면, 고객 사용성 부족&lt;/li&gt;
&lt;li&gt;적절히 섞어서 사용하되, 최종 서버 검증은 필수&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;em&gt;이전 프로젝트를 일부 수정한 &lt;code&gt;validation-start&lt;/code&gt;프로젝트에서 진행&lt;/em&gt;&lt;/p&gt;
&lt;hr&gt;

&lt;h2 class="relative group"&gt;검증 처리
 &lt;div id="검증-처리" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#%ea%b2%80%ec%a6%9d-%ec%b2%98%eb%a6%ac" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;고객이 폼을 잘못 입력한 경우
&lt;figure&gt;&lt;img
 class="my-0 rounded-md"
 loading="lazy"
 decoding="async"
 fetchpriority="auto"
 alt=""
 width="808"
 height="529"
 src="https://log.j2234.cc/posts/velog/056-%EA%B2%80%EC%A6%9D1-validation/img/image-01_hu_405aae531202fafc.webp"
 srcset="https://log.j2234.cc/posts/velog/056-%EA%B2%80%EC%A6%9D1-validation/img/image-01_hu_405aae531202fafc.webp 800w, https://log.j2234.cc/posts/velog/056-%EA%B2%80%EC%A6%9D1-validation/img/image-01.webp 1280w"
 sizes="(min-width: 768px) 50vw, 65vw"
 data-zoom-src="https://log.j2234.cc/posts/velog/056-%EA%B2%80%EC%A6%9D1-validation/img/image-01.webp"&gt;&lt;/figure&gt;
&lt;/p&gt;</description><media:content xmlns:media="http://search.yahoo.com/mrss/" url="https://log.j2234.cc/posts/velog/056-%EA%B2%80%EC%A6%9D1-validation/featured.webp"/></item><item><title>메시지,국제화</title><link>https://log.j2234.cc/posts/velog/057-%EB%A9%94%EC%8B%9C%EC%A7%80%EA%B5%AD%EC%A0%9C%ED%99%94/</link><pubDate>Tue, 24 Jan 2023 18:23:52 +0000</pubDate><guid>https://log.j2234.cc/posts/velog/057-%EB%A9%94%EC%8B%9C%EC%A7%80%EA%B5%AD%EC%A0%9C%ED%99%94/</guid><description>&lt;h2 class="relative group"&gt;메시지, 국제화 소개
 &lt;div id="메시지-국제화-소개" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#%eb%a9%94%ec%8b%9c%ec%a7%80-%ea%b5%ad%ec%a0%9c%ed%99%94-%ec%86%8c%ea%b0%9c" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;

&lt;h3 class="relative group"&gt;메시지
 &lt;div id="메시지" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#%eb%a9%94%ec%8b%9c%ec%a7%80" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h3&gt;
&lt;p&gt;기획자가 &lt;strong&gt;&amp;ldquo;상품명&amp;rdquo;&lt;/strong&gt; 이란 단어를 모두 &lt;strong&gt;&amp;ldquo;상품이름&lt;/strong&gt;&amp;rdquo; 으로 고쳐달라고 하면?
&lt;em&gt;HTML 파일에 메시지가 하드코딩 되어 있어 모든 화면을 고쳐야 한다&lt;/em&gt; &lt;del&gt;ㅅㅂ&lt;/del&gt;&lt;/p&gt;
&lt;p&gt;이런 다양한 메시지를 한 곳(파일)에서 관리하는 기능을 메시지 기능이라 한다.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;EX)&lt;/strong&gt;
&lt;code&gt;messages.properties&lt;/code&gt;라는 파일을 만들고&lt;/p&gt;
&lt;div class="highlight-wrapper"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;item=상품
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;item.itemName=상품명
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;...&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;HTML에서 해당 데이터를 key값으로 불러서 사용한다
&lt;strong&gt;addForm.html&lt;/strong&gt;
&lt;code&gt;&amp;lt;label for=&amp;quot;itemName&amp;quot; th:text=&amp;quot;#{item.itemName}&amp;quot;&amp;gt;&amp;lt;/label&amp;gt;&lt;/code&gt;&lt;/p&gt;</description></item><item><title>타임리프 스프링 통합</title><link>https://log.j2234.cc/posts/velog/058-%ED%83%80%EC%9E%84%EB%A6%AC%ED%94%84-%EC%8A%A4%ED%94%84%EB%A7%81-%ED%86%B5%ED%95%A9/</link><pubDate>Mon, 23 Jan 2023 20:12:41 +0000</pubDate><guid>https://log.j2234.cc/posts/velog/058-%ED%83%80%EC%9E%84%EB%A6%AC%ED%94%84-%EC%8A%A4%ED%94%84%EB%A7%81-%ED%86%B5%ED%95%A9/</guid><description>&lt;h2 class="relative group"&gt;프로젝트 설정
 &lt;div id="프로젝트-설정" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#%ed%94%84%eb%a1%9c%ec%a0%9d%ed%8a%b8-%ec%84%a4%ec%a0%95" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://velog.io/@jiheon2234/%EC%8A%A4%ED%94%84%EB%A7%81-MVC-%EC%9B%B9%ED%8E%98%EC%9D%B4%EC%A7%80%EB%A7%8C%EB%93%A4%EA%B8%B0" target="_blank" rel="noreferrer"&gt;저번에했던 프로젝트&lt;/a&gt; 조금 수정해서 진행&lt;/p&gt;
&lt;hr&gt;

&lt;h2 class="relative group"&gt;타임리프 스프링 통합
 &lt;div id="타임리프-스프링-통합" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#%ed%83%80%ec%9e%84%eb%a6%ac%ed%94%84-%ec%8a%a4%ed%94%84%eb%a7%81-%ed%86%b5%ed%95%a9" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://www.thymeleaf.org/doc/tutorials/3.1/thymeleafspring.html" target="_blank" rel="noreferrer"&gt;공식문서&lt;/a&gt;
&lt;strong&gt;추가되는 기능들&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;SpringEL 문법 통합&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;&amp;hellip;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;스프링 부트에서는&lt;code&gt;build.gradle&lt;/code&gt;의
&lt;code&gt; implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'&lt;/code&gt;가 있으면, 자동으로 설정해준다.&lt;/p&gt;
&lt;hr&gt;

&lt;h2 class="relative group"&gt;입력 폼 처리
 &lt;div id="입력-폼-처리" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#%ec%9e%85%eb%a0%a5-%ed%8f%bc-%ec%b2%98%eb%a6%ac" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;div class="highlight-wrapper"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-html" data-lang="html"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;form&lt;/span&gt; &lt;span class="na"&gt;action&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;item.html&amp;#34;&lt;/span&gt; &lt;span class="na"&gt;th:action&lt;/span&gt; &lt;span class="na"&gt;th:object&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;${item}&amp;#34;&lt;/span&gt; &lt;span class="na"&gt;method&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;post&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;label&lt;/span&gt; &lt;span class="na"&gt;for&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;itemName&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;상품명&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;label&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;input&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;text&amp;#34;&lt;/span&gt; &lt;span class="na"&gt;th:field&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;*{itemName}&amp;#34;&lt;/span&gt; &lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;form-control&amp;#34;&lt;/span&gt; &lt;span class="na"&gt;placeholder&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;이름을 입력하세요&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;th:object=&amp;quot;{item}&amp;quot;&lt;/code&gt; : &lt;code&gt;form&lt;/code&gt;에서 사용할 객체를 지정&lt;/li&gt;
&lt;li&gt;&lt;code&gt;th:field=&amp;quot;*{itemName}&amp;quot;&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;선택변수식 &lt;code&gt;*{itemName}&lt;/code&gt; == &lt;code&gt;${item.itemName}&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;th:field&lt;/code&gt;는 id, name, value 속성을 자동으로 생성&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;

&lt;h2 class="relative group"&gt;체크박스
 &lt;div id="체크박스" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#%ec%b2%b4%ed%81%ac%eb%b0%95%ec%8a%a4" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;&lt;em&gt;&lt;code&gt;logging.level.org.apache.coyote.http11=debug&lt;/code&gt; 서버에서 http 요청 메시지를 볼 수 있다.&lt;/em&gt;&lt;/p&gt;</description></item><item><title>Thymeleaf</title><link>https://log.j2234.cc/posts/velog/060-thymeleaf/</link><pubDate>Tue, 17 Jan 2023 16:14:31 +0000</pubDate><guid>https://log.j2234.cc/posts/velog/060-thymeleaf/</guid><description>&lt;h2 class="relative group"&gt;프로젝트 생성
 &lt;div id="프로젝트-생성" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#%ed%94%84%eb%a1%9c%ec%a0%9d%ed%8a%b8-%ec%83%9d%ec%84%b1" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;figure&gt;&lt;img
 class="my-0 rounded-md"
 loading="lazy"
 decoding="async"
 fetchpriority="auto"
 alt=""
 width="1509"
 height="611"
 src="https://log.j2234.cc/posts/velog/060-thymeleaf/img/image-01_hu_7c4ffb147110bef5.webp"
 srcset="https://log.j2234.cc/posts/velog/060-thymeleaf/img/image-01_hu_7c4ffb147110bef5.webp 800w, https://log.j2234.cc/posts/velog/060-thymeleaf/img/image-01_hu_6eb211c2c68d4324.webp 1280w"
 sizes="(min-width: 768px) 50vw, 65vw"
 data-zoom-src="https://log.j2234.cc/posts/velog/060-thymeleaf/img/image-01.webp"&gt;&lt;/figure&gt;
&lt;hr&gt;

&lt;h2 class="relative group"&gt;소개
 &lt;div id="소개" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#%ec%86%8c%ea%b0%9c" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://www.thymeleaf.org/documentation.html" target="_blank" rel="noreferrer"&gt;공식문서&lt;/a&gt;&lt;/p&gt;

&lt;h3 class="relative group"&gt;타임리프 특징
 &lt;div id="타임리프-특징" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#%ed%83%80%ec%9e%84%eb%a6%ac%ed%94%84-%ed%8a%b9%ec%a7%95" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;서버사이드 렌더링&lt;/li&gt;
&lt;li&gt;내추럴 템플릿&lt;/li&gt;
&lt;li&gt;스프링 통합 지원&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;타임리프 사용 선언&lt;/strong&gt;
&lt;code&gt;&amp;lt;html xmlns:th&amp;quot;http://www.thymeleaf.org&amp;quot;&amp;gt;&lt;/code&gt;&lt;/p&gt;
&lt;hr&gt;

&lt;h2 class="relative group"&gt;텍스트 - text,utext
 &lt;div id="텍스트---textutext" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#%ed%85%8d%ec%8a%a4%ed%8a%b8---textutext" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;&lt;em&gt;기본적으로 HTML 태그 속성에 기능을 정의해서 동작&lt;/em&gt;&lt;/p&gt;</description><media:content xmlns:media="http://search.yahoo.com/mrss/" url="https://log.j2234.cc/posts/velog/060-thymeleaf/featured.webp"/></item><item><title>Port 8080 was already in use</title><link>https://log.j2234.cc/posts/velog/061-port-8080-was-already-in-use/</link><pubDate>Tue, 17 Jan 2023 00:57:15 +0000</pubDate><guid>https://log.j2234.cc/posts/velog/061-port-8080-was-already-in-use/</guid><description>&lt;p&gt;오늘 하도 서버를 켯다껐다해서 그런가
&lt;code&gt;Port 8080 was already in use&lt;/code&gt; 에러가 뜨면서 실행이 안된다.
인터넷에서 해결방안을 찾아서 써논다.&lt;/p&gt;

&lt;h2 class="relative group"&gt;해결하는 방법
 &lt;div id="해결하는-방법" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#%ed%95%b4%ea%b2%b0%ed%95%98%eb%8a%94-%eb%b0%a9%eb%b2%95" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;application.properties&lt;/code&gt;에서
&lt;code&gt;server.port=????&lt;/code&gt;로 포트 번호를 설정해준다.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;ol start="2"&gt;
&lt;li&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight-wrapper"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;lsof -i tcp:8080 
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 8080포트를 쓰고 있는 프로세스를 찾는다.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo &lt;span class="nb"&gt;kill&lt;/span&gt; -9 &lt;span class="o"&gt;[&lt;/span&gt;PID&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="c1"&gt;#로 죽여버린다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;*참고
&lt;code&gt;lsof&lt;/code&gt;는 list of open file로, 열려있는 파일과 그에대한 정보를 알려준다 &lt;del&gt;리눅스는 모든게 파일임&lt;/del&gt;
&lt;code&gt;-i&lt;/code&gt; [프로토콜:포트번호]를 주면 특정 포트를 사용하는 프로세스 정보를 출력한다&lt;/p&gt;</description></item><item><title>스프링 MVC-웹페이지만들기</title><link>https://log.j2234.cc/posts/velog/062-%EC%8A%A4%ED%94%84%EB%A7%81-mvc-%EC%9B%B9%ED%8E%98%EC%9D%B4%EC%A7%80%EB%A7%8C%EB%93%A4%EA%B8%B0/</link><pubDate>Sun, 15 Jan 2023 19:39:57 +0000</pubDate><guid>https://log.j2234.cc/posts/velog/062-%EC%8A%A4%ED%94%84%EB%A7%81-mvc-%EC%9B%B9%ED%8E%98%EC%9D%B4%EC%A7%80%EB%A7%8C%EB%93%A4%EA%B8%B0/</guid><description>&lt;h2 class="relative group"&gt;프로젝트 생성
 &lt;div id="프로젝트-생성" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#%ed%94%84%eb%a1%9c%ec%a0%9d%ed%8a%b8-%ec%83%9d%ec%84%b1" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;figure&gt;&lt;img
 class="my-0 rounded-md"
 loading="lazy"
 decoding="async"
 fetchpriority="auto"
 alt=""
 width="1509"
 height="621"
 src="https://log.j2234.cc/posts/velog/062-%EC%8A%A4%ED%94%84%EB%A7%81-mvc-%EC%9B%B9%ED%8E%98%EC%9D%B4%EC%A7%80%EB%A7%8C%EB%93%A4%EA%B8%B0/img/image-01_hu_a235e8ad537ab8d9.webp"
 srcset="https://log.j2234.cc/posts/velog/062-%EC%8A%A4%ED%94%84%EB%A7%81-mvc-%EC%9B%B9%ED%8E%98%EC%9D%B4%EC%A7%80%EB%A7%8C%EB%93%A4%EA%B8%B0/img/image-01_hu_a235e8ad537ab8d9.webp 800w, https://log.j2234.cc/posts/velog/062-%EC%8A%A4%ED%94%84%EB%A7%81-mvc-%EC%9B%B9%ED%8E%98%EC%9D%B4%EC%A7%80%EB%A7%8C%EB%93%A4%EA%B8%B0/img/image-01_hu_47d20a92bbe2f339.webp 1280w"
 sizes="(min-width: 768px) 50vw, 65vw"
 data-zoom-src="https://log.j2234.cc/posts/velog/062-%EC%8A%A4%ED%94%84%EB%A7%81-mvc-%EC%9B%B9%ED%8E%98%EC%9D%B4%EC%A7%80%EB%A7%8C%EB%93%A4%EA%B8%B0/img/image-01.webp"&gt;&lt;/figure&gt;
&lt;hr&gt;

&lt;h2 class="relative group"&gt;요구사항 분석
 &lt;div id="요구사항-분석" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#%ec%9a%94%ea%b5%ac%ec%82%ac%ed%95%ad-%eb%b6%84%ec%84%9d" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;&lt;em&gt;상품 관리 서비스&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;상품 도메인 모델&lt;/strong&gt;
(ID, 명, 가격, 수량)&lt;/p&gt;
&lt;p&gt;** 서비스 흐름 **
상품 관리 기능 = CRUD
&lt;figure&gt;&lt;img
 class="my-0 rounded-md"
 loading="lazy"
 decoding="async"
 fetchpriority="auto"
 alt=""
 width="1614"
 height="678"
 src="https://log.j2234.cc/posts/velog/062-%EC%8A%A4%ED%94%84%EB%A7%81-mvc-%EC%9B%B9%ED%8E%98%EC%9D%B4%EC%A7%80%EB%A7%8C%EB%93%A4%EA%B8%B0/img/image-02_hu_9c87d4a42ec5eafc.webp"
 srcset="https://log.j2234.cc/posts/velog/062-%EC%8A%A4%ED%94%84%EB%A7%81-mvc-%EC%9B%B9%ED%8E%98%EC%9D%B4%EC%A7%80%EB%A7%8C%EB%93%A4%EA%B8%B0/img/image-02_hu_9c87d4a42ec5eafc.webp 800w, https://log.j2234.cc/posts/velog/062-%EC%8A%A4%ED%94%84%EB%A7%81-mvc-%EC%9B%B9%ED%8E%98%EC%9D%B4%EC%A7%80%EB%A7%8C%EB%93%A4%EA%B8%B0/img/image-02_hu_9e4716c5f71d366e.webp 1280w"
 sizes="(min-width: 768px) 50vw, 65vw"
 data-zoom-src="https://log.j2234.cc/posts/velog/062-%EC%8A%A4%ED%94%84%EB%A7%81-mvc-%EC%9B%B9%ED%8E%98%EC%9D%B4%EC%A7%80%EB%A7%8C%EB%93%A4%EA%B8%B0/img/image-02.webp"&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr&gt;

&lt;h2 class="relative group"&gt;타임리프
 &lt;div id="타임리프" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#%ed%83%80%ec%9e%84%eb%a6%ac%ed%94%84" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;타임리프 사용 선언&lt;/strong&gt;
&lt;code&gt;&amp;lt;html xmlns:th=&amp;quot;http://www.thymeleaf.org&amp;quot;&amp;gt;&lt;/code&gt;&lt;/p&gt;</description><media:content xmlns:media="http://search.yahoo.com/mrss/" url="https://log.j2234.cc/posts/velog/062-%EC%8A%A4%ED%94%84%EB%A7%81-mvc-%EC%9B%B9%ED%8E%98%EC%9D%B4%EC%A7%80%EB%A7%8C%EB%93%A4%EA%B8%B0/featured.webp"/></item><item><title>스프링MVC-기본 기능</title><link>https://log.j2234.cc/posts/velog/063-%EC%8A%A4%ED%94%84%EB%A7%81mvc-%EA%B8%B0%EB%B3%B8-%EA%B8%B0%EB%8A%A5/</link><pubDate>Fri, 13 Jan 2023 14:47:59 +0000</pubDate><guid>https://log.j2234.cc/posts/velog/063-%EC%8A%A4%ED%94%84%EB%A7%81mvc-%EA%B8%B0%EB%B3%B8-%EA%B8%B0%EB%8A%A5/</guid><description>&lt;h2 class="relative group"&gt;프로젝트 생성
 &lt;div id="프로젝트-생성" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#%ed%94%84%eb%a1%9c%ec%a0%9d%ed%8a%b8-%ec%83%9d%ec%84%b1" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;&lt;figure&gt;&lt;img
 class="my-0 rounded-md"
 loading="lazy"
 decoding="async"
 fetchpriority="auto"
 alt=""
 width="1503"
 height="608"
 src="https://log.j2234.cc/posts/velog/063-%EC%8A%A4%ED%94%84%EB%A7%81mvc-%EA%B8%B0%EB%B3%B8-%EA%B8%B0%EB%8A%A5/img/image-01_hu_b2031e3bd490edeb.webp"
 srcset="https://log.j2234.cc/posts/velog/063-%EC%8A%A4%ED%94%84%EB%A7%81mvc-%EA%B8%B0%EB%B3%B8-%EA%B8%B0%EB%8A%A5/img/image-01_hu_b2031e3bd490edeb.webp 800w, https://log.j2234.cc/posts/velog/063-%EC%8A%A4%ED%94%84%EB%A7%81mvc-%EA%B8%B0%EB%B3%B8-%EA%B8%B0%EB%8A%A5/img/image-01_hu_ea0a849fd8856781.webp 1280w"
 sizes="(min-width: 768px) 50vw, 65vw"
 data-zoom-src="https://log.j2234.cc/posts/velog/063-%EC%8A%A4%ED%94%84%EB%A7%81mvc-%EA%B8%B0%EB%B3%B8-%EA%B8%B0%EB%8A%A5/img/image-01.webp"&gt;&lt;/figure&gt;

build.gradle 파일로 프로젝트 열기&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Welcome Page&lt;/em&gt;
스프링 부트에 &lt;code&gt;Jar&lt;/code&gt;dmf tkdydgkaus &lt;code&gt;/resources/static/index.html/&lt;/code&gt; 자동 처리&lt;/p&gt;
&lt;hr&gt;

&lt;h2 class="relative group"&gt;로깅
 &lt;div id="로깅" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#%eb%a1%9c%ea%b9%85" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;로깅 라이브러리&lt;/strong&gt;
스프링 부트를 사용하면, &lt;code&gt;spring-boot-logging&lt;/code&gt;이 함께 포함됨
기본적으로 &lt;code&gt;SL4J&lt;/code&gt; (인터페이스) 의 구현체 &lt;code&gt;Logback&lt;/code&gt;을 사용&lt;/p&gt;
&lt;p&gt;trace&amp;gt;debug&amp;gt;info&amp;gt;warn&amp;gt;error 5레벨 있으며
로깅을 사용해서 특정 수준 이상의 로그만 볼 수 있음
&lt;code&gt;application.properties&lt;/code&gt;에서 설정 가능&lt;/p&gt;</description><media:content xmlns:media="http://search.yahoo.com/mrss/" url="https://log.j2234.cc/posts/velog/063-%EC%8A%A4%ED%94%84%EB%A7%81mvc-%EA%B8%B0%EB%B3%B8-%EA%B8%B0%EB%8A%A5/featured.webp"/></item><item><title>스프링MVC 구조</title><link>https://log.j2234.cc/posts/velog/064-%EC%8A%A4%ED%94%84%EB%A7%81mvc-%EA%B5%AC%EC%A1%B0/</link><pubDate>Thu, 12 Jan 2023 19:59:27 +0000</pubDate><guid>https://log.j2234.cc/posts/velog/064-%EC%8A%A4%ED%94%84%EB%A7%81mvc-%EA%B5%AC%EC%A1%B0/</guid><description>&lt;h2 class="relative group"&gt;스프링 MVC 전체 구조
 &lt;div id="스프링-mvc-전체-구조" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#%ec%8a%a4%ed%94%84%eb%a7%81-mvc-%ec%a0%84%ec%b2%b4-%ea%b5%ac%ec%a1%b0" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;&lt;figure&gt;&lt;img
 class="my-0 rounded-md"
 loading="lazy"
 decoding="async"
 fetchpriority="auto"
 alt=""
 width="1608"
 height="734"
 src="https://log.j2234.cc/posts/velog/064-%EC%8A%A4%ED%94%84%EB%A7%81mvc-%EA%B5%AC%EC%A1%B0/img/image-01_hu_283b9458aea003e1.webp"
 srcset="https://log.j2234.cc/posts/velog/064-%EC%8A%A4%ED%94%84%EB%A7%81mvc-%EA%B5%AC%EC%A1%B0/img/image-01_hu_283b9458aea003e1.webp 800w, https://log.j2234.cc/posts/velog/064-%EC%8A%A4%ED%94%84%EB%A7%81mvc-%EA%B5%AC%EC%A1%B0/img/image-01_hu_848a2e1cb019f41f.webp 1280w"
 sizes="(min-width: 768px) 50vw, 65vw"
 data-zoom-src="https://log.j2234.cc/posts/velog/064-%EC%8A%A4%ED%94%84%EB%A7%81mvc-%EA%B5%AC%EC%A1%B0/img/image-01.webp"&gt;&lt;/figure&gt;

&lt;a href="https://velog.io/@jiheon2234/MVC-%EB%A7%8C%EB%93%A4%EA%B8%B0" target="_blank" rel="noreferrer"&gt;이전에 만들었던 서블릿 프레임워크&lt;/a&gt;와 같은 구조이다!!&lt;/p&gt;

&lt;h2 class="relative group"&gt;DispatcherServlet
 &lt;div id="dispatcherservlet" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#dispatcherservlet" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;스프링 MVC의 &lt;strong&gt;프론트 컨트롤러&lt;/strong&gt;가 **&lt;code&gt;DispatcherServlet&lt;/code&gt;**이다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;부모 클래스에서 &lt;code&gt;HttpServlet&lt;/code&gt;을 상속받아서 사용하고, 서블릿으로 동작&lt;/li&gt;
&lt;li&gt;스프링은 &lt;code&gt;DispatcherServlet&lt;/code&gt;을 서블릿으로 자동등록하며, 모들 경로에 대해서 매핑&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;요청 흐름&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;서블릿이 호출되면, &lt;code&gt;HttpServlet&lt;/code&gt;의 &lt;code&gt;service()&lt;/code&gt;가 호출됨&lt;/li&gt;
&lt;li&gt;스프링은 &lt;code&gt;DispatcherServlet&lt;/code&gt;의 부모인 &lt;code&gt;FrameworkServlet.service()&lt;/code&gt;가 오버라이딩 되있음&lt;/li&gt;
&lt;li&gt;&lt;code&gt;FrameworkServlet.service()&lt;/code&gt;를 시작으로, 여러 메서드가 호출되며 &lt;code&gt;DispatcherServlet.doDispatch()&lt;/code&gt;가 호출&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;

&lt;h2 class="relative group"&gt;MVC 시작
 &lt;div id="mvc-시작" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#mvc-%ec%8b%9c%ec%9e%91" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;현재 스프링 컨트롤러는 &lt;strong&gt;99,9%&lt;/strong&gt; 어노테이션 기반으로 동작&lt;/p&gt;</description><media:content xmlns:media="http://search.yahoo.com/mrss/" url="https://log.j2234.cc/posts/velog/064-%EC%8A%A4%ED%94%84%EB%A7%81mvc-%EA%B5%AC%EC%A1%B0/featured.webp"/></item><item><title>MVC 만들기</title><link>https://log.j2234.cc/posts/velog/065-mvc-%EB%A7%8C%EB%93%A4%EA%B8%B0/</link><pubDate>Wed, 11 Jan 2023 11:50:04 +0000</pubDate><guid>https://log.j2234.cc/posts/velog/065-mvc-%EB%A7%8C%EB%93%A4%EA%B8%B0/</guid><description>&lt;h2 class="relative group"&gt;프런트 컨트롤러 패턴
 &lt;div id="프런트-컨트롤러-패턴" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#%ed%94%84%eb%9f%b0%ed%8a%b8-%ec%bb%a8%ed%8a%b8%eb%a1%a4%eb%9f%ac-%ed%8c%a8%ed%84%b4" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;특징&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;서블릿 하나로 요청을 받음&lt;/li&gt;
&lt;li&gt;프런트 컨트롤러가 요청에 맞는 컨트롤러 호출 (입구 하나)&lt;/li&gt;
&lt;li&gt;나머지 컨트롤러는 서블릿 사용 ❌&lt;/li&gt;
&lt;/ul&gt;
&lt;figure&gt;&lt;img
 class="my-0 rounded-md"
 loading="lazy"
 decoding="async"
 fetchpriority="auto"
 alt=""
 width="793"
 height="408"
 src="https://log.j2234.cc/posts/velog/065-mvc-%EB%A7%8C%EB%93%A4%EA%B8%B0/img/image-01.webp"
 srcset="https://log.j2234.cc/posts/velog/065-mvc-%EB%A7%8C%EB%93%A4%EA%B8%B0/img/image-01.webp 800w, https://log.j2234.cc/posts/velog/065-mvc-%EB%A7%8C%EB%93%A4%EA%B8%B0/img/image-01.webp 1280w"
 sizes="(min-width: 768px) 50vw, 65vw"
 data-zoom-src="https://log.j2234.cc/posts/velog/065-mvc-%EB%A7%8C%EB%93%A4%EA%B8%B0/img/image-01.webp"&gt;&lt;/figure&gt;
&lt;hr&gt;

&lt;h2 class="relative group"&gt;v1
 &lt;div id="v1" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#v1" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;&lt;em&gt;기본 구조는 그대도되, Front Controller 추가&lt;/em&gt;
&lt;figure&gt;&lt;img
 class="my-0 rounded-md"
 loading="lazy"
 decoding="async"
 fetchpriority="auto"
 alt=""
 width="796"
 height="425"
 src="https://log.j2234.cc/posts/velog/065-mvc-%EB%A7%8C%EB%93%A4%EA%B8%B0/img/image-02.webp"
 srcset="https://log.j2234.cc/posts/velog/065-mvc-%EB%A7%8C%EB%93%A4%EA%B8%B0/img/image-02.webp 800w, https://log.j2234.cc/posts/velog/065-mvc-%EB%A7%8C%EB%93%A4%EA%B8%B0/img/image-02.webp 1280w"
 sizes="(min-width: 768px) 50vw, 65vw"
 data-zoom-src="https://log.j2234.cc/posts/velog/065-mvc-%EB%A7%8C%EB%93%A4%EA%B8%B0/img/image-02.webp"&gt;&lt;/figure&gt;
&lt;/p&gt;</description><media:content xmlns:media="http://search.yahoo.com/mrss/" url="https://log.j2234.cc/posts/velog/065-mvc-%EB%A7%8C%EB%93%A4%EA%B8%B0/featured.webp"/></item><item><title>JSP &amp; MVC</title><link>https://log.j2234.cc/posts/velog/066-jsp--mvc/</link><pubDate>Tue, 10 Jan 2023 16:55:25 +0000</pubDate><guid>https://log.j2234.cc/posts/velog/066-jsp--mvc/</guid><description>&lt;h2 class="relative group"&gt;템플릿 엔진
 &lt;div id="템플릿-엔진" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#%ed%85%9c%ed%94%8c%eb%a6%bf-%ec%97%94%ec%a7%84" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;서블릿과 자바 코드만으로 HTML을 동적으로 만들 수 있다.
&lt;em&gt;하지만&lt;/em&gt;&lt;/p&gt;
&lt;div class="highlight-wrapper"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;PrintWriter&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getWriter&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;&amp;lt;html&amp;gt;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;&amp;lt;head&amp;gt;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34; &amp;lt;meta charset=\&amp;#34;UTF-8\&amp;#34;&amp;gt;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34; &amp;lt;title&amp;gt;Title&amp;lt;/title&amp;gt;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;&amp;lt;/head&amp;gt;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;&amp;lt;body&amp;gt;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;&amp;lt;a href=\&amp;#34;/index.html\&amp;#34;&amp;gt;메인&amp;lt;/a&amp;gt;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;&amp;lt;table&amp;gt;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34; &amp;lt;thead&amp;gt;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34; &amp;lt;th&amp;gt;id&amp;lt;/th&amp;gt;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34; &amp;lt;th&amp;gt;username&amp;lt;/th&amp;gt;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;이런 짓은 사람이 할게 아니다.&lt;/p&gt;
&lt;p&gt;따라서, 자바 코드에서 HtTML을 만들지 않고 HTML 문서에 자바 코드를 넣어서 동적 HTML을 만들게 되었고, 이게 &lt;strong&gt;템플릿 엔진&lt;/strong&gt;이다.
&lt;em&gt;(JSP,Thymeleaf등)&lt;/em&gt;&lt;/p&gt;</description><media:content xmlns:media="http://search.yahoo.com/mrss/" url="https://log.j2234.cc/posts/velog/066-jsp--mvc/featured.webp"/></item><item><title>서블릿</title><link>https://log.j2234.cc/posts/velog/067-%EC%84%9C%EB%B8%94%EB%A6%BF/</link><pubDate>Wed, 04 Jan 2023 20:00:13 +0000</pubDate><guid>https://log.j2234.cc/posts/velog/067-%EC%84%9C%EB%B8%94%EB%A6%BF/</guid><description>&lt;h2 class="relative group"&gt;프로젝트 생성
 &lt;div id="프로젝트-생성" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#%ed%94%84%eb%a1%9c%ec%a0%9d%ed%8a%b8-%ec%83%9d%ec%84%b1" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;&lt;em&gt;서블릿은 스프링이 필요없지만, 환경설정이 잘 되 있어 스프링 사용&lt;/em&gt;
&lt;a href="https://start.spring.io/" target="_blank" rel="noreferrer"&gt;spring boot starter&lt;/a&gt; 에서 생성
&lt;figure&gt;&lt;img
 class="my-0 rounded-md"
 loading="lazy"
 decoding="async"
 fetchpriority="auto"
 alt=""
 width="1464"
 height="581"
 src="https://log.j2234.cc/posts/velog/067-%EC%84%9C%EB%B8%94%EB%A6%BF/img/image-01_hu_8b8c8de7639d7a49.webp"
 srcset="https://log.j2234.cc/posts/velog/067-%EC%84%9C%EB%B8%94%EB%A6%BF/img/image-01_hu_8b8c8de7639d7a49.webp 800w, https://log.j2234.cc/posts/velog/067-%EC%84%9C%EB%B8%94%EB%A6%BF/img/image-01_hu_e924030a717ad80d.webp 1280w"
 sizes="(min-width: 768px) 50vw, 65vw"
 data-zoom-src="https://log.j2234.cc/posts/velog/067-%EC%84%9C%EB%B8%94%EB%A6%BF/img/image-01.webp"&gt;&lt;/figure&gt;

다운 후, build.gradle 선택해서 열기&lt;/p&gt;

&lt;h2 class="relative group"&gt;Hello 서블릿
 &lt;div id="hello-서블릿" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#hello-%ec%84%9c%eb%b8%94%eb%a6%bf" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;@ServeltComponentScan&lt;/code&gt;을 통하여 스프링에서 서블릿 자동 등록&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;모든 서블렛은 &lt;code&gt;javax.servlet.http.HttpServlet&lt;/code&gt;를 상속받음
&lt;code&gt;@Webservlet&lt;/code&gt;으로 url mapping
요칭이 오면, 오버라이딩된 &lt;code&gt;service&lt;/code&gt;메소드 실행&lt;/p&gt;</description><media:content xmlns:media="http://search.yahoo.com/mrss/" url="https://log.j2234.cc/posts/velog/067-%EC%84%9C%EB%B8%94%EB%A6%BF/featured.webp"/></item><item><title>웹 어플리케이션</title><link>https://log.j2234.cc/posts/velog/068-%EC%9B%B9-%EC%96%B4%ED%94%8C%EB%A6%AC%EC%BC%80%EC%9D%B4%EC%85%98/</link><pubDate>Wed, 04 Jan 2023 19:17:43 +0000</pubDate><guid>https://log.j2234.cc/posts/velog/068-%EC%9B%B9-%EC%96%B4%ED%94%8C%EB%A6%AC%EC%BC%80%EC%9D%B4%EC%85%98/</guid><description>&lt;h2 class="relative group"&gt;웹서버, WAS
 &lt;div id="웹서버-was" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#%ec%9b%b9%ec%84%9c%eb%b2%84-was" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;

&lt;h3 class="relative group"&gt;웹 서버
 &lt;div id="웹-서버" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#%ec%9b%b9-%ec%84%9c%eb%b2%84" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h3&gt;
&lt;blockquote&gt;&lt;p&gt;Http 기반으로 정적 리소스들을 주고받는 서버&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 class="relative group"&gt;WAS (web application server)
 &lt;div id="was-web-application-server" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#was-web-application-server" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h3&gt;
&lt;blockquote&gt;&lt;p&gt;웹 서버의 기능을 포함하며, 프로그램 코드를 실행해 애플리케이션 로직 수행
자바는 서벌릿 컨테이너 기능을 제공하면 WAS (ex.tomcat)&lt;/p&gt;</description><media:content xmlns:media="http://search.yahoo.com/mrss/" url="https://log.j2234.cc/posts/velog/068-%EC%9B%B9-%EC%96%B4%ED%94%8C%EB%A6%AC%EC%BC%80%EC%9D%B4%EC%85%98/featured.webp"/></item><item><title>Init</title><link>https://log.j2234.cc/posts/velog/069-init/</link><pubDate>Wed, 04 Jan 2023 00:05:21 +0000</pubDate><guid>https://log.j2234.cc/posts/velog/069-init/</guid><description>&lt;blockquote&gt;&lt;p&gt;인프런 할인 이벤트를 보고, 눈여겨보고 있었던 김영한님의 스프링 MVC강의 1~2편을 다 샀다.&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;열심히 공부해서 다른 사람의 도움을 받지 않고, 나만의 포트폴리오를 만들 생각이다&lt;/p&gt;
&lt;/blockquote&gt;&lt;/blockquote&gt;&lt;p&gt;앞으로 이 시리즈에 강의내용을 정리해서 올릴 예정이다.
&lt;em&gt;화이팅!&lt;/em&gt;&lt;/p&gt;</description></item></channel></rss>