<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>SOLEE.log</title>
        <link>https://velog.io/</link>
        <description>Front-End Developer</description>
        <lastBuildDate>Sun, 16 Apr 2023 14:45:54 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>SOLEE.log</title>
            <url>https://images.velog.io/images/soulee__/profile/fd38d0da-11bd-4c30-8206-5b80dd03c909/KakaoTalk_20210816_190346431_01.jpg</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. SOLEE.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/soulee__" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[MyBatis ]]></title>
            <link>https://velog.io/@soulee__/MyBatis</link>
            <guid>https://velog.io/@soulee__/MyBatis</guid>
            <pubDate>Sun, 16 Apr 2023 14:45:54 GMT</pubDate>
            <description><![CDATA[<h2 id="1-mybatis">1. MyBatis</h2>
<ul>
<li>SQL Mapping Framework로, 자바코드와 SQL(XML로 작성)와의 매핑을 도움</li>
<li>자바 코드로부터 SQL문을 분리해서 관리</li>
<li>매개변수 설정과 쿼리 결과를 읽어오는 코드를 제거! (setString, getString 등등)</li>
<li>작성할 코드가 줄어서 생산성 향상 &amp; 유지 보수 편리!<ul>
<li>try-catch문 쓸 필요 없어짐</li>
</ul>
</li>
<li>JPA (OOP, SQL&amp;모델링)<pre><code class="language-xml">&lt;mapper namespace=&quot;com.fastcampus.ch4.dao.UserMapper&quot;&gt;
  &lt;insert id=&quot;insert&quot; parameterType=&quot;com.fastcampus.ch4.domain.UserDto&quot;&gt;
    INSERT INTO user_info
    VALUES ( #{id}, #{pwd}, ... );
  &lt;/insert&gt;
&lt;/mapper&gt;</code></pre>
<pre><code class="language-java">private SqlSession session;
private static String namespace = &quot;com.fastcampus.ch4.dao.UserMapper.&quot;;
</code></pre>
</li>
</ul>
<p>@Override
public int insert(User user) {
    return session.insert(namespace+&quot;insert&quot;, user); 
}</p>
<pre><code>
## 2. SqlSessionFactoryBean과 SqlSessionTemplate
(인터페이스)
- SqlSessionFactory : SqlSession을 생성(openSession())해서 제공
- SqlSession : SQL명령을 수행하는데 **필요한 메서드 제공**
* my-batis에서 제공 둘 다 interface!

(구현체) - mybatis-spring
- SqlSessionFactoryBean : SqlSession를 Spring에서 사용하기 위한 빈
- SqlSessionTemplate : SQL명령을 수행하는데 **필요한 메서드 제공** **thread-safe**

&gt; thread-safe란?
&gt; 1. BoardDao, UserDao 등 여러개 DAO가 동시에 SqlSessionTemplate를 공유 가능하다!
&gt; 2. 멀티쓰레드에 안전하다

(in root-context.xml)
```xml
    &lt;bean id=&quot;sqlSessionFactory&quot; class=&quot;org.mybatis.spring.SqlSessionFactoryBean&quot;&gt;
        &lt;property name=&quot;dataSource&quot; ref=&quot;dataSource&quot;/&gt;
        &lt;property name=&quot;configLocation&quot;  value=&quot;classpath:mybatis-config.xml&quot;/&gt;
        &lt;property name=&quot;mapperLocations&quot; value=&quot;classpath:mapper/*Mapper.xml&quot;/&gt;
    &lt;/bean&gt;

    &lt;bean id=&quot;sqlSession&quot; class=&quot;org.mybatis.spring.SqlSessionTemplate&quot;&gt;
        &lt;constructor-arg ref=&quot;sqlSessionFactory&quot;/&gt;
    &lt;/bean&gt;</code></pre><h2 id="3-sqlsession-주요-메서드">3. SqlSession 주요 메서드</h2>
<ol>
<li>int insert(SQL문 이름, parameter Object 객체)</li>
<li>int delete</li>
<li>int update</li>
<li>selectOne : 하나의 행을 반환하는 select에 사용 parameter로 SQL에 바인딩될 값 제공</li>
<li>selectList : <strong>여러 행</strong>을 반환하는 select에 사용 parameter로 SQL에 바인딩될 값 제공</li>
<li>selectMap : <strong>여러 행</strong>을 반환하는 select에 사용 keyCol에 Map의 key로 사용할 컬럼 지정</li>
</ol>
<h2 id="4-mapper-xml의-작성">4. Mapper XML의 작성</h2>
<ul>
<li>namespace : SQL문의 각 ID를 구분하기 위함<pre><code class="language-XML">&lt;insert id=&quot;insert&quot; parameterType=&quot;com.fastcampus.ch3.domain.BoardDto&quot;&gt;
INSERT INTO board
    (title, content, writer)
VALUES
    (#{title}, #{content}, #{writer})
&lt;!-- BoardDto 객체 값들이 #{}에 매핑됨! getter()이용 --&gt;
&lt;/insert&gt;  
</code></pre>
</li>
</ul>
<p><select id="select" parameterType="int" 
                    resultType="com.fastcampus.ch3.domain.BoardDto">
  <!-- int : Java.Lang.Integer -->
  SELECT bno, title, content, writer, view_cnt, comment_cnt, reg_date
  FROM board
  WHERE bno = #{bno}
  <!-- #{} : parameterType 객체가 매핑됨 -->
</insert>  </p>
<pre><code>
## 5. `&lt;typeAliases&gt;`로 이름 짧게 하기
- AS-IS : parameterType=&quot;com.fastcampus.ch3.domain.BoardDto&quot;
- TO-BE
```XML
&lt;typeAliases&gt;
  &lt;typeAlias alias=&quot;BoardDto&quot; type=&quot;com.fastcampus.ch4.domain.BoardDto&quot;/&gt;
&lt;/typeAliases&gt;

&lt;select id=&quot;select&quot; parameterType=&quot;int&quot; resultType=&quot;BoardDto&quot;&gt;
  SELECT bno, title, content, writer, view_cnt, comment_cnt, reg_date
  FROM board
  WHERE bno = #{bno}
&lt;/insert&gt;  </code></pre><ul>
<li>별명은 대소문자 구분 안함</li>
</ul>
<p><br><hr><br></p>
<h2 id="1-boarddao의-작성">1. BoardDao의 작성</h2>
<ol>
<li>DB테이블 생성</li>
<li>Mapper XML &amp; DTO 작성</li>
<li>DAO 인터페이스 작성</li>
<li>DAO 인터페이스 구현 &amp; 테스트 (3.로 하고 Extract Interface하면 O)
참고) <a href="https://stella-ul.tistory.com/entry/Repository-DAO-DTO-VO-%EB%AD%90%EA%B0%80-%EB%8B%A4%EB%A5%B8%EA%B1%B8%EA%B9%8C?category=1029209">https://stella-ul.tistory.com/entry/Repository-DAO-DTO-VO-%EB%AD%90%EA%B0%80-%EB%8B%A4%EB%A5%B8%EA%B1%B8%EA%B9%8C?category=1029209</a></li>
</ol>
<h2 id="2-dto란---data-trasnfer-object">2. DTO란? - Data Trasnfer Object</h2>
<ul>
<li>계층간의 데이터를 주고 받기 위해 사용되는 객체</li>
<li>테이블에 저장된 내용과 Mapping을 위해 정의</li>
<li>변환&amp;검증 : 요청 값이 int일 때 null이면 변환에러가 나옴 (Integer로 기입해야 됨)</li>
</ul>
<h3 id="내부-3계층-controller-→-service-→-repository">내부 3계층 (@Controller → @Service → @Repository)</h3>
<ul>
<li>모든 계층 간의 데이터 전달은 DTO가 담당!</li>
</ul>
<ol>
<li>@Controller</li>
</ol>
<ul>
<li>요청과 응답을 처리</li>
<li>데이터 유효성 검증</li>
<li>실행 흐름을 제어 (redirect &amp; forward)</li>
</ul>
<ol start="2">
<li>@Service (try-catch)</li>
</ol>
<ul>
<li>비즈니스 로직 담당</li>
<li>트랜잭션 처리</li>
</ul>
<ol start="3">
<li>@Repository (보고)</li>
</ol>
<ul>
<li><p>순수 Data Access 기능 (DAO)</p>
</li>
<li><p>조회, 등록, 수정, 삭제</p>
</li>
<li><p>예외처리 (예외 되던지기)
1) Service 계층
2) Controller (무조건 컨트롤러로 넘기면 됨)
3) 둘 다</p>
</li>
</ul>
<h2 id="3-와-의-차이">3. #{}와 ${}의 차이</h2>
<ul>
<li>#{} : pstmt를 씀 (값에만 쓸 수 있고, SQL Injection을 막아줌!)</li>
<li>${} : stmt를 씀 (유연, 제약이 적음)</li>
</ul>
<h2 id="4-xml의-특수-문자-처리">4. XML의 특수 문자 처리</h2>
<ul>
<li>XML내의 특수문자(&lt;, &gt;, &amp;, ...)는 &lt; &gt;로 변환 필요</li>
<li>또는 특수문자가 포함된 쿼리를 <![CDATA[와]]]]><![CDATA[>로 감싼다
※ XML 태그가 없다는 뜻! (Character 데이터)<pre><code class="language-xml">&lt;![CDATA[
UPDATE board
SET title = #{title}
where bno = #{bno} and bno &lt;&gt; 0
]]&gt;</code></pre>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[JS] Event 성능 향상]]></title>
            <link>https://velog.io/@soulee__/JS-Event-%EC%84%B1%EB%8A%A5-%ED%96%A5%EC%83%81</link>
            <guid>https://velog.io/@soulee__/JS-Event-%EC%84%B1%EB%8A%A5-%ED%96%A5%EC%83%81</guid>
            <pubDate>Mon, 10 Apr 2023 11:55:48 GMT</pubDate>
            <description><![CDATA[<h2 id="기존-방법-settimeout">기존 방법 (setTimeout)</h2>
<ul>
<li>setTimeout 적용해서 지정된 시간마다 한번씩만 이벤트가 실행되게...</li>
</ul>
<pre><code class="language-js">let timeout = null;

watch(searchText, () =&gt; {
  clearTimeout(timeout);

  timeout = setTimeout(() =&gt; {
    getTodos(1);
  }, 1000)
});
</code></pre>
<h2 id="throttle--debounce">Throttle &amp; Debounce</h2>
<ul>
<li>throttle : 지정한 시간마다 최대 1번만 실행될 수 있도록 도움</li>
<li>Debounce : 리스너가 실행된 후 다음 실행까지의 딜레이를 설정할 수 있도록 도와줌</li>
</ul>
<p>page 안에는 router 컴포넌트들이 들어가게 됨</p>
<p>ex)
/ : pages/index.vue
/todos : pages/todos/todos.vue</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Algorithm] 타겟 넘버 (Java)]]></title>
            <link>https://velog.io/@soulee__/Algorithm-%ED%83%80%EA%B2%9F-%EB%84%98%EB%B2%84-Java-36ks8u13</link>
            <guid>https://velog.io/@soulee__/Algorithm-%ED%83%80%EA%B2%9F-%EB%84%98%EB%B2%84-Java-36ks8u13</guid>
            <pubDate>Mon, 10 Apr 2023 11:55:25 GMT</pubDate>
            <description><![CDATA[<pre><code class="language-java">class Solution {
    public int solution(int[] numbers, int target) {
        return dfs(numbers, target, 0, 0);
    }    

    public int dfs(int[] numbers, int target, int count, int sum) {

        if(count == numbers.length) {
            if (sum == target) {
                return 1;
            }
            return 0;
        }

        return dfs(numbers, target, count + 1, sum + numbers[count]) + dfs(numbers, target, count + 1, sum - numbers[count]);
    }
}</code></pre>
<ul>
<li>dfs 보다는 동적 계획법에 가까운 풀이법...</li>
<li>```html</li>
<li>arr[0] -arr[1]<pre><code>   +arr[0]</code></pre></li>
</ul>
<p>+arr[0] -arr[1]
        +arr[0] ...</p>
<p>```
  이런식으로 분기 처리를 해 나가면서 모든 경우의 수를 구하는 방법!</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[redirect와 forward]]></title>
            <link>https://velog.io/@soulee__/redirect%EC%99%80-forward</link>
            <guid>https://velog.io/@soulee__/redirect%EC%99%80-forward</guid>
            <pubDate>Mon, 10 Apr 2023 11:54:59 GMT</pubDate>
            <description><![CDATA[<h1 id="redirect와-forward">redirect와 forward</h1>
<h2 id="1-redirect와-forward의-처리-과정-비교">1. redirect와 forward의 처리 과정 비교</h2>
<h3 id="1-redirect">1) redirect</h3>
<ul>
<li><p>status-code : 300 (redirect = 다른 URL로 재요청)</p>
</li>
<li><p>브라우저가 <strong>자동</strong>으로 Location을 읽어서 해당 위치로 이동!</p>
</li>
<li><p>과정 : 1. 요청 -&gt; 2. 응답 =&gt; 3. 요청 -&gt; 4. 응답</p>
</li>
<li><p>어떤 요청이든 redirect로 의한 호출은 get으로 호출</p>
</li>
<li><p>요청 / 응답 모두 2번!</p>
</li>
</ul>
<h3 id="2-forward">2) forward</h3>
<ul>
<li>클라이언트 요청시, 서버 처리 후 일부 요청을 forward location에 전달</li>
<li>과정 : 1. 요청 -(전달)-&gt; 2. 요청 (forward) -&gt; 3. 응답</li>
<li>write.jsp (Controller 역할 - 처리) / request (Model - 객체) / login.jsp (View - 최종 응답)</li>
<li>이 때, 두번째 요청시 첫번째 요청의 response 내용을 함께 전달!
ex) 잘못된 요청을 맞는 부서에 자동으로 전달~</li>
<li>스프링이 forward를 통해 MVC를 구현함</li>
</ul>
<h2 id="2-redirectview">2. RedirectView</h2>
<p>1) 스프링 redirect처리 과정</p>
<ul>
<li>/ch2/register/save (요청) -&gt; DispatcherServlet -&gt; Controller (요청 처리를 위한 컨트롤러 호출) -&gt; redirect:/register/add 응답</li>
<li>RedirectView 응답 생성<pre><code class="language-html">(응답 헤더)
HTTP/1.1 302
Location:/ch2/...</code></pre>
</li>
<li>응답</li>
</ul>
<h2 id="3-jstlview-jsp뷰-처리">3. JstlView (JSP뷰 처리)</h2>
<ul>
<li>/ch2/register/add (요청) -&gt; DispatcherServlet -&gt; Controller (요청 처리를 위한 컨트롤러 호출) -&gt; registerForm 응답 -&gt; DS가 해당 응답을 InternalResourceViewResolver에게 전달 -&gt; registerForm 해석 -&gt; 해당 Resolver가 해당 파일의 진짜 이름을 DS에게 전달 /WEB-INF/views/registerForm.jsp -&gt; JstlView가 해당 .jsp에게 Model을 넘겨줌 (JSP 뷰)</li>
</ul>
<h2 id="4-internalresourceview-forward">4. InternalResourceView (forward)</h2>
<p>1) 과정</p>
<ul>
<li>/ch2/register/save (요청) -&gt; DispatcherServlet -&gt; Controller (요청 처리를 위한 컨트롤러 호출) -&gt; forward:/register/add -&gt;</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[Spring DI활용하기]]></title>
            <link>https://velog.io/@soulee__/Spring-DI%ED%99%9C%EC%9A%A9%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@soulee__/Spring-DI%ED%99%9C%EC%9A%A9%ED%95%98%EA%B8%B0</guid>
            <pubDate>Mon, 10 Apr 2023 11:54:40 GMT</pubDate>
            <description><![CDATA[<h1 id="autowired">@Autowired</h1>
<ul>
<li>객체 자동 연결하기</li>
</ul>
<h1 id="isinstance">isInstance</h1>
<pre><code class="language-java">object.getClass().equals(clazz)</code></pre>
<h1 id="autowired-vs-resource">@Autowired vs @Resource</h1>
<ul>
<li>@Autowired : byType으로 먼저 찾은 후, 여러개면 이름으로 검색! ( @Qualifier )</li>
<li>@Resource : byName으로 찾음<pre><code class="language-java">@Resource(name=&quot;superEngine&quot;)</code></pre>
</li>
</ul>
<p><br><hr><br></p>
<h1 id="1-빈bean이란">1. 빈(bean)이란?</h1>
<h3 id="javabeans">JavaBeans</h3>
<ul>
<li>재사용 가능한 컴포넌트, 상태(iv), getter&amp;setter, no-args constructor</li>
</ul>
<h3 id="servlet--jsp-bean">Servlet &amp; JSP bean</h3>
<ul>
<li>MVC의 Model (Data 전달), EL, scopre, JSP container에 담아서 관리하는 객체!</li>
</ul>
<p>...</p>
<h3 id="spring-bean">Spring Bean</h3>
<ul>
<li>POJO (Plain Old Java Object) &lt;-&gt; (EJB)</li>
<li>단순 독립적</li>
<li>Spring Container가 관리!</li>
</ul>
<p><br><hr><br></p>
<h1 id="2-beanfactory와-application-context">2. BeanFactory와 Application Context</h1>
<h3 id="1-bean-pojo">1) Bean (POJO)</h3>
<ul>
<li>Spring Container가 관리하는 객체</li>
</ul>
<h3 id="2-spring-container">2) Spring Container</h3>
<ul>
<li>Bean 저장소</li>
<li>Bean을 저장, 관리 (생성, 소멸, 연결)
※ (생성, 소멸) Bean의 LifeCycle을 관리 
※ (연결) 객체 간의 관계까지 연결해줌 = Autowiring / @Autowired</li>
</ul>
<ol>
<li>BeanFactory (Bean 공장) - Bean을 생성, 연결 등의 기본 기능을 정의해놓은 인터페이스</li>
<li>ApplicationContext - <strong>BeanFactory를 확장해서 여러 기능을 추가 정의</strong></li>
</ol>
<p><br><hr><br></p>
<h1 id="3-applicationcontext의-종류">3. ApplicationContext의 종류</h1>
<ul>
<li>다양한 종류의 ApplicationContext구현체 제공</li>
</ul>
<h2 id="ac의-종류">AC의 종류</h2>
<h3 id="1-xml">1. XML</h3>
<p>1) non-Web : GenericXmlApplcationContext
2) Web : <code>XmlWebApplcationContext</code>
<br></p>
<h3 id="2-java-config">2. Java Config</h3>
<p>1) non-Web : AnnotationConfigApplcationContext
2) Web : <code>AnnotationConfigWebApplcationContext</code></p>
<pre><code class="language-java">// in xml (텍스트 문서)
&lt;bean id ... /&gt;

