<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>연습장</title>
    <link>https://practicingjava.tistory.com/</link>
    <description></description>
    <language>ko</language>
    <pubDate>Sun, 9 Aug 2026 10:56:09 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>자바응애</managingEditor>
    <item>
      <title>TypeScript 두 번째</title>
      <link>https://practicingjava.tistory.com/293</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;제네릭(Generics)&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;제네릭은 타입스크립트에서 &lt;b&gt;재사용 가능한 컴포넌트(함수, 클래스, 인터페이스 등)를 만들 때 사용되는 기능&lt;/b&gt;. 한 마디로, &lt;b&gt;코드를 작성할 때 타입을 미리 정하지 않고, 그 코드를 사용할 때(호출할 때) 타입을 결정할 수 있도록 해주는 문법&lt;/b&gt;.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어 특정 타입의 데이터를 배열로 받아서 첫 번째 요소를 반환하는 함수를 만든다고 할 때&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre class=&quot;actionscript&quot;&gt;&lt;code&gt;// 1. 특정 타입에만 동작하는 함수 (string만)
function getFirstString(arr: string[]): string {
    return arr[0];
}

// 2. 다른 타입을 처리하려면 또 다른 함수를 만들어야 함 (number도)
function getFirstNumber(arr: number[]): number {
    return arr[0];
}
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 방식은 string이나 number뿐만 아니라 boolean, 객체 등 다양한 타입에 대해 함수를 계속해서 만들어야 하는 비효율성이 있다. 이때 &lt;b&gt;제네릭&lt;/b&gt;을 사용하면 하나의 함수로 모든 타입을 처리 가능.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot;&gt;&lt;code&gt;// 제네릭 T (Type의 약자)를 사용하여 어떤 타입이든 받을 수 있게 함
function getFirstElement&amp;lt;T&amp;gt;(arr: T[]): T {
    return arr[0];
}

let numArr = [1, 2, 3];
let strArr = [&quot;a&quot;, &quot;b&quot;, &quot;c&quot;];

let firstNum = getFirstElement(numArr); // T는 number로 추론됨, firstNum은 number 타입
let firstStr = getFirstElement(strArr); // T는 string으로 추론됨, firstStr은 string 타입

// 타입을 명시적으로 지정할 수도 있습니다.
let firstBoolean = getFirstElement&amp;lt;boolean&amp;gt;([true, false]); // firstBoolean은 boolean 타입&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 예시에서 &amp;lt;T&amp;gt;는 &quot;이 함수가 어떤 특정 타입 T를 사용할 것이다&quot;라고 선언하는 것. 함수를 호출할 때 T의 실제 타입이 결정되며, 타입스크립트는 이 T를 사용하여 함수 내부의 타입 검사를 수행.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;제네릭을 사용하는 주된 이유:&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;코드 재사용성:&lt;/b&gt; 다양한 타입에 대해 동일한 로직을 적용할 수 있어 중복 코드를 줄임.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;타입 안정성:&lt;/b&gt; any를 사용하는 것과 달리, 제네릭은 사용 시점에 타입을 명확히 지정하거나 추론하여 타입 안정성을 유지.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;유연성:&lt;/b&gt; 코드를 작성할 때는 유연하게 타입을 비워두고, 실제 사용 시점에서 구체적인 타입을 지정할 수 있음.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1. 인터페이스(Interface)에 제네릭 사용&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;인터페이스에 제네릭을 사용하면, 인터페이스가 정의하는 구조가 특정 타입에 국한되지 않고 다양한 타입을 포용할 수 있게 됨&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot;&gt;&lt;code&gt;// 제네릭 인터페이스: Box
// &amp;lt;T&amp;gt;는 이 인터페이스를 사용할 때 결정될 타입.
interface Box&amp;lt;T&amp;gt; {
    value: T; // value 속성은 T 타입의 값을 가짐.
    label: string;
    // T 타입의 값을 받아들이는 메서드도 정의할 수 있음.
    unwrap(): T;
}

// string 타입을 위한 Box 인스턴스
const stringBox: Box&amp;lt;string&amp;gt; = {
    value: &quot;Hello Generics&quot;,
    label: &quot;문자열 상자&quot;,
    unwrap() {
        return this.value;
    }
};

console.log(stringBox.unwrap()); // &quot;Hello Generics&quot;
// stringBox.value = 123; // 오류: 'number' 타입은 'string' 타입에 할당될 수 없음

// number 타입을 위한 Box 인스턴스
const numberBox: Box&amp;lt;number&amp;gt; = {
    value: 123,
    label: &quot;숫자 상자&quot;,
    unwrap() {
        return this.value;
    }
};

console.log(numberBox.unwrap()); // 123

// 커스텀 객체 타입을 위한 Box 인스턴스
interface User {
    id: number;
    name: string;
}

const userBox: Box&amp;lt;User&amp;gt; = {
    value: { id: 1, name: &quot;Alice&quot; },
    label: &quot;사용자 상자&quot;,
    unwrap() {
        return this.value;
    }
};

console.log(userBox.unwrap().name); // &quot;Alice&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 예시에서 Box&amp;lt;T&amp;gt; 인터페이스는 어떤 타입 T라도 value 속성의 타입으로 받을 수 있게 정의되어 있음. 이를 통해 string, number, User 등 다양한 타입의 값을 담는 Box를 생성.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2. 타입 별칭(Type Alias)에 제네릭 사용&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;타입 별칭 또한 인터페이스와 유사하게 제네릭을 사용하여 유연한 타입 정의를 할 수 있음. 타입 별칭은 인터페이스보다 더 다양한 타입 조합(유니온, 튜플 등)에도 제네릭을 적용할 수 있다는 장점이 있음.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot;&gt;&lt;code&gt;// 제네릭 타입 별칭: Pair
// &amp;lt;K, V&amp;gt;는 각각 키(Key)와 값(Value)의 타입.
type Pair&amp;lt;K, V&amp;gt; = {
    key: K;
    value: V;
};

// string 키와 number 값을 가지는 Pair
const idValuePair: Pair&amp;lt;string, number&amp;gt; = {
    key: &quot;userId&quot;,
    value: 12345
};

console.log(idValuePair.key, idValuePair.value); // &quot;userId&quot; 12345

// number 키와 boolean 값을 가지는 Pair
const statusPair: Pair&amp;lt;number, boolean&amp;gt; = {
    key: 200,
    value: true
};

console.log(statusPair.key, statusPair.value); // 200 true

// 제네릭 타입 별칭: ArrayOf&amp;lt;T&amp;gt; (배열 타입에 별칭을 부여)
type ArrayOf&amp;lt;T&amp;gt; = T[];

const numbers: ArrayOf&amp;lt;number&amp;gt; = [10, 20, 30];
// numbers = [&quot;hello&quot;]; // 오류: 'string' 타입은 'number' 타입에 할당될 수 없음

// 제네릭 타입 별칭: Result&amp;lt;T, E&amp;gt; (성공 또는 실패 결과를 나타낼 때 유용)
type Result&amp;lt;T, E&amp;gt; = { success: true; data: T } | { success: false; error: E };

function fetchDataResult(): Result&amp;lt;string, Error&amp;gt; {
    const success = Math.random() &amp;gt; 0.5;
    if (success) {
        return { success: true, data: &quot;데이터를 성공적으로 가져왔습니다!&quot; };
    } else {
        return { success: false, error: new Error(&quot;네트워크 오류 발생!&quot;) };
    }
}