// in java Config (컴파일러가 관리!)
@Bean</code></pre>
<p><br><hr><br></p>
<h1 id="4-root-ac와-servlet-ac">4. Root AC와 Servlet AC</h1>
<ul>
<li>두 개의 xml설정파일, 두 개의 XmlWebApplicationContext()를 만들면서 두 개를 연결해줌!</li>
<li>부모 (공통 bean / root-context) - 자식 (개별 bean / dispatcher-servlet)</li>
<li>부모 : non-web</li>
<li>자식 : 각 모듈에서 쓰는 애들을 씀 web!<pre><code class="language-JAVA">new XmlWebApplicationContext();</code></pre>
<br>
```xml
...contextConfigLocation...
.../WEB-INF/spring root-context.xml...
<!-- 해당 위치의 XML을 이용해서 해당 객체를 생성! -->
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
<!-- 이벤트처리기 : 톰캣이 시작할 때 이벤트를 체크해서 new XmlWebApplicationContext를 시작해줌 -->
...
<!-- DispatcherServlet을 등록! -->
<servlet>
    <servlet-name> ...
  <init-param>
    <param-value>/WEB-INF/.../servlet-context.xml</param-value>
  </init-param>
</servlet>  
<!-- 초기화하면서 XmlWebApplicationContext를 하나 더 만듦 -->
```

</li>
</ul>
<h1 id="5-applicationcontext의-주요-메서드">5. ApplicationContext의 주요 메서드</h1>
<h3 id="bean-얻기">bean 얻기</h3>
<ul>
<li>getBean() : 빈 얻기 ( == @autowired)</li>
</ul>
<h3 id="bean-타입-확인">bean 타입 확인</h3>
<p>1) isPrototype(String name)
2) isSingleton(String name)
3) isTypeMatch(String name, Class&lt;//T&gt; typeToMatch)</p>
<h3 id="정의된-bean-개수-확인">정의된 bean 개수 확인</h3>
<ul>
<li>getBeanDefinitionCount()</li>
</ul>
<h1 id="-스프링-deploy-단계">※ 스프링 deploy 단계</h1>
<ul>
<li>시스템 property값 생성 : key - value 형태
1) Root Web AC 초기화! (root-context.xml 기반)
 ※ 해당 부분이 안되면 root-context.xml에 문제가 있다고 판단!
2) DS 초기화 &amp; DS 내부에 XmlWebApplicationContext 생성 (servletAC) !
 (servlet-context.xml 기반)
3) AutowriedAnnotationBeanPostProcesseor
4) RequestMappingHandlerMapping
5) Deploy 끝!</li>
</ul>
<p><br><hr><br></p>
<h1 id="6-ioc와-di">6. IoC와 DI</h1>
<p>1) 제어의 역전 IoC : 제어의 흐름을 <strong>전통적인 방식과 다르게 뒤바꾸는 것</strong></p>
<ul>
<li><p>Control : flow control (실행 흐름이 바뀜!)</p>
</li>
<li><p>전통적인 방식 : 다른 사람이 작성한 코드를 호출</p>
</li>
<li><p>IoC : 사용자가 제공한 코드를 라이브러리가 호출!
= 다른 사람이 만든 코드가 우리가 만든 코드를 호출!</p>
</li>
<li><p>분리 1. 관심사 2. 변하는 것, 변하지 않는 것 3. 중복 코드</p>
<pre><code class="language-JAVA">void turboDrive() {
  engine = new TurboEngine();
  // superEngine으로 바꾸고 싶으면..! 
  // 라이브러리 자체를 뜯어 고쳐야됨~~
  engine.start();
}</code></pre>
</li>
</ul>
<p>2) 의존성 주입 DI : 사용할 객체를 외부에서 주입받는 것</p>
<ul>
<li>라이브러리 : 단순 기능 제공</li>
<li>프레임워크 : 기능 + 프로그래밍 패턴 / 형식 제공<pre><code class="language-JAVA">car.drive(new SuperEngine()); // 수동 주입!
// 자동 주입 : @Autowired
</code></pre>
</li>
</ul>
<p>...</p>
<p>void drive(Engine engine) {
    engine.start();
    ...
}</p>
<pre><code>
# @Autowired (byType)
- 인스턴스 변수(iv), setter, 참조형 매개변수를 가진 생성자, 메서드에 적용
- *생성자에는 @ 생략 가능!*
=&gt; 단, 매개변수 없는 생성자가 있으면 안됨
```java
// 1. iv
class Car {
    @Autowired Engine engine;
}
...
// 2. setter
@Autowired
public void setEngineAndDoor(Engine engine) {
    this.engine = engine;
}
...
// 3. 참조형 매개변수 생성자, 메서드에 적용
@Autowired
public Car (@Value(&quot;red&quot;) String color, Engine engine) {
    this.color = color;
    this.engine = engine;
}</code></pre><p>=&gt; 1,2는 빼먹을 수도 있으니까 생성자에 한꺼번에 주입하는게 나음!</p>
<ul>
<li><p>Spring container에서 타입으로 빈 검색 -&gt; 참조 변수에 자동 주입(DI)</p>
</li>
<li><p>검색된 빈이 n개 이면, 그 중에 참조 변수와 이름이 일치하는 것을 주입!</p>
</li>
<li><p>주입 대상이 변수일 때, 검색된 빈이 1개 아니면 예외 발생
=&gt; 반드시 1개여야 함</p>
</li>
<li><p>주입 대상이 배열일 때, 검색된 빈이 n개라도 예외 발생 X</p>
</li>
<li><p>@Autowired(required=false)일 때, 주입할 빈을 못찾아도 예외 발생 X</p>
</li>
</ul>
<h1 id="resource-byname">@Resource (byName)</h1>
<ul>
<li>Spring container에서 <em>이름으로 빈을 검색</em>해서 참조 변수에 자동 주입(DI)</li>
<li>일치하는 이름의 빈이 없으면, 예외 발생!<pre><code class="language-JAVA">class Car {
  @Resource(name=&quot;superEngine&quot;)
  Engine engine;
}
</code></pre>
</li>
</ul>
<p>class Car {
    @Autowired // 1. 타입 검색 후,
    @Qualifier(&quot;superEngine&quot;) // 2. 어떤거 주입할지 지정!
    Engine engine;
}</p>
<p>class Car {
    @Resource(name=&quot;engine&quot;)
    @Resource // 이름 생략 가능!
    Engine engine;
}</p>
<pre><code>
# @Component
- `&lt;component-scan&gt;`으로 @Component가 클래스를 자동 검색해서 빈으로 등록
- @Controller, @Service, @Repository, @ControllerAdvice의 메타 애너테이션

```xml
&lt;context:component-scan base-package=&quot;com.fastcampus.ch3&quot; /&gt;
&lt;!-- 서브 패키지까지 다 검색해서 
     @Component 붙은 클래스들 다 모아서 빈으로 등록해줌 --&gt;</code></pre><pre><code class="language-java">package com.fastcampus.ch3;
import org.springframework.stereotype.*;

// 1. &lt;bean id=&quot;superEngine&quot; 
//    class=&quot;com.fastcampus.ch3.SuperEngine&quot;&gt;

// 2. @Component(&quot;superEngine&quot;) // 이름 생략 가능

@Component
class SuperEngine extends Engine {}</code></pre>
<h1 id="value와-propertysource">@Value와 @PropertySource</h1>
<pre><code class="language-java">@Value(&quot;#{systemProperties[&#39;user.timezone&#39;]}&quot;)
// 시스템 속성 / 환경 변수 가져올 때!
...
Properties prop = System.getProperties();

@Value(&quot;${autosaveDir}&quot;)</code></pre>
<p><br><hr><br></p>
<h1 id="7-스프링-애너테이션-vs-표준-애너테이션">7. 스프링 애너테이션 vs 표준 애너테이션</h1>
<p>1) @Autowired = @Inject
2) @Qualifier = @Resource (annotations-api.jar 가 필요함!)
3) @Scope(&quot;singleton&quot;) : 표준에서는 prototype이 디폴트
4) @Component
※ annotations-api.jar : @Qualifier, @PreDestroy, @Singleton</p>
<h1 id="8-빈-초기화-property와-setter">8. 빈 초기화 <code>&lt;property&gt;</code>와 setter</h1>
<ul>
<li><code>&lt;property&gt;</code>를 이용한 빈 초기화 (setter 이용)</li>
<li><code>&lt;constructor-arg&gt;</code>를 이용한 빈 초기화 (생성자 이용)</li>
<li><code>&lt;list&gt;</code>, <code>&lt;set&gt;</code>, <code>&lt;map&gt;</code></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[DispatcherServlet 파헤치기]]></title>
            <link>https://velog.io/@soulee__/DispatcherServlet-%ED%8C%8C%ED%97%A4%EC%B9%98%EA%B8%B0</link>
            <guid>https://velog.io/@soulee__/DispatcherServlet-%ED%8C%8C%ED%97%A4%EC%B9%98%EA%B8%B0</guid>
            <pubDate>Sun, 19 Mar 2023 10:36:01 GMT</pubDate>
            <description><![CDATA[<h1 id="dispatcherservlet이란">DispatcherServlet이란?</h1>
<ul>
<li>기능 : 컨트롤러 / 서블릿 파일에 존재하는 &#39;입력&#39; 부분을 앞으로 빼 공통 로직으로 활용!</li>
<li>기능 : 전처리담당 (각 서블릿 / 컨트롤러가 활용하는 공통 부분을 앞에서 처리)</li>
<li>절차
1) 브라우저 요청을 DispatcherServlet가 받음<ul>
<li>이 때, HandlerMapping이 동작!
2) DispatcherServlet &lt;-&gt; Controller (메소드 호출)</li>
<li>이 때, HandlerAdapter이 동작
2-1) 해당 컨트롤러의 메소드 호출 후, 뷰의 이름을 받음</li>
<li>이 때, ViewResolver가 동작! (실제 뷰 경로)
3) 뷰 이름으로 해당 뷰를 찾아 호출 &amp; 데이터가 담겨있는 model을 전달!</li>
<li>이 때, JstlView가 동작!
4) JSP 파일이 모델 활용, 응답 결과를 만든 후 클라이언트에게 전달!</li>
</ul>
</li>
</ul>
<h1 id="1-handlermapping">1. HandlerMapping</h1>
<ul>
<li>K-V 형태</li>
<li>URL - 메소드 두 개를 매핑 시켜놓고
요청이 들어왔을 때 요청을 어떤 메소드가 처리하면 좋을지 대답해주는 역할</li>
<li>URL과 일치하는 메소드를 반환</li>
<li>DispatcherServlet이 이걸 받아서 메소드를 호출해줌</li>
</ul>
<h1 id="2-handleradapter">2. HandlerAdapter</h1>
<ul>
<li>DispatcherServlet이 controller 메소드를 호출 할 때, 사용</li>
<li>어떤 HandlerAdapter가 어떤 controller가 처리할 수 있는지 보고 그 컨트롤러를 호출하고 DispatcherServlet에게 전달!</li>
<li>controller 뿐만 아니라 서블릿도 호출 가능! (다양한 객체를 호출하고자 설계됨)</li>
</ul>
<h1 id="3-viewresolver">3. ViewResolver</h1>
<ul>
<li>InternalResourceViewResolver : servlet-context.xml<pre><code class="language-xml">&lt;beans:bean class=&quot;org.springframework.web.servlet.view.InternalResourceViewResolver&quot;&gt;
      &lt;beans:property name=&quot;prefix&quot; value=&quot;/WEB-INF/views/&quot; /&gt;
      &lt;beans:property name=&quot;suffix&quot; value=&quot;.jsp&quot; /&gt;
  &lt;/beans:bean&gt;</code></pre>
</li>
<li>&quot;registerForm&quot; -&gt; &quot;/WEB-INF/views/registerForm.jsp&quot;</li>
<li>실제 뷰의 이름, 경로를 호출하게 변경해줌</li>
</ul>
<h1 id="관심사의-분리">관심사의 분리</h1>
<ul>
<li>역할이 다른 것들은 분리한다!</li>
<li>느슨한 연결 = 변경의 유리한 설계를 함</li>
</ul>
<hr>

<h1 id="dispatcherservlet-소스-분석">DispatcherServlet 소스 분석</h1>
<ul>
<li>DispatcherServlet.class (webmvc.. .jar에 포함)</li>
<li></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[MVC구조 형태]]></title>
            <link>https://velog.io/@soulee__/MVC%EA%B5%AC%EC%A1%B0-%ED%98%95%ED%83%9C</link>
            <guid>https://velog.io/@soulee__/MVC%EA%B5%AC%EC%A1%B0-%ED%98%95%ED%83%9C</guid>
            <pubDate>Sat, 18 Mar 2023 05:50:06 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/soulee__/post/4c4b4ea4-08a3-47f5-aa70-57d4095e3a2c/image.png" alt=""></p>
<h2 id="controller">Controller</h2>
<ul>
<li>view에서 요청이 들어올 때, 요청을 수행할 <strong>화면이나 비즈니스 로직(model)을 제어</strong>하는 객체</li>
<li><strong>모델과 뷰를 연결</strong>해주는 중간다리 역할 = 서비스에 매칭해주는 역할만 담당!</li>
<li>컨트롤러는 요청에 따른 <strong>처리방식만 결정</strong>, 실제로 서비스를 수행하는 것은 model 영역</li>
<li><code>@Controller</code></li>
</ul>
<h2 id="service">Service</h2>
<ul>
<li><strong>controller에서 servicempl 객체를 생성한 뒤 호출</strong>하는 방식으로 동작 = 요청 처리 방식을 정의</li>
<li>서비스 레이어에서 <strong>세분화된 비즈니스 로직을 제어</strong>하는 객체</li>
<li>** [구성]**<ul>
<li>interface : 서비스의 구조를 결정</li>
<li>implementation : 이것을 상속받아 override 형태로 실제 로직을 구현</li>
</ul>
</li>
<li><code>@Service</code> / <code>@implementation</code></li>
</ul>
<h2 id="dao">DAO</h2>
<ul>
<li><strong>DB에 접근하는 요청</strong>을 처리</li>
<li>service에서 <strong>DAO객체를 생성한 뒤 호출</strong>하는 방식으로 동작</li>
<li><strong>sqlsession객체</strong>를 통해 전달받은 파라미터로 DB처리를 수행</li>
</ul>
<h2 id="vo">VO</h2>
<ul>
<li>계층 간의 데이터 교환을 위한 객체로, 구조를 결정함으로서 알지 못하는 데이터가 들어오는 상황을 방지
= <strong>주고 받는 데이터 객체의 구조를 결정</strong></li>
<li>말 그대로 <strong>구조만 결정</strong> (멤버변수 / Getter, Setter만이 존재)</li>
<li>DB의 테이블 요소들을 모두 포함하고 있어야 정상적으로 동작
<a href="https://velog.io/@homil9876/Spring-%EC%9E%90%EC%A3%BC-%EC%93%B0%EC%9D%B4%EB%8A%94-Annotation-%EC%A0%95%EB%A6%AC">https://velog.io/@homil9876/Spring-%EC%9E%90%EC%A3%BC-%EC%93%B0%EC%9D%B4%EB%8A%94-Annotation-%EC%A0%95%EB%A6%AC</a></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[스파르타 코딩]]></title>
            <link>https://velog.io/@soulee__/%EC%8A%A4%ED%8C%8C%EB%A5%B4%ED%83%80-%EC%BD%94%EB%94%A9</link>
            <guid>https://velog.io/@soulee__/%EC%8A%A4%ED%8C%8C%EB%A5%B4%ED%83%80-%EC%BD%94%EB%94%A9</guid>
            <pubDate>Wed, 01 Mar 2023 15:31:14 GMT</pubDate>
            <description><![CDATA[<h1 id="1-dependencies">1. Dependencies</h1>
<ul>
<li>Spring web</li>
<li>H2 Database</li>
<li>MySQL Driver</li>
<li>Lombok</li>
<li>Spring Data JPA</li>
</ul>
<h1 id="2-웹의-기본개념">2. 웹의 기본개념</h1>
<ul>
<li>API : 하나의 &quot;약속&quot; 정해진 요구를 하면 정해진 답변을 주는 것!</li>
<li>스프링의 담당 : 서버! </li>
</ul>
<h1 id="3-객체-지향-프로그래밍">3. 객체 지향 프로그래밍</h1>
<ul>
<li>객체지향프로그래밍 : 프로그래밍을 현실 세계에 빗대어 체계적으로 해보자는 발상</li>
<li>클래스<ul>
<li>정보를 묶는 것!</li>
<li>현실과 비슷한 개념(객체)을 나타내기 위한 자바의 도구</li>
<li>멤버 변수 : 클래스 내 정보</li>
</ul>
</li>
</ul>
<h1 id="4-restcontroller">4. RestController</h1>
<ul>
<li>controller (자동 응답기)<ul>
<li>클라이언트의 요청을 전달받는 코드</li>
</ul>
</li>
<li>RestController<ul>
<li>JSON 만을 돌려주는 것은 RestController라고 함</li>
</ul>
</li>
</ul>
<h1 id="5-그레이들-gradle">5. 그레이들 (Gradle)</h1>
<ul>
<li>js : npm</li>
<li>python : pip</li>
<li>java : mavenCentral, jcenter
=&gt; 다운로드받고 적용하는 과정을 보다 편하게! &amp; 빌드도 도와줌</li>
</ul>
<h1 id="6-사용할-기술">6. 사용할 기술</h1>
<ul>
<li>H2 = MYSQL</li>
<li>H2는 RDBMS의 한 종류로, 서버가 켜져있는 동안에만 작동하는 RDB</li>
<li>JPA : 자바 명령어를 SQL로 변환해주는 애!</li>
<li>Repository : JPA를 작동시키는 매개체!</li>
<li>API</li>
<li>Lombok : 코드 절약 가능!</li>
<li>DTO : 현업에서 데이터를 주고받을 때 사용!</li>
</ul>
<h1 id="7-rdbms">7. RDBMS</h1>
<ul>
<li>컴퓨터에 정보를 저장하고 관리하는 기술</li>
<li>성능/관리 면에서 매우 고도화된 엑셀</li>
<li>H2 : In-memory DB (서버가 작동을 멈추면 데이터가 모두 삭제! / 연습용)</li>
<li>MySQL : AWS RDS에 붙일 예정!</li>
</ul>
<h1 id="8-h2-웹콘솔-띄워보기">8. H2 웹콘솔 띄워보기</h1>
<ul>
<li>스프링 디렉토리<ul>
<li>main &gt; java : 소스코드 작성</li>
<li>main &gt; resources : 설정 파일<pre><code class="language-java">spring.h2.console.enabled=true
spring.datasource.url=jdbc:h2:mem:testdb</code></pre>
</li>
</ul>
</li>
</ul>
<h1 id="9-jpa">9. JPA</h1>
<h2 id="정의">정의</h2>
<ul>
<li>SQL을 쓰지 않고 데이터를 생성, 조회, 수정, 삭제할 수 있도록 해주는 번역기!</li>
</ul>
<h2 id="설정">설정</h2>
<pre><code class="language-java">// save a few customers
repository.save(new Customers(&quot;Jack&quot;, &quot;Bauer&quot;));
repository.save(new Customers(&quot;Chloe&quot;, &quot;O&#39;Brain&quot;));</code></pre>
<h2 id="domain과-repository">Domain과 Repository</h2>
<ul>
<li>domain : entity = table</li>
<li>repository : SQL 역할</li>
</ul>
<h2 id="interface란">Interface란</h2>
<ul>
<li>JPA는 인터페이스만을 가지고 쓸 수 있음 (인터페이스로 Repository 생성!)</li>
<li>인터페이스 : 클래스에서 멤버가 빠진, <strong>메소드 모음집</strong>!</li>
</ul>
<h1 id="10-스프링의-구조">10. 스프링의 구조</h1>
<ol>
<li>Controller<ul>
<li>가장 바깥 부분, 요청/응답을 처리함</li>
</ul>
</li>
<li>Service (컨트롤러 - Repo 사이)<ul>
<li>중간 부분, 실제 중요한 작동이 많이 일어나는 부분</li>
</ul>
</li>
<li>Repo<ul>
<li>가장 안쪽 부분, DB와 맞닿아 있음.</li>
<li>여태 배운 녀석 (Repository, Entity)</li>
</ul>
</li>
</ol>
<p>(값 업데이트 하기)</p>
<ul>
<li><p>Service.java</p>
<pre><code class="language-java">  // final: 서비스에게 꼭 필요한 녀석임을 명시
  private final CourseRepository courseRepository;

  // 생성자를 통해, Service 클래스를 만들 때
  // 꼭 Repository를 넣어주도록
  // 스프링에게 알려줌
  public CourseService(CourseRepository courseRepository) {
      this.courseRepository = courseRepository;
  }

  @Transactional // SQL 쿼리가 일어나야 함을 스프링에게 알려줌
  public Long update(Long id, Course course) {
      Course course1 = courseRepository.findById(id).orElseThrow(
              () -&gt; new IllegalArgumentException(&quot;해당 아이디가 존재하지 않습니다.&quot;)
      );
      course1.update(course);
      return course1.getId();
  }</code></pre>
</li>
<li><p>Annotation 목록</p>
<ul>
<li>@Service : </li>
<li>@Transactional : SQL 쿼리가 일어나야 함을 스프링에게 알림</li>
</ul>
</li>
</ul>
<p>(Delete 해보기)</p>
<pre><code class="language-java">courseRepository.deleteAll();</code></pre>
<h1 id="11-lombok">11. Lombok</h1>
<ul>
<li><p>Lombok : 코드를 절약하기 위한 라이브러리로, 자바 프로젝트 진행시, 필수적으로 필요한 메소드를 자동생성!</p>
</li>
<li><p>단축키</p>
<ul>
<li>ctrl + alt + s : 환경설정</li>
<li>shift + shift : 찾기</li>
<li>alt + enter : import 클래스</li>
</ul>
</li>
<li><p>Annotation 목록</p>
<pre><code class="language-java">@Getter
@NoArgsConstructor
@RequiredArgsConstructor (service.java에서 ~Repository 전달받아야 할 때)</code></pre>
</li>
</ul>
<pre><code class="language-java">    // 생성자를 통해, Service 클래스를 만들 때
    // 꼭 Repository를 넣어주도록
    // 스프링에게 알려줌
    public CourseService(CourseRepository courseRepository) {
        this.courseRepository = courseRepository;
    }

    =

    @RequiredArgsConstructor</code></pre>
<h1 id="12-dto">12. DTO</h1>
<ul>
<li><p>데이터값을 변경할 때 이에 대한 매개체로 Course 클래스를 직접 사용하면 안됨!</p>
</li>
<li><p>내가 아닌 다른 사람이 마음대로 변경하게 되면 시스템에 오류 날 가능성이 커짐 </p>
</li>
<li><p>이에 DB에 연결된 클래스는 그대로 두고 이에 대한 완충재로 활용하는 것이 DTO!</p>
</li>
<li><p>DTO : 해당 클래스에 대한 데이터를 그대로 물고 다니는 녀석!</p>
</li>
</ul>
<pre><code class="language-JAVA">package com.example.week01_hw.domain;

import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.Setter;

@Getter
@Setter
@RequiredArgsConstructor
public class CourseRequestDto {
    private final String title;
    private final String tutor;
}</code></pre>
<p>= 꼭 필요한 녀석은 final로 선언이 되어야 함</p>
<h1 id="13-api">13. API</h1>
<ul>
<li><p>API </p>
<ul>
<li>클라이언트 - 서버 간의 약속</li>
<li>클라이언트가 서버에게 요청을 보내면, 서버가 요구사항을 처리하여 응답을 반환</li>
</ul>
</li>
<li><p>REST 규칙</p>
<ul>
<li>주소에 <strong>명사</strong>, 요청 방식에 <strong>동사</strong>를 사용함으로써 의도를 명확히 드러냄</li>
<li>동사 = CRUD</li>
<li>생성 (POST), 조회 (GET), 수정 (PUT), 삭제 (DELETE)</li>
<li>주의사항<ul>
<li>주소에 들어가는 명사들은 복수형을 사용 <code>/courses</code></li>
<li>주소에 동사는 가급적 사용하지 않음 <code>/accounts/edit</code> (edit =&gt; put 방식 대체)</li>
</ul>
</li>
</ul>
</li>
<li><p>데이터 요청방식</p>
</li>
</ul>
<ol>
<li><p>GET</p>
<ul>
<li><p>데이터 조회 API</p>
<pre><code class="language-java">@RequiredArgsConstructor
@RestController
public class CourseController {

 private final CourseRepository courseRepository;

 @GetMapping(&quot;/api/courses&quot;)
 public List&lt;Course&gt; getCourses() {
     return courseRepository.findAll();
 }
}</code></pre>
</li>
</ul>
</li>
<li><p>POST</p>
<ul>
<li><p>생성 요청</p>
<pre><code class="language-java">@PostMapping(&quot;/api/courses&quot;)
public Course createCourse(@RequestBody CourseRequestDto requestDto) {
  Course course = new Course(requestDto);

  return courseRepository.save(course);
}</code></pre>
</li>
<li><p>해당 메소드는 기본적으로 생성한 Course 객체를 반환함</p>
</li>
<li><p>@RequestBody : 요청을 받는 녀석임을 나타내주는 어노테이션</p>
</li>
</ul>
</li>
<li><p>PUT</p>
<ul>
<li><p>수정 요청</p>
<pre><code class="language-JAVA"></code></pre>
</li>
<li><p>@PathVariable : 스프링이 알아서 필요한 값을 path에 mapping 시켜줌</p>
</li>
</ul>
</li>
</ol>
<h1 id="14-개념-정리">14. 개념 정리</h1>
<ul>
<li>Controller : 자동응답기</li>
<li>Service : 업데이트를 쓰는 녀석</li>
<li>Repository : 직접 쿼리를 날리는 녀석</li>
<li>DTO : 계층 간 소통 (정보를 물고 다닐 때)</li>
</ul>
<h1 id="15-api-작성">15. API 작성</h1>
<ul>
<li>서비스 계층 (3계층)</li>
</ul>
<ol>
<li>Controller</li>
<li>Service</li>
<li>Repository</li>
</ol>
<ul>
<li>API 설계</li>
</ul>
<h1 id="16-service-클래스에-꼭-필요한-annotation">16. service 클래스에 꼭 필요한 annotation</h1>
<ul>
<li><p>@RequiredArgsConstructor
  : memoRepository 값을 찾아 넣어줘라~</p>
</li>
<li><p>@Service
  : 해당 클래스가 service 객체임을 알림</p>
</li>
<li><p>@Transactional
  : DB에 진짜 반영이 되어야함을 알려줌!</p>
<pre><code class="language-java">@RequiredArgsConstructor
@Service
public class MemoService {
  private final MemoRepository memoRepository;

  @Transactional
  public Long update(Long id, MemoRequestDto requestDto) {
      Memo memo = memoRepository.findById(id).orElseThrow(
              () -&gt; new NullPointerException(&quot;id값 없는데용?&quot;)
      );

      memo.update(requestDto);
      return id;
  }
}</code></pre>
</li>
<li><p>@RequestBody 어노테이션</p>
<pre><code class="language-java">  @PostMapping(&quot;/api/memos&quot;)
  public Memo createMemos(@RequestBody  MemoRequestDto requestDto) {
      Memo memo = new Memo(requestDto);
      return memoRepository.save(memo);
  }</code></pre>
<ul>
<li>날아오는 녀석을 정확이 requestDTO에 넣기 위해서는 requestBody 어노테이션이 꼭 필요!</li>
<li>requestBody로 말아 넣어줘야 해!!!</li>
</ul>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[스프링] 쿠키 & 세션 이론 2]]></title>
            <link>https://velog.io/@soulee__/%EC%8A%A4%ED%94%84%EB%A7%81-%EC%BF%A0%ED%82%A4-%EC%84%B8%EC%85%98-%EC%9D%B4%EB%A1%A0-2</link>
            <guid>https://velog.io/@soulee__/%EC%8A%A4%ED%94%84%EB%A7%81-%EC%BF%A0%ED%82%A4-%EC%84%B8%EC%85%98-%EC%9D%B4%EB%A1%A0-2</guid>
            <pubDate>Sun, 26 Feb 2023 12:56:24 GMT</pubDate>
            <description><![CDATA[<h1 id="1-세션-실습">1. 세션 실습</h1>
<p>[동작]</p>
<ol>
<li>index.jsp -&gt; board 클릭</li>
<li>BoardController.java -&gt; 로그인? -(yes)-&gt; boardList.jsp<pre><code>                           -(no )-&gt; loginForm.jsp</code></pre></li>
<li>loginController.java -&gt; id/pwd 일치? -(yes)-&gt; index.jsp<pre><code>                                -(no )-&gt; loginForm.jsp</code></pre></li>
</ol>
<h1 id="2-sessionscope">2. sessionScope</h1>
<pre><code class="language-java">&lt;c:set var=&quot;loginOutLink&quot; value=&quot;${sessionScope.id == null ? &#39;/login/login&#39; : &#39;/login/logout&#39;}&quot;/&gt;
&lt;c:set var=&quot;loginOut&quot; value=&quot;${sessionScope.id == null ? &#39;Login&#39; : &#39;LogOut&#39;}&quot;/&gt;</code></pre>
<h1 id="3-redirect-처리">3. redirect 처리</h1>
<ul>
<li>from 정보 : <code>request.getHeader(&quot;refer&quot;)</code></li>
<li>to 정보 : <code>request.getRequestURL()</code></li>
</ul>
<h1 id="4-세션-시간-관리">4. 세션 시간 관리</h1>
<ul>
<li>세션 유지 기간은 가능한 짧아야 한다.<pre><code class="language-JAVA">session=true; // 새션 없을 때 새로 생성 O = default 값
session=false; // 세션 없을 때 새로 생성 X = false를 만나도 세션이 끝나지않음</code></pre>
</li>
<li>session=&quot;false&quot; <ul>
<li>세션이 필요없는 JSP 화면</li>
<li>session false가 기존 세션에 영향 X (새로 생성할지 말지만 결정!)</li>
</ul>
</li>
</ul>
<pre><code class="language-java">&lt;%@ page session=&quot;false&quot; %&gt;</code></pre>
<h3 id="sessionfalse일-때-주의점-📢">session=&quot;false&quot;일 때 주의점 📢</h3>
<ul>
<li>sessionScope, pageContext.session은 사용 불가</li>
<li>sessionScope.id를 <strong>pageContext.request.getSession(false).getAttribute(&quot;id&quot;)</strong>로 변경해야 함!</li>
<li>(참고) getSession(true)는 session이 없는 경우 session을 새로 생성하기 때문에 session이 없어도 새로 생성하지 않도록 <strong>getSession(false)를 사용</strong></li>
</ul>
<h1 id="5-쿠키-값-반환-cookievalue">5. 쿠키 값 반환 (@CookieValue)</h1>
<ul>
<li><code>@CookieValue(&quot;id&quot;) String cookieId</code> : cookie 값 중에 &quot;id&quot;라는 키를 가지고 있는 애를 반환해줌
ex) <code>@CookieValue(&quot;JSESSIONID&quot;)</code></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[스프링] 쿠키 & 세션 이론]]></title>
            <link>https://velog.io/@soulee__/%EC%8A%A4%ED%94%84%EB%A7%81-%EC%BF%A0%ED%82%A4-%EC%84%B8%EC%85%98-%EC%9D%B4%EB%A1%A0</link>
            <guid>https://velog.io/@soulee__/%EC%8A%A4%ED%94%84%EB%A7%81-%EC%BF%A0%ED%82%A4-%EC%84%B8%EC%85%98-%EC%9D%B4%EB%A1%A0</guid>
            <pubDate>Sat, 25 Feb 2023 10:31:55 GMT</pubDate>
            <description><![CDATA[<h1 id="1-servlet-contextxml">1. servlet-context.xml</h1>
<ul>
<li>in spring &gt; appServlet &gt; servlet-context.xml<pre><code class="language-java">&lt;view-controller path=&quot;/register/add&quot; view-name=&quot;registerForm&quot; /&gt;
// 해당 소스는 get 요청밖에 처리를 못함</code></pre>
</li>
</ul>
<h1 id="2-redirect-vs-forward-차이">2. redirect vs forward 차이</h1>
<ul>
<li><code>redirect</code> : 다른 url 주소로 이동</li>
<li><code>forward</code> : 같은 url에서 화면만 변화
※ redirect와 달리 forward는 요청이 하나</li>
</ul>
<p>2) redirect는 302 / forward는 200</p>
<h1 id="3-쿠키">3. 쿠키</h1>
<p>1) 정의 : 클라이언트를 구분하기 위한 기술 (식별)</p>
<ul>
<li>서버는 클라이언트를 모르니 경우에 따라서, 클라이언트를 구분해야 되는 경우가 있음! (쿠키를 사용)</li>
</ul>
<p>2) 설명</p>
<ul>
<li>이름과 값의 쌍으로 구성된 작은 정보. (name - value)</li>
<li>유효기간도 존재 (Max-Age)</li>
<li>아스키 문자만 가능 <ul>
<li>;, 공백 문자열 저장 x</li>
<li>한글 URL 인코딩</li>
</ul>
</li>
<li>서버에서 생성 후 전송, 브라우저에 저장 (유효기간 이후 자동 삭제)</li>
<li>서버에 요청시 domain, path(하위경로 포함)가 일치하는 경우에만 자동 전송!<pre><code class="language-html">ex)
Domain : fastcampus.co.kr
path : /ch2/login</code></pre>
</li>
</ul>
<p>3) 동작 과정
(1) 브라우저 -(요청)-&gt; 서버
    * 이 때, domain, path 일치
(2) 서버에서 쿠키를 생성 (response.addCookie(cookie))</p>
<ul>
<li>in java<pre><code class="language-java">Cookie cookie = new Cookie(&quot;id&quot;, &quot;asdf&quot;);
response.addCookie(cookie);</code></pre>
</li>
<li>응답 헤더 (response header) &amp; 쿠키 전달<pre><code class="language-html">HTTP/1.1 200
Set-Cookie: id=asdf
Content-Type: text/html; charset=UTF-8
Content-Language: ko-KR
Content-Length: 175
Date: Mon, 15 Nov 2021 07:50:09 GMT</code></pre>
(3) 클라이언트가 쿠키를 받아서 브라우저에 저장!
(4) 최초에 쿠키를 받게 되면 이후 요청은 쿠키와 함께 전달</li>
<li>요청 헤더 (request header)<pre><code class="language-html">POST /ch2/login/login HTTP/1.1
Host: localhost
Connection: keep-alive
Content-Length: 26
Cache-Control: max-age=0
Cookie: id=asdf; JSESSIONID=2F460A779BD0DD7339FB68220B814B75</code></pre>
</li>
<li>서버 == 도서관 ID카드!</li>
</ul>
<p>4) 쿠키 생성방법</p>
<pre><code class="language-JAVA">Cookie cookie = new Cookie(&quot;id&quot;,&quot;asdf&quot;); // 쿠키 생성
cookie.setMaxAge(60*60*24);              // 유효기간 설정(초)
response.addCookie(cookie);              // 응답에 쿠키 추가</code></pre>
<ul>
<li>유효기간 (브라우저마다 상이! / 전세계, 하드웨어마다 설정된 시간이 상이할 수도 있으니!)<ul>
<li>max-age : 상대시간</li>
<li>Expries=True, 절대시간</li>
</ul>
</li>
</ul>
<p>5) 쿠키 삭제방법</p>
<pre><code class="language-JAVA">Cookie cookie = new Cookie(&quot;id&quot;,&quot;&quot;); // 변경할 쿠키와 같은 이름 쿠키 생성
cookie.setMaxAge(0);                 // 유효기간을 0으로 설정(삭제)
response.addCookie(cookie);          // 응답에 쿠키 추가</code></pre>
<p>6) 쿠키 변경방법</p>
<pre><code class="language-JAVA">Cookie cookie = new Cookie(&quot;id&quot;,&quot;&quot;);       // 변경할 쿠키와 같은 이름 쿠키 생성
cookie.setValue(URLEncoder.encode(&quot;이솔&quot;)); // 값 변경
// 쿠키 값으로는 아스크코드만 가능하니..!
cookie.setDomain(&quot;www.fastcampus.co.kr&quot;);  // 도메인 변경
cookie.setPath(&quot;/ch2&quot;);                    // 경로 변경
cookie.setMaxAge(60*60*24*7);              // 유효기간 변경
response.addCookie(cookie);                // 응답에 쿠키 추가</code></pre>
<p>7) 쿠키 읽어오기</p>
<pre><code class="language-java">Cookie[] cookies = request.getCookies(); // 쿠키 읽기