const apiResponse = fetchDataResult();
if (apiResponse.success) {
    console.log(apiResponse.data); // 'data'는 string 타입
} else {
    console.log(apiResponse.error.message); // 'error'는 Error 타입
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Pair&amp;lt;K, V&amp;gt; 타입 별칭은 다양한 키와 값 타입을 갖는 객체를 정의할 때 유용, Result&amp;lt;T, E&amp;gt;는 비동기 작업의 성공/실패 결과를 명확한 타입으로 표현할 수 있게 해준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3. 변수(Variable)에 제네릭 사용 (함수, 클래스, 인터페이스 등의 인스턴스)&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;변수 자체에 제네릭 타입을 직접 선언하는 경우는 드물지만, &lt;b&gt;제네릭이 적용된 함수, 클래스, 인터페이스 등의 타입을 변수에 할당할 때&lt;/b&gt; 제네릭 타입 매개변수를 지정하여 사용.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot;&gt;&lt;code&gt;// 1. 제네릭 함수를 변수에 할당하는 경우
function identity&amp;lt;T&amp;gt;(arg: T): T {
    return arg;
}

// 변수 myIdentity는 제네릭 함수 identity의 타입 시그니처를 가짐.
// 타입스크립트가 자동으로 T를 number로 추론.
let myIdentity = identity(100); // myIdentity: number

// 명시적으로 T를 string으로 지정할 수도 있음.
let myStringIdentity: &amp;lt;T&amp;gt;(arg: T) =&amp;gt; T = identity;
let resultString = myStringIdentity&amp;lt;string&amp;gt;(&quot;TypeScript&quot;); // resultString: string

// 2. 제네릭 클래스 인스턴스를 변수에 할당하는 경우
class LinkedListNode&amp;lt;T&amp;gt; {
    constructor(public value: T, public next: LinkedListNode&amp;lt;T&amp;gt; | null = null) {}
}

// ListNode 변수는 string 타입의 값을 가지는 LinkedListNode 인스턴스.
const headNode: LinkedListNode&amp;lt;string&amp;gt; = new LinkedListNode(&quot;first&quot;);
headNode.next = new LinkedListNode(&quot;second&quot;);

console.log(headNode.value); // &quot;first&quot;
console.log(headNode.next?.value); // &quot;second&quot;

// 3. 제네릭 인터페이스의 인스턴스를 변수에 할당하는 경우 (위 인터페이스 예시에서 다시 가져옴)
interface Box&amp;lt;T&amp;gt; {
    value: T;
    label: string;
}

// string 타입 값을 담는 Box 인스턴스를 변수에 할당
const myProductBox: Box&amp;lt;string&amp;gt; = {
    value: &quot;Laptop&quot;,
    label: &quot;전자제품&quot;
};

console.log(myProductBox.value); // &quot;Laptop&quot;

// number 타입 값을 담는 Box 인스턴스를 변수에 할당
const myQuantityBox: Box&amp;lt;number&amp;gt; = {
    value: 500,
    label: &quot;재고수량&quot;
};

console.log(myQuantityBox.value); // 500&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 예시들처럼, 변수 자체에 &amp;lt;T&amp;gt;와 같은 제네릭 선언을 하는 것이 아니라, &lt;b&gt;제네릭이 적용된 다른 타입(함수 타입, 클래스 타입, 인터페이스 타입)을 변수에 할당할 때&lt;/b&gt; 제네릭 타입 인자(string, number 등)를 지정하여 사용.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;인터페이스(Interface)와 타입 별칭(Type Alias)의 차이점과 공통점&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;타입스크립트에서 객체의 모양(shape)을 정의하거나 복잡한 타입을 재사용할 때 인터페이스(interface)와 타입 별칭(type)이라는 두 가지 방법이 있음. 이 둘은 많은 부분에서 유사하게 사용될 수 있지만, 중요한 차이점과 그에 따른 사용 권장 사항이 있다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;공통점&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;객체의 타입 정의:&lt;/b&gt; 가장 기본적인 공통점은 둘 다 객체의 구조(속성과 메서드)를 정의하는 데 사용된다.
&lt;div&gt;
&lt;div&gt;
&lt;pre class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot;&gt;&lt;code&gt;interface PersonInterface {
    name: string;
    age: number;
}

type PersonType = {
    name: string;
    age: number;
};

const user1: PersonInterface = { name: &quot;Alice&quot;, age: 30 };
const user2: PersonType = { name: &quot;Bob&quot;, age: 25 };&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;b&gt;&lt;/b&gt;&lt;b&gt;&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;함수의 타입 정의:&lt;/b&gt; 함수 시그니처를 정의하는 데 사용.
&lt;div&gt;
&lt;div&gt;
&lt;pre class=&quot;typescript&quot;&gt;&lt;code&gt;interface GreetFunctionInterface {
    (message: string): void;
}

type GreetFunctionType = (message: string) =&amp;gt; void;

const greet: GreetFunctionInterface = (msg) =&amp;gt; console.log(msg);
const sayHello: GreetFunctionType = (msg) =&amp;gt; console.log(`Hello, ${msg}`);
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;b&gt;&lt;/b&gt;&lt;b&gt;&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;확장(extends) 또는 인터섹션(&amp;amp;)을 통한 결합:&lt;/b&gt; 두 타입 모두 기존 타입을 확장하거나 결합하여 새로운 타입을 만들 수 있다.&lt;br /&gt;&lt;b&gt;&lt;b&gt;&lt;i&gt;&lt;br /&gt;참고: 인터페이스도 &amp;amp;를 사용하여 인터섹션 타입을 만들 수 있고, 타입 별칭도 extends와 비슷한 방식으로 인터섹션(&amp;amp;)을 통해 확장 효과를 낼 수 있다.&lt;br /&gt;&lt;/i&gt;&lt;/b&gt;&lt;/b&gt;
&lt;pre style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-language=&quot;typescript&quot;&gt;&lt;code&gt;// 인터페이스 확장
interface Animal {
    name: string;
}
interface Dog extends Animal {
    breed: string;
}
const myDog: Dog = { name: &quot;Buddy&quot;, breed: &quot;Golden&quot; };

// 타입 별칭 인터섹션
type Draggable = { drag(): void; };
type Resizable = { resize(): void; };
type UIElement = Draggable &amp;amp; Resizable; // 두 타입의 모든 속성을 가짐
const button: UIElement = {
    drag: () =&amp;gt; console.log(&quot;dragging&quot;),
    resize: () =&amp;gt; console.log(&quot;resizing&quot;)
};&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;제네릭 사용:&lt;/b&gt; 둘 다 제네릭과 함께 사용가능.
&lt;div&gt;
&lt;div&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;interface BoxInterface&amp;lt;T&amp;gt; {
    value: T;
}
type BoxType&amp;lt;T&amp;gt; = {
    value: T;
};

const stringBox: BoxInterface&amp;lt;string&amp;gt; = { value: &quot;hello&quot; };
const numberBox: BoxType&amp;lt;number&amp;gt; = { value: 123 };
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;차이점&lt;/h3&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;확장 방식 (Declaring Merging / Declaration Augmentation):&lt;/b&gt; &lt;b&gt;인터페이스는 동일한 이름으로 여러 번 선언하면 자동으로 병합(Merge)됨.&lt;/b&gt; 타입 별칭은 동일한 이름을 두 번 정의하면 오류가 발생.
&lt;div&gt;
&lt;pre class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot;&gt;&lt;code&gt;type MyType = { a: string; };
// type MyType = { b: number; }; // 오류: 중복 식별자 'MyType'&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot;&gt;&lt;code&gt;// Interface Merging (인터페이스만 가능!)
interface Car {
    brand: string;
}

interface Car { // 동일한 이름의 Car 인터페이스를 다시 선언
    model: string;
}

const myCar: Car = { brand: &quot;Hyundai&quot;, model: &quot;Sonata&quot; }; // brand와 model 모두 가짐
// `myCar`는 `{ brand: string; model: string; }` 타입이 됨.&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;b&gt;&lt;/b&gt;&lt;b&gt;&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;다양한 타입 정의 능력:&lt;/b&gt; &lt;b&gt;타입 별칭은 인터페이스보다 더 다양한 타입을 정의할 수 있다.&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;원시 타입, 유니온 타입, 튜플 타입, 리터럴 타입 등:&lt;/b&gt; 인터페이스는 주로 객체(object)의 형태를 정의하는 데 사용되지만, 타입 별칭은 객체 외의 다양한 타입 조합을 정의할 수 있다.
&lt;div&gt;
&lt;div&gt;
&lt;pre class=&quot;typescript&quot;&gt;&lt;code&gt;// Type Alias만 가능한 경우
type ID = string | number; // 유니온 타입
type Point = [number, number]; // 튜플 타입
type Direction = &quot;up&quot; | &quot;down&quot; | &quot;left&quot; | &quot;right&quot;; // 리터럴 유니온 타입
type MyString = string; // 원시 타입의 별칭

// interface MyID = string | number; // 오류: 인터페이스는 유니온 타입을 정의할 수 없음
// interface MyPoint = [number, number]; // 오류
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;implements 키워드 사용:&lt;/b&gt; 클래스가 특정 타입을 따르도록 강제할 때, &lt;b&gt;인터페이스는 implements 키워드를 통해 클래스가 해당 인터페이스를 구현하도록 강제할 수 있음.&lt;/b&gt; 타입 별칭은 이 기능을 직접적으로 제공하지 않음.
&lt;div&gt;
&lt;div&gt;
&lt;pre class=&quot;typescript&quot;&gt;&lt;code&gt;interface Shape {
    getArea(): number;
}

class Circle implements Shape { // 클래스가 인터페이스를 구현
    constructor(public radius: number) {}
    getArea() {
        return Math.PI * this.radius * this.radius;
    }
}

// class Square implements Point { /* 오류: 'Point'는 인터페이스가 아님 */ }
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;언제 무엇을 사용해야 하는가?&amp;nbsp;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;객체의 형태를 정의하고, 나중에 확장 또는 병합될 가능성이 있다면 &lt;span style=&quot;color: #006dd7;&quot;&gt;interface&lt;/span&gt;&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;특히 라이브러리를 작성하거나, 서드파티 모듈의 타입을 확장해야 할 때 매우 유용&lt;/li&gt;
&lt;li&gt;객체 지향적인 개념(implements, extends)과 더 잘 어울림.&lt;/li&gt;
&lt;li&gt;명시적인 객체 구조를 선언하는 데 더 적합.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;객체 외의 다른 타입(원시 타입, 유니온 타입, 튜플, 리터럴 타입 등)을 정의하거나, 복잡한 타입 조합에 이름을 부여하고 싶다면 &lt;span style=&quot;color: #006dd7;&quot;&gt;type&lt;/span&gt;&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;함수 시그니처를 정의할 때 type이 더 간결할 수 있다.&lt;/li&gt;
&lt;li&gt;인터섹션 타입을 통해 여러 타입을 결합할 때 유용&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;일반적인 규칙:&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;많은 경우에 둘 중 아무거나 사용해도 무방하며, 개인 또는 팀의 코딩 스타일에 따라 선택할 수 있다. 하지만 위에서 설명한 차이점들을 고려하여 적절한 도구를 선택하는 것이 좋다. 최근에는 유연성 때문에 type 키워드의 사용이 늘어나는 추세&lt;/p&gt;</description>
      <category>Next.js + TypeScript</category>
      <author>자바응애</author>
      <guid isPermaLink="true">https://practicingjava.tistory.com/293</guid>
      <comments>https://practicingjava.tistory.com/293#entry293comment</comments>
      <pubDate>Tue, 22 Jul 2025 17:15:05 +0900</pubDate>
    </item>
    <item>
      <title>TypeScript 첫 번째</title>
      <link>https://practicingjava.tistory.com/292</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1. 기본 타입&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1-1 원시 타입&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;boolean (불리언):&lt;/b&gt; true 또는 false 값
&lt;div&gt;
&lt;div&gt;
&lt;pre class=&quot;groovy&quot;&gt;&lt;code&gt;let isDone: boolean = false;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;b&gt;&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;number (숫자):&lt;/b&gt; 정수, 부동 소수점 숫자 등 모든 숫자
&lt;div&gt;
&lt;div&gt;
&lt;pre class=&quot;maxima&quot;&gt;&lt;code&gt;let decimal: number = 6;
let hex: number = 0xf00d;
let binary: number = 0b1010;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;b&gt;&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;string (문자열):&lt;/b&gt; 텍스트 데이터. 백틱(`)을 사용한 템플릿 리터럴도 가능
&lt;div&gt;
&lt;div&gt;
&lt;pre class=&quot;qml&quot;&gt;&lt;code&gt;let fullName: string = &quot;John Doe&quot;;
let sentence: string = `Hello, my name is ${fullName}.`;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;b&gt;&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;null과 undefined:&lt;/b&gt; 자바스크립트와 동일한 의미를 가짐. 기본적으로 다른 모든 타입의 하위 타입으로 간주
&lt;div&gt;
&lt;div&gt;
&lt;pre class=&quot;javascript&quot;&gt;&lt;code&gt;let u: undefined = undefined;
let n: null = null;
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;b&gt;symbol (심볼):&lt;/b&gt; ECMAScript 2015에 추가된 고유하고 변경 불가능한 값
&lt;div&gt;
&lt;div&gt;
&lt;pre class=&quot;dart&quot;&gt;&lt;code&gt;const sym: symbol = Symbol('key');
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;bigint (큰 정수):&lt;/b&gt; ES2020에 추가된, 매우 큰 정수를 다룰 때 사용
&lt;div&gt;
&lt;div&gt;
&lt;pre class=&quot;armasm&quot;&gt;&lt;code&gt;let bigNumber: bigint = 100n;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1-2 특별 타입&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;any (모든 타입):&lt;/b&gt; 어떤 타입의 값이라도 할당할 수 있음을 나타냄. 타입스크립트의 장점을 해치므로 &lt;b&gt;가능한 한 사용을 피해야 함.&lt;/b&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre class=&quot;nix&quot;&gt;&lt;code&gt;let notSure: any = 4;
notSure = &quot;maybe a string instead&quot;;
notSure = false; // boolean
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;b&gt;&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;unknown (알 수 없는 타입):&lt;/b&gt; any와 비슷하게 어떤 타입의 값이든 가질 수 있지만, any보다 &lt;b&gt;타입 안정성이 높음.&lt;/b&gt; unknown 타입의 값을 사용하려면 먼저 타입을 좁히는 작업(예: typeof 또는 instanceof를 사용한 타입 검사)이 필요.
&lt;div&gt;
&lt;div&gt;
&lt;pre class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot;&gt;&lt;code&gt;let value: unknown = 10;
value = &quot;hello&quot;;

// let someString: string = value; // 오류: 'unknown' 타입은 'string' 타입에 할당될 수 없음

if (typeof value === 'string') {
    let someString: string = value; // 이제 안전하게 string으로 사용 가능
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;b&gt;&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;void (반환 값이 없음):&lt;/b&gt; 주로 함수가 아무런 값을 반환하지 않을 때 사용
&lt;div&gt;
&lt;div&gt;
&lt;pre class=&quot;actionscript&quot;&gt;&lt;code&gt;function warnUser(): void {
    console.log(&quot;This is my warning message&quot;);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;b&gt;&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;never (절대 도달할 수 없는 타입):&lt;/b&gt; 함수가 값을 반환할 수 없거나(항상 예외를 던지거나 무한 루프에 빠지는 경우) 절대 도달할 수 없는 코드 경로를 나타낼 때 사용.
&lt;div&gt;
&lt;div&gt;
&lt;pre class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot;&gt;&lt;code&gt;function error(message: string): never {
    throw new Error(message);
}

function infiniteLoop(): never {
    while (true) {}
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2. 타입 명시하기&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2-1. 변수 타입 명시&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;변수 이름 뒤에 콜론(:)을 붙이고 타입을 작성&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre class=&quot;xquery&quot;&gt;&lt;code&gt;let age: number = 30;
let name: string = &quot;Alice&quot;;
let isActive: boolean = true;
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2-2 함수 타입 명시&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;함수의 매개변수와 반환 값에 타입을 명시&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot;&gt;&lt;code&gt;// 매개변수 타입 명시
function add(x: number, y: number): number { // 반환 값도 number 타입이라고 명시
    return x + y;
}

let result = add(5, 3); // result는 자동으로 number 타입으로 추론됨
// add(&quot;5&quot;, 3); // 오류: 'string' 타입의 인수는 'number' 타입의 매개변수에 할당될 수 없음&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2-3 배열의 타입은 두 가지 방식으로 정의&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;요소 타입 뒤에 [ ] 붙이기:&lt;/b&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot;&gt;&lt;code&gt;let list: number[] = [1, 2, 3];&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;제네릭 배열 타입 Array&amp;lt;엘리먼트타입&amp;gt; 사용:&lt;/b&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot;&gt;&lt;code&gt;let list: Array&amp;lt;number&amp;gt; = [1, 2, 3];&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2-4 튜플&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;튜플은 요소의 &lt;b&gt;개수와 각 요소의 타입이 미리 정해진 배열&lt;/b&gt;. 정의된 순서와 타입에 맞춰 값을 할당해야 함.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot;&gt;&lt;code&gt;// string과 number 타입을 가지는 두 개의 요소 튜플
let x: [string, number];

x = [&quot;hello&quot;, 10]; // 성공
// x = [10, &quot;hello&quot;]; // 오류: 순서와 타입이 맞지 않음
// x = [&quot;hello&quot;, 10, true]; // 오류: 요소 개수가 맞지 않음&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2-5 열거형 (enum)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;열거형은 특정 값들의 집합에 이름을 부여하는 것. 기본적으로 숫자 열거형으로 동작하며, 문자열 열거형도 가능.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;1. 숫자 열거형 (Numeric Enums)&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;각 멤버는 자동으로 0부터 시작하는 숫자로 할당. 값을 수동으로 지정할 수도 있음.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot;&gt;&lt;code&gt;enum Direction {
    Up,    // 0
    Down,  // 1
    Left,  // 2
    Right  // 3
}

let dir: Direction = Direction.Up; // dir은 0
console.log(dir); // 0
console.log(Direction.Left); // 2

// 값을 수동으로 지정
enum Status {
    Pending = 1,
    Success, // 2
    Failed   // 3
}
console.log(Status.Success); // 2&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;2. 문자열 열거형 (String Enums)&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모든 멤버에게 문자열 값을 할당해야함.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot;&gt;&lt;code&gt;enum UserRole {
    Admin = &quot;ADMIN&quot;,
    Editor = &quot;EDITOR&quot;,
    Viewer = &quot;VIEWER&quot;
}

let role: UserRole = UserRole.Admin;
console.log(role); // &quot;ADMIN&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2-6 객체&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;객체의 속성들에 타입을 정의할 수 있음.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot;&gt;&lt;code&gt;// 익명 객체 타입 정의
let user: { name: string; age: number; };

user = {
    name: &quot;Bob&quot;,
    age: 25
};

// user = { name: &quot;Bob&quot; }; // 오류: age 속성이 없음

// 선택적 속성 (Optional Properties): ? 를 붙이면 해당 속성이 없어도 됨.
let anotherUser: { name: string; age?: number; };
anotherUser = { name: &quot;Charlie&quot; }; // age 속성 없어도 됨

// 읽기 전용 속성 (Readonly Properties): readonly 를 붙이면 초기 할당 후 변경 불가
let config: { readonly id: string; url: string; };
config = { id: &quot;123&quot;, url: &quot;http://example.com&quot; };
// config.id = &quot;456&quot;; // 오류: 읽기 전용 속성이므로 변경 불가&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2-7 타입 별칭&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;복잡한 타입을 재사용하거나 코드의 가독성을 높이고 싶을 때 type 키워드를 사용하여 타입 별칭을 정의할 수 있음.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot;&gt;&lt;code&gt;type User = {
    id: number;
    name: string;
    email?: string; // 선택적 속성
};

type Admin = User &amp;amp; { //type의 확장
	isAdmin: boolean;
}

let admin: User = {
    id: 1,
    name: &quot;Admin User&quot;,
    email: &quot;admin@example.com&quot;,
    isAdmin: true
};

let guest: User = {
    id: 2,
    name: &quot;Guest User&quot;
};

type Point = [number, number]; // 튜플 타입에 대한 별칭
let coordinate: Point = [10, 20];

type ID = string | number; // 유니온 타입에 대한 별칭 (아래 설명)
let userId: ID = &quot;abc-123&quot;;
let productId: ID = 456;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2-8 인터페이스&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;인터페이스는 객체의 모양(shape)을 정의하는&amp;nbsp; 방법. 객체가 가져야 할 속성과 메서드를 명시. type 별칭과 비슷하지만, 주로 객체의 구조를 정의하는 데 사용되며 확장(extends) 및 구현(implements)이 가능.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot;&gt;&lt;code&gt;interface Person {
    name: string;
    age: number;
    greet(): string; // 메서드 정의
}

class Employee implements Person { // 클래스가 인터페이스를 '구현'
    name: string;
    age: number;
    employeeId: string; // Employee에만 있는 속성

    constructor(name: string, age: number, employeeId: string) {
        this.name = name;
        this.age = age;
        this.employeeId = employeeId;
    }

    greet() {
        return `Hello, my name is ${this.name} and I am an employee.`;
    }
}

let john: Person = {
    name: &quot;John&quot;,
    age: 30,
    greet: function() {
        return `Hello, my name is ${this.name}.`;
    }
};

interface Animal {
    name: string;
}

interface Dog extends Animal { // 인터페이스 확장
    breed: string;
}

let myDog: Dog = {
    name: &quot;Buddy&quot;,
    breed: &quot;Golden Retriever&quot;
};



interface User{
	name: string
}

interface User{
	age: number
}

const user: User = { //같은 이름의 인터페이스는 병합됨. type은 불가능
	name: &quot;kim&quot;,
    age: 20
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2-9&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;유니온 타입은 &lt;b&gt;두 개 이상의 타입 중 하나&lt;/b&gt;가 될 수 있음을 의미. 파이프 기호(|)를 사용하여 정의.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot;&gt;&lt;code&gt;function printId(id: number | string) {
    console.log(`Your ID is: ${id}`);
    // 여기서 id는 number 또는 string 타입일 수 있으므로,
    // 해당 타입에 공통적으로 사용 가능한 속성/메서드만 직접 접근 가능.

    // 예를 들어
    // id.toUpperCase(); // 오류: number 타입에는 toUpperCase 메서드가 없음
    if (typeof id === &quot;string&quot;) {
        console.log(id.toUpperCase()); // 타입 좁히기 후 사용 가능
    }
}

printId(101); // Your ID is: 101
printId(&quot;202&quot;); // Your ID is: 202
// printId(true); // 오류: 'boolean' 타입의 인수는 'number | string' 타입에 할당될 수 없음&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2-10 인터섹션 타입&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;인터섹션 타입은 &lt;b&gt;두 개 이상의 타입을 모두 만족하는&lt;/b&gt; 타입을 생성하는 것. 앰퍼샌드 기호(&amp;amp;)를 사용하여 정의&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre class=&quot;typescript&quot;&gt;&lt;code&gt;interface Draggable {
    drag(): void;
}

interface Resizable {
    resize(): void;
}

type UIElement = Draggable &amp;amp; Resizable; // Draggable과 Resizable의 모든 속성을 가짐

let button: UIElement = {
    drag() { console.log(&quot;드래그!&quot;); },
    resize() { console.log(&quot;리사이즈!&quot;); }
};

button.drag();
button.resize();&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2-11 리터럴 타입&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;리터럴 타입은 특정 &lt;b&gt;고정된 값 자체를 타입&lt;/b&gt;으로 사용하는 것. 특정 문자열, 숫자, 불리언 값만 허용하도록 제한할 때 유용.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;&lt;span&gt;TypeScript&lt;/span&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre class=&quot;accesslog&quot;&gt;&lt;code&gt;type Direction = &quot;north&quot; | &quot;south&quot; | &quot;east&quot; | &quot;west&quot;; // 유니온 리터럴 타입

let move: Direction = &quot;north&quot;;
// move = &quot;up&quot;; // 오류: '&quot;up&quot;' 타입은 'Direction' 타입에 할당될 수 없음

type HTTPMethod = &quot;GET&quot; | &quot;POST&quot; | &quot;PUT&quot; | &quot;DELETE&quot;;

function fetchData(url: string, method: HTTPMethod) {
    // ...
}

fetchData(&quot;/api/users&quot;, &quot;GET&quot;);
// fetchData(&quot;/api/users&quot;, &quot;PATCH&quot;); // 오류&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Next.js + TypeScript</category>
      <author>자바응애</author>
      <guid isPermaLink="true">https://practicingjava.tistory.com/292</guid>
      <comments>https://practicingjava.tistory.com/292#entry292comment</comments>
      <pubDate>Tue, 22 Jul 2025 16:32:09 +0900</pubDate>
    </item>
    <item>
      <title>Next.js 두 번째</title>
      <link>https://practicingjava.tistory.com/291</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;서버 컴포넌트 / 클라이언트 컴포넌트&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;서버 컴포넌트는 말 그대로 보여주기적 요소만 있는 컴포넌트, 또는 동적 기능이 없는 컴포넌트&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정적 렌더링과 보안적 특성이 강함 -&amp;gt; axios,fetch 등 get 요청을 할 때는 서버 컴포넌트에서 사용하는게 좋음&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;대신 상태/이벤트 핸들링이 불가능 -&amp;gt; useState, useEffect 같은 훅 사용이 불가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정적인 화면이므로 인터랙션이 불가능.&lt;/p&gt;
&lt;pre id=&quot;code_1753155968416&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;// 서버 컴포넌트 (초기 데이터 fetch)
export default async function Page() {
  const data = await fetch('https://api.example.com/items');
  const items = await data.json();
  
  return &amp;lt;ItemList initialItems={items} /&amp;gt;;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가장 먼저 파일 최상단에 &quot;use client&quot; 작성.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;클라이언트 컴포넌트는 실질적 기능과 로직을 수행하는 컴포넌트. useState나 useEffect 등을 사용 가능함. 또한 이벤트 핸들러를 여기서 작성&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ajax 중 put, post, delete는 클라이언트 컴포넌트에서 수행. get만 서버 컴포넌트에서 사용. 왜냐하면 앞의 세 메서드는 사용자와의 상호작용과 함께 실행하는게 보통이기 때문&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 put, post,delete를 사용할 함수들은 가장 첫 줄에 &quot;use server&quot; 를 달아 함수가 서버에서 실행되도록 명시.&lt;/p&gt;
&lt;pre id=&quot;code_1753157317426&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;export async function createItem(formData: FormData) {
  'use server';
  const name = formData.get('name');
  const description = formData.get('description');
  // DB 작업...
  console.log('서버에서 아이템 생성:', { name, description });
  await new Promise(resolve =&amp;gt; setTimeout(resolve, 500));
  revalidatePath('/practice03');
  return { success: true, message: '아이템이 성공적으로 생성되었습니다.' };
}

export async function updateItem(id: string, formData: FormData) {
  'use server';
  const name = formData.get('name');
  // DB 작업...
  console.log(`서버에서 아이템 ${id} 업데이트:`, { name });
  await new Promise(resolve =&amp;gt; setTimeout(resolve, 500));
  revalidatePath('/practice03');
  return { success: true, message: '아이템이 성공적으로 업데이트되었습니다.' };
}

export async function deleteItem(id: string) {
  'use server';
  // DB 작업...
  console.log(`서버에서 아이템 ${id} 삭제`);
  await new Promise(resolve =&amp;gt; setTimeout(resolve, 500));
  revalidatePath('/practice03');
  return { success: true, message: '아이템이 성공적으로 삭제되었습니다.' };
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한 Next.js 에서는 axios 보단 fetch를 주로 사용.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;axios는 재검증과 캐싱 방식을 제어할 수 없어서 개선된 fetch를 주로 사용한다고 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일단 Next.js는 여기까지 알아보고 클론코딩하면서 막히면 더 알아보는 식으로 진행&lt;/p&gt;</description>
      <category>Next.js + TypeScript</category>
      <author>자바응애</author>
      <guid isPermaLink="true">https://practicingjava.tistory.com/291</guid>
      <comments>https://practicingjava.tistory.com/291#entry291comment</comments>
      <pubDate>Tue, 22 Jul 2025 14:15:09 +0900</pubDate>
    </item>
    <item>
      <title>아쿠아플라넷 일산 클론 코딩 (개인 프로젝트)</title>
      <link>https://practicingjava.tistory.com/290</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;클론 코딩 기간 : 2025.05.16 - 2025.07.17&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;네트리파이 주소 : &lt;a href=&quot;https://clone-aquaplanet-ilsan.netlify.app/aquaplanet/ilsan&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://clone-aquaplanet-ilsan.netlify.app/aquaplanet/ilsan&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1752810729575&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;아쿠아플라넷 일산&quot; data-og-description=&quot;&quot; data-og-host=&quot;clone-aquaplanet-ilsan.netlify.app&quot; data-og-source-url=&quot;https://clone-aquaplanet-ilsan.netlify.app/aquaplanet/ilsan&quot; data-og-url=&quot;https://clone-aquaplanet-ilsan.netlify.app/aquaplanet/ilsan&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://clone-aquaplanet-ilsan.netlify.app/aquaplanet/ilsan&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://clone-aquaplanet-ilsan.netlify.app/aquaplanet/ilsan&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;아쿠아플라넷 일산&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;clone-aquaplanet-ilsan.netlify.app&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;깃 주소 : &lt;a href=&quot;https://github.com/kimsanghoTT/clone-aquaplanet-ilsan.git&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/kimsanghoTT/clone-aquaplanet-ilsan.git&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1752810728066&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;object&quot; data-og-title=&quot;GitHub - kimsanghoTT/clone-aquaplanet-ilsan&quot; data-og-description=&quot;Contribute to kimsanghoTT/clone-aquaplanet-ilsan development by creating an account on GitHub.&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/kimsanghoTT/clone-aquaplanet-ilsan.git&quot; data-og-url=&quot;https://github.com/kimsanghoTT/clone-aquaplanet-ilsan&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/cTE70m/hyZnwqMZb8/89XqiRwc5pDjXKEgK6cwEK/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/cbXTPS/hyZjxycNJ1/CKfstdG3lbLmpIAYuckjJ1/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600&quot;&gt;&lt;a href=&quot;https://github.com/kimsanghoTT/clone-aquaplanet-ilsan.git&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/kimsanghoTT/clone-aquaplanet-ilsan.git&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/cTE70m/hyZnwqMZb8/89XqiRwc5pDjXKEgK6cwEK/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/cbXTPS/hyZjxycNJ1/CKfstdG3lbLmpIAYuckjJ1/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;GitHub - kimsanghoTT/clone-aquaplanet-ilsan&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Contribute to kimsanghoTT/clone-aquaplanet-ilsan development by creating an account on GitHub.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;원본 사이트 아쿠아플라넷 일산 주소 : &lt;a href=&quot;https://www.aquaplanet.co.kr/ilsan/index.do&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.aquaplanet.co.kr/ilsan/index.do&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1752810757697&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;아쿠아플라넷 일산&quot; data-og-description=&quot;도심 속 해저여행과 정글탐험을 동시에 즐기는 국내 최초 놀이형 생태체험 아쿠아플라넷 일산 입니다.&quot; data-og-host=&quot;www.aquaplanet.co.kr&quot; data-og-source-url=&quot;https://www.aquaplanet.co.kr/ilsan/index.do&quot; data-og-url=&quot;https://www.aquaplanet.co.kr/ilsan/index.do&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/AtnMj/hyZnisDoBU/OfHVkjbdR7v1xLIkHqrJnk/img.jpg?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/bFRLYj/hyZna9dbrX/43nkqPTKukNqgawvfI9vNK/img.jpg?width=423&amp;amp;height=217&amp;amp;face=0_0_423_217&quot;&gt;&lt;a href=&quot;https://www.aquaplanet.co.kr/ilsan/index.do&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.aquaplanet.co.kr/ilsan/index.do&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/AtnMj/hyZnisDoBU/OfHVkjbdR7v1xLIkHqrJnk/img.jpg?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/bFRLYj/hyZna9dbrX/43nkqPTKukNqgawvfI9vNK/img.jpg?width=423&amp;amp;height=217&amp;amp;face=0_0_423_217');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;아쿠아플라넷 일산&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;도심 속 해저여행과 정글탐험을 동시에 즐기는 국내 최초 놀이형 생태체험 아쿠아플라넷 일산 입니다.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.aquaplanet.co.kr&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;네트리파이 시연용 입력값은 깃 주소 README 참조.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;b&gt;사용 기술 스택&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;프론트 엔드&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;i&gt;&lt;span style=&quot;color: #000000;&quot;&gt;사용 언어&lt;/span&gt;&lt;/i&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;JavaScript, CSS, HTML&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;i&gt;&lt;span style=&quot;color: #000000;&quot;&gt;사용 라이브러리&lt;/span&gt;&lt;/i&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;React, Ant Design, Axios, GSAP, Swiper, Moment, React Scroll, React Barcode, ESLint, Prettier&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;백 엔드&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;i&gt;&lt;b&gt;사용 언어&lt;/b&gt;&lt;/i&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Java&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;i&gt;&lt;b&gt;사용 라이브러리&lt;/b&gt;&lt;/i&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SpringBoot, Mybatis, Lombok, Spring Mail&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;&lt;b&gt;데이터베이스&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;MySQL&lt;/p&gt;</description>
      <category>클론코딩(아쿠아플라넷 일산)</category>
      <author>자바응애</author>
      <guid isPermaLink="true">https://practicingjava.tistory.com/290</guid>
      <comments>https://practicingjava.tistory.com/290#entry290comment</comments>
      <pubDate>Fri, 18 Jul 2025 13:15:23 +0900</pubDate>
    </item>
    <item>
      <title>Next.js 시작</title>
      <link>https://practicingjava.tistory.com/289</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;설치 명령어&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일반&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;npx create-next-app 프로젝트명&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;yarn&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;yarn create next-app 프로젝트명&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;설치 시 설정 분기&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Would you like to use TypeScript? ... Yes&lt;/li&gt;
&lt;li&gt;Would you like to use ESLint? ... Yes&lt;/li&gt;
&lt;li&gt;Would you like your code inside a src/ directory? ... Yes&lt;/li&gt;
&lt;li&gt;Would you like to use App Router? (recommended) ... Yes&lt;/li&gt;
&lt;li&gt;Would you like to use Turbopack for next dev? ... Yes&lt;/li&gt;
&lt;li&gt;Would you like to customize the import alias (@/* by default)? ... No&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;리액트와 next.js의 다른점은 라우터를 따로 쓸 필요가 없다는 것.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;게다가 App.js가 없다. app폴더가 곧 Router가 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 폴더경로가 곧 url이 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;app 폴더에 만든 폴더 이름 = url&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;263&quot; data-origin-height=&quot;759&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/uP6Lk/btsPpTbUzRA/EIpGw8wiKnclRQHg9RPElk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/uP6Lk/btsPpTbUzRA/EIpGw8wiKnclRQHg9RPElk/img.png&quot; data-alt=&quot;연습용 폴더 구성&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/uP6Lk/btsPpTbUzRA/EIpGw8wiKnclRQHg9RPElk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FuP6Lk%2FbtsPpTbUzRA%2FEIpGw8wiKnclRQHg9RPElk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;263&quot; height=&quot;759&quot; data-origin-width=&quot;263&quot; data-origin-height=&quot;759&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;연습용 폴더 구성&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;components 폴더 = 실질적으로 페이지를 구성하는 컴포넌트들&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;app 폴더 = components 폴더에서 만든 컴포넌트의 최종 렌더링 단위.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;components/practice01/index.tsx&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1752816496464&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&quot;use client&quot;;
import Practice01_01 from &quot;./sub_components/practice01_01&quot;;
import Practice01_02 from &quot;./sub_components/practice01_02&quot;;

const NextPractice01 = () =&amp;gt; {

    return (
        &amp;lt;div&amp;gt;
            &amp;lt;Practice01_01/&amp;gt;
            &amp;lt;Practice01_02/&amp;gt;
        &amp;lt;/div&amp;gt;
    )
}
export default NextPractice01;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;app/practice01/page.tsx&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1752816534864&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import NextPractice01 from &quot;@/components/practice01&quot;;

const Practice01 = () =&amp;gt; {

    return (
        &amp;lt;NextPractice01/&amp;gt;
    )
}
export default Practice01;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;page.tsx에서 불러올 컴포넌트의 이름이 index.tsx면 임포트 경로에서 바로 직전 폴더명까지만 적어도 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 때 해당 페이지로 가는 경로는 &lt;b&gt;localhost:3000/practice01&lt;/b&gt; 이 된다. 굳이 라우터로 지정하지 않아도 폴더만으로 경로가 자동 생성된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Layout의 경우 기존 리액트 처럼 따로 wrapper에 넣는게 아니라&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Layout.tsx로 공통의 레이아웃을 정한다.&lt;/p&gt;
&lt;pre id=&quot;code_1752816721079&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import type { Metadata } from &quot;next&quot;;
import { Geist, Geist_Mono } from &quot;next/font/google&quot;;
import &quot;./globals.css&quot;;

export default function RootLayout({children,}: {children: React.ReactNode;}) {
  return (
    &amp;lt;html lang=&quot;ko&quot;&amp;gt;
      &amp;lt;body&amp;gt;
      &amp;lt;Header/&amp;gt;
        {children}
      &amp;lt;Footer/&amp;gt;
        &amp;lt;/body&amp;gt;
    &amp;lt;/html&amp;gt;
  );
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 children은 app 폴더에 있는 page.tsx이 들어간다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;next.js에서 Link는 리액트와 달리 to와 state 대신 href와 query를 사용&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;리액트&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;lt;Link to=&quot;경로&quot; state={{보낼 데이터}}&amp;gt;&amp;nbsp;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;next&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;lt;Link href=&quot;경로&quot; query={보낼 데이터}&amp;gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;오늘은 여기까지&lt;/p&gt;</description>
      <category>Next.js + TypeScript</category>
      <author>자바응애</author>
      <guid isPermaLink="true">https://practicingjava.tistory.com/289</guid>
      <comments>https://practicingjava.tistory.com/289#entry289comment</comments>
      <pubDate>Fri, 18 Jul 2025 12:47:21 +0900</pubDate>
    </item>
    <item>
      <title>하루 하나 c언어 문제 정리</title>
      <link>https://practicingjava.tistory.com/288</link>
      <description>&lt;p style=&quot;color: #555555; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;(2020 1회차)&lt;/b&gt;&lt;b&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #555555; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;12. 다음은 C언어 소스 코드이다. 출력 결과를 쓰시오.&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1748219796123&quot; class=&quot;angelscript&quot; style=&quot;color: #555555; text-align: start;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;cs&quot;&gt;&lt;code&gt; #include &amp;lt;stdio.h&amp;gt;
 void main(){
 	int i,j;
    int temp;
    int a[5] = {75,95,85,100,50};
    
    for(i=0; i&amp;lt;4; i++){
    	for(j=0; j&amp;lt;4-i; j++){
        	if(a[j] &amp;gt; a[j+1]){
            	temp=a[j];
                a[j] = a[j+1];
                a[j+1] = temp;
             }
           }
        }
        
       	for(i=0; i&amp;lt;5; i++){
        	printf(&quot;%d&quot;, a[i]);
        }
  }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;#정렬, #for문, #이중for문, #배열, #서식 지정자 주의&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;a[j] &amp;gt; a[j+1] 일 때 큰 수가 뒤로 가는 로직이 실행되고, 서식 지정자에서 다른 형식이 없으므로&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;출력 결과는 &lt;b&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;50758595100&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #555555; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;(2020 3회차)&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #555555; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2. 다음은 C언어 소스 코드이다. 출력 결과를 쓰시오.&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1748321991764&quot; class=&quot;cpp&quot; style=&quot;color: #555555; text-align: start;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;csharp&quot;&gt;&lt;code&gt;#include &amp;lt;stdio.h&amp;gt;
	void main(){
    	int i=0, c=0;
        while (i&amp;lt;10){
        i++;
        c*=i;
        }
        printf(&quot;%d&quot;,c);
   }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;#while문 #후위 연산자&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;i = 0 시작 &amp;gt; i++로 인해 i = 1, c = 0 * 1 = 0&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이후 i 값이 얼마나 늘어나든 0에 i를 곱하는 형태이므로&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;출력 결과는 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;0&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #555555; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;(2020 3회차)&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #555555; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;13. 다음은 C언어 소스 코드이다. 출력 결과를 쓰시오.&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1748409368670&quot; class=&quot;cpp&quot; style=&quot;color: #555555; text-align: start;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;python&quot;&gt;&lt;code&gt;#include &amp;lt;studio.h&amp;gt;
int r1(){
	return 4;
}
int r10(){
	return (30+r1());
}
int r100(){
	return (200+r10());
}
int main(){
	printf(&quot;%d\n&quot;, r100());
    return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;#함수 호출 #함수 호출 중첩&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;r100() 호출 &amp;gt; 200 + r10()&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;r10() 호출 &amp;gt; 30 + r1()&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;r1() 호출 &amp;gt; 4&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;r10() = 30 + 4 = 34&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;r100() = 200 + 34 = 234&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;출력 결과는 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;234&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #555555; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;(2021 1회차)&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #555555; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;15. 다음은 C언어 프로그램이다. 실행 결과를 쓰시오.&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1748439027450&quot; class=&quot;cpp&quot; style=&quot;color: #555555; text-align: start;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;cpp&quot;&gt;&lt;code&gt;#include &amp;lt;stdio.h&amp;gt;

struct good {
	char name[10];
    int age;
 };
 
 void main(){
 	struct good s[] = {&quot;Kim&quot;,28,&quot;Lee&quot;,38,&quot;Seo&quot;,50,&quot;Park&quot;,35};
    
    struct good *p;
    p = s;
    p++;
    printf(&quot;%s\n&quot;, p-&amp;gt; name);
    printf(&quot;%d\n&quot;, p-&amp;gt; age);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;#구조체 #포인터 #포인터연산 #후위연산자 #배열&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;p = s 로 포인터 변수 p는 배열 s의 첫 번째 값, s[0] (&quot;kim&quot;, 28)의 주소를 저장한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 p++ 로 인해 인덱스 하나 뒤의 값, s[1]의 주소를 저장한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉 p = s + 1이 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 출력 결과는&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;Lee&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;38&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #555555; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;(2021 2회차)&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #555555; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;16. 다음은 C언어에 관한 소스코드이다. 실행 결과값을 작성하시오.&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1748592348100&quot; class=&quot;cpp&quot; style=&quot;color: #555555; text-align: start;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;java&quot;&gt;&lt;code&gt;int main(){
   int res;
   res = mp(2,10);
   printf(&quot;%d&quot;,res);
   return 0;
}

int mp(int base, int exp) {
   int res = 1;
   for(int i=0; i &amp;lt; exp; i++){
      res = res * base;
   }
   
   return res;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;#함수 #반복문 #return&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;res = mp(2, 10)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;mp(2, 10) 은&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;{&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;int res = 1&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;for(int i = 0; i &amp;lt; 10; i++) { res = res * 2 }&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;}&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이므로&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1.&amp;nbsp;res&amp;nbsp;=&amp;nbsp;1&amp;nbsp;x&amp;nbsp;2 &lt;br /&gt;2.&amp;nbsp;res&amp;nbsp;=&amp;nbsp;2&amp;nbsp;x&amp;nbsp;2 &lt;br /&gt;3. res = 4 x 2 &lt;br /&gt;4. res = 8 x 2 &lt;br /&gt;5. res = 16 x 2 &lt;br /&gt;6. res = 32 x 2 &lt;br /&gt;7. res = 64 x 2 &lt;br /&gt;8. res = 128 x 2 &lt;br /&gt;9. res = 256 x 2 &lt;br /&gt;10. res = 512 x 2&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 1024 반환&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;출력 결과는 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;1024&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;</description>
      <category>정처기 실기</category>
      <author>자바응애</author>
      <guid isPermaLink="true">https://practicingjava.tistory.com/288</guid>
      <comments>https://practicingjava.tistory.com/288#entry288comment</comments>
      <pubDate>Mon, 26 May 2025 09:45:42 +0900</pubDate>
    </item>
    <item>
      <title>27일차</title>
      <link>https://practicingjava.tistory.com/281</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;이제 정말 마지막.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;내가 담당한 페이지들은 다음과 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;메인 페이지 + 날씨 위젯&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1919&quot; data-origin-height=&quot;2980&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/FiNDI/btsJA6WAjQq/L7nZTT6RuRPGGWkCTkxJT1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/FiNDI/btsJA6WAjQq/L7nZTT6RuRPGGWkCTkxJT1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/FiNDI/btsJA6WAjQq/L7nZTT6RuRPGGWkCTkxJT1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FFiNDI%2FbtsJA6WAjQq%2FL7nZTT6RuRPGGWkCTkxJT1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1919&quot; height=&quot;2980&quot; data-origin-width=&quot;1919&quot; data-origin-height=&quot;2980&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;실시간 스트리밍 + 채팅&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;864&quot; data-origin-height=&quot;1078&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/6vvHV/btsJACBQjGf/JzlYjI74Ix75Cio1mi1wLK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/6vvHV/btsJACBQjGf/JzlYjI74Ix75Cio1mi1wLK/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/6vvHV/btsJACBQjGf/JzlYjI74Ix75Cio1mi1wLK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F6vvHV%2FbtsJACBQjGf%2FJzlYjI74Ix75Cio1mi1wLK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;864&quot; height=&quot;1078&quot; data-origin-width=&quot;864&quot; data-origin-height=&quot;1078&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;내가 제작한 페이지들을 총 정리하자면&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;메인페이지(모든 페이지에 들어갈 헤더, 푸터 포함)&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;날씨 위젯&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;실시간 스트리밍 + 채팅&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;주요 기능은&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;실시간 채팅&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;실시간 비디오 스트리밍&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;실시간 채팅 삭제&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;실시간 채팅 금지 / 허용&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;실시간 INPUT 비활성화&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;특정 사용자 채팅 내역 검색&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;이모지 메시지&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;캐러셀&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;날씨 API 받고, 사용자 위치를 역산해 시/도 단위 날씨 예보&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;아이템 랜덤으로 뽑아오기&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;프로젝트 기간 동안 내 주요역할은&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;실시간 스트리밍 + 채팅&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;메인 페이지&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;전체적인 css 테마 지정&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;팀원들의 에러 수집 및 지원&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;자세한 최종 결과물은 링크와 시연 영상을 걸도록 하며 프로젝트를 마감하도록 한다.&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;a href=&quot;https://github.com/kimsanghoTT/B2O4.git&quot;&gt;https://github.com/kimsanghoTT/B2O4.git&lt;/a&gt;&lt;/b&gt;&lt;/p&gt;

            &lt;figure class=&quot;unsupported component-kakaotv&quot; contenteditable=&quot;false&quot; style=&quot;background:#000;margin:16px 0;min-height:72px;padding:10px 16px;display:flex;align-items:center;justify-content:center;text-align:center;box-sizing:border-box;width:100%;max-width:100%;&quot;&gt;
                &lt;p contenteditable=&quot;false&quot; style=&quot;margin:0;color:#8a8a8a;font-size:13px;line-height:1.6;user-select:none;pointer-events:none;&quot;&gt;동영상 서비스가 종료되어 해당 콘텐츠를 재생할 수 없습니다.&lt;/p&gt;
            &lt;/figure&gt;
        
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;

            &lt;figure class=&quot;unsupported component-kakaotv&quot; contenteditable=&quot;false&quot; style=&quot;background:#000;margin:16px 0;min-height:72px;padding:10px 16px;display:flex;align-items:center;justify-content:center;text-align:center;box-sizing:border-box;width:100%;max-width:100%;&quot;&gt;
                &lt;p contenteditable=&quot;false&quot; style=&quot;margin:0;color:#8a8a8a;font-size:13px;line-height:1.6;user-select:none;pointer-events:none;&quot;&gt;동영상 서비스가 종료되어 해당 콘텐츠를 재생할 수 없습니다.&lt;/p&gt;
            &lt;/figure&gt;
        
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;

            &lt;figure class=&quot;unsupported component-kakaotv&quot; contenteditable=&quot;false&quot; style=&quot;background:#000;margin:16px 0;min-height:72px;padding:10px 16px;display:flex;align-items:center;justify-content:center;text-align:center;box-sizing:border-box;width:100%;max-width:100%;&quot;&gt;
                &lt;p contenteditable=&quot;false&quot; style=&quot;margin:0;color:#8a8a8a;font-size:13px;line-height:1.6;user-select:none;pointer-events:none;&quot;&gt;동영상 서비스가 종료되어 해당 콘텐츠를 재생할 수 없습니다.&lt;/p&gt;
            &lt;/figure&gt;
        
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>FCB2O4</category>
      <author>자바응애</author>
      <guid isPermaLink="true">https://practicingjava.tistory.com/281</guid>
      <comments>https://practicingjava.tistory.com/281#entry281comment</comments>
      <pubDate>Fri, 13 Sep 2024 11:54:21 +0900</pubDate>
    </item>
    <item>
      <title>jsp-EL</title>
      <link>https://practicingjava.tistory.com/280</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;EL&lt;/b&gt;&lt;/span&gt;&amp;nbsp;:&amp;nbsp;Expression&amp;nbsp;Language &lt;br /&gt;EL&amp;nbsp;형식을&amp;nbsp;통해&amp;nbsp;자바&amp;nbsp;코드를&amp;nbsp;최소화하고&amp;nbsp;데이터를&amp;nbsp;쉽게&amp;nbsp;출력하거나&amp;nbsp;조작할&amp;nbsp;수&amp;nbsp;있음 &lt;br /&gt;&lt;br /&gt;표현 방법: &lt;u&gt;&lt;b&gt;${ }&lt;/b&gt;&lt;/u&gt; (예시 : &lt;b&gt;${username}&lt;/b&gt;)&amp;nbsp; &lt;br /&gt;&amp;lt;%&amp;nbsp;%&amp;gt;를&amp;nbsp;이용해&amp;nbsp;자바에서&amp;nbsp;전달할&amp;nbsp;값을&amp;nbsp;설정,&amp;nbsp;설정받은&amp;nbsp;값을&amp;nbsp;전달&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예제&lt;/p&gt;
&lt;pre id=&quot;code_1726035628968&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;%
request.setAttribute(&quot;username&quot;, &quot;홍길동&quot;);
request.setAttribute(&quot;userage&quot;, 20);
request.setAttribute(&quot;balance&quot;, 160.88);
request.setAttribute(&quot;fruits&quot;, new String[] { &quot;사과&quot;, &quot;바나나&quot;, &quot;포도&quot; });
%&amp;gt;
&amp;lt;!-- 변수 출력 --&amp;gt;
&amp;lt;p&amp;gt;사용자 이름 : ${username }&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;사용자 나이 : ${userage }&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;사용자 잔고 : ${balance }&amp;lt;/p&amp;gt;

&amp;lt;!-- 배열 출력 --&amp;gt;
&amp;lt;ul&amp;gt;
    &amp;lt;c:forEach var=&quot;fruit&quot; items=&quot;${fruits }&quot;&amp;gt;
        &amp;lt;li&amp;gt;${fruit }&amp;lt;/li&amp;gt;&amp;lt;!-- EL 태그 --&amp;gt;
    &amp;lt;/c:forEach&amp;gt;
&amp;lt;/ul&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;** EL / JSTL 차이&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;u&gt;&lt;b&gt;EL(Expression&amp;nbsp;Language)&lt;/b&gt;&lt;/u&gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;JSP&amp;nbsp;페이지에서&amp;nbsp;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;요청(request)이나&amp;nbsp;세션(session)&amp;nbsp;같은&amp;nbsp;데이터를&amp;nbsp;쉽게&amp;nbsp;가져와서&amp;nbsp;출력&lt;/b&gt;&lt;/span&gt;하는&amp;nbsp;데&amp;nbsp;사용 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;- 사용법 : &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;${ }&lt;/b&gt;&lt;/span&gt; 사용해서 값을 출력 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;단점&amp;nbsp;:&amp;nbsp;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;반복문,&amp;nbsp;조건문&amp;nbsp;불가능&lt;/b&gt;&lt;/span&gt; &lt;br /&gt;&lt;br /&gt;&lt;u&gt;&lt;b&gt;JSTL(JSP&amp;nbsp;Standard&amp;nbsp;Tag&amp;nbsp;Library)&lt;/b&gt;&lt;/u&gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;JSP&amp;nbsp;페이지에서&amp;nbsp;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;반복,&amp;nbsp;조건문,&amp;nbsp;데이터&amp;nbsp;포맷팅,&amp;nbsp;데이터베이스&amp;nbsp;접근과&amp;nbsp;같은&amp;nbsp;작업을&amp;nbsp;수행&lt;/b&gt;&lt;/span&gt;할&amp;nbsp;때&amp;nbsp;사용 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;사용법&amp;nbsp;:&amp;nbsp;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;prefix=&quot;설정한변수명&quot;&amp;nbsp;후&amp;nbsp;&amp;lt;설정한변수명:기능&amp;gt;&lt;/b&gt;&lt;/span&gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;prefix&amp;nbsp;안의&amp;nbsp;&lt;u&gt;변수명을&amp;nbsp;설정할&amp;nbsp;떄는&amp;nbsp;&lt;a style=&quot;color: #000000;&quot; href=&quot;http://java.sun.com/jsp/jstl/core&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;http://java.sun.com/jsp/jstl/core&lt;/a&gt; 같은 주소에서&amp;nbsp;&lt;/u&gt;&lt;u&gt;마지막에 끝나는 단어 첫 글자를 따서 주로 사용&lt;/u&gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;단점&amp;nbsp;:&amp;nbsp;&lt;b&gt;문법이&amp;nbsp;복잡함&lt;/b&gt;.&amp;nbsp;태그를&amp;nbsp;익히는&amp;nbsp;데&amp;nbsp;시간&amp;nbsp;소모&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;** request&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;-&amp;nbsp;&lt;u&gt;&lt;b&gt;request.setAttribute()&lt;/b&gt;&lt;/u&gt;&amp;nbsp;:&amp;nbsp;JSP에서&amp;nbsp;요청(request)&amp;nbsp;범위에&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;&amp;nbsp;데이터를&amp;nbsp;저장하는&amp;nbsp;데&amp;nbsp;사용되는&amp;nbsp;메서드&lt;/b&gt;&lt;/span&gt; &lt;br /&gt;- HttpServletRequest 객체에 저장해서 JSP 페이지 내에서 그 &lt;b&gt;데이터를 다른 페이지로 전달하거나&amp;nbsp;그 페이지 내에서 사용할 수 있도록 설정&lt;/b&gt; &lt;br /&gt;-&amp;nbsp;문법&amp;nbsp;:&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;&amp;nbsp;request.setAttribute(String&amp;nbsp;name,&amp;nbsp;자료형&amp;nbsp;value)&lt;/b&gt;&lt;/span&gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;name&lt;/b&gt;&lt;/span&gt;&amp;nbsp;:&amp;nbsp;&lt;u&gt;&lt;b&gt;데이터를&amp;nbsp;저장할&amp;nbsp;때&amp;nbsp;사용할&amp;nbsp;key&lt;/b&gt;&lt;/u&gt;.&amp;nbsp;이&amp;nbsp;것을&amp;nbsp;사용해서&amp;nbsp;데이터를&amp;nbsp;가져올&amp;nbsp;수&amp;nbsp;있음 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;value&lt;/b&gt;&lt;/span&gt;&amp;nbsp;:&amp;nbsp;&lt;u&gt;&lt;b&gt;저장할&amp;nbsp;실제&amp;nbsp;값&lt;/b&gt;&lt;/u&gt;.&amp;nbsp;어떠한&amp;nbsp;데이터&amp;nbsp;유형이든&amp;nbsp;저장할&amp;nbsp;수&amp;nbsp;있음&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;예제&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1726035857439&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;%
String name = &quot;홍길동&quot;;
int age = 20;

//데이터를 request 객체에 저장
request.setAttribute(&quot;username&quot;, name); //username 변수명 안에 홍길동이라는 이름을 저장
request.setAttribute(&quot;userage&quot;, age); //userage 변수명 안에 20이라는 숫자를 저장
%&amp;gt;
&amp;lt;!-- JSP 페이지에서 데이터를 EL로 출력 --&amp;gt;
&amp;lt;p&amp;gt;이름 : ${username }&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;나이 : ${userage }&amp;lt;/p&amp;gt;

&amp;lt;!-- request에 저장된 값을 다른 페이지로 전달해서 출력 --&amp;gt;
&amp;lt;%
request.setAttribute(&quot;msg&quot;, &quot;index.jsp에서 hello.jsp로 데이터 전달&quot;);

//hello.jsp로 데이터 전달
RequestDispatcher dispatcher = request.getRequestDispatcher(&quot;hello.jsp&quot;);

//servlet springboot를 사용하지 않을 때 작성법 -&amp;gt; springboot의 controller로 넘겨줄 떄는 사용 x
//RequestDispatcher dispatcher = request.getRequestDispatcher(&quot;/WEB-INF/jsp/hello.jsp&quot;);
dispatcher.forward(request, response);
%&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1726035887526&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;%@ page language=&quot;java&quot; contentType=&quot;text/html; charset=UTF-8&quot;
    pageEncoding=&quot;UTF-8&quot;%&amp;gt;
    &amp;lt;%@ taglib uri=&quot;http://java.sun.com/jsp/jstl/core&quot; prefix=&quot;c&quot; %&amp;gt;
&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html&amp;gt;
&amp;lt;head&amp;gt;
&amp;lt;meta charset=&quot;UTF-8&quot;&amp;gt;
&amp;lt;title&amp;gt;인사메시지 페이지&amp;lt;/title&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
	&amp;lt;h1&amp;gt;index.jsp에서 받은 데이터 출력&amp;lt;/h1&amp;gt;
	
	&amp;lt;!-- request로 전달된 데이터 출력 --&amp;gt;
	&amp;lt;p&amp;gt;받은 메시지 : ${msg }&amp;lt;/p&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;** forTokens&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;forTokens&amp;nbsp;:&amp;nbsp;특정&amp;nbsp;값을&amp;nbsp;기준으로&amp;nbsp;구분해서&amp;nbsp;반복&amp;nbsp;출력 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;var&amp;nbsp;&lt;/b&gt;&lt;/span&gt;:&amp;nbsp;&lt;u&gt;구분자(delims)로&amp;nbsp;인해&amp;nbsp;끊어진&amp;nbsp;값들을&amp;nbsp;하나씩&amp;nbsp;담아&amp;nbsp;출력하기&amp;nbsp;위해&amp;nbsp;설정하는&amp;nbsp;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;변수명&lt;/b&gt;&lt;/span&gt;&lt;/u&gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;items&lt;/b&gt;&lt;/span&gt;&amp;nbsp;:&amp;nbsp;&lt;u&gt;어떤&amp;nbsp;값을&amp;nbsp;구분자(delims)로&amp;nbsp;끊을&amp;nbsp;것인지&lt;/u&gt;&amp;nbsp;작성.&amp;nbsp;&lt;u&gt;&lt;b&gt;변수값이나&amp;nbsp;구분자가&amp;nbsp;들어간&amp;nbsp;값을&amp;nbsp;직접&amp;nbsp;넣을&amp;nbsp;수&amp;nbsp;있음&lt;/b&gt;&lt;/u&gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;delims&lt;/b&gt;&lt;/span&gt;&amp;nbsp;:&amp;nbsp;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;기준이&amp;nbsp;되는&amp;nbsp;구분자(특정&amp;nbsp;기호나&amp;nbsp;값)&lt;/b&gt;&lt;/span&gt;를&amp;nbsp;설정&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1726036073982&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;c:set var=&quot;str&quot; value=&quot;사과,배,포도&quot; /&amp;gt;
&amp;lt;c:forTokens var=&quot;fruit&quot; items=&quot;${str}&quot; delims=&quot;,&quot;&amp;gt;
    &amp;lt;li&amp;gt;${fruit }&amp;lt;/li&amp;gt;
&amp;lt;/c:forTokens&amp;gt;
&amp;lt;c:forTokens var=&quot;s&quot; items=&quot;키위!참외!수박&quot; delims=&quot;!&quot;&amp;gt;
    &amp;lt;li&amp;gt;${s}&amp;lt;/li&amp;gt;
&amp;lt;/c:forTokens&amp;gt;
&amp;lt;c:set var=&quot;food&quot; value=&quot;햄버거~피자~오렌지~치킨~파스타~냉모밀~냉면~라멘&quot;/&amp;gt;
&amp;lt;c:forTokens var=&quot;fd&quot; items=&quot;${food }&quot; delims=&quot;~&quot;&amp;gt;
    &amp;lt;li&amp;gt;${fd}&amp;lt;/li&amp;gt;
&amp;lt;/c:forTokens&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;** remove&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;-&amp;nbsp;JSTL에서&amp;nbsp;특정&amp;nbsp;변수값을&amp;nbsp;삭제하는&amp;nbsp;태그 &lt;br /&gt;-&amp;nbsp;작성법 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;&amp;nbsp;c:remove&amp;nbsp;var=&quot;값을&amp;nbsp;삭제할&amp;nbsp;변수명&quot;&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;※ JSTL에서 system.out.println은&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt; c:out&lt;/b&gt;&lt;/span&gt;을 이용해서 작성 &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000; text-align: start;&quot;&gt;-&amp;nbsp;작성법&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000; text-align: start;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;c:out&amp;nbsp;defult=&quot;작성될&amp;nbsp;내용&quot;&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000; text-align: start;&quot;&gt;-&amp;nbsp;&lt;/span&gt;&lt;u&gt;&lt;b&gt;특정&amp;nbsp;변수&lt;/b&gt;&lt;/u&gt;&lt;span style=&quot;color: #000000; text-align: start;&quot;&gt;의&amp;nbsp;값&amp;nbsp;출력&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000; text-align: start;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;&amp;nbsp;c:out&amp;nbsp;var=&quot;변수명&quot;&amp;nbsp;default=&quot;변수명을&amp;nbsp;불러오지&amp;nbsp;못하거나&amp;nbsp;특정&amp;nbsp;값이&amp;nbsp;없으면&amp;nbsp;보여줄&amp;nbsp;내용&quot;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1726036194599&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;c:set var=&quot;tempVar&quot; value=&quot;삭제될 값 입니다&quot;/&amp;gt;
&amp;lt;c:out value=&quot;${tempVar}&quot;/&amp;gt;
&amp;lt;c:remove var=&quot;tempVar&quot;/&amp;gt;
&amp;lt;c:out value=&quot;${tempVar }&quot; default=&quot;없는 값입니다&quot;/&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;** catch&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;특정&amp;nbsp;문제나&amp;nbsp;에러가&amp;nbsp;발생했을&amp;nbsp;때&amp;nbsp;예외처리를&amp;nbsp;작성할&amp;nbsp;수&amp;nbsp;있음 &lt;br /&gt;&lt;br /&gt;c:catch&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;특정&amp;nbsp;문제가&amp;nbsp;발생할&amp;nbsp;것을&amp;nbsp;대비해서&amp;nbsp;감싸주는&amp;nbsp;것.&amp;nbsp;에러&amp;nbsp;방지 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;- c:if를 사용할 때 catch 안에 주로 사용 &lt;br /&gt;&lt;br /&gt;에러 관련 구문이 보이지 않다면&lt;br /&gt;&amp;nbsp;-&amp;gt;&amp;nbsp;계산이나&amp;nbsp;태그&amp;nbsp;안에&amp;nbsp;문제가&amp;nbsp;발생할&amp;nbsp;경우,&amp;nbsp;jsp에서&amp;nbsp;문제&amp;nbsp;처리를&amp;nbsp;미리&amp;nbsp;진행한&amp;nbsp;다음에&amp;nbsp;코드를&amp;nbsp;보여주기&amp;nbsp;때문에&amp;nbsp;보이지&amp;nbsp;않음&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1726036507813&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;c:catch var=&quot;e&quot;&amp;gt;
    &amp;lt;c:set var=&quot;result&quot; value=&quot;${10/0 }&quot;/&amp;gt; &amp;lt;!-- 계산 에러 유도 --&amp;gt;
    &amp;lt;c:if test=&quot;${not empty e}&quot;&amp;gt;
        에러 발생 : ${e.message}
    &amp;lt;/c:if&amp;gt;
&amp;lt;/c:catch&amp;gt;&lt;/code&gt;&lt;/pre&gt;</description>
      <category>JSP</category>
      <author>자바응애</author>
      <guid isPermaLink="true">https://practicingjava.tistory.com/280</guid>
      <comments>https://practicingjava.tistory.com/280#entry280comment</comments>
      <pubDate>Wed, 11 Sep 2024 15:35:16 +0900</pubDate>
    </item>
    <item>
      <title>jsp - jstl</title>
      <link>https://practicingjava.tistory.com/279</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;JSTL&lt;/b&gt;&lt;/span&gt;&amp;nbsp;:&amp;nbsp;JSP&amp;nbsp;Standard&amp;nbsp;Tag&amp;nbsp;Library,&amp;nbsp;jsp&amp;nbsp;표준&amp;nbsp;태그&amp;nbsp;라이브러리 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;JSP에서&amp;nbsp;반복문,&amp;nbsp;조건문,&amp;nbsp;변수&amp;nbsp;처리 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;사용&amp;nbsp;방법 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;taglib로&amp;nbsp;맨&amp;nbsp;위에&amp;nbsp;사용한다고&amp;nbsp;설정 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;&amp;nbsp;%@&amp;nbsp;taglib&amp;nbsp;uri=&quot;&lt;a href=&quot;http://java.sun.com/jsp/jstl/core&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;http://java.sun.com/jsp/jstl/core&lt;/a&gt;&quot;&amp;nbsp;prefix=&quot;c&quot;%&amp;nbsp;&amp;gt; &lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1725958045452&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;        &amp;lt;c:set var=&quot;이름&quot; value=&quot;홍길동&quot;/&amp;gt;
        &amp;lt;p&amp;gt;NAME : ${이름}&amp;lt;/p&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;c:로&amp;nbsp;jstl에&amp;nbsp;저장된&amp;nbsp;기능을&amp;nbsp;가져올&amp;nbsp;수&amp;nbsp;있음. &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;set&amp;nbsp;=&amp;nbsp;setter,&amp;nbsp;이름이라는&amp;nbsp;변수명에&amp;nbsp;value로&amp;nbsp;설정한&amp;nbsp;홍길동을&amp;nbsp;넣음을&amp;nbsp;명시&lt;u&gt;&lt;b&gt;&lt;/b&gt;&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;** if문 설정 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;&amp;nbsp;c:if&amp;nbsp;test=&quot;${테스트할&amp;nbsp;조건&amp;nbsp;작성}&quot;&lt;/b&gt;&lt;/span&gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;c:if문은&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;u&gt;&lt;b&gt;&amp;nbsp;else가&amp;nbsp;존재하지&amp;nbsp;않음.&amp;nbsp;if만&amp;nbsp;사용&lt;/b&gt;&lt;/u&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1725958094322&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;	&amp;lt;c:set var=&quot;age&quot; value=&quot;20&quot;/&amp;gt;
	&amp;lt;c:if test=&quot;${age &amp;gt;= 18 }&quot;&amp;gt;
		&amp;lt;p&amp;gt;당신은 성인 입니다.&amp;lt;/p&amp;gt;
	&amp;lt;/c:if&amp;gt;
	&amp;lt;c:if test=&quot;${age &amp;lt; 18 }&quot;&amp;gt;
		&amp;lt;p&amp;gt;청소년입니다.&amp;lt;/p&amp;gt;
	&amp;lt;/c:if&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;** c:forEach&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1725957694079&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;%
String[] fruits = {&quot;apple&quot;, &quot;banana&quot;, &quot;grape&quot;};
pageContext.setAttribute(&quot;fruits&quot;, fruits);
//pageContext : 페이지 내에서 변수명에 담긴 내용을 전체적으로 사용할 수 있도록 유지하는 역할
//setAttribute(&quot;저장할이름&quot;,저장할변수명)
%&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이때 EL과 JSTL이 좀 다른데&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;EL&amp;nbsp;:&lt;b&gt;&amp;nbsp;&amp;lt;c:set&amp;nbsp;var=&quot;fruits&quot;&amp;nbsp;value=&quot;${['apple',&amp;nbsp;'banana',&amp;nbsp;'grape']&amp;nbsp;}&quot;/&amp;gt;&lt;/b&gt; &lt;br /&gt;JSTL : 배열을 &lt;u&gt;&lt;b&gt;&amp;lt;% 에 담아서 사용&lt;/b&gt;&lt;/u&gt;해야함&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이후 forEach문은&lt;/p&gt;
&lt;pre id=&quot;code_1725957758325&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;ul&amp;gt;
    &amp;lt;c:forEach var=&quot;fruit&quot; item=&quot;${fruits }&quot;&amp;gt;
        &amp;lt;li&amp;gt;${fruit}&amp;lt;/li&amp;gt;
    &amp;lt;/c:forEach&amp;gt;
&amp;lt;/ul&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;** fmt:format&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;uri=&quot;&lt;a href=&quot;http://java.sun.com/jsp/jstl/fmt&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;http://java.sun.com/jsp/jstl/fmt&lt;/a&gt;&quot;&amp;nbsp;prefix=&quot;fmt&quot; &lt;br /&gt;:&amp;nbsp;날짜,&amp;nbsp;숫자를&amp;nbsp;쉽게&amp;nbsp;포맷팅할&amp;nbsp;수&amp;nbsp;있도록&amp;nbsp;도와주는&amp;nbsp;태그 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;gt;&amp;nbsp;날짜의&amp;nbsp;형식을&amp;nbsp;바꾸거나&amp;nbsp;숫자를&amp;nbsp;통화,&amp;nbsp;퍼센트&amp;nbsp;형식으로&amp;nbsp;변환할&amp;nbsp;수&amp;nbsp;있음 &lt;br /&gt;&lt;br /&gt;&lt;u&gt;&lt;b&gt;숫자&amp;nbsp;포멧팅&amp;nbsp;태그&lt;/b&gt;&lt;/u&gt; &lt;br /&gt;fmt:&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;formatNumber&lt;/b&gt;&lt;/span&gt;&amp;nbsp;::&amp;nbsp;숫자를&amp;nbsp;특정&amp;nbsp;형식으로&amp;nbsp;변환할&amp;nbsp;때&amp;nbsp;사용 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;type=&quot;&lt;u&gt;&lt;b&gt;currency&lt;/b&gt;&lt;/u&gt;&quot;&amp;nbsp;:&amp;nbsp;숫자를&amp;nbsp;현재&amp;nbsp;위치한&amp;nbsp;지역에&amp;nbsp;맞춰&amp;nbsp;&lt;b&gt;통화&amp;nbsp;기호가&amp;nbsp;자동으로&amp;nbsp;추가&lt;/b&gt;&amp;nbsp;($,&amp;nbsp;₩,&amp;nbsp;&amp;euro;) &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;type=&quot;&lt;u&gt;&lt;b&gt;percent&lt;/b&gt;&lt;/u&gt;&quot;&amp;nbsp;:&amp;nbsp;숫자를&amp;nbsp;&lt;b&gt;퍼센트&amp;nbsp;형식&lt;/b&gt;으로&amp;nbsp;변환 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;type=&quot;&lt;u&gt;&lt;b&gt;number&lt;/b&gt;&lt;/u&gt;&quot;&amp;nbsp;:&amp;nbsp;숫자를&amp;nbsp;&lt;b&gt;소수점&amp;nbsp;자리까지&amp;nbsp;조정하면서&amp;nbsp;표현&lt;/b&gt; &lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;u&gt;&lt;b&gt;&amp;nbsp;maxFractionDigits&lt;/b&gt;&lt;/u&gt;&amp;nbsp;:&amp;nbsp;지정한&amp;nbsp;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;소수점&amp;nbsp;자리&amp;nbsp;&lt;span style=&quot;color: #ee2323;&quot;&gt;이하&lt;/span&gt;까지만&lt;/b&gt;&lt;/span&gt;&amp;nbsp;보여주기.&lt;u&gt;&amp;nbsp;2로&amp;nbsp;작성&amp;nbsp;시&amp;nbsp;소수점&amp;nbsp;두&amp;nbsp;자리까지만&amp;nbsp;표기&lt;/u&gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;u&gt;&lt;b&gt;&amp;nbsp;maxIntegerDigits&lt;/b&gt;&lt;/u&gt;&amp;nbsp;:&amp;nbsp;지정한&amp;nbsp;&lt;span style=&quot;color: #ee2323;&quot;&gt;소수점&amp;nbsp;자리&amp;nbsp;이상을&amp;nbsp;보여주기&lt;/span&gt;.&amp;nbsp;&lt;u&gt;2로&amp;nbsp;작성시&amp;nbsp;최소&amp;nbsp;소수점&amp;nbsp;두&amp;nbsp;자리부터&amp;nbsp;표기&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1725957920870&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;c:set var=&quot;n&quot; value=&quot;1234567.89&quot;/&amp;gt;
&amp;lt;p&amp;gt;일반적인 숫자 : &amp;lt;fmt:formatNumber value=&quot;${n}&quot; type=&quot;number&quot;/&amp;gt;&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;소수점 2자리까지 표현 : &amp;lt;fmt:formatNumber value=&quot;${n}&quot; type=&quot;number&quot; maxFractionDigits=&quot;2&quot;/&amp;gt;&amp;lt;/p&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;-&amp;nbsp;&lt;b&gt;c:choose&lt;/b&gt;&amp;nbsp;::&amp;nbsp;&lt;u&gt;&lt;b&gt;다중&amp;nbsp;조건을&amp;nbsp;처리&lt;/b&gt;&lt;/u&gt;할&amp;nbsp;때&amp;nbsp;사용하는&amp;nbsp;태그 &lt;br /&gt;-&lt;b&gt;&amp;nbsp;c:when&amp;nbsp;test=&quot;&quot;&lt;/b&gt;&amp;nbsp;::&amp;nbsp;&lt;u&gt;&lt;b&gt;조건이&amp;nbsp;true일&amp;nbsp;때&amp;nbsp;실행&lt;/b&gt;&lt;/u&gt;되는&amp;nbsp;태그 &lt;br /&gt;-&amp;nbsp;&lt;b&gt;c:otherwise&lt;/b&gt;&amp;nbsp;::&amp;nbsp;&lt;u&gt;&lt;b&gt;모든&amp;nbsp;조건이&amp;nbsp;false일&amp;nbsp;때&amp;nbsp;실행&lt;/b&gt;&lt;/u&gt;되는&amp;nbsp;태그&lt;/p&gt;
&lt;pre id=&quot;code_1725957988402&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;c:set var=&quot;grade&quot; value=&quot;B&quot; /&amp;gt;
&amp;lt;c:choose&amp;gt;
    &amp;lt;c:when test=&quot;${grade == 'A'}&quot;&amp;gt;
        &amp;lt;p&amp;gt;훌륭한 성적입니다.&amp;lt;/p&amp;gt;
    &amp;lt;/c:when&amp;gt;
    &amp;lt;c:if test=&quot;${ grade == 'B' }&quot;&amp;gt;
        &amp;lt;p&amp;gt;공부 열심히 하셨네요&amp;lt;/p&amp;gt;
    &amp;lt;/c:if&amp;gt;
    &amp;lt;c:otherwise&amp;gt;
        &amp;lt;p&amp;gt;좀 더 노력합시다&amp;lt;/p&amp;gt;
    &amp;lt;/c:otherwise&amp;gt;
&amp;lt;/c:choose&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>JSP</category>
      <author>자바응애</author>
      <guid isPermaLink="true">https://practicingjava.tistory.com/279</guid>
      <comments>https://practicingjava.tistory.com/279#entry279comment</comments>
      <pubDate>Tue, 10 Sep 2024 17:48:51 +0900</pubDate>
    </item>
    <item>
      <title>JSP + springboot 연결</title>
      <link>https://practicingjava.tistory.com/278</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;- 컨트롤러에서 jsp를 연결할 때&lt;b&gt; src/main/webapp/WEB-INF/jsp&lt;/b&gt; 폴더를 지정해서 연결 &lt;br /&gt;-&lt;u&gt;&lt;b&gt; jsp 폴더 안에 .jsp 관련 파일을 작성&lt;/b&gt;&lt;/u&gt;해서 코드를 수행할 수 있도록 설정 &lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;※ 주의점&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;src/main/webapp/WEB-INF/jsp&lt;/b&gt;&lt;/span&gt;&amp;nbsp;-&amp;gt;&amp;nbsp;옳은&amp;nbsp;경로 &lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;src/main/resources/webapp/WEB-INF/jsp&lt;/b&gt;&lt;/span&gt;&amp;nbsp;-&amp;gt;&amp;nbsp;잘못된&amp;nbsp;경로.&lt;u&gt;&lt;b&gt;&amp;nbsp;resources에&amp;nbsp;작성하는&amp;nbsp;게&amp;nbsp;아님.&lt;/b&gt;&lt;/u&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;&amp;lt;%@ %&amp;gt;&lt;/b&gt;&lt;/span&gt; : 지시자 태그&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;JSP&amp;nbsp;페이지에서&amp;nbsp;&lt;u&gt;&lt;b&gt;설정을&amp;nbsp;정의.&amp;nbsp;다른&amp;nbsp;jsp&amp;nbsp;파일을&amp;nbsp;포함해서&amp;nbsp;재사용율을&amp;nbsp;높일&amp;nbsp;수&amp;nbsp;있음&lt;/b&gt;&lt;/u&gt; &lt;br /&gt;대표적으로&amp;nbsp;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;page,&amp;nbsp;include,&amp;nbsp;taglib&lt;/b&gt;&lt;/span&gt;&amp;nbsp;지시자가&amp;nbsp;존재 &lt;br /&gt;&lt;br /&gt;-&amp;nbsp;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;page&lt;/b&gt;&lt;/span&gt;&amp;nbsp;:&lt;u&gt;&lt;b&gt; jsp&amp;nbsp;페이지의 속성&amp;nbsp;설정&lt;/b&gt;&lt;/u&gt;.&amp;nbsp;html&amp;nbsp;형식인지,&amp;nbsp;글자타입은&amp;nbsp;무엇인지(utf-8)&amp;nbsp;설정&lt;/p&gt;
&lt;pre id=&quot;code_1725872747625&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;%@ page language=&quot;java&quot; contentType=&quot;text/html; charset=utf-8&quot; pageEncoding=&quot;utf-8&quot;%&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;-&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;&amp;nbsp;include&lt;/b&gt;&lt;/span&gt;&amp;nbsp;:&amp;nbsp;다른&amp;nbsp;jsp&amp;nbsp;파일을&amp;nbsp;포함해서&amp;nbsp;사용&amp;nbsp;-&amp;gt;&lt;u&gt;&lt;b&gt;&amp;nbsp;jsp&amp;nbsp;파일을&amp;nbsp;가져옴&lt;/b&gt;&lt;/u&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1725872777155&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;%@ include file=&quot;파일명.jsp&quot; %&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;-&amp;nbsp;&lt;b&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;taglib&lt;/span&gt;&lt;/b&gt;&amp;nbsp;:&amp;nbsp;&lt;u&gt;&lt;b&gt;외부에서&amp;nbsp;bootstrap이나&amp;nbsp;jquery,&amp;nbsp;ajax&amp;nbsp;같은&amp;nbsp;기능을&amp;nbsp;가져와&amp;nbsp;사용&lt;/b&gt;&lt;/u&gt;할 수 있도록 설정&lt;/p&gt;
&lt;pre id=&quot;code_1725872813233&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;%@ taglib uri=&quot;http://java.sun.com/jsp/jstl/core&quot; prefix=&quot;c&quot; %&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;uri&lt;/b&gt;&amp;nbsp;:&amp;nbsp;숫자(urn)나&amp;nbsp;주소(url)로&amp;nbsp;된&amp;nbsp;값&amp;nbsp;가져오기&lt;br /&gt;&lt;b&gt;prefix&lt;/b&gt;&amp;nbsp;:&amp;nbsp;가져온&amp;nbsp;값을&amp;nbsp;c라는&amp;nbsp;이름으로&amp;nbsp;지칭해서&amp;nbsp;사용&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;index.jsp&lt;/b&gt;&lt;/span&gt;와 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;header.jsp&lt;/b&gt;&lt;/span&gt; 를 통합해서 화면에 보이기&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;header.jsp&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1725872938490&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;%@ page contentType=&quot;text/html; charset=UTF-8&quot; language=&quot;java&quot; %&amp;gt;
&amp;lt;%@ taglib uri=&quot;http://java.sun.com/jsp/jstl/core&quot; prefix=&quot;c&quot; %&amp;gt;

&amp;lt;header&amp;gt;
    &amp;lt;div style=&quot;background-color: #333; color: white; padding: 15px 10px;&quot;&amp;gt;
        &amp;lt;h1 style=&quot;display: inline; margin-right: 50px;&quot;&amp;gt;My Website&amp;lt;/h1&amp;gt;
        &amp;lt;img src=&quot;/images/logo.png&quot; alt=&quot;Website Logo&quot; style=&quot;height: 50px; vertical-align: middle;&quot; /&amp;gt;

        &amp;lt;nav style=&quot;display: inline; float: right;&quot;&amp;gt;
            &amp;lt;a href=&quot;/&quot; style=&quot;color: white; margin-right: 15px;&quot;&amp;gt;Home&amp;lt;/a&amp;gt;
            &amp;lt;a href=&quot;/array&quot; style=&quot;color: white; margin-right: 15px;&quot;&amp;gt;과일들&amp;lt;/a&amp;gt;
            &amp;lt;a href=&quot;/list&quot; style=&quot;color: white; margin-right: 15px;&quot;&amp;gt;리스트&amp;lt;/a&amp;gt;
            &amp;lt;a href=&quot;/for&quot; style=&quot;color: white;&quot;&amp;gt;for문&amp;lt;/a&amp;gt;
        &amp;lt;/nav&amp;gt;
    &amp;lt;/div&amp;gt;
&amp;lt;/header&amp;gt;
&amp;lt;hr&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;index.jsp&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1725872897274&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;%@ include file=&quot;header.jsp&quot; %&amp;gt;
&amp;lt;%@ page language=&quot;java&quot; contentType=&quot;text/html; charset=UTF-8&quot;
    pageEncoding=&quot;utf-8&quot;%&amp;gt;
&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html&amp;gt;
&amp;lt;head&amp;gt;
&amp;lt;meta charset=&quot;utf-8&quot;&amp;gt;
&amp;lt;title&amp;gt;jsp 파일 경로 설정&amp;lt;/title&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
	&amp;lt;h1&amp;gt;연결확인&amp;lt;/h1&amp;gt;

&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1583&quot; data-origin-height=&quot;244&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/KmGth/btsJwsehQtx/UJVtzYcFwdnF0mqBfJ61W1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/KmGth/btsJwsehQtx/UJVtzYcFwdnF0mqBfJ61W1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/KmGth/btsJwsehQtx/UJVtzYcFwdnF0mqBfJ61W1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FKmGth%2FbtsJwsehQtx%2FUJVtzYcFwdnF0mqBfJ61W1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1583&quot; height=&quot;244&quot; data-origin-width=&quot;1583&quot; data-origin-height=&quot;244&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;lt;%@ %&amp;gt;를 사용해서 헤더가 합쳐짐&lt;/p&gt;</description>
      <category>JSP</category>
      <author>자바응애</author>
      <guid isPermaLink="true">https://practicingjava.tistory.com/278</guid>
      <comments>https://practicingjava.tistory.com/278#entry278comment</comments>
      <pubDate>Mon, 9 Sep 2024 17:57:46 +0900</pubDate>
    </item>
  </channel>
</rss>