for(Cookie cookie : cookies) {
    String name = cookie.getName();
    String value = cookie.getValue();

    System.out.println(&quot;[cookie]name=%s, value=%s%n&quot;, name, value);
}</code></pre>
<h1 id="4-세션">4. 세션</h1>
<ol>
<li><p>정의</p>
<ul>
<li>서로 관련된 요청들을 하나로 묶음 <ul>
<li>(<strong>독립적인 요청들을 하나로 묶은게 세션</strong>! = 쿠키 이용)</li>
</ul>
</li>
<li>browser마다 개별 저장소(session객체)를 <strong>서버에서 제공</strong>! <ul>
<li>(브라우저 - 세션 1:1 관계)</li>
</ul>
</li>
<li>&quot;a collection of related HTTP transactions made by one browser to one server&quot;<ul>
<li>(HTTP 트랜젝션 = 요청 / 응답이 한 SET)</li>
</ul>
</li>
<li>비슷한 요청에 <strong>같은 세션</strong>이라는 꼬리표를 제공 (그룹화)</li>
<li>같은 세션에 있는 동안 같은 세션저장소를 공유</li>
<li>하나의 세션을 끊는 방법<ul>
<li>수동 종료 : Invalidate() = 로그아웃</li>
<li>자동 종료 : Time-out &amp; 새로운 세션 ID 제공</li>
</ul>
</li>
</ul>
</li>
<li><p>생성 과정
 1) 브라우저 요청시, 서버는 무조건 Session 객체(저장소)를 만듦</p>
<pre><code> - 세션 객체마다 sessionId를 가지고 있음</code></pre><p> 2) 저장소를 쓸 수 있게 JSESSIONID 쿠키를 만들어서 브라우저에 보냄
 3) 브라우저에 쿠키 저장
 4) 다음 요청부터는 JSESSIONID를 request header에 자동으로 넣어서 보냄!</p>
<p> = 서버는 응답헤더에 Set-Cookie를 써서 보냄
 = 브라우저에 쿠키가 만들어지고 JSESSIONID가 붙어서 가짐 (브라우저 구분용)
 = JSESSIONID가 일치하는 세션저장소를 사용할 수 있음</p>
</li>
<li><p>세션 객체 얻기</p>
<pre><code class="language-JAVA">// 컨트롤러에서 세션저장소 사용하는 방법
</code></pre>
</li>
</ol>
<p>HttpSession session = request.getSession();
// 1. 요청 객체로부터 JSESSIONID를 보고 일치하는 것을 찾음
session.setAttribute(&quot;id&quot;, &quot;asdf&quot;);
// 2. 반환값을 보고 해당 세션저장소에 값을 수정함!</p>
<pre><code>
4. 세션과 관련된 메서드
1) 속성 관련 메서드
- getAttribute : 지정된 이름의 속성 값 반환
- setAttribute : 지정된 이름의 속성에 값을 저장
- removeAttribute : 지정된 이름의 속성 삭제
- getAttributeName : 기본 객체에 저장된 모든 속성 이름 반환
* pageContext, request, session, application 모두 다 값을 저장하고 받아올 수 있음 그 때 쓰는 메소드!

2) 메서드
- getId : 세션 ID 반환
- getLastAccessedTime : 최근 요청을 받은 시간 반환
- isNew : 새로 생성된 세션인지 반환 
- invalidate : 세션 종료 (즉시)
- setMaxInactiveInterval : 예약 종료
- getMaxInactiveInterval : 예약된 세션 종료 시간을 반환

5. 세션의 종료
1) **수동** 종료 (초 단위)
```JAVA
HttpSession session = request.getSession();
session.invalidate();                   // 1. 세션 즉시 종료
session.setMaxInactiveInterval(30 * 60) // 2. 예약 종료 (30분 후)</code></pre><p>2) <strong>자동</strong> 종료 - web.xml (분 단위)</p>
<pre><code class="language-xml">&lt;session-config&gt;
      &lt;session-timeout&gt;30&lt;/session-timeout&gt;
&lt;/session-config&gt;</code></pre>
<p>= 세션이 종료되면 새로운 세션ID가 발급됨 (새로운 객체 생성)
= StandardManager가 세션의 생성과 소멸을 관리해줌
= 세션 객체는 서버에 오래 남아있기 쉬우니 부담을 줄이기 위해 많은 것을 저장하면 안됨</p>
<ol start="6">
<li>쿠키 vs 세션
1) 쿠키</li>
</ol>
<ul>
<li>브라우저에 저장</li>
<li>서버 부담 X</li>
<li>보안에 불리</li>
<li>서버 다중화에 유리</li>
</ul>
<p>2) 세션</p>
<ul>
<li>서버에 저장</li>
<li>서버 부담 O</li>
<li>보안에 유리</li>
<li>서버 다중화에 불리 (세션 객체를 모든 서버에 동기화하는 과정이 필요!)</li>
</ul>
<ol start="7">
<li>쿠키 수집을 허용하지 않는 브라우저 대응 방법</li>
</ol>
<ul>
<li>모든 요청마다 URL 뒤에 JSESSIONID를 보내줘야 함 (Get으로!)</li>
<li>.jsp 안에 &lt;c:url value=&quot;&quot;&gt; = 이 알아서 url뒤에 session id를 붙여서 보내줌
(이렇게 안하면 매 요청마다 세션객체가 만들어져서 서버 부담이 커짐!)</li>
</ul>
<p>세션이 없는 첫 번째 요청마다 무조건 
1)서버가 url 뒤에 session id를 붙여서 보내줌
2) set cookie로 쿠키로 저장하게끔도 보내줌!
이 후 요청부터는 url 뒤에 session id가 안붙음</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[@RequestParam과 @ModelAttribute]]></title>
            <link>https://velog.io/@soulee__/RequestParam%EA%B3%BC-ModelAttribute</link>
            <guid>https://velog.io/@soulee__/RequestParam%EA%B3%BC-ModelAttribute</guid>
            <pubDate>Wed, 22 Feb 2023 15:03:14 GMT</pubDate>
            <description><![CDATA[<h2 id="1-1-requestparam">1-1. @RequestParam</h2>
<ul>
<li>요청의 파라미터를 연결할 매개변수에 붙이는 애너테이션 (파라미터 - 매개변수)<pre><code class="language-java">// pulbic String main2(@RequestParam(name=&quot;year&quot; required=false String year) 아래와 동일
pulbic String main2(String year)</code></pre>
</li>
<li>required가 true면 앞에 어노테이션 들어감!<pre><code class="language-java">// pulbic String main2(@RequestParam(name=&quot;year&quot; required=true String year) 아래와 동일
pulbic String main2(@RequestParam String year) // 안넘어오면 클라이언트 잘못!</code></pre>
</li>
<li>required가 false일 때 처리<ul>
<li>기본 값을 부여해줘야 함 (defaultValue로)<pre><code class="language-java">pulbic String main2(@RequestParam (required=false, defaultValue=&quot;1&quot;) String year) // 안넘어오면 클라이언트 잘못!</code></pre>
</li>
</ul>
</li>
<li>required가 true일 때 처리<ul>
<li>반드시 예외처리를 해주어야 함<pre><code class="language-java">pulbic String main2(@RequestParam (required=true) String year) // 안넘어오면 클라이언트 잘못!</code></pre>
</li>
</ul>
</li>
</ul>
<h2 id="1-2-exceptionhandlerexceptionclass">1-2. @ExceptionHandler(Exception.class)</h2>
<ul>
<li>괄호 안에 있는 예외가 발생했을 때 아래 핸들러가 호출이 됨<pre><code class="language-java">@ExceptionHandler(Exception.class)
public String catcher(Exception ex) {
  return &quot;yoilError&quot;;
}</code></pre>
</li>
</ul>
<h2 id="2-modelattribute">2. @ModelAttribute</h2>
<ul>
<li>적용 대상을 <strong>Model의 속성으로 자동 추가</strong>해주는 애너테이션</li>
<li><strong>반환 타입</strong> 또는 <strong>컨트롤러 메서드의 매개변수</strong>에 적용 가능</li>
</ul>
<p>1) 매개변수에 적용한 예제</p>
<pre><code class="language-java">@RequestMapping(&quot;/getYoilMVC5&quot;)
// public String main(@ModelAttribute (&quot;myDate&quot;) MyDate date, Model M) {
public String main(@ModelAttribute MyDate date, Model m) { // 위와 동일!
    char yoil = getYoil(date);

    // m.addModelAttribute(&quot;myDate&quot;, date);
    // -&gt; 이걸 안써줘도 Model에 자동 적재! (@ModelAttribute 어노테이션을 썼으니까!)
    // 첫번째 객체에 소문자로 된 key값으로 적재 &quot;myDate&quot;

    m.addModelAttribute(&quot;yoil&quot;, yoil);

    return &quot;yoil&quot;;
}</code></pre>
<p>2) 반환 타입에 적용한 예제</p>
<ul>
<li>함수의 호출 결과를 모델에 저장! (key : &quot;yoil&quot;, value : return 값)<pre><code class="language-java">private @ModelAttribute(&quot;yoil&quot;) char getYoil(Mydate date) {
  return getYoil(date.getYear(), date.getMonth(), date.getDay());
}</code></pre>
</li>
<li>참조형 매개변수 앞에 ModelAttribute를 붙여서 표현할 수도 있지만 <strong>생략도 가능</strong>함!</li>
</ul>
<p>3) <strong>컨트롤러 매개변수</strong>에 붙을 수 있는 어노테이션</p>
<ul>
<li>@RequestParam : type이 <strong>기본형 / String</strong> 일 때는 생략!
ㄴ 기본형 / String일 때는 모델에 저장할 필요 x (param에서 꺼내쓰면 되니까!)
ㄴ <code>${param.파라미터명}</code></li>
<li>@ModelAttribute : <strong>type이 참조형</strong>일 때는 생략!</li>
</ul>
<h2 id="3-webdatabinder">3. WebDataBinder</h2>
<ul>
<li><p>컨트롤러의 메소드가 선언되어있을 때, 메소드를 호출했을시 메소드의 파라미터를
참조형 객체의 타입에 맞게 1) <strong>타입을 변환</strong>해주고 2) <strong>데이터를 검증</strong>해주는 역할을 수행</p>
</li>
<li><p>브라우저를 통해서 요청받은 값이 실제 객체에 바인딩될 때 중간 역할을 수행</p>
</li>
<li><p>과정
1) 타입 변환시, 결과&amp;오류를 BindingResult에 저장
2) 타입 변환 후, 데이터 검증 (Validation) 결과&amp;오류를 BindingResult에 저장
3) 바인딩 결과를 담아서 컨트롤러에 넘겨주어 컨트롤러가 결과값을 확인
4) 이 때, BindingResult는 Binding할 객체의 바로 뒤에 와야 함
ex) <code>MyDate date, BindingResult result</code></p>
</li>
</ul>
<pre><code class="language-java">    @ExceptionHandler(Exception.class)
    public String catcher(Exception ex, BindingResult result) {
        System.out.println(&quot;result : &quot; + result);
        FieldError error = result.getFieldError();
        // method의 반환값이 field error임

        System.out.println(&quot;code : &quot; + error.getCode());
        System.out.println(&quot;field : &quot; + error.getField());
        System.out.println(&quot;message : &quot; + error.getDefaultMessage());

        ex.printStackTrace();
        return &quot;yoilError&quot;;
    }</code></pre>
<h2 id="4-실습">4. 실습</h2>
<ul>
<li><p>설정파일 경로 : src/main/WEB-INF/spring
1) root-context.xml : non-web 관련 설정파일
2) servlet-context.xml : web 관련 설정파일</p>
</li>
<li><p>ascii가 아닌 것들은 URL인코딩 된 값이 넘어가짐</p>
</li>
</ul>
<h2 id="5-jstl-문법">5. JSTL 문법</h2>
<ul>
<li><code>&lt;c:url&gt;</code>
1) context root 자동 추가
2) session id 자동 추가</li>
<li><code>action=&quot;&lt;c:url value=&quot;/register/save&quot;/&gt;&quot;</code>
=&gt; 이렇게 쓰면 컨택스트 루트 안써도 됨 (&#39;/ch2/&#39; 생략가능)</li>
</ul>
<h2 id="6-getmapping--postmapping">6. GetMapping / PostMapping</h2>
<ul>
<li>servlet-context.xml
<code>&lt;view-controller path=&quot;/register/add&quot; view-name=&quot;registerForm&quot; /&gt;</code></li>
<li>jsp 페이지 - URL 간의 화면연결을 도움</li>
<li>접두어 생략 가능한 경우 (MVC일 경우~)</li>
</ul>
<p>1) @RequestMapping</p>
<ul>
<li><code>@RequestMapping(&quot;/register&quot;)</code></li>
<li>맵핑될 URL의 공통 부분을 @RequestMapping으로 클래스에 적용</li>
</ul>
<p>2) @GetMapping</p>
<ul>
<li><code>@GetMapping(&quot;/add&quot;)</code></li>
</ul>
<p>3) @PostMapping</p>
<ul>
<li><p><code>@PostMapping(&quot;/add&quot;)</code></p>
</li>
<li><p>메소드가 다르면 충돌이 안남, 요청이 메소드로 구분되기 때문!</p>
</li>
</ul>
<p>4) @RequestMappnig의 URL패턴</p>
<ul>
<li><code>?</code>는 한 글자, <code>*</code>는 여러 글자, <code>**</code>는 하위 경로 포함
ex) <code>/login/*</code> (경로 맵핑), <code>*.do</code> (확장자 맵핑)</li>
</ul>
<h2 id="7-url인코딩---퍼센트-인코딩">7. URL인코딩 - 퍼센트 인코딩</h2>
<ul>
<li>URL에 포함된 <strong>non-ASCII문자</strong>를 문자 코드(16진수) 문자열로 변환
-&gt; 문자를 숫자로!
ex)
남궁성 URLEncoder.encode() -&gt; &quot;%EB%82%A8%&quot;</li>
<li>URL인코딩 =/= Base64 : 6bit씩 끊어서 A-Z, a-z 문자들로 변환!</li>
<li>Base64 : 바이너리 데이터를 Text로 변환!</li>
<li>URL인코딩 : 브라우저가 자동으로 인코딩해서 서버가 받음</li>
<li><blockquote>
<p>서버가 받은 URL을 디코딩해줌 (UTF-8)</p>
</blockquote>
</li>
</ul>
<h2 id="8-dofilterinternel">8. doFilterInternel</h2>
<ul>
<li>in pom.xml<pre><code class="language-java">request.setCharacterEncoding(encoding);
</code></pre>
</li>
</ul>
<p>filterChain.doFilter(request, response);
// -&gt; DispatcherServlet으로 보내기 전에 전처리 작업
// 필터가 하는 일 : DS로 가기 전 응답 - 요청을 거치는 구간!</p>
<pre><code>
- .m2 : repository 한꺼번에 날리고 리프레쉬! (메이븐 업데이트 / 꼬였을 때 이거 삭제하면 됨)
</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[서블릿과 JSP (1)]]></title>
            <link>https://velog.io/@soulee__/%EC%84%9C%EB%B8%94%EB%A6%BF%EA%B3%BC-JSP-1</link>
            <guid>https://velog.io/@soulee__/%EC%84%9C%EB%B8%94%EB%A6%BF%EA%B3%BC-JSP-1</guid>
            <pubDate>Wed, 18 Jan 2023 14:44:20 GMT</pubDate>
            <description><![CDATA[<h1 id="서블릿과-jsp">서블릿과 JSP</h1>
<ul>
<li>서블릿을 발전시킨게 Spring!</li>
<li>DispatcherServlet = spring</li>
</ul>
<h2 id="1-서블릿과-컨트롤러-비교">1. 서블릿과 컨트롤러 비교</h2>
<pre><code class="language-java">package com.fastcampus.ch2;

import java.io.*;

import javax.servlet.annotation.WebServlet;
import javax.servlet.http.*;

@WebServlet(&quot;/rollDice2&quot;)
// 1. @Controller + @RequestMapping 합친거랑 동일한 효과!
public class TwoDiceServlet extends HttpServlet {
    // 2. HttpServlet을 상속 받아야함! (java는 단일상속!)
    public void service(HttpServletRequest request, HttpServletResponse response) throws IOException {
        // 3. service 메소드로 변경! (기존은 main) 고정메소드
        int idx1 = (int) (Math.random() * 6) + 1;
        int idx2 = (int) (Math.random() * 6) + 2;

        response.setContentType(&quot;text/html&quot;);
        response.setCharacterEncoding(&quot;utf-8&quot;);

        PrintWriter out = response.getWriter();
        out.println(&quot;&lt;html&gt;&quot;);
        out.println(&quot;&lt;head&gt;&quot;);
        out.println(&quot;&lt;/head&gt;&quot;);
        out.println(&quot;&lt;body&gt;&quot;);
        out.println(&quot;&lt;h1&gt;안녕하세요?&lt;/h1&gt;&quot;);
        out.println(&quot;&lt;/body&gt;&quot;);
        out.println(&quot;&lt;/html&gt;&quot;);
    }
}</code></pre>
<h3 id="차이점">차이점</h3>
<ol>
<li>상속을 안받음</li>
<li>매개변수도 필요한것만 받음</li>
<li>어노테이션도 나눠서 처리!
4-1. webservlet은 매핑을 클래스 하나 당으로 처리하기 땨문에 매핑 하나 당 클래스를 만들어야 함
4-2. 컨트롤러는 메소드에다가 매핑을 해서 하나의 클래스에 새로운 메소드를 만들기만 하면 가능!</li>
</ol>
<h2 id="2-서블릿의-생명주기">2. 서블릿의 생명주기</h2>
<pre><code class="language-java">package com.fastcampus.ch2;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet(&quot;/hello&quot;)
public class HelloServlet extends HttpServlet {
    public void init() throws ServletException {
        // 서블릿 초기화 - 서블릿이 생성 또는 리로딩 때, 단 한번만 수행됨.
        System.out.println(&quot;[HelloServlet] init()&quot;);
    }

    @Override // 호출될 때 마다 반복적으로 수행됨.
    public void service(HttpServletRequest request, HttpServletResponse response) {
//        1. 입력
//        2. 처리
//        3. 출력
        System.out.println(&quot;[HelloServlet] service()&quot;);
    }

    public void destroy() {
        // 뒷 정리 작업 - 서블릿이 메모리상에서 제거(unload)될 때, 단 한번만 수행됨
        System.out.println(&quot;[HelloServlet] destroy()&quot;);
    }
}
</code></pre>
<h2 id="2-생명주기-관리">2. 생명주기 관리</h2>
<h3 id="servletcontainer">ServletContainer</h3>
<ul>
<li>이런 메소드들은 서블릿 컨테이너가 자동으로 호출하며, 서블릿을 만들 때
메소드의 내용만 채워주면 됨.</li>
</ul>
<h3 id="생명주기">생명주기</h3>
<p>[Servlet Context]</p>
<ol>
<li>요청 → 서블릿 인스턴스 존재? (children을 보고 확인)
1-1. (Yes) service() 메소드 실행
1-2. (No) 서블릿 클래스 로딩 &amp; 인스턴스 생성 → init() 메소드 실행 후 service() 메소드 제공</li>
<li>프로그램 변경, 웹 App이 종료돼서 Servlet이 메모리에 변경될 때 Destroy() 호출!</li>
</ol>
<p>[Servlet Context &gt; children]</p>
<ul>
<li>서블릿의 정보가 Map 형태로 구성되어 있음</li>
<li>Key : 서블릿 이름</li>
<li>Value : 서블릿</li>
</ul>
<h3 id="서블릿">서블릿</h3>
<ol>
<li>Single Tone 형태 (요청하는 사람마다 동일한 작업을 수행!)<ul>
<li>사용자마다 다른 일을 할 필요가 없음</li>
</ul>
</li>
<li>한 개의 인스턴스만 만들고 재활용함</li>
</ol>
<h2 id="3-jsp란">3. JSP란?</h2>
<ul>
<li><p>JSP : Java Server Pages = servlet (변환됨) / html 안에 java 코드가 있는 것</p>
<pre><code class="language-html">// in jsp 값 출력할 때
&lt;img src=&#39;resource/img/dice&lt;%=idx1%&gt;.jpg&#39;&gt;</code></pre>
<pre><code class="language-html">&lt;%@ page language=&quot;java&quot; contentType=&quot;text/html; charset=EUC-KR&quot;
  pageEncoding=&quot;utf-8&quot;%&gt;
&lt;%@ page import=&quot;java.util.Random&quot; %&gt;
&lt;!-- 클래스 영역 --&gt;
&lt;%!
  int getRandomInt(int range) {
      return new Random().nextInt(range)+1;
  }
%&gt;
&lt;!-- 메서드 영역 - service()의 내부 --&gt;
&lt;%
  int idx1 = getRandomInt(6);
  int idx2 = getRandomInt(6);
%&gt;
&lt;!DOCTYPE html&gt;
&lt;html&gt;
&lt;head&gt;
&lt;meta charset=&quot;EUC-KR&quot;&gt;
&lt;title&gt;twoDice.jsp&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
  &lt;img src=&#39;resource/img/dice&lt;%=idx1%&gt;.jpg&#39;&gt;
  &lt;img src=&#39;resource/img/dice&lt;%=idx2%&gt;.jpg&#39;&gt;
&lt;/body&gt;
&lt;/html&gt;</code></pre>
</li>
<li><blockquote>
<p>아래 메서드 영역부분이 다 webServlet의 service 메서드 안에 들어감</p>
</blockquote>
</li>
<li><p><code>&lt;%</code>와 <code>&lt;%!</code>의 차이</p>
<ol>
<li><code>&lt;%</code> : 지역 변수</li>
<li><code>&lt;%!</code> : 인스턴스 변수, 상수 선언 -&gt; 서비스 메서드가 아닌 클래스 안에 들어감</li>
</ol>
</li>
<li><p><code>.jsp</code> 파일의 경로
  : src/main/webApp/ ...</p>
</li>
</ul>
<h2 id="4-jsp의-호출-과정">4. JSP의 호출 과정</h2>
<h3 id="절차">절차</h3>
<ol>
<li>*.jsp 요청 → JspServlet
(서블릿 인스턴스 존재?)
1-1. (Yes) 서블릿 인스턴스 _jspService()
1-2. (No) .jsp → servlet으로 변환 &amp; 서블릿 소스파일 컴파일 → 서블릿 클래스 파일 → 인스턴스 생성 _jspInit() (초기화) → 서블릿 인스턴스 _jspService()</li>
</ol>
<p>-&gt; 처음 호출할 때는 시간 지연이 있음
2. 서블릿 인스턴스가 응답! (서비스 메서드가 응답)
3. *.jsp 변경시 변환과정 동일하게 진행</p>
<h3 id="특징">특징</h3>
<ol>
<li>초기화</li>
</ol>
<ul>
<li>서블릿 : lazy-init (지연된 초기화)</li>
<li>Spring : early-init (미리 초기화)</li>
</ul>
<ol start="2">
<li>동일한 Single Tone 형태</li>
</ol>
<h2 id="5-jsp의-기본-객체">5. JSP의 기본 객체</h2>
<ul>
<li>생성없이 사용할 수 있는 객체
<code>request</code>, <code>response</code>, <code>session</code>, <code>pageContext</code>, <code>out</code></li>
<li><blockquote>
<p>jsp가 servlet으로 객체되니까 생성없이 호출할 수 있음 (service 메서드의 로컬 변수 형태로!)</p>
</blockquote>
</li>
</ul>
<hr>

<h2 id="6-유효-범위scope와-속성attribute">6. 유효 범위(scope)와 속성(attribute)</h2>
<h3 id="http-특징">HTTP 특징</h3>
<ul>
<li>(stateless) 상태 정보를 저장하지 않는다 &lt;-&gt; stateful : 상태 정보 저장 O
  -&gt; 따라서, 4개 저장소 (map형태) 운영 (1) 접근 범위 (2) 생존 기간</li>
</ul>
<h3 id="4개-저장소-특징">4개 저장소 특징</h3>
<ol>
<li>pageContext<ul>
<li>목적 : 지역변수, 기본 객체 (request, response, out, session) 저장</li>
<li>범위 : login.jsp (해당 페이지 안에서만 접근 가능) =&gt; R/W 가능</li>
<li>예시 : <code>${idx1}</code></li>
<li>특징<ol>
<li>EL (${}) 에서는 지역 변수에 직접 접근이 불가능함. EL에서 쓰려면 해당 저장소에 먼저 저장을 해야 함. =&gt; 따라서, 같은 페이지 안이지만 읽고 쓰기가 가능하기 위해서 해당 저장소를 이용</li>
<li>요청할 때 마다 새로 초기화</li>
</ol>
</li>
</ul>
</li>
<li>application (전체)<ul>
<li>목적 : 공용 저장소</li>
<li>범위 : WebApp 전체에서 접근가능한 저장소 (전체 딱 하나!) map 형태로 저장</li>
<li>메소드 1) 쓰기(저장) : setAttribute() // key = 속성 (attribute)<pre><code>  2) 읽기(조회) : getAttribute()</code></pre></li>
<li>특징<ol>
<li>전체 App에서 공용으로 쓰기 때문에, 개별 페이지 속성을 구분하기에는 좋은 저장소가 아님  </li>
<li>web app 시작부터 종료까지 context 내부 어디서나 접근 가능</li>
<li>모든 클라이언트가 공유!</li>
<li>context마다 1개</li>
</ol>
</li>
</ul>
</li>
<li>session (개별 / ★ 가장 편리하지만, <strong>메모리 부담</strong>이 큼)<ul>
<li>목적 : 개별 저장소 (클라이언트 1:1)</li>
<li>용도 : id, 장바구니 등 사용자 개별 저장소!</li>
<li>특징 1) 사용자마다 하나씩 있는 개별 저장소 * 사용자 수, 최소한의 데이터만 저장!<pre><code>  2) 서버 부담이 제일 큼!</code></pre></li>
</ul>
</li>
<li>request 저장소 (★ 가장 부담이 적음 / 요청이 처리되는 동안에만 유지)<ul>
<li>목적 : 하나의 요청마다 생김</li>
<li>특징 : a.jsp 거쳐서 b.jsp에 접근해야 될때도 사용 (forward)</li>
</ul>
</li>
</ol>
<h3 id="속성-관련-메서드">속성 관련 메서드</h3>
<ol>
<li>setAttribute() : 지정된 값을 지정된 속성 이름(name)으로 저장 (쓰기)</li>
<li>getAttribute() : 지정된 이름으로 저장된 속성의 값을 반환 (읽기)</li>
<li>removeAttribute() : 지정된 이름의 속성을 삭제</li>
<li>getAttributeNames() : 기본 객체에 저장된 모든 속성의 이름을 반환</li>
</ol>
<h2 id="7-url-패턴">7. URL 패턴</h2>
<ul>
<li>webServlet으로 서블릿을 URL에 맵핑할 때 사용!</li>
<li>loadOnStartup=1 (미리 초기화 / 우선순위)<ul>
<li>servlet : lazy-init (늦은 초기화)</li>
</ul>
</li>
</ul>
<ol>
<li>exact mapping : 정확히 매칭 (<code>/login/hello.do</code>)</li>
<li>path mapping : 경로 매핑 (<code>/login/*</code>)</li>
<li>extension mapping : 확장자 매핑 (<code>*.do</code>) ex) .../hi.do</li>
<li>default mapping : 모든 주소에 매핑됨</li>
</ol>
<h3 id="servletmappings">servletMappings</h3>
<p>[절차]</p>
<ol>
<li>요청이 들어오면, key값을 확인</li>
<li>key값이 존재하면 해당 value가 children(서블릿) key값에 존재하는지 확인</li>
<li>value (StandardWrapper) 메모리 값에 따라 서비스를 찾음</li>
</ol>
<p>ex) /hello, *.jsp = 동적 리소스 (서블릿) / / = 정적 리소스 (default)
=&gt; 요청에 해당하는 서블릿이 없으면 다 dispatcherServlet이 받음!</p>
<p>== 스프링의 경우 jsp, servlet이 없으니까 모~든 요청을 다 dispatcherServlet이 받음!
&amp; dispatcherServlet 내부에 이런 매핑을 다 가지고 있음 (@RequestMapping)</p>
<h2 id="8-el-expression-language">8. EL (Expression Language)</h2>
<ul>
<li><code>&lt;%=값%&gt;</code> =&gt; <code>${값}</code></li>
<li>empty는 null / 빈 컬렉션 배열 일때는 true 반환!</li>
</ul>
<h2 id="9-jstl-jsp-standard-tag-library">9. JSTL (JSP Standard Tag Library)</h2>
<ul>
<li>&lt;% ~ %&gt; : 이런걸 다 없애려고 나옴 (jstl)
<code>&lt;c:set&gt;</code>,<code>&lt;c:if&gt;</code>,<code>&lt;c:forEach&gt;</code></li>
<li><code>&lt;c:set&gt;</code> : el값이 지역 변수를 사용하지 못하니까 저장소에 저장하기 위해서 고안
=&gt; scope = &quot;page&quot;</li>
</ul>
<h2 id="10-filter">10. Filter</h2>
<ul>
<li>공통적인 요청 전처리와 응답 후처리에 사용 ex) 로깅, 인코딩 (변환) 등</li>
<li>서블릿은 처리 부분만 담당!</li>
<li>필터가 여러 개일 수 있음! filter1 → filter2 -&gt; 서블릿 -&gt; filter2 (후처리) -&gt; filter1</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[관심사의 분리와 MVC패턴]]></title>
            <link>https://velog.io/@soulee__/%EA%B4%80%EC%8B%AC%EC%82%AC%EC%9D%98-%EB%B6%84%EB%A6%AC%EC%99%80-MVC%ED%8C%A8%ED%84%B4</link>
            <guid>https://velog.io/@soulee__/%EA%B4%80%EC%8B%AC%EC%82%AC%EC%9D%98-%EB%B6%84%EB%A6%AC%EC%99%80-MVC%ED%8C%A8%ED%84%B4</guid>
            <pubDate>Wed, 18 Jan 2023 05:29:59 GMT</pubDate>
            <description><![CDATA[<h1 id="관심사의-분리-mvc패턴---이론">관심사의 분리, MVC패턴 - 이론</h1>
<h2 id="1-관심사의-분리-speration-of-concerns">1. 관심사의 분리 Speration of Concerns</h2>
<ul>
<li>관심사? : 입력, 처리 출력 세 부분으로 구성된 코드를 의미 
(우리가 관심을 갖고 해야 할 작업)</li>
<li>OOP 5대 설계 원칙 (SOLID)
1) Speration : 단일 책임 원칙<ul>
<li>하나의 메소드는 하나의 책임(= 관심사)만 진다</li>
<li>3개의 관심사를 분리해야 함.
2) 분리</li>
<li><strong>관심사의 분리</strong></li>
<li><strong>변하는 것, 자주 변하지 않는 것</strong>의 분리 (common, uncommon)</li>
<li><strong>공통코드</strong>의 분리 (중복코드)</li>
</ul>
</li>
</ul>
<h2 id="2-공통-코드의-분리">2. 공통 코드의 분리</h2>
<h3 id="--입력의-분리">- 입력의 분리</h3>
<ul>
<li>Controller의 구성<ol>
<li>입력 : request.getParameter()</li>
<li>처리</li>
<li>출력
=&gt; (입력만 따로 분리)</li>
<li>입력 -&gt; 2. 처리 / 3. 출력 (개별 매개변수로 직접 받게 설계!)</li>
</ol>
</li>
<li><blockquote>
<ol start="2">
<li>처리 / 3. 출력
-&gt; 2. 처리 / 3. 출력</li>
</ol>
</blockquote>
</li>
</ul>
<h2 id="3-출력view의-분리">3. 출력(View)의 분리</h2>
<h3 id="--변하는-것과-변하지-않는-것의-분리">- 변하는 것과 변하지 않는 것의 분리</h3>
<ul>
<li>MODEL 객체(중간 객체)를 만들어놓고, 결과를 출력하는데 필요한 값들을 다 저장!</li>
<li>MVC 패턴
  1) Controller : 처리
  2) View : 결과를 출력하는데 보여주는 부분
  3) Model : 필요한 값을 저장 (C - V 간의 데이터 전달을 위함)</li>
<li>MVC 패턴 처리 방식
  1) 입력 (Dispatcher servlet이 처리) &amp; 변환 &amp; 모델 생성 // new Model();
  2) Controller가 처리 결과를 Model에 저장해서 다시 전달 
  &amp; model객체에 key - value 형식으로!
  &amp; 작업 결과를 보여줄 View의 이름을 변환!<pre><code class="language-java">  return &quot;yoil&quot; // WEB-INF/views/yoil.jsp</code></pre>
  3) Dispatcher servlet가 출력(View)에 전달~ (응답을 만들어내서 클라이언트에 전송!)<pre><code class="language-html">  &lt;h1&gt;${year}년 ${month}&lt;/h1&gt;</code></pre>
</li>
</ul>
<h2 id="4-실습">4. 실습</h2>
<ul>
<li>EL (Expression Language)</li>
</ul>
<h2 id="5-modelandview">5. ModelAndView</h2>
<ul>
<li>매개변수에 model을 선언하지 않으면, ModelAndView 객체를 직접 생성 &amp; 결과지정 &amp; 뷰지정 &amp; mv 반환하는 과정을 거침 =&gt; DispatcherServlet이 view에 model을 전달!</li>
</ul>
<h2 id="6-컨트롤러-메서드의-반환타입">6. 컨트롤러 메서드의 반환타입</h2>
<ul>
<li>[String] : 뷰 이름을 반환<ul>
<li>return &quot;yoil&quot;</li>
</ul>
</li>
<li>[Void] : 맵핑된 url의 끝단어가 뷰 이름<ul>
<li>@RequestMapping(&quot;/yoil&quot;)</li>
</ul>
</li>
<li>[ModelAndView] : Model과 뷰 이름을 반환<ul>
<li>ModelAndView mv = new ModelAndView();</li>
<li>mv.setViewName(&quot;yoil&quot;);</li>
<li>return mv;</li>
</ul>
</li>
</ul>
<hr>
```java
StringJoiner paramList = new StringJoiner(", ", "(", ")");
            // 구분자, 접두사, 접미사
```

<h1 id="관심사의-분리-mvc패턴---원리1">관심사의 분리, MVC패턴 - 원리(1)</h1>
<h2 id="1-매개변수의-이름-얻어오는-법">1. 매개변수의 이름 얻어오는 법</h2>
<p>1) Reflection API (-parameters 옵션 / jdk1.8 ↑ 이상부터 가능!)
2) Class file을 직접 읽는 방법</p>
<ul>
<li>1번을 시도하고 2번 방법을 시도~</li>
</ul>
<h2 id="2">2.</h2>
<pre><code class="language-java">mc.main {
      hashMap[0x100]
  main() {
      hashMap[0x100]
  }
}</code></pre>
<h1 id="관심사의-분리-mvc패턴---원리2">관심사의 분리, MVC패턴 - 원리(2)</h1>
<ul>
<li>Parameter 가져오는 방식<pre><code class="language-java">Parameter[] paramArr = main.getParameter();
Object[] argArr = new Object[main.getParameterCount()];
</code></pre>
</li>
</ul>
<p>for (int i=0; i&lt;paramArr.length; i++) {
    String paramName = paramArr[i].getName();
    Class paramType = paramArr[i].getType();
    Object value = map.get(paramName);</p>
<pre><code>if (paramType == Model.class) {
    argArr[i] = model = new BindingAwareModelMap();
} else if(paramType == HttpServeletRequest.class) {
    argArr[i] = request;
} else if(paramType == HttpServeletResponse.class) {
    argArr[i] = response;
} else if(value != null) {
    String strValue = ((String[])value)[0];
    // 실제로 value는 String[] 형태로 넘어와서, 해당 배열의 첫번째껄 꺼내서 가져옴!
    argArr[i] = convertTo(strValue, paramType);
}</code></pre><p>}</p>
<pre><code>
- 렌더링하는 방식
```java
privaite void render(Model model, String viewName, HttpServletResponse response) throws IOException {
    response.setContentType(&quot;text/html&quot;);
    response.setCharacterEncoding(&quot;utf-8&quot;);
    PrinterWriter out = reponse.getWriter();

    ...

    out.println(result);
}</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[HTTP 요청과 응답]]></title>
            <link>https://velog.io/@soulee__/HTTP-%EC%9A%94%EC%B2%AD%EA%B3%BC-%EC%9D%91%EB%8B%B5</link>
            <guid>https://velog.io/@soulee__/HTTP-%EC%9A%94%EC%B2%AD%EA%B3%BC-%EC%9D%91%EB%8B%B5</guid>
            <pubDate>Sun, 08 Jan 2023 15:05:28 GMT</pubDate>
            <description><![CDATA[<h2 id="1-프로토콜-protocol">1. 프로토콜 (Protocol)</h2>
<ul>
<li>서로 간의 통신을 위한 약속 규칙 / <strong>주고 받을 데이터에 대한 형식</strong>을 정의</li>
</ul>
<h3 id="1-http-hyper-text-transfer-protocol">1) HTTP (Hyper Text Transfer Protocol)</h3>
<ol>
<li>텍스트(html) 기반의 프로토콜</li>
<li>상태를 유지하지 않음 (stateless) =&gt; 클라이언트 정보를 저장 X, 요청을 구분할 수 없음</li>
</ol>
<ul>
<li>이를 보완하고자 쿠키 &amp; 세션을 이용해서 사용자를 구분</li>
</ul>
<ol start="3">
<li>확장 가능 =&gt; 커스텀 헤더 추가 가능
ex) HTTP 응답 메세지</li>
</ol>
<ul>
<li>헤더 = 헤더 이름 : 값 (Content-Length : 1024) =&gt; 대소문자 구분 X
=&gt; 표준에 정해놓지 않은 헤더들을 사용할 수 있음!</li>
</ul>
<h2 id="2-http-메세지-요청---응답-편지">2. HTTP 메세지 (요청 - 응답 편지)</h2>
<h3 id="1-http-메세지---응답-메세지-형식-구성요소">1) HTTP 메세지 - 응답 메세지 형식 (구성요소)</h3>
<h4 id="1-상태코드-상태라인--요청라인">(1) 상태코드 (상태라인) // 요청라인</h4>
<ul>
<li>1xx : Informational =&gt; HTTP/1.1 때 추가 (정보교환의 의미)</li>
<li>2xx : Success</li>
<li>3xx : Redirect (다른 URL로 재요청하라는 의미)</li>
<li>4xx : <strong>Client</strong> Error</li>
<li>5xx : <strong>Server</strong> Error
→ 요청 OK, 서버처리 中 에러</li>
</ul>
<h4 id="2-헤더">(2) 헤더</h4>
<h4 id="3-바디-실제-응답-내용">(3) 바디 (실제 응답 내용)</h4>
<h3 id="2-http-메세지---요청-메세지">2) HTTP 메세지 - 요청 메세지</h3>
<h4 id="--요청-method">- 요청 Method</h4>
<h4 id="1-get">(1) GET</h4>
<ul>
<li><strong>리소스를 가져오기 위함</strong> (read)</li>
<li>대신 데이터를 보낼게 있으면 쿼리스트링 형태(소용량)로 보낼 수 있음
=&gt; But. URL에 데이터 노출되므로 보안에 취약!</li>
<li><strong>데이터 공유</strong>에 유리</li>
<li>body X<h4 id="2-post">(2) POST</h4>
</li>
<li>서버에 정보를 제공해줄 때 사용!</li>
<li>body를 통해서 서버에 전송할 data를 body에 담아서 전달 (대용량)
(write / login / join / 파일 첨부)</li>
<li>body O</li>
<li>HTTPS를 통해 전달 (HTTP + TLS / 암호화) =&gt; TLS 프로토콜을 써서 보안에 유리!</li>
<li><code>&lt;form&gt;</code> 태그를 써야되는데 귀찮아서.. postman 사용할거</li>
</ul>
<hr>

<h2 id="3-http-요청과-응답">3. HTTP 요청과 응답</h2>
<h3 id="1-텍스트-파일-vs-바이너리-파일">1) 텍스트 파일 VS 바이너리 파일</h3>
<ul>
<li>바이너리 파일 : <strong>문자 / 숫자</strong> (image) (데이터를 있는 그대로 읽고 씀)</li>
<li>텍스트 : <strong>문자</strong>만 (숫자를 문자로 변환 후 씀)
ex) 숫자 : 12 (int 4byte), 12.625f (float 4byte)
=&gt; 문자 : &#39;1&#39;,&#39;2&#39; / &#39;1&#39;,&#39;2&#39;,&#39;.&#39;,&#39;6&#39;,&#39;2&#39;,&#39;5&#39;</li>
</ul>
<h3 id="2-mime-multipurpose-internet-mail-extensions">2) MIME (Multipurpose Internet Mail Extensions)</h3>
<ul>
<li><strong>텍스트 기반 프로토콜</strong>에 <strong>바이너리 데이터 전송</strong>하기 위해 고안</li>
<li>HTTP의 <strong>Content-Type 헤더</strong>에 사용. <strong>데이터 타입을 명시</strong></li>
</ul>
<p>ex) text = text/plain, text/html
image = image/bmp
...
=&gt; 바이너리인지 텍스트인지 구분하기 위해서 어떤 타입을 보낼건지 정확히 보냄!</p>
<pre><code class="language-text">Preview Limitations
POST /ch2/getYoil HTTP/1.1
Host: localhost:8080
Cache-Control: no-cache

----WebKitFormBoundaryE19zNvXGzXaLvS5C
Content-Disposition: form-data; name=&quot;year&quot;

2023
----WebKitFormBoundaryE19zNvXGzXaLvS5C
Content-Disposition: form-data; name=&quot;img file&quot;; filename=&quot;그림1.png&quot;
Content-Type: image/png


----WebKitFormBoundaryE19zNvXGzXaLvS5C</code></pre>
<h3 id="3-base64-인코딩">3) Base64 인코딩</h3>
<ul>
<li>바이너리 데이터를 <strong>텍스트 데이터로 변환</strong>할 때 사용</li>
<li>64진법은 &#39;0&#39; ~ &#39;9&#39;, &#39;A&#39; ~ &#39;Z&#39;, &#39;a&#39; ~ &#39;z&#39;, &#39;+&#39;, &#39;/&#39; 모두 64개의 문자로 구성</li>
<li>2^6 = 6bit
=&gt; 빈자리는 padding!</li>
<li>16진수 = 2^4 = 4bit씩!</li>
<li>ASCII = 128개 = 2^7 = 7bit (특수문자)</li>
<li>UTF-8 : 영문자, 숫자가 1byte<pre><code class="language-html">&lt;img src=&quot;data:image/jpeg;base64,[img를 base64로 인코딩한 값]&quot;&gt;</code></pre>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[톰캣 설정 파일 server.xml, web.xml]]></title>
            <link>https://velog.io/@soulee__/%ED%86%B0%EC%BA%A3-%EC%84%A4%EC%A0%95-%ED%8C%8C%EC%9D%BC-server.xml-web.xml</link>
            <guid>https://velog.io/@soulee__/%ED%86%B0%EC%BA%A3-%EC%84%A4%EC%A0%95-%ED%8C%8C%EC%9D%BC-server.xml-web.xml</guid>
            <pubDate>Thu, 05 Jan 2023 14:12:20 GMT</pubDate>
            <description><![CDATA[<h2 id="1-tomcat의-설정-파일">1. Tomcat의 설정 파일</h2>
<ul>
<li>.../conf/server.xml : Tomcat 서버 설정 파일</li>
<li>.../conf/web.xml : Tomcat의 모든 web app의 공통 설정</li>
<li>.../WEB-INF/web.xml : web app의 개별 설정</li>
</ul>
<h2 id="2-sts---server">2. (sts) - Server</h2>
<ol>
<li>server.xml
1) 이 파일들은 conf 폴더에 있는 설정 파일의 복사본
2) 하나의 Tomcat 프로그램을 공유하면서 설정만 다른 여러 서버를 등록가능</li>
<li>Engine : 여러 Host 포함 가능, 그 중에서 어떤 Host를 default로 할 것인지 지정 O</li>
<li>web.xml
1) Servers/Tomcat/web.xml</li>
</ol>
<ul>
<li>모든 webapp 공통 설정
2) ch2/Tomcat/web.xml</li>
<li>프로젝트 개별 설정</li>
</ul>
<h2 id="3-원격프로그램-등록-방법-공통-webxml">3. 원격프로그램 등록 방법 (공통 web.xml)</h2>
<ol>
<li>서블릿 등록 =&gt; @Controllter</li>
<li>url 연결 =&gt; @RequestMapping</li>
</ol>
<h2 id="4-webxml-개별설정">4. web.xml 개별설정</h2>
<ul>
<li>context</li>
<li>listener</li>
<li>@Controller</li>
<li>@RequestMapping</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[HTTP 요청과 응답 - 실습]]></title>
            <link>https://velog.io/@soulee__/HTTP-%EC%9A%94%EC%B2%AD%EA%B3%BC-%EC%9D%91%EB%8B%B5-%EC%8B%A4%EC%8A%B5</link>
            <guid>https://velog.io/@soulee__/HTTP-%EC%9A%94%EC%B2%AD%EA%B3%BC-%EC%9D%91%EB%8B%B5-%EC%8B%A4%EC%8A%B5</guid>
            <pubDate>Thu, 05 Jan 2023 13:30:09 GMT</pubDate>
            <description><![CDATA[<h2 id="1-http-요청-작동-원리">1. HTTP 요청 작동 원리</h2>
<p>1) 원격 프로그램을 브라우저로 url을 입력해서 호출하면
   톰캣이 HttpServletRequest 객체를 만듦</p>
<p>2) 요청한 정보를 해당 객체에 담음</p>
<p>3) 해당 객체를 main 메소드 매개변수로 넘겨줌
   <code>public void main(HttpServletRequest request)</code>
   =&gt; 톰캣이 해당 객체를 만들고 요청 정보를 담아서 매개변수로 전달해줌
   =&gt; java YoilTeller [매개변수1, 매개변수2, ...]</p>
<p>   ※ 메소드의 매개변수는 원하는대로 적을 수 있고 스프링이 알아서 적어줌
   ※ 스프링에 필요한 것만 매개변수로 적어주면 매개변수에 해당하는 객체, 값을 보내줌!</p>
<p>4) request 객체를 이용해서 요청 url 정보를 얻음 </p>
<h2 id="2-httpservletrequest의-메서드">2. HttpServletRequest의 메서드</h2>
<p><img src="https://velog.velcdn.com/images/soulee__/post/766017a8-f316-4c63-a8a0-28e30e07d593/image.png" alt=""></p>
<p>1) <code>http</code> : getScheme()
2) <code>52.78.190</code> : getServerName()
3) <code>:8080</code> : getServerPort()
4) <code>/ch2</code> : getContextPath()
5) <code>/requestInfo</code> : getServletPath()</p>
<ul>
<li>1 ~ 5) : getRequestURL()</li>
<li>4 ~ 5) : getRequestURI()
6) <code>?year=2021&amp;month=10&amp;day=1</code> : getQueryString() = 추가 데이터</li>
<li>쿼리스트링 : 값을 전달할 때 사용 (&amp; 표시를 구분해서 name=value 형태로 값을 보냄)
ex) ?year=2021 // String year = request.getParameter(&quot;year&quot;)</li>
</ul>
<p>cf) </p>
<p>1) Enumeration enum = request.getParameterNames();
   // Enumeration (old) == Iterator (new)
2) Map paramMap = request.getParameterMap();
   // 쿼리스트링을 key - value 형태의 Map으로 반환해줌
3) String[] yearArr = request.getParameterValues(&quot;year&quot;); 
   // name의 이름이 같을 경우!</p>
<h2 id="3-클라이언트와-서버">3. 클라이언트와 서버</h2>
<p>(역할에 따른 구분)</p>
<ul>
<li>클라이언트 : 서비스를 <strong>요청</strong>하는 App</li>
<li>서버 : 서비스를 <strong>제공</strong>하는 App</li>
<li>프로그램을 실행 
-&gt; 결과가 <html> 형태의 문서로 return됨 (Text문서 문자열)
-&gt; 브라우저에게 전달해주면 브라우저가 html 태그를 요소별로 구조화해서 보여줌
-&gt; out.println() 으로 출력!</li>
</ul>
<h2 id="4-서버의-종류">4. 서버의 종류</h2>
<ul>
<li><p>종류 : 어떤 서비스를 제공하느냐에 따라서 달라짐.</p>
<p>1) Email Server
2) File Server
3) Web Server (80 // 생략가능) : 브라우저를 통해 받을 수 있는 모든 서비스를 제공!</p>
<ul>
<li>한 대의 PC에 서버가 여러 개면 어떤 서버를 제공할지 알 수 없음
따라서, port번호를 같이 써줘야 함 (ip = 대표 전화번호 / port = 내선번호 // 서버와 바인딩되어있음 [listening])</li>
<li>well-known port : 0 ~ 1023 / 그 외 ~ 65535까지 사용 가능!</li>
</ul>
</li>
</ul>
<h2 id="5-웹-애플리케이션-서버was">5. 웹 애플리케이션 서버(WAS)</h2>
<ul>
<li>정의 : 웹을 서비스하는 서버 (프로그램을 서비스!)
= 서버에 프로그램을 설치해놓고 클라이언트가 해당 프로그램을 사용할 수 있게 하는 것!
= 만든 프로그램을 원격으로 제공할 수 있게 함
(과거엔 클라이언트에 프로그램을 설치했었음 = 업데이트 문제 존재)</li>
</ul>
<h2 id="6-tomcat의-내부-구조">6. Tomcat의 내부 구조</h2>
<ul>
<li>클라이언트가 브라우저를 통해 요청을 보내면 Server(Tomcat)에서 대기 중인 스레드 풀에서 응답을 접수.<ul>
<li>server <ul>
<li>service </li>
<li>Connector (HTTP1.1, HTTP2, AJP) </li>
<li>Engine(Catalina) <ul>
<li>Host (도메인네임이 다른 n개 호스트 가능 / <a href="http://www.fastcampus.co.kr">www.fastcampus.co.kr</a> ...) </li>
<li>Context(/event, 하나의 Web App로써 별도의 Web App [하나의 sts프로젝트, 서로 영향을 주지 않는 독립적인 공간에서 동작함]) = 스프링 프로젝트</li>
<li>servlet (작은 서버 프로그램 = controller, /event/list)
=&gt; 그래서 하나의 호스트에 별도의 웹 어플리케이션을 설치해줄 수 있음</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
<h2 id="7-스레드-풀">7. 스레드 풀</h2>
<ul>
<li>여러 스레드를 만들어놓고 있다가 요청이 오면 작업하고 있지 않은 스레드가 바로 작업을 받아서 수행~!
ex) 스레드 풀 &gt; 커넥터 (HTTP11 프로세서) &gt; 엔진 &gt; 호스트 &gt; 컨텍스트 &gt; 필터 (서블릿 전처리) &gt; 디스패처 서블릿 &gt; 컨트롤러 &gt; main() 호출!</li>
<li>http11 프로세서에서 request, response 객체를 만들어서 다음으로 전달해줌!</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[DAsP] 1과목]]></title>
            <link>https://velog.io/@soulee__/DAsP-1%EA%B3%BC%EB%AA%A9</link>
            <guid>https://velog.io/@soulee__/DAsP-1%EA%B3%BC%EB%AA%A9</guid>
            <pubDate>Sun, 06 Nov 2022 04:04:25 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/soulee__/post/2e7b9835-14a3-4142-937f-8e1f0a8b0eb3/image.png" alt=""></p>
<h1 id="1과목">1과목</h1>
<h2 id="--전사-아키텍처-이해-1-전사-아키텍처-개요">- 전사 아키텍처 이해 1) 전사 아키텍처 개요</h2>
<h3 id="1-전사아키텍처-정의">1. 전사아키텍처 정의</h3>
<h4 id="01-전사아키텍처-개념">01. 전사아키텍처 개념</h4>
<p>1) 도입배경</p>
<ul>
<li>건축물의 설계도처럼 <strong>기업의 전체 시스템을 파악</strong>하는 것이 필요해짐.</li>
<li>전사 아키텍처 : <strong>기업의 시스템을 파악하기 쉽게 정리</strong>하는 것 (복잡한 기업 시스템을 필요한 형태로 변화시키는 것을 좀 더 쉽게 하기 위해 도입)</li>
</ul>
<p>2) 전사 아키텍처 정의</p>
<ul>
<li><strong>IT인프라의 각 부분들이 어떻게 구성되고 작동되어야 하는가를 체계적</strong></li>
<li><strong>다양한 측면 (비즈니스, 데이터, 애플리케이션, 기술 등)에서 기업을 분석, 표현, 정보체계 구축 및 활용</strong></li>
<li>IT투자 대비 효과 최대화, 목적 달성 최대화로 IT 인프라 구성</li>
</ul>
<p>※ 다양한 정보기술의 혁신 활동, 관리 통제를 포함, 시스템의 도입과 구축뿐만 아니라 운영과 평가까지 통합적으로 관리하는 것을 의미</p>
<p>(1) 전사</p>
<ul>
<li>기업 또는 기관</li>
<li>기업의 클 경우, 하나의 기업이 여러 개의 전사로 구성될 수 있음
(각각의 전사가 독립적 운영 주체로 구성 / 구분 가능한 다수의 사업 영역으로 구성)</li>
</ul>
<p>(2) 아키텍처</p>
<ul>
<li>정보체계, 소프트웨어 내장형 체계, 지휘통제 통신체계 등을 구축하는데 적용
<img src="https://velog.velcdn.com/images/soulee__/post/fe4f9a38-01d1-4006-9c60-9cb869639dae/image.png" alt=""></li>
<li>규칙 관점 : 준수하여야 하는 원칙 수립, 적용함으로써 아키텍처의 연속적인 모습을 관리</li>
<li>모델 관점 : 구체적 모델, 기법에 의하여 분석된 후 정의된 표기법에 의하여 표현됨. 아키텍처의 모델은 각 아키텍처 도메인에 대한 분석 결과가 아키텍처와 관련된 담당자 간 공유되어야 하는 중요한 정보</li>
</ul>
<h4 id="02-전사아키텍처-추진-현황">02. 전사아키텍처 추진 현황</h4>
<ul>
<li>EA와 ITA</li>
<li>ITA : 정보기술 아키텍처 (정보기술 중심의 아키텍처)</li>
<li>EA : 광의의 아키텍처 개념</li>
</ul>
<BR/>

<h3 id="2-전사아키텍처-프레임워크">2. 전사아키텍처 프레임워크</h3>
<h4 id="01-ea-프레임워크-개념">01. EA 프레임워크 개념</h4>
<ul>
<li>전사아키텍처 활동에서 얻어지는 <strong>산출물을 분류, 조직화하고 이를 유지 관리하기 위한 전체적인 틀을 정의</strong></li>
<li>EA 수립 전에 프레임워크를 정의</li>
</ul>
<h4 id="02-ea-프레임워크-구성">02. EA 프레임워크 구성</h4>
<ul>
<li>3개 영역 : 정책, 정보, 관리
<img src="https://velog.velcdn.com/images/soulee__/post/479dfc08-bf92-45c7-a06f-fbe5ce5eb94d/image.png" alt="">
1) 전사아키텍처 정책</li>
<li>기업이 EA 수립을 어떻게 할 것인가의 방향을 정의</li>
<li>아키텍처 매트릭스, 비전, 원칙 등으로 구성
2) 전사아키텍처 정보</li>
<li>기업이 구축하는 EA 정보의 구체적인 모습</li>
<li>현행 아키텍처, 목표 아키텍처, 이행계획으로 구성
3) 전사아키텍처 관리</li>
<li>구축된 EA를 어떻게 관리하고 활용할 것인가를 정의</li>
<li>EA 관리 체계, EA 관리 시스템, EA 평가 모형 등으로 구성</li>
</ul>
<h4 id="03-ea-정책">03. EA 정책</h4>
<ul>
<li>EA 구축 목적, 방향을 정의하는 단계</li>
<li>EA 수립을 통해 궁극적인 모습, EA 효과적으로 관리, 활용하기 위한 원칙을 정의</li>
</ul>
<p>1) 아키텍처 매트릭스</p>
<ul>
<li>EA 정보를 체계적으로 분류한 툴</li>
<li>기업이 관리하려고 하는 EA 정보 수준, 활용 계층을 결정하는 수단</li>
<li>뷰 (계획자, 책임자, 설계자 등), 관점(BA, AA, DA)의 두 차원으로 EA 정보를 구분하고, 뷰, 관점이 교차하는 각 셀에는 EA 저옵의 실체가 되는 산출물을 정의하는 구조</li>
<li>각 셀은 전후 좌우의 셀과 연관성을 가지며, 셀 간의 추적성이 확보되어야 함</li>
</ul>
<p>2) 전사아키텍처 비전</p>
<ul>
<li>EA 수립을 통해 기업이 궁극적으로 달성하고자 하는 모습</li>
<li>EA 구축 목표, 목표 달성을 위한 전략, 방향 등이 포함</li>
</ul>
<p>3) EA 원칙</p>
<ul>
<li>EA 정보를 효율적으로 구축, 목적에 맞게 EA 정보를 효과적으로 활용하기 위해 조직 구성원이 공유해야 할 규범</li>
<li>EA 대원칙, 아키텍처 원칙, 표준 등을 포함</li>
</ul>
<h4 id="04-ea-정보">04. EA 정보</h4>
<ul>
<li>EA 구축을 위해, 아키텍처 매트릭스에서 정의한 </li>
<li><strong>각 아키텍처 산출물에 현재 상태, 목표 상태의 정보를 구축하고 목표 아키텍처 달성을 위한 이행계획을 수립</strong></li>
</ul>
<p>(1) 현행 아키텍처</p>
<ul>
<li><strong>기업의 현재 상태를 아키텍처 정보로 정의</strong></li>
</ul>
<p>(2) 목표 아키텍처</p>
<ul>
<li>기업이 궁극적으로 달성하고자 하는 목표 아키텍처 상태를 아키텍처 정보로 정의</li>
</ul>
<p>(3) 전사아키텍처 이행계획</p>
<ul>
<li>아키텍처 도메인 별 현재 모습에서 바람직한 목표 모습으로 이행하기 위한 이행 전략, 이행계획을 정의한 것</li>
</ul>
<p>1) 아키텍처 도메인 </p>
<ul>
<li>아키텍처 정보 구축을 위해 아키텍처 정보 영역을 구분</li>
<li>아키텍처 매트릭스 상에서 뷰의 관점으로 아키텍처 영역을 구분하는 것</li>
<li>현행 아키텍처와 목표 아키텍처는 이런 아키텍처 도메인별로 아키텍처 정보를 구축
<img src="https://velog.velcdn.com/images/soulee__/post/cc6c7aac-be5e-4f7b-8ddf-0112d36d3b1f/image.png" alt=""></li>
</ul>
<p>(1) 비즈니스 아키텍처</p>
<ul>
<li>업무 활동 단위로 분할해 표현한 아키텍처
(2) 데이터 아키텍처</li>
<li>어떤 정보가 사용되고 전달되어야 하는지 표현한 아키텍처</li>
<li>전사 데이터 구성 분류, 데이터 모델 정의
(3) 애플리케이션 아키텍처</li>
<li>애플리케이션의 기능 및 이들 간의 관계들을 정의한 것</li>
<li>기업의 애플리케이션 단위를 분류, 인터페이스를 정의
(4) 기술 아키텍처</li>
<li>다른 아키텍처를 지원하는데 필요한 정보 기술 인프라 요소 및 구조, 이들 간의 관계를 표현한 아키텍처</li>
<li>전사의 기술 영역 분류, 표준 프로파일과 기술 아키텍처 모델을 정의</li>
</ul>
<h4 id="05-ea-관리">05. EA 관리</h4>
<p>1) 관리 체계 (EA 거버넌스)</p>
<ul>
<li>구축된 EA 유지, 개선하기 위한 <strong>제도적 기반</strong> 수립</li>
<li>정의된 EA 원칙 준수하도록 확인, 통제하기 위한 조직과 프로세스를 정의하는 것을 포함</li>
<li>EA 활동 관리, EA 정보 변경 통제, IT프로젝트가 EA 기본원칙, 정책을 준수하도록 설정</li>
</ul>
<p>2) EA 관리 시스템</p>
<ul>
<li><p>EA의 정보 관리의 효율성을 제고하고 정보 공유 활성화를 위해 구축하는 정보시스템</p>
</li>
<li><p>구성 요소</p>
</li>
<li><p>EA 정보를 정의하는 모델링 도구</p>
</li>
<li><p>EA 정보를 저장하는 EA 리포지터리</p>
</li>
<li><p>EA 정보를 사용자에게 배포하는 EA 포털 등으로 구성</p>
</li>
</ul>
<p>3) EA 평가</p>
<ul>
<li>EA 성숙 모형이 필요함</li>
</ul>
<h3 id="3-아키텍처-도메인-구성">3. 아키텍처 도메인 구성</h3>
<p><img src="https://velog.velcdn.com/images/soulee__/post/5ed37bb1-d20f-4676-8589-3122da4dbee8/image.png" alt=""></p>
<h4 id="01-아키텍처-도메인-구성">01. 아키텍처 도메인 구성</h4>
<p>1) 전사 사업 모델 (계획자 관점)
<img src="https://velog.velcdn.com/images/soulee__/post/d7ee3d8a-8e46-42ff-a175-d02c111e4171/image.png" alt=""></p>
<ul>
<li>전사의 범위를 정의하는 것에서부터 시작</li>
<li>내외부 이해관계자를 분석, 외부 객체와의 가치사슬을 분석하여 전사를 정의</li>
</ul>
<p>2) 조직 모델 (계획자 관점)</p>
<ul>
<li>기업의 사업 모델을 지원하기 위한 기업의 조직 구조를 정의 (업무분장 정의)</li>
</ul>
<p>3) 업무 기능 모델 (책임자 관점)</p>
<ul>
<li>기업의 업무 기능을 계층적으로 분할, 기능 내용을 정의</li>
<li>기능을 분할할 때는 업무 기능의 유사성, 연관성을 기준으로 정의</li>
<li>상위 업무 기능은, 하위 업무 기능들의 합으로 완전히 표현될 수 있어야 함</li>
</ul>
<p>4) 프로세스 모델 (설계자 관점)</p>
<ul>
<li>업무 기능을 상세화하여 계층적으로 프로세스를 분할하고 프로세스의 활동내용을 정의하는 것</li>
<li>데이터, 애플리케이션과 상호 비교를 통한 연관분석이 반복적으로 이루어짐</li>
</ul>
<p>5) 업무 메뉴얼 (개발자 관점)</p>
<ul>
<li>업무 기능, 프로세스별 업무 내역을 상세히 기술한 자료</li>
<li>전사아키텍처에서는 목록 수준의 정보를 관리</li>
</ul>
<h4 id="02-애플리케이션-아키텍처">02. 애플리케이션 아키텍처</h4>
<p>※ AA 정의</p>
<ul>
<li>기업의 업무를 지원하는 전체 애플리케이션을 식별하고, 연관성을 정의</li>
<li>업무, IT 특성을 고려해 <strong>그룹화하고 범주함으로써 전체 애플리케이션 구조를 체계화</strong></li>
</ul>
<p>※ 애플리케이션 서비스 정의</p>
<ul>
<li>애플리케이션이 <strong>지원하는 업무와 데이터의 특성을 고려하여 정의</strong></li>
<li>서비스 간의 상호 연관관계를 분석 정의함</li>
<li>향후 애플리케이션에 대한 배치, 통합, 프트폴리오 관리를 위한 시각을 제공</li>
</ul>
<p>1) 전사 애플리케이션 영역 모델 (계획자 관점)</p>
<ul>
<li>애플리케이션을 <strong>식별, 특성 분석을 통해 전사 수준에서 구조화</strong></li>
<li>기능, 특성에 따라 독립되어 구현되고 운영될 수 있는 애플리케이션을 정의</li>
<li>애플리케이션과 관련된 업무, 데이터와 IT 특성을 감안해 그룹화, 영역 정의
== 업무 영역별 애플리케이션 그룹화 &amp; 정의</li>
</ul>
<p>2) 애플리케이션 모델 (책임자 관점)</p>
<ul>
<li>각 앱이 지원하는 <strong>기능, 데이터 정보를 정의</strong>하고 앱이 제공하는 서비스를 도출한 후, 이들 간의 연관관계를 정의</li>
<li>앱, 서비스가 어느 업무 프로세스에서 활용, 어떤 정보를 생산, 관리하는지 연관성 분석을 함 (개발 방법론에 의존적)</li>
</ul>
<p>3) 컴포넌트 모델, 클래스 모델 (설계자 관점)</p>
<ul>
<li><strong>실제 앱 개발에 필요한 설계 정보를 관리</strong>하는 것</li>
<li>컴포넌트 / 클래스 정의, 데이터 흐름도 (DFD) 등이 해당되며, 기업의 개발 방법론에 영향을 많이 받음</li>
<li>기업이 가지고 있는 업무 영역별로 앱 개발 환경은 상이할 수 있음
ex) 정보계 - 컴포넌트 기반 개발 (CBD) 방법론
  운영계 - 메인 프레임 중심의 구조적 방법론을 사용</li>
</ul>
<p>4) 프로그램 목록 (개발자 관점)</p>
<ul>
<li>프로그램에 대한 정보를 관리</li>
</ul>
<h4 id="03-데이터-아키텍처">03. 데이터 아키텍처</h4>
<p>※ DA 정의</p>
<ul>
<li>기업의 업무 수행에 필요한 <strong>데이터의 구조를 체계적으로 정의</strong></li>
<li>전사의 데이터 영역을 분류함 (업무 (운영계, 정보계) 데이터)</li>
<li>주제 영역 모델, 개념데이터 모델을 정의, 영역별로 논리 데이터 모델, 물리 데이터 모델을 정의</li>
</ul>
<p>1) 전사 데이터 영역 모델 (계획자 관점) = 개괄 데이터 모델</p>
<ul>
<li><strong>상위 수준의 전사 데이터 영역을 분류</strong>해 표현</li>
<li>상위 주제 영역 수준의 데이터 구성도가 이에 해당됨
※ 주제 영역 : 업무 기능과 대응되는 개념, 유사 데이터를 그룹화 한 것</li>
</ul>
<p>2) 개념 데이터 모델 (책임자 관점) = 전사 수준의 데이터 모델</p>
<ul>
<li><strong>단위 주제 영역, 핵심 엔터티 정도</strong>를 표현한 데이터 모델</li>
<li>전사 수준에서 사용하는 데이터를 전체적으로 표현할 수 있는 기본 틀</li>
<li>핵심 엔터티는 일반적으로 단위 주제 영역별로 한 두 개 정도가 도출됨</li>
</ul>
<p>3) 논리 데이터 모델 (설계자 관점)</p>
<ul>
<li>개념 데이터 모델에서 정의된 기본 정보를 기반으로 업무 요건 충족을 위한 <strong>데이터 상세 구조를 논리적으로 구체화</strong>한 것</li>
<li>엔터티, 속성에 대한 명칭, 정의, 형식, 규칙 코드 등을 전사적 차원의 표준으로 정의하여 관리
※ 논리 데이터 모델링 : 수집된 업무 관련 데이터 정보, 사전에 작성된 산출물을 기반으로 필요한 모든 엔터티를 도출하고, 식별자, 속성, 관계와 서브타입 등을 정의</li>
</ul>
<p>4) 물리 데이터 모델 (개발자 관점)</p>
<ul>
<li>기술적 환경, 특성을 고려해 <strong>물리적 데이터 구조를 설계하고 DB 객체를 정의</strong>
(1) 논리 데이터 모델을 물리적 데이터 구조로 전환
(2) 데이터 무결성을 보완하여 정의
(3) 데이터 분산 설계에 따른 데이터 무결성 등 추가적인 무결성 규칙을 정의
(4) DB의 성능을 고려해 이미 설계된 데이터 구조에 추가적으로 데이터의 접근 성능 향상을 위한 인덱스 설계, 데이터 구조에 대한 비정규화 과정을 수행</li>
</ul>
<h4 id="04-기술아키텍처">04. 기술아키텍처</h4>
<p>※ 정의</p>
<ul>
<li>비즈니스, 데이터, 애플리케이션 아키텍처에서 정의된 요건을 지원하는 <strong>전사의 기술 인프라 체계를 정의</strong></li>
<li><strong>기술 참조 모델, 표준 프로파일 구축을 통해 애플리케이션 이식성, 확장성을 강화</strong>하고, 벤더로부터의 독립성의 확보하며, 시스템 간의 상호운용성을 강화하는 효과를 기대할 수 있음.</li>
<li>개별 기업에서도 기술 참조 모델을 정의하는 것이 일반적</li>
</ul>
<p>※ 기술 인프라</p>
<ul>
<li>H/W, 시스템 소프트웨어, 통신 네트워크, 시스템 개발도구, 시스템 관리도구, 최종 사용자 소프트웨어 등을 포함</li>
</ul>
<p>1) 전사 기술 영역 모델, 기술 참조 모델 (계획자 관점)</p>
<ul>
<li>기업이 <strong>업무활동에 필요한 정보기술의 영역을 상위 수준에서 분류</strong>한 것
<img src="https://velog.velcdn.com/images/soulee__/post/28de1a79-1bd7-4649-b0b4-46edb49a755a/image.png" alt="">
※ 기술 참조 모델 : 기업이 업무 활동에 필요한 기능들을 수행하기 위해 요구되는 정보기술을 <strong>상위 수준에서 논리적으로 분류</strong>한 툴 (= 전사 기술 영억 모델과 같은 범주이나, 일반적인 표준을 최대한 수렴해 정의)</li>
</ul>
<p>2) 표준 프로파일 (책임자 관점)</p>
<ul>
<li>기술 참조 모델에 <strong>명시된 서비스를 지원하기 위한 정보기술 표준들의 집합</strong></li>
<li>기업의 모든 기술 아키텍처 요소들에 영향을 미치는 표준들을 포함</li>
<li>시스템 이식성, 확장성, 상호운용성, 호환성을 제고</li>
<li>기술표준을 프로파일의 대상으로 하며, 최근에는 제품을 프로파일링 대상에 포함시킴</li>
</ul>
<p>3) 기술 아키텍처 모델</p>
<ul>
<li>전사 기술 영역 모델이나 기술 참조 모델에서 정의된 <strong>서비스 카테고리별로 아키텍처 패턴을 정의</strong></li>
<li>기업의 SW, HW, 네트워크 등의 구성 요소에 대한 배치도를 정의</li>
</ul>
<p>4) 기술자원 목록, 제품 목록</p>
<ul>
<li>기술자원 목록, 제품 목록을 기술 아키텍처 정보로 관리</li>
</ul>
<h4 id="05-ea-프레임워크-사례">05. EA 프레임워크 사례</h4>
<p>※ 종류</p>
<ul>
<li>자크만 프레임워크 (ZEAF), 미연방정부 프레임워크(FEAF), 미재무성 프레임워크(TEAF), 미국방성 프레임워크(DoDAF), 오픈그룹 프레임워크(TOGAF), 한국정보 프레임워크 등</li>
</ul>
<p>1) 자크만 프레임워크 (ZEAF)</p>
<ul>
<li>다섯 가지 관점 (P,O,D,B,S)과 각 관점에 따르는 여섯가지 묘사 방법 (D,F,N,P,T,M)을 정의하고 있음
※ 5개 관점 : Planner, Owner, Designer, Builder, Sub-contractor
※ 6개 묘사 방법 : Data, Function, Network, People, Time, Motivation</li>
</ul>
<p>2) 미연방정부 프레임워크(FEAF) </p>
<ul>
<li>8개 구성요소로 이루어져 있고, 4단계에 걸쳐 점차적으로 진행하여 마지막 단계에 자크만 프레임워크의 모델 내용을 모두 관리</li>
</ul>
<p>※ 프레임워크 : 각 세그먼트별 접근법을 채택해 현행, 목표의 갭분석을 통한 이행계획과 프로세스를 포함됨</p>
<p>3) 오픈그룹 프레임워크(TOGAF)</p>
<ul>
<li>아키텍처 개발 방법(ADM), 정보기술을 체계적으로 분류한 기술 참조 모델, 표준 요약 정보를 모아놓은 DB인 표준정보기반(SIB)로 구성됨</li>
<li>빌딩블록 정의에 대한 접근 방식으로 구성 단위의 문제해결 방식을 제안</li>
</ul>
<p><a href="https://quizlet.com/kr/619999332/dap-%EB%AC%B8%EC%A0%9C%ED%92%80%EC%9D%B4-flash-cards/">https://quizlet.com/kr/619999332/dap-%EB%AC%B8%EC%A0%9C%ED%92%80%EC%9D%B4-flash-cards/</a></p>
<p><a href="https://velog.io/@elfinsun/DASP-%EC%A0%84%EC%82%AC%EC%95%84%ED%82%A4%ED%85%8D%EC%B2%98EA-%EC%9D%B4%ED%95%B4-%EC%98%A4%EB%8B%B5%EB%85%B8%ED%8A%B8">https://velog.io/@elfinsun/DASP-%EC%A0%84%EC%82%AC%EC%95%84%ED%82%A4%ED%85%8D%EC%B2%98EA-%EC%9D%B4%ED%95%B4-%EC%98%A4%EB%8B%B5%EB%85%B8%ED%8A%B8</a></p>
<p><a href="https://dataonair.or.kr/db-tech-reference/d-guide/da-guide/?pageid=8&amp;mod=document&amp;uid=248">https://dataonair.or.kr/db-tech-reference/d-guide/da-guide/?pageid=8&amp;mod=document&amp;uid=248</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Springboot 주요 라이브러리]]></title>
            <link>https://velog.io/@soulee__/Springboot-%EC%A3%BC%EC%9A%94-%EB%9D%BC%EC%9D%B4%EB%B8%8C%EB%9F%AC%EB%A6%AC</link>
            <guid>https://velog.io/@soulee__/Springboot-%EC%A3%BC%EC%9A%94-%EB%9D%BC%EC%9D%B4%EB%B8%8C%EB%9F%AC%EB%A6%AC</guid>
            <pubDate>Tue, 01 Nov 2022 13:56:41 GMT</pubDate>
            <description><![CDATA[<ul>
<li><p>settings &gt; gradle &gt; build and run using : intelliJ IDEA</p>
<ul>
<li>gradle을 거치지 않고 자바를 바로 띄워줌!</li>
</ul>
<h2 id="라이브러리">라이브러리</h2>
<ul>
<li>gradle / maven : 라이브러리 간 의존관계를 찾아줌 (다 땡겨와줌)
ㄴ 스프링 코어까지 다 땡겨옴</li>
<li>spring-boot-starter-tomcat : 요즘에는 톰캣 was 서버를 임베디드 하고 있음
ㄴ embed-core...</li>
<li>logging (스프링 표준)
ㄴ slf4j : 인터페이스 
ㄴ logback : 로그를 어떤 구현체로 출력할 것인지 선택할 때</li>
</ul>
</li>
</ul>
<h2 id="테스트-관련-라이브러리">테스트 관련 라이브러리</h2>
<ul>
<li><p>Junit : 테스트 프레임워크</p>
</li>
<li><p>mockito : 목 라이브러리</p>
</li>
<li><p>assertj : 테스트 코드를 좀 더 편하게 작성하게 도와주는 라이브러리</p>
</li>
<li><p>spring-test : 스프링과 통합해서 테스트할 수 있게 도와주는 라이브러리</p>
<h2 id="스프링-부트-라이브러리">스프링 부트 라이브러리</h2>
<ul>
<li><p>spring-boot-starter-web</p>
</li>
<li><p>spring-boot-starter-tomcat : 톰캣 (웹서버)</p>
</li>
<li><p>spring-webmvc : 스프링 웹 MVC</p>
</li>
<li><p>spring-boot-starter-thymeleaf : 타임리프 템플릿 엔진(View)</p>
</li>
<li><p>spring-boot-starter (공통) : 스프링 부트 + 스프링 코어 + 로깅</p>
</li>
<li><p>spring-boot</p>
<ul>
<li>spring-core</li>
</ul>
</li>
<li><p>spring-boot-starter-logging</p>
<ul>
<li>logback, slf4j</li>
</ul>
</li>
</ul>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[인프라 2장]]></title>
            <link>https://velog.io/@soulee__/%EC%9D%B8%ED%94%84%EB%9D%BC-2%EC%9E%A5</link>
            <guid>https://velog.io/@soulee__/%EC%9D%B8%ED%94%84%EB%9D%BC-2%EC%9E%A5</guid>
            <pubDate>Sun, 23 Oct 2022 02:48:50 GMT</pubDate>
            <description><![CDATA[<h2 id="1-서버의-종류">[1] 서버의 종류</h2>
<h3 id="1-랙-마운트형-타워형-서버-차이">1. 랙 마운트형, 타워형 서버 차이</h3>
<p>1) 랙 마운트 형 : 데이터 센터, 서버 룸에 설치된 랙 안에 들어감 
    (19인치 렉에 수용, 1U, 2U처럼 유닛 단위로 사이즈 지정)
    - 엔트리 서버 : 1U
    - 미들레인지 서버 : 2U
2) 타워형 : 사내 서버룸, 사무실 또는 점포 등에도 설치</p>
<ul>
<li>설치 장소
1) 데이터 센터, 서버 룸 : 냉바 장치 설치 &amp; 밀폐된 전용 공간
2) 사무실, 점포 : 사무실 설치용 저소음 타워형 서버, 사내 렉 설치 (무대 하중에 주의)</li>
</ul>
<h3 id="2-엔트리-미들레인지-하이엔드-서버">2. 엔트리, 미들레인지, 하이엔드 서버</h3>
<ol>
<li>엔트리 서버</li>
</ol>
<ul>
<li><strong>웹, 애플리케이션 서버</strong> </li>
<li>소켓 단위로 1~2개 CPU 탑재</li>
</ul>
<ol start="2">
<li>미들레인지 서버</li>
</ol>
<ul>
<li>DB, 기간계 서버</li>
<li>소켓 단위로 4개 이상 CPU 탑재</li>
<li>기간계 시스템 (미션 크리티컬 시스템, 엔터프라이즈 시스템, 백본 시스템) : 기업 경영을 지속하는 데 핵심이 되는 재무, 업무, 생산 관리 등을 담당하는 시스템</li>
</ul>
<ol start="3">
<li>하이엔드 서버</li>
</ol>
<ul>
<li>DB, 기간계 서버</li>
<li>소켓 단위로 수십 개 이상 CPU 탑재</li>
</ul>
<h3 id="3-ia서버">3. IA서버</h3>
<ul>
<li>인텔, AMD 등 인텔 호환 CPU 탑재, 일반 컴퓨터와 같은 아키텍처를 기반으로 해 만들어진 서버</li>
<li>IA서버 선택시 고려 요소
1) (규격) 데이터 센터의 렉에 서버가 제대로 장착되는가? 
2) (부품) 설치할 수 있는 부품 수
3) (장애) 장애 발생 시 지원 체계
4) (원격) 원격 제어 기능</li>
</ul>
<h3 id="4-엔터프라이즈-서버">4. 엔터프라이즈 서버</h3>
<ul>
<li>기간계에 사용되는 서버 
  (대용량 액세스가 가능한 수용량, 내구성이 높은 기기로 구성)</li>
<li>IA와 달리 고가</li>
<li>중요도가 높을 경우, 하드웨어 이상 경고가 발생하면 자동으로 업체에 통보</li>
<li>서버에 전화 회선을 연결하는 서버스를 이용할 수도 있음</li>
</ul>
<h3 id="cf-서버---일반-컴퓨터-차이">cf) 서버 - 일반 컴퓨터 차이</h3>
<ul>
<li>용도 차이에 의해 설계 철학이 다름</li>
</ul>
<ol>
<li>서버</li>
</ol>
<ul>
<li>24/365일 가동되는 것을 전제 </li>
<li>하드웨어가 잘 고장나지 않고, 시스템이 멈추지 않게 설계</li>
<li>서버 부품 자체의 품질이 높고, 주요 부품을 이중화하여 고장이 발생해도 서비스를 멈추지 않은 채 교환 가능</li>
</ul>
<h2 id="2-서버의-선정">[2] 서버의 선정</h2>
<h3 id="1-조건">1. 조건</h3>
<ul>
<li>사양 결정시 필요 하드웨어 자원의 사용량 결정 후 CPU, 메모리, 디스크, NIC 포트 수 등을 결정</li>
<li>또한, 부가적인 요소로서 RAID 유무, PSU 이중화, 보수 연수 / 수준, 확장성, 물리 사이즈, 중량 등도 함께 결정</li>
</ul>
<h3 id="2-사양-결정-방법">2. 사양 결정 방법</h3>
<ol>
<li>실제 환경을 시험적으로 구축, 측정 결과를 보고 판단</li>
</ol>
<ul>
<li>기간계의 경우 1번 방식을 선택하는 것이 좋음 (단 노력, 시간 필요)</li>
</ul>
<ol start="2">
<li>임시 결정 사양을 현장 투입 후,실제 HW 자원 이용 상황 측정 후, 서버와 서버의 부품을 늘리거나 줄임</li>
</ol>
<ul>
<li>온라인 게임처럼 액세스 양을 사전에 예상할 수 없을 경우에 사용</li>
</ul>
<ol start="3">
<li>소거법으로 사양 좁혀나감</li>
</ol>
<ul>
<li>서비스의 성질이 정해져 있을 경우 (웹 서버 - 메모리 이외의 HW 리소스는 그다지 소비되지 않으므로 메모리만 넉넉하게 설치)</li>
</ul>
<h3 id="3-스케일-아웃---업">3. 스케일 아웃 - 업</h3>
<ol>
<li>스케일 아웃 (서버 대수 증가)</li>
</ol>
<ul>
<li>성능 부족시, 서버의 수를 늘려 <strong>수용량</strong>을 늘림</li>
<li><strong>부하 분선이 쉬운 웹 서버</strong>의 경우, 가격이 싼 장비로 구성하고 성능이 부족해지면 서버 수를 더 늘려감</li>
</ul>
<ol start="2">
<li>스케일 업</li>
</ol>
<ul>
<li>성능 부족시, 메모리 증설 등 부품을 추가/교환하거나 상위 기종으로 교체해 <strong>서버 성능을 높이는 방법</strong>
ex) 부하 분산이 어려운 DB서버는 1세트만 준비, 성능이 부족해지면 더 고가의 기종으로 교체하는 방식으로 대응</li>
</ul>
<h3 id="4-업체-선정">4. 업체 선정</h3>
]]></description>
        </item>
        <item>
            <title><![CDATA[인프라 1장]]></title>
            <link>https://velog.io/@soulee__/%EC%9D%B8%ED%94%84%EB%9D%BC-1%EC%9E%A5</link>
            <guid>https://velog.io/@soulee__/%EC%9D%B8%ED%94%84%EB%9D%BC-1%EC%9E%A5</guid>
            <pubDate>Sun, 23 Oct 2022 02:07:03 GMT</pubDate>
            <description><![CDATA[<h2 id="01-인프라-엔지니어-업무">01. 인프라 엔지니어 업무</h2>
<ul>
<li>인프라 설계, 구축, 운영 세단계로 분류</li>
</ul>
<ol>
<li><p>설계
 1) 조건 정리</p>
<ul>
<li><strong>구성 목적을 고려한</strong> 필요 기능, 성능 등의 <strong>조건을 기준으로 정리</strong>
2) 기획서, 설계서 작성</li>
<li>비용, 기간을 예상하는 작업</li>
</ul>
</li>
<li><p>구축
1) 구축 작업</p>
<ul>
<li>기기의 운반 조립, 장착, 설치, 설정, 동작 테스트, 부하 테스트 등으로 분류</li>
<li>SI 업계의 경우, 
(1) CE (커스터머) : 기기 설치, 하드웨어 관련 작업
(2) SE (시스템) : 서버, 스토리지 설정
(3) NE (네트워크) : 네트워크 장비 설정</li>
</ul>
</li>
<li><p>운영</p>
</li>
</ol>
<ul>
<li>MSP : IT인프라 운영 관리 업자</li>
<li>장애 대응, 수용량 관리, 인프라가 원인이 아닌 문제의 파악 등의 업무 수행
  1) 장애 대응<ul>
<li>하드웨어 고장, 급격한 액세스 증가에 대한 대책, 부적절한 권한 설정에 의해 엑세스가 불가능한 상황 해소
2) 수용량 관리</li>
<li>엑세수 수, 데이터 양 변화에 따른 수용력 재검토 필요
3) 인프라가 원인이 아닌 문제의 파악</li>
</ul>
</li>
</ul>
<h2 id="02-it인프라-구성요소">02. IT인프라 구성요소</h2>
<ol>
<li><strong>퍼실리티</strong> : 건물, 시설 설비
 ex) 데이터 센터, 렉, 에어컨, 발전기 등.... </li>
<li>*<em>서버, 스토리지 *</em>
1) 서버 : it서비스 제공<pre><code>         2) 스토리지 : 데이터 대량 저장</code></pre></li>
<li><strong>네트워크</strong>
: 서버 - 스토리지 연결 및 인터넷에 접속하는 네트워크</li>
</ol>
<h2 id="03-기술자로서의-인프라-엔지니어">03. 기술자로서의 인프라 엔지니어</h2>
<ol>
<li><strong>서버 하드웨어 (IA서버, 엔터프라이즈 서버)</strong></li>
</ol>
<ul>
<li>메인보드, CPU, 메모리디스크, NIC (네트워크 인터페이스 카드), 파워 서플라이 유닛과 같은 주요 부속의 조합으로 구성</li>
</ul>
<ol start="2">
<li><strong>서버 OS</strong></li>
</ol>
<ul>
<li>리눅스, 윈도, 유닉스 세 가지로 집약</li>
</ul>
<ol start="3">
<li><strong>스토리지</strong></li>
</ol>
<ul>
<li>디스크의 대용량화, 플래시 디스크의 등장에 따른 고속화, 데이터의 폭발적 증가를 배경으로 <strong>스토리지 가상화, 씬 프로비저닝, 중복 제거, 스냅샷</strong> 등의 신기술이 속속 등장</li>
</ul>
<ol start="4">
<li><strong>네트워크 설계와 구축</strong></li>
</ol>
<ul>
<li>인터넷 상 네트워크 : 외부 네트워크와 연결되어야 비로서 성립</li>
</ul>
<ol start="5">
<li><strong>네트워크 장비 (통신의 교환)</strong></li>
</ol>
<ul>
<li>연결하는 서버 및 네트워크 장비의 수, 커넥트의 차이</li>
<li>어느 정도 통신량을 얼마나 빠르게 교환하고 싶은지</li>
<li>라우터, L2,L3,L4,L7 스위치 차이를 파악해 두면 네트워크 장비 선정에서 크게 실수할 일은 없음</li>
</ul>
<h2 id="04-선정자로서의-인프라-엔지니어">04. 선정자로서의 인프라 엔지니어</h2>
<p>프로젝트 성질, 기업문화 혹은 최종 결재권자의 사고 방식에 따라 인프라는 다르게 구성</p>
<p>시스템, 서버 사양, 네트워크, DB설계</p>
<ol>
<li>시스템 구성</li>
</ol>
<ul>
<li>프로젝트에 대해서 어떤 시스템을 어느 정도의 규모로 어떻게 구성할 것인지 검토</li>
<li>구성 패턴
1) 최소 구성 (L2 - 메일 서버)
2) 이중화 구성 (L2 - 메일 서버 * 2)
3) 데이터 영역 분리 구성 (L2 - 메일 - L2 - ISCSI스토리지)</li>
</ul>
<ol start="2">
<li>서버 사양</li>
</ol>
<ul>
<li>CPU, 메모리, 디스크, RAID (Redundant Array of inexpensive Disk), NIC, PSU 이중화 필요성, 보수 연수, 보수 레벨, 확장성, 물리적 크기 및 중량</li>
</ul>
<ol start="3">
<li>네트워크 구성</li>
</ol>
<ul>
<li>렉 스위치 개수, 스위치 수용량, 채택 업체, 보증 기간, NI 별 통신량 결정 및 이중화 여부 결정</li>
</ul>
<ol start="4">
<li>DB설계</li>
</ol>
<ul>
<li>RDBMS 선정</li>
<li>필요 용량 계산</li>
<li>DB 스키마, 물리적 데이터 배치 결정</li>
</ul>
<ol start="5">
<li>운영 시스템</li>
</ol>
<ul>
<li><p>시스템 감시, 운영 방법 검토</p>
</li>
<li><p>예시
1) 장애 발생을 시스템 감시 도구로 감지, 장애 발생을 감지했을 떄만 사원이 대응
2) 1차 대응은 MSP 업체에 위임, 그 이후에는 문제 전달 후 단계적 대응
3) 별도 조직 구성 후, 24/365 감시 운용 시스템 구축</p>
</li>
<li><p>사내 책임 범위 : 서비스 기술, 시스템 별로 사내 책임 범위를 결정</p>
</li>
</ul>
<p>(추가로 공부해야 될 것) <a href="https://shlee0882.tistory.com/110">https://shlee0882.tistory.com/110</a></p>
]]></description>
        </item>
    </channel>
</rss>