<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>kong-al.log</title>
        <link>https://velog.io/</link>
        <description>웹개발 공부중!(❁´◡`❁)</description>
        <lastBuildDate>Wed, 22 Feb 2023 05:23:47 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>kong-al.log</title>
            <url>https://velog.velcdn.com/images/kong-al/profile/d94791f2-f6cb-4e3c-9a35-62d311dca42b/image.jpg</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. kong-al.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/kong-al" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[[ 카페24 ] 스프링부트 + 타임리프 + 마리아db 호스팅 연결하기]]></title>
            <link>https://velog.io/@kong-al/%EC%B9%B4%ED%8E%9824-%ED%98%B8%EC%8A%A4%ED%8C%85-%EC%97%B0%EA%B2%B0</link>
            <guid>https://velog.io/@kong-al/%EC%B9%B4%ED%8E%9824-%ED%98%B8%EC%8A%A4%ED%8C%85-%EC%97%B0%EA%B2%B0</guid>
            <pubDate>Wed, 22 Feb 2023 05:23:47 GMT</pubDate>
            <description><![CDATA[<p>남들은 쉽게 해결하던데 나는 이틀이나 걸렸다!
그래도 결국 해결책을 찾긴 찾았기에 적어보기로 한다.</p>
<blockquote>
<p>결과적으로 sts / 스프링부트 / 자바8 / 타임리프 / 마리아DB / JPA / gradle / yml 을 이용하였다.</p>
</blockquote>
<p>카페 24의 Tomcat JSP호스팅 비즈니스 를 사용했고 
서버 환경 버전에는 
<img src="https://velog.velcdn.com/images/kong-al/post/908e95bc-42aa-4231-a3bf-afa06f260040/image.png" alt=""></p>
<p>이렇게 세가지가 있다. 버전 선택은 이 글을 끝까지 읽고 본인이 원하는것으로 선택하면 될 것이다.</p>
<p>나는 자바11버전이 익숙해서 자바11버전으로 개발 후 톰캣10을 이용해 배포하려고 했었다.
해결하고 나니 별거 아닌 문제들이였지만 그 당시의 나는 꽤 스트레스를 받았다. 인터넷으로 하라는대로 하는데 안되니까 ㅎ</p>
<h2 id="bulidgradle-파일-설정하기">bulid.gradle 파일 설정하기</h2>
<h4 id="먼저-카페24에-배포하기-위해서는-war-파일이-필요하다">먼저 카페24에 배포하기 위해서는 war 파일이 필요하다.</h4>
<p>bulid.gradle 파일안에 플러그인에 [ id &#39;war&#39; ] 를 추가하여 war 파일을 만들 수 있게 설정해주자.</p>
<pre><code class="language-java">plugins {
    id &#39;java&#39;
    id &#39;war&#39;
    id &#39;org.springframework.boot&#39; version &#39;2.7.8&#39;
    id &#39;io.spring.dependency-management&#39; version &#39;1.0.15.RELEASE&#39;
}</code></pre>
<h4 id="다음-외장-톰캣을-이용하기-위해서는-스프링부트에-있는-톰캣을-중지시켜야한다">다음 외장 톰캣을 이용하기 위해서는 스프링부트에 있는 톰캣을 중지시켜야한다.</h4>
<pre><code class="language-java">    providedRuntime &#39;org.springframework.boot:spring-boot-starter-tomcat&#39;</code></pre>
<p>bulid.gradle 파일안에 dependencies 에 작성해준다. (war 사용시에만 가능)
providedRuntime는 runtime 시에만 실행되고 실행환경에서 제공되는 dependency를 설정한다.</p>
<p>메이븐에서는 아래를 추가해준다.</p>
<pre><code>&lt;dependency&gt;
         &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
         &lt;artifactId&gt;spring-boot-starter-tomcat&lt;/artifactId&gt;
         &lt;scope&gt;provided&lt;/scope&gt;
 &lt;/dependency&gt;</code></pre><h4 id="자바-버전도-맞게-설정해줘야한다">자바 버전도 맞게 설정해줘야한다</h4>
<pre><code class="language-java">sourceCompatibility = &#39;1.8&#39;
// 자바 8버전의 경우 &#39;1.8&#39; 
// 자바 11버전의 경우 &#39;11&#39;
// 자바 17버전의 경우 &#39;17&#39; 을 입력해준다.</code></pre>
<h2 id="main-class-확인">main class 확인</h2>
<p>main class가 있는 곳 하위에 컨트롤러가 잘 들어가있는지도 확인하자</p>
<p><img src="https://velog.velcdn.com/images/kong-al/post/b4cfec88-e32a-42ae-9b3d-4d0b965bae98/image.png" alt=""></p>
<p>이런식으로 메인클래스가 있는 패키지 하위에 컨트롤러가 위치해야 한다.</p>
<p>또한 메인클래스에 SpringBootServletInitializer를 상속해주자.</p>
<pre><code class="language-java">@SpringBootApplication
public class 메인클래스명 extends SpringBootServletInitializer {

    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
        // TODO Auto-generated method stub
        return builder.sources(메인클래스명.class);
    }

    public static void main(String[] args) {SpringApplication.run(메인클래스명.class, args);}
}</code></pre>
<h2 id="톰캣-9버전과-10버전의-차이">톰캣 9버전과 10버전의 차이</h2>
<p><a href="https://blog.itcode.dev/posts/2022/02/12/tomcat-9-and-10">https://blog.itcode.dev/posts/2022/02/12/tomcat-9-and-10</a></p>
<p>결론적으로 톰캣10버전에서는 javax 를 인식하지 못하기때문에 war 파일을 webapps가 아닌 webapps-javaee 로 담아 실행하면 되는것같다. 실행해보지는 않았다. </p>
<p>나의 경우에는 자바11로 개발 당시 javax를 이용해 코드를 작성했고 그걸 톰캣10버전에 webapps에 올리다보니 404에러가 계속 발생하였다.</p>
<p>자바17을 사용하면 javax가 아닌 jakarta*를 자동으로 사용한다.</p>
<h2 id="yml-파일작성">yml 파일작성</h2>
<pre><code class="language-java">spring:
  datasource:
    1 ) url: jdbc:mariadb://카페24 호스팅아이디.cafe24.com:3306/카페24 호스팅아이디
    2 ) url: jdbc:mariadb://localhost:3306/카페24 호스팅아이디
    username: 카페24 호스팅아이디
    password: DB비밀번호
    driver-class-name: org.mariadb.jdbc.Driver</code></pre>
<p>yml파일에 디비를 연동해야한다.</p>
<p>1) 로컬(내 컴퓨터) 에서 사용하는 url 경로이다.
2) 배포(카페24서버)에 올릴때 사용하는 url 경로이다.</p>
<h2 id="war-파일-만들기">war 파일 만들기</h2>
<p>프로젝트 오른쪽마우스 클릭 -&gt; run As -&gt;run configurations -&gt; Gradle Task 더블 클릭 </p>
<p>이렇게 창이 열린다.
Gradle Tasks에 Add 버튼을 눌러 task가 생기면 클랙해서 war로 변경해준다.
<img src="https://velog.velcdn.com/images/kong-al/post/9761a47c-7aea-4a79-958c-420bd62df6ae/image.png" alt="">
그 후에 Working Directory에 workspace를 등록해 내가 war파일로 만들 프로젝트를 선택해준다
<img src="https://velog.velcdn.com/images/kong-al/post/4022a98a-d3f3-4142-91fa-1eb5b6182b6e/image.png" alt=""></p>
<p>프로젝트를 선택하면 run 버튼이 활성화되고 run 버튼을 클릭하게되면 war파일이 생성된다.
프로젝트\build\libs 안에 war 파일이 만들어져 있다.</p>
<h2 id="war-파일-업로드">war 파일 업로드</h2>
<p>file zila를 사용해 서버에 war 파일을 올려준다.</p>
<blockquote>
<p><a href="https://filezilla.softonic.kr/">https://filezilla.softonic.kr/</a></p>
</blockquote>
<p>다운받은 후 실행한 뒤 버튼을 클릭하여 서버에 연결해준다.
<img src="https://velog.velcdn.com/images/kong-al/post/d0b99537-c5ea-45c8-aade-5d36a0d761ac/image.png" alt=""></p>
<p>아이디와 비밀번호 입력 후 연결해준다
<img src="https://velog.velcdn.com/images/kong-al/post/a21ae01a-b5d2-41a3-b0c3-10122484257d/image.png" alt=""></p>
<p>톰캣 하위의 webapps 파일에 ROOT.war 파일을 넣어준다.
드래그 앤 드롭으로 가능하다.
<img src="https://velog.velcdn.com/images/kong-al/post/260fdadd-74ac-428e-9880-c680da841e45/image.png" alt=""></p>
<p>ROOT.war를 넣으면 톰캣이 자동으로 압축을 풀어준다. 당장 ROOT파일이 보이지 않아도 만들어져있으니 당황하지 말자.</p>
<h2 id="서버-재시작">서버 재시작</h2>
<p>PuTTy를 이용하여 서버를 재시작한다.
서버를 재 시작해야 ROOT파일이 제대로 열린다.</p>
<blockquote>
<p><a href="https://www.chiark.greenend.org.uk/~sgtatham/putty/latest.html">https://www.chiark.greenend.org.uk/~sgtatham/putty/latest.html</a></p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/kong-al/post/0c1c6b19-076d-407b-ba12-fade4fe35e16/image.png" alt=""></p>
<p>카페24도메인을 입력한다. [  카페24ID.cafe24.com  ]
open을 입력하면</p>
<p><img src="https://velog.velcdn.com/images/kong-al/post/5f51ef33-c8c6-4d0e-ba67-c9a553328851/image.png" alt=""></p>
<p>창이뜨고 login as : 카페24 아이디 (엔터)
비밀번호 하라고 나오는데 키보드를 입력해도 보이는것은 없다. 그래도 잘 입력되고 있으니 괜찮다.
비밀번호를 여러번 틀려도 기회를 계속 주니 걱정하지말고 입력하자!
<img src="https://velog.velcdn.com/images/kong-al/post/dfe89ef0-6f7f-4f73-8034-841c3c50b30f/image.png" alt="">
완료되면 로그인한 날짜와 시간이 나온다.</p>
<blockquote>
<p>~/tomcat/bin/shutdown.sh    // 서버종료
~/tomcat/bin/startup.sh     // 서버시작</p>
</blockquote>
<p>차례로 입력해주면 서버가 종료됐다 재시작 되며 ROOT.war 파일을 인식해 
카페24도메인에 접속이 가능해진다!</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[ spring ] RequestParam 과 ResponseParam]]></title>
            <link>https://velog.io/@kong-al/spring-RequestParam-%EA%B3%BC-ResponseParam</link>
            <guid>https://velog.io/@kong-al/spring-RequestParam-%EA%B3%BC-ResponseParam</guid>
            <pubDate>Wed, 23 Nov 2022 08:29:53 GMT</pubDate>
            <description><![CDATA[<h2 id="requestparam-과-responseparam">RequestParam 과 ResponseParam</h2>
<p>우리는 jsp로 개발을 할 때 HttpServletRequest의 getParametar() 메소드를 이용하여 값을 받아 올 수 있었다. spring에서는 @RequestParam 어노테이션을 사용하여 값을 받아올 수 있다.</p>
<pre><code class="language-java">    public void requestParamV1(HttpServletRequest request, HttpServletResponse response) throws IOException {
        String username = request.getParameter(&quot;username&quot;);
        int age = Integer.parseInt(request.getParameter(&quot;age&quot;));

        System.out.println(&quot;username : &quot; + username);
        System.out.println(&quot;age : &quot; + age);

        response.getWriter().write(&quot;ok&quot;);
    }
</code></pre>
<p>기존에 우리가 HttpServletRequest를 사용하여 값을 받아오던 방식이다.
아직은 jsp에 익숙해서 이 방식도 불편하다고 생각하지 않지만 @RequestParam 을 사용하면
더욱 간편하게 작성할 수 있다. </p>
<p>@RequestParam을 사용한 방법들에 대해 알아보자.</p>
<h3 id="requestparam">RequestParam</h3>
<h4 id="첫번째">첫번째</h4>
<pre><code class="language-java">@ResponseBody
@RequestMapping(&quot;/request-param-v2&quot;)
public String requestParamV2( @RequestParam(&quot;username&quot;) String username , @RequestParam(&quot;age&quot;) int age){

    System.out.println(&quot;username : &quot; + username);
    System.out.println(&quot;age : &quot; + age);

    return &quot;ok&quot;;
}</code></pre>
<ul>
<li><p>url</p>
<blockquote>
<p><a href="http://localhost:9090/request-param-v2?username=test&amp;age=20">http://localhost:9090/request-param-v2?username=test&amp;age=20</a></p>
</blockquote>
</li>
<li><p>@ResponseBody</p>
<blockquote>
<p>view 조회를 무시하고 , HTTP message body에 직접 해당 내용 입력!!
화면이동이 되지않고 return 값이 화면에 바로 출력된다.</p>
</blockquote>
</li>
<li><p>@RequestParam</p>
<blockquote>
<p>파라미터 이름으로 바인딩된다.
name 속성이 파라미터 이름으로 사용</p>
</blockquote>
</li>
</ul>
<h4 id="두번째">두번째</h4>
<p>http 파라미터 이름이 변수 이름과 같으면 @RequestParam(&quot;변수이름&quot;) 생략가능</p>
<pre><code class="language-java">@ResponseBody
@RequestMapping(&quot;/request-param-v3&quot;)
public String requestParamV3(@RequestParam String username , @RequestParam int age){

    System.out.println(&quot;username : &quot; + username);
    System.out.println(&quot;age : &quot; + age);

    return &quot;ok&quot;;
}</code></pre>
<ul>
<li>url<blockquote>
<p><a href="http://localhost:9090/request-param-v3?username=test&amp;age=20">http://localhost:9090/request-param-v3?username=test&amp;age=20</a></p>
</blockquote>
</li>
</ul>
<h4 id="세번째">세번째</h4>
<p>String, int 등 단순타입이면  @RequestParam 도 생략가능하다.
MVC내부에서 required=false를 적용한다.
추천하지 않음</p>
<pre><code class="language-java">@ResponseBody
@RequestMapping(&quot;/request-param-v4&quot;)
public String requestParamV4( String username , int age){

    System.out.println(&quot;username : &quot; + username);
    System.out.println(&quot;age : &quot; + age);

    return &quot;ok&quot;;
}</code></pre>
<ul>
<li>url<blockquote>
<p><a href="http://localhost:9090/request-param-v4?username=test&amp;age=20">http://localhost:9090/request-param-v4?username=test&amp;age=20</a></p>
</blockquote>
</li>
</ul>
<h4 id="네번째">네번째</h4>
<ul>
<li>required
required = true    : 반드시 파라미터 값이 들어와야 한다. (기본값)
required = false: 필수값은 아닐 수 있다.</li>
</ul>
<pre><code class="language-java">@ResponseBody
@RequestMapping(&quot;/request-param-required&quot;)
public String requestParamRequired(@RequestParam(required = true) String username 
                                    ,@RequestParam(required = false) Integer age){

    System.out.println(&quot;username : &quot; + username);
    System.out.println(&quot;age : &quot; + age);

    return &quot;ok&quot;;
}</code></pre>
<ul>
<li>url<blockquote>
<p><a href="http://localhost:9090/request-param-required?username=test&amp;age=20">http://localhost:9090/request-param-required?username=test&amp;age=20</a>
/request-param-required                    -&gt; username이 없으므로 에러
/request-param-required?username=            -&gt; 빈 문자로 통과
/request-param-required?username=test        -&gt;null을 int에 입력하는 것이 불가능 , 따라서 Integer로 변경해야 함 </p>
</blockquote>
</li>
</ul>
<h4 id="다섯번째">다섯번째</h4>
<ul>
<li><p>defaultValue
파라미터 값이 없는 경우 defaultValue를 사용하면 기본값을 적용할 수 있다.
기본값이 있기 때문에 required는 의미가 없다
빈 문자열에도 적용된다.</p>
<pre><code class="language-java">@ResponseBody
@RequestMapping(&quot;/request-param-default&quot;)
public String requestParameDefault(
      @RequestParam(required = true, defaultValue = &quot;geust&quot;) String username ,
      @RequestParam(required = false, defaultValue = &quot;-1&quot;) Integer age){

  System.out.println(&quot;username : &quot; + username);
  System.out.println(&quot;age : &quot; + age);

  return &quot;ok&quot;;
}</code></pre>
</li>
<li><p>url</p>
<blockquote>
<p><a href="http://localhost:9090/request-param-default?username=test&amp;age=20">http://localhost:9090/request-param-default?username=test&amp;age=20</a>
/request-param-default?username=test&amp;age=20        -&gt; 
/request-param-default?username=test            -&gt; age는-1
/request-param-default?username=                -&gt;username = geust</p>
</blockquote>
</li>
</ul>
<h4 id="여섯번째">여섯번째</h4>
<ul>
<li><p>Map으로 조회하기</p>
<pre><code class="language-java">@ResponseBody
@RequestMapping(&quot;/request-param-map&quot;)
public String requestParamMap( @RequestParam Map&lt;String, Object&gt; paramMap ){

 System.out.println(&quot;username : &quot; + paramMap.get(&quot;username&quot;));
 System.out.println(&quot;age : &quot; + paramMap.get(&quot;age&quot;));

 return &quot;ok&quot;;
}</code></pre>
<ul>
<li>url<blockquote>
<p><a href="http://localhost:9090/request-param-default?username=test&amp;age=20">http://localhost:9090/request-param-default?username=test&amp;age=20</a></p>
</blockquote>
<h4 id="일곱번째">일곱번째</h4>
</li>
</ul>
</li>
<li><p>객체로 받기</p>
</li>
</ul>
<pre><code class="language-java">@ResponseBody
@RequestMapping(&quot;/model-attribute-v1&quot;)
public String modelAttributeV1( @RequestParam String username, @RequestParam int age ){

    helloData hello = new helloData();
    hello.setUsername(username);
    hello.setAge(age);

    System.out.println(&quot;username : &quot; + hello.getUsername());
    System.out.println(&quot;age : &quot; + hello.getAge());

    return &quot;ok&quot;;
}</code></pre>
<h4 id="여덟번째">여덟번째</h4>
<ul>
<li>ModelAttribute
파라미터를 받아서 필요한 객체를 만들고 그 객체에 값을 넣어주는 과정을 자동화!</li>
</ul>
<pre><code class="language-java">@ResponseBody
@RequestMapping(&quot;/model-attribute-v2&quot;)
public String modelAttributeV2(@ModelAttribute helloData helloData ){

    System.out.println(&quot;username : &quot; + helloData.getUsername());
    System.out.println(&quot;age : &quot; + helloData.getAge());
    System.out.println(&quot;hello : &quot; + helloData.toString());

    return &quot;ok2&quot;;
}</code></pre>
<ul>
<li>@ModelAttribute 생략가능<blockquote>
<p>String,int 같은 단순 타입    -&gt;  @RequestParam
객체                     -&gt; @ModelAttribute</p>
</blockquote>
</li>
</ul>
<h3 id="responseparam">ResponseParam</h3>
<p>ResponseParam은 값을 화면으로 넘겨준다.</p>
<h4 id="첫번째-1">첫번째</h4>
<ul>
<li>ModelAndView
controller 처리 결과 후 응답할 view 와 view에 전달할 값을 저장<pre><code class="language-java">@RequestMapping(&quot;/response-view-v1&quot;)
public ModelAndView responseViewV1() {
ModelAndView mav = new ModelAndView(&quot;response/hello&quot;).addObject(&quot;data&quot;,&quot;hello&quot;);
return mav;
</code></pre>
</li>
</ul>
<p>}</p>
<pre><code>### 두번째
 - @Controller에서 return이 String이면 view의 논리적인 이름이 된다.
```java
@ResponseBody    // 페이지를 이동하지않고 리턴된 문자열만 화면에 보여지게된다. 넣지안도록 주의한다.
@RequestMapping(&quot;/response-view-v2&quot;)
public String responseViewV2(Model model) {
    model.addAttribute(&quot;data&quot;, &quot;model data&quot;);

    return &quot;response/hello&quot;;

}</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[[ spring ] spring framework]]></title>
            <link>https://velog.io/@kong-al/spring-spring-framework</link>
            <guid>https://velog.io/@kong-al/spring-spring-framework</guid>
            <pubDate>Wed, 23 Nov 2022 00:12:29 GMT</pubDate>
            <description><![CDATA[<h2 id="spring-framework">spring framework</h2>
<p>경량 프레임워크(light-weight)
예전 프레임워크는 다양한 경우를 처리할 수 있는기능을 가지도록 만들다 보니 하나의 기능을 위해서 너무 많은 구조가 필요했다. 기술이 너무 복잡하고 방대했기때문에 전체를 이해하고 개발하기에는 어려움이 많아 스프링 프레임 워크가 등장했다.
특정 기능 위주로 간단한 jar파일등을 이용해서 모든 개발이 가능하도록 구성되어있다.</p>
<h3 id="장점">장점</h3>
<ul>
<li>복잡함에 반기를 들어 만들어진 프레임워크로 간편하다</li>
<li>프로젝트 전체 구조를 설계할 때 유용하다</li>
<li>다른 프레임 워크들을 포용하기에 여러 프레임워크를 혼용해서 사용가능하다</li>
<li>개발 생산성과 개발도구를 지원한다.</li>
</ul>
<h3 id="특징">특징</h3>
<blockquote>
</blockquote>
<ul>
<li><p>POJO기반의 구성</p>
</li>
<li><p>의존성 주입(DI)을 통한 객체간의 관계구성</p>
</li>
<li><p>AOP 지원</p>
</li>
<li><p>편리한 MVC구조</p>
</li>
<li><p>WAS에 종속적이지 않은 개발환경</p>
<h4 id="pojo기반의-구성">POJO기반의 구성</h4>
<p>Plain Old Java Object , 단순한 자바 오브젝트</p>
<p>POJO란 , 객체 지향적인 원리에 충실하면서 환경과 기술에 종속되지 않고 필요에 따라 재활용 될 수 있는     방식으로 설계된 오브젝트를 말한다.자바코드에서 일반적으로 객체를 구성하는 방식을 스프링 프레임워크에서 그대로 사용할 수 있다는 의미이다.</p>
<h4 id="의존성-주입-di을-통한-객체-간의-관계-구성--di--dependency-injection">의존성 주입 (DI)을 통한 객체 간의 관계 구성 ( DI : Dependency Injection)</h4>
<p>의존성(dependency) 이란 하나의 객체가 다른 객체 없이 제대로 된 역할을 할 수 없다는 것</p>
</li>
</ul>
<p>객체간의 의존성이 존재할 경우 개발자가 직접 객체를 생성하거나 제어하는것이 아니라 제어반전에 의하여 특정 객체에 필요한 다른 객체를 프레임워크가 자동으로 연결시켜주는 것을 말한다. 개발자는 자신에게 필요한 객체를 직접 할당하지 않고, 인터페이스를 통해 선언한 객체에 스프링 프레임워크에 의해 주입받아 사용할 수 있기때문에 비지니스 로직에만 집중 할 수있다. 개발자는 객체를 선언만 할 뿐 프레임 워크에서 자동으로 이루어진다.</p>
<ul>
<li><p>의존성
 ⓐ→→→→→→→→→→→ⓑ
 a 객체에서 b 객체를 직접 생성</p>
</li>
<li><p>의존성 주입
 ⓐ→→→→→????↔↔↔↔ⓑ
 a 객체는 b객체가 필요하다는 신호만 보내고, b 객체를 주입하는 것은 외부에서 이루어진다.</p>
<p>의존성 주입방식을 사용하기 위해서는 ????라는 존재가 필요하게 된다.
 스프링 프레임워크에서는 ApplicationContext가 ???라는 존재이며, 
 필요한 객체들을 생성하고, 필요한 객체들을 주입해 주는 역할을 한다.
 따라서 개발자들은 기존의 프로그래밍과 달리 객체와 객체를 분리해서 생성하고,
 이러한 객체들을 엮는 (Wri 작업의 형태로 개발하게 된다.</p>
</li>
</ul>
<p>   ApplicationContext가 관리하는 객체들을 &#39; 빈(Bean)&#39;이라 부르고, 
    빈과 빈 사이의 의존 관계를 처리하는 방식으로 어노테이션 , 필드주입 , 수정자주입 방식을 이용할 수 있다. </p>
<p>   @어노테이션</p>
<pre><code class="language-java">    private final MemberService memberService;
    @Autowired
    public MemberController(MemberService memberService) {
        this.memberService = memberService;
    }</code></pre>
<p>  필드주입(Field Injection)</p>
<pre><code class="language-java">//final 키워드를 사용할 수 없어, 순환참조가 발생할 수 있다. 권장하지 않는다.
@Autowired private final MemberService memberService;</code></pre>
<p>수정자 주입( Setter Injection )</p>
<pre><code class="language-java">//public으로 노출이 되깅떄문에 다른곳에서 주입이 가능하다.

private MemberService MemberService;
@Autowired
public void setMember(MemberService memberService) {
    this.memberService = memberService;
}</code></pre>
<h4 id="aop의-지원">AOP의 지원</h4>
<pre><code>관점지향 프로그래망</code></pre><p>  좋은 개발환경에서는 개발자가 비지니스 로직에만 집중 할 수 있게한다.
  스프링 프레임워크는 반복적인 코드를 제거해줌으로써 핵심 비지니스 로직에만 집중할 수 있도록 해준다.</p>
<p>  보안이나 로그 , 트랜잭션과 같이 비지니스 로직은 아니지만 반드시 처리가 필요한 부분을 횡단관심사라고 한다. 스프링 프레임 워크는 이런한 횡단 관심사를 분리해서 제작하는것이 가능하고 , 횡단관심사를 모듈로 분리하는 프로그래밍을 AOP라고 한다. 이를통해서 3가지 이점이 생긴다.</p>
<ul>
<li>핵심 비지니스 로직에만 집중하여 코드개발</li>
<li>각 프로젝트마다 다른 관심사 적용 시 코드 수정 최소화</li>
<li>원하는 관심사의 유지보수가 수월한 코드 구성 가능</li>
</ul>
<h4 id="was에-종속적이지-않은-개발-환경---단위-테스트">WAS에 종속적이지 않은 개발 환경 - 단위 테스트</h4>
<p> 전체 Application을 실행하지 않아도 기능별 단위 테스트가 용이하기 때문에 버그를 줄이고 개발 시간을 단축할 수 있다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[ framework ] framework 와 library]]></title>
            <link>https://velog.io/@kong-al/framework-framework-%EC%99%80-library</link>
            <guid>https://velog.io/@kong-al/framework-framework-%EC%99%80-library</guid>
            <pubDate>Tue, 22 Nov 2022 08:17:06 GMT</pubDate>
            <description><![CDATA[<h2 id="framework-와-library">framework 와 library</h2>
<h3 id="framework란">framework란</h3>
<blockquote>
<p>뼈대나 근간을 이루는 코드들의 묶음</p>
</blockquote>
<p>개발자는 각 개개인의 능력치가 큰 직종이고 개발자의 구성 ( 초급 , 중급 등) 에 따라 프로젝트의 결과 역시 크게 달라진다. 이런 상황을 극복하기 위한 코드의 결과물이 바로 프레임워크이다 . 프로그램의 기본 흐름이나 구조를 미리 정해두고 모든 팀원이 이 구조에 자신의 코드를 추가하는 방식으로 개발하게되어 개개인의 실력차이를 줄이고 유지보수에 용이한 형태로 개발이 진행된다.</p>
<p>Spring, Django, Ruby on Rails 등이 있다.</p>
<h3 id="library란">library란</h3>
<blockquote>
<p>자주 사용되는 로직을 재사용하기 편리하도록 잘 정리한 코드들의 집합</p>
</blockquote>
<p>프레임워크는 만들어둔 틀에서만 작업이 가능하다면 라이브러리는 내가 원하는대로 이용할수 있는 도구들의 모음이라고 볼수있다 . 프레임워크보다 자유도가 높아 꼭 사용하지 않아도 된다는 장점이 있다.</p>
<h3 id="공통점">공통점</h3>
<p>개발을 할 때 좀 더 편리하게 작업을 도와준다.</p>
<h3 id="차이점">차이점</h3>
<p>프레임워크는 꼭 짜여진 틀대로 작업해야하며 라이브러리는 내가 원하는대로 사용이 가능하다.</p>
<h2 id="프레임워크의-장-단점">프레임워크의 장, 단점</h2>
<h3 id="장점">장점</h3>
<ul>
<li><p>효율적</p>
</li>
<li><p>유지보수에 용이하다</p>
</li>
<li><p>이미 검증된 코드들을 이용하므로 버그 발생 가능성을 낮춰준다.</p>
<h3 id="단점">단점</h3>
<ul>
<li>학습시간이 오래걸린다</li>
<li>제약사항이 많다.</li>
</ul>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[ jsp ] summernote 이미지 업로드]]></title>
            <link>https://velog.io/@kong-al/jsp-summernote-%EC%9D%B4%EB%AF%B8%EC%A7%80-%EC%97%85%EB%A1%9C%EB%93%9C</link>
            <guid>https://velog.io/@kong-al/jsp-summernote-%EC%9D%B4%EB%AF%B8%EC%A7%80-%EC%97%85%EB%A1%9C%EB%93%9C</guid>
            <pubDate>Wed, 09 Nov 2022 08:32:43 GMT</pubDate>
            <description><![CDATA[<h2 id="-jsp--summernote">[ jsp ] summernote</h2>
<p>프로젝트를 진행하던 도중 재밌는 기능을 알게되었다.
사용법이 복잡하진 않았지만 검색 중 내가 원하는 결과대로 정리해둔 블로그가 없어 글을 작성한다.
(조각조각 찾으면 방법을 찾을 수 있지만 한번에 정리되어있지 않았다.다 스프링만있고....)</p>
<p>먼저 나는 servlet을 이용한 mvc2 패턴을 사용하였고 수정한 파일은
jsp파일/ frontcontroller / controller / dao / dto / xml
톰캣 server의 server.xml 파일이다.</p>
<p>파일업로드에 사용할 DTO를 먼저 만들어 주었다.</p>
<h3 id="dto">DTO</h3>
<pre><code class="language-java">public class FileDTO {
    private String file_path;
       private String file_name;

    public String getFile_path() {
        return file_path;
    }
    public void setFile_path(String file_path) {
        this.file_path = file_path;
    }
    public String getFile_name() {
        return file_name;
    }
    public void setFile_name(String file_name) {
        this.file_name = file_name;
    }
}
</code></pre>
<p>파일 insert / select 할 xml을 만들어준다.</p>
<h3 id="xml">XML</h3>
<pre><code class="language-xml">&lt;mapper namespace=&quot;File&quot;&gt;
    &lt;insert id=&quot;insert&quot; parameterType=&quot;filedto&quot;&gt;
        insert into TBL_FILE (file_path,file_name) VALUES(#{file_path},#{file_name})
    &lt;/insert&gt;
    &lt;select id=&quot;select&quot; parameterType=&quot;string&quot; resultType=&quot;filedto&quot;&gt;
        select * from TBL_FILE where file_name in (#{file_name})
    &lt;/select&gt;
&lt;/mapper&gt;
</code></pre>
<p>dao에서 xml에서 만든 쿼리를 사용한다.</p>
<h3 id="dao">DAO</h3>
<pre><code class="language-java">// insert
    public boolean Fileinsert(FileDTO fdto) {
        boolean check = false;
        if(sqlsession.insert(&quot;File.insert&quot;, fdto) != 0) {
            check = true;
        };
        return check;
    }

// select
    public FileDTO Fileselect(String file_name){
        return = sqlsession.selectOne(&quot;File.select&quot;, file_name);
    }</code></pre>
<p>jsp 파일에 summernote를 적용해준다.
보통 div나 textarea에 사용하며 내가 본 대부분의 블로그에서는 textarea에 사용하고있었다.</p>
<h3 id="jsp-파일">jsp 파일</h3>
<pre><code class="language-jsp">&lt;body&gt;
&lt;form action=&quot;&quot; method=&quot;post&quot; name=&quot;boardForm&quot;&gt;
    &lt;table&gt;
        &lt;tr align=&quot;center&quot; valign=&quot;middle&quot;&gt;
            &lt;td&gt;&lt;h3&gt;게시판&lt;/h3&gt;&lt;/td&gt;
        &lt;/tr&gt;
    &lt;/table&gt;

    &lt;table border=&quot;1&quot; style=&quot;border-collapse: collapse;&quot;&gt;
        &lt;tr height=&quot;30px;&quot;&gt;
            &lt;th align=&quot;center&quot; width=&quot;150px;&quot;&gt;제목&lt;/th&gt;
                &lt;td&gt;
                    &lt;input name=&quot;boardtitle&quot; size=&quot;50&quot; maxlength=&quot;100&quot; placeholder=&quot;제목을 입력하세요.&quot;&gt;
                &lt;/td&gt;
            &lt;/tr&gt;
        &lt;tr height=&quot;30px;&quot;&gt;
            &lt;th align=&quot;center&quot; width=&quot;150px;&quot;&gt;글쓴이&lt;/th&gt;
                &lt;td&gt;
                    &lt;input name=&quot;username&quot; size=&quot;50&quot; maxlength=&quot;20&quot; placeholder=&quot;이름을 입력하세요.&quot;&gt;
                &lt;/td&gt;
            &lt;/tr&gt;
        &lt;tr height=&quot;30px;&quot;&gt;
            &lt;th align=&quot;center&quot; width=&quot;150px;&quot;&gt;내용&lt;/th&gt;
            &lt;td&gt;&lt;textarea name=&quot;boardcontents&quot; id=&quot;summernote&quot;&gt;
                &lt;/textarea&gt;
            &lt;/td&gt;
        &lt;/tr&gt;
    &lt;/table&gt;
    &lt;table style=&quot;border: 0px;&quot;&gt;
        &lt;tr align=&quot;right&quot; valign=&quot;middle&quot;&gt;
            &lt;td&gt;
                &lt;a href=&quot;&quot;&gt;[등록]&lt;/a&gt;
                &lt;a href=&quot;&quot;&gt;[목록]&lt;/a&gt;
            &lt;/td&gt;
        &lt;/tr&gt;
    &lt;/table&gt;
&lt;/form&gt;    
&lt;script&gt;
// 썸머노트
    $(&#39;#summernote&#39;).summernote({ // summernote를 사용하기 위한 선언
        height: 350,
        callbacks: { // 콜백을 사용
               // 이미지를 업로드할 경우 이벤트를 발생
            onImageUpload: function(files, editor, welEditable) {
                sendFile(files[0], this);
            }
           }
    });


    function sendFile(files, editor) {
        // 파일 전송을 위한 폼생성
            data = new FormData();
            data.append(&quot;uploadFile&quot;, files);

            $.ajax({
                data: data,
                type: &quot;post&quot;,
                url: &quot;내가 원하는 url&quot;,
                 // 원래 있던 기능을 막기 위해
                 cache : false,
                contentType : false,    
                processData : false,

                success : function(data){
                    $(editor).summernote(&#39;editor.insertImage&#39;, data.url);
                }
            });
        }
&lt;/script&gt;    
&lt;/body&gt;</code></pre>
<h3 id="textarea에-summernote">textarea에 summernote</h3>
<pre><code class="language-jsp">&lt;textarea name=&quot;boardcontents&quot; id=&quot;summernote&quot;&gt;

&lt;/textarea&gt;</code></pre>
<p>jsp 파일에 있는거랑 똑같다 </p>
<h3 id="frontcontroller">frontcontroller</h3>
<pre><code class="language-java">@WebServlet(&quot;*.url경로&quot;)
public class 프론트컨트롤러 extends HttpServlet{

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) 
            throws ServletException, IOException {
        doProcess(req, resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) 
            throws ServletException, IOException {
        doProcess(req, resp);
    }

    protected void doProcess(HttpServletRequest req, HttpServletResponse resp) 
            throws ServletException, IOException {
        String requestURI = req.getRequestURI();
        ActionForward forward = null;

        switch(requestURI) {
            case &quot;jsp파일 ajax에서 적은 경로&quot;:
                /*컨트롤러 컨트롤러이름 = new 컨트롤러();
                   컨트롤러이름.execute(req, resp);*/
                IMGUploadAction imgUploadAction = new IMGUploadAction();
                   imgUploadAction.execute(req, resp);
                   break;
        }</code></pre>
<p>나는 컨트롤러를 인터페이스로 구현해 상속받은 후 무조건 이동할 페이지의 경로와 전달방식(forword/redirect) 를 리턴받는 방식으로 만들었다. 하지만 여기서는 페이지 이동없이 ajax로 db값만 받아올것이기 때문에 경로와 전달방식은 받아올 필요가 없다.</p>
<h3 id="controller">controller</h3>
<pre><code class="language-java">public class IMGUploadAction {
    public void execute(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        BoardDAO bdao = new BoardDAO();        // 쿼리를 실행해줄 dao
        FileDTO fdto = new FileDTO();        // db에서 가져온 파일을 담을 dto

        MultipartRequest multi = null;
        try {
            multi = new MultipartRequest(req, &quot;C:\\upload&quot;, // 업로드 될 경로를 지정
                    1000 * 1024 * 1024, // 파일의 크기를 지정(1000메가)
                    &quot;UTF-8&quot;, // 인코딩 방식
                    new DefaultFileRenamePolicy());
        } catch (IOException e) {
            e.printStackTrace();
        }

        Enumeration params = multi.getParameterNames();

        while (params.hasMoreElements()) {
            String name = (String) params.nextElement();
            String value = multi.getParameter(name);
        }
        Enumeration files = multi.getFileNames();

        while (files.hasMoreElements()) {
            String file_name = multi.getFilesystemName(name); // 파일 이름 얻기
            String file_path = file.getPath();

            if (file != null) {
            fdto.setFile_path(file_path);
            fdto.setFile_name(file_name);
              if(bdao.Fileinsert(fdto)) {  //  summernote로 받아온 파일 insert
                  JSONObject job = new JSONObject();
                  job.put(&quot;url&quot;,&quot;/upload/&quot;+bdao.Fileselect(file_name).getFile_name());
                  // 저장된 파일 select 해서 json으로 넣어주기
                  // /upload/ 는 server.xml에서 내가 지정해준 경로

                  resp.setContentType(&quot;application/json&quot;);

                  PrintWriter out = resp.getWriter();
                  out.print(job.toJSONString());

                }
            }
        }
    }
}</code></pre>
<p>톰캣서버는 로컬 폴더로 바로 접근이 불가능하기때문에 경로를 수정해 주어야한다.</p>
<h3 id="severxml">sever.xml</h3>
<pre><code class="language-xml">    &lt;Host&gt;
        &lt;Context path=&quot;/upload/&quot; reloadable=&quot;true&quot; docBase=&quot;C:/upload&quot;/&gt;
       &lt;/Host&gt;</code></pre>
<p>호스트 안에 context로 경로를 수정해 준다.
docBase에 로컬 폴더 경로를 넣고 path에 내가 톰캣으로 접근할 경로를 작성해준다.
docBase와 path가 연동 되어서 path를 입력하면 docBase에 접근할 수 있다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[ 도커 ] 톰캣 연결 오류 404 에러 ]]></title>
            <link>https://velog.io/@kong-al/%EB%8F%84%EC%BB%A4-%ED%86%B0%EC%BA%A3-%EC%97%B0%EA%B2%B0-%EC%98%A4%EB%A5%98-404-%EC%97%90%EB%9F%AC</link>
            <guid>https://velog.io/@kong-al/%EB%8F%84%EC%BB%A4-%ED%86%B0%EC%BA%A3-%EC%97%B0%EA%B2%B0-%EC%98%A4%EB%A5%98-404-%EC%97%90%EB%9F%AC</guid>
            <pubDate>Wed, 02 Nov 2022 02:35:23 GMT</pubDate>
            <description><![CDATA[<h2 id="도커-톰캣-연결-오류-404-에러">도커 톰캣 연결 오류 404 에러</h2>
<p>팀프로젝트를 시작하면서 팀원들과 개발환경을 통일하기 위하며 도커를 공부하게 되었다.
도커 프로그램을 잘 알지못하는 상태라 유투브 영상과 책을 보며 이론을 어느정도 안다고 생각했지만 막상 도커파일을 제작하려고하니 톰캣서버는 작동이 되지만 넣어준 war 파일을 인식하지 못하여 계속 404 오류가 나왔다.</p>
<p>다른 팀원들의 도움을 받아 많은 시행착오를 겪었지만 팀원의 컴퓨터에서는 작동을 하고(도커파일 사용x) 본인의 컴퓨터에서는 작동하지 않아 같이 알아보는것도 무의미해지던 중 war파일을 복사하지 않고 아니라 톰캣자체만 실행해보면 어떨까 싶어 실행 해보았는데 톰캣자체도 실행되지않아 war파일 문제가 아니라는것을 알게되었다.</p>
<h3 id="처음-작성했던-도커파일">처음 작성했던 도커파일.</h3>
<p><img src="https://velog.velcdn.com/images/kong-al/post/998a3898-7a93-405d-9028-583088a611f3/image.png" alt=""></p>
<p>톰캣9버전을 다운로드받고 
기존에 ROOT폴더를 삭제해준 뒤 
도커파일과 같은 선상에 담아둔 war파일을 이미지 안에있는 ROOT파일로 옮겨담아 주었다.
외부 포트번호와 연결할 이미지 내부포트번호를 지정해주었다.</p>
<h3 id="오류화면">오류화면</h3>
<p><img src="https://velog.velcdn.com/images/kong-al/post/a16e2e1c-5a49-4381-88a4-2328d446ce91/image.png" alt=""></p>
<p>외부포트번호를 8082로 연결해서 화면을 띄우니 404에러가 나왔다.
처음에 오류를 검색하니 저 화면이 뜨면 톰캣은 연결이 됐지만 내부에서 war파일을 찾지못하면 저렇게 오류가 나온다는 글이 많았다. 그래서 당연히 톰캣은 연결됐을꺼라고 생각하고 그 쪽을 의심해보지 않은 내탓이다.</p>
<p>우선 저렇게 오류가 났을 경우 생성한 도커 컨테이너에 war파일이 제대로 생성되어 있는지 확인해보았다.</p>
<p>터미널 창에</p>
<pre><code>$ docker ps</code></pre><p>를 검색하면 지금 도커에서 돌아가고 있는 컨터이너를 확인 할 수있다.</p>
<p><img src="https://velog.velcdn.com/images/kong-al/post/8eaf0938-a325-4565-844d-2019e3a508c6/image.png" alt=""></p>
<pre><code> docker exec -it [내가생성해준 컨테이너 이름 또는 컨테이너ID] /bin/bash
 docker exec -it tomtom /bin/bash</code></pre><p>명령어를 실행하면 생성한 컨테이너로 접속가능하다.</p>
<p><img src="https://velog.velcdn.com/images/kong-al/post/a885326d-ba72-4d09-b83a-f140bd800b98/image.png" alt=""></p>
<p>컨테이너에 접속한 채로</p>
<pre><code>ls</code></pre><p>명령어를 입력하면 컨테이너 안에 있는 폴더의 리스트를 확인 할 수 있다.</p>
<p><img src="https://velog.velcdn.com/images/kong-al/post/5db0c19f-09c1-48e8-8b5d-9d69fd0500f3/image.png" alt=""></p>
<pre><code>cd webapps</code></pre><p>webapps에 접속 후</p>
<pre><code>ls</code></pre><p>를 검색하면 
webapps안에 있는 파일을 볼수있다.
<img src="https://velog.velcdn.com/images/kong-al/post/1ed54c1b-be53-45d1-bbc0-91243629426b/image.png" alt=""></p>
<p>위와 마찬가지로</p>
<pre><code>cd ROOT</code></pre><p>ROOT에 접속 후</p>
<pre><code>ls</code></pre><p>를 검색하면 ROOT안에 있는 파일들을 볼 수있으며, 내가 만든 war파일이 제대로 들어가있는걸 확인 할 수있다.
<img src="https://velog.velcdn.com/images/kong-al/post/a90ec8d5-1201-460a-9ffd-d4876cd06f9c/image.png" alt=""></p>
<p>이 때 톰캣오류를 의심했어야하는데 계속 war 파일을 의심하며 war 파일을 구동할때 필요한 로컬에 설치되어있는 자바, 오라클 , 톰캣도 삭제해보고 ( 이 때 , 다른팀원분이 war파일 import 해보면 lib에 담겨있는 jar파일들이 빌드패스가 안되어있다고 빌드패스 후 새로 war파일 export해서 도커에 올리니 잘 작동한다고 하셨다. 다음에 안된다면 이부분도 확인해보는게 좋겠다.) 새벽까지 난리를 쳤지만 딱히 실행이 되진 않았다. </p>
<p>다음날 도커파일을 이용하지 않고 터미널로 톰캣서버부터 하나씩 확인해가는 과정중 톰캣이 그냥 문제였던것을 알게되었다.</p>
<p>도커 톰캣 설치</p>
<pre><code>docker run -d -it -p [로컬에서 접근할 포트번호]:8080 --name [생성할 컨테이너 이름] [다운로드할 톰캣버전]

docker run -d -it -p 8888:8080 --name tomom tomcat:9</code></pre><p>톰캣을 설치 후 localhost:8888 로 접근하면 tomcat 홈페이지가 나와야한다고 했다.
하지만 내가 본 화면은 절망스러운 404..........</p>
<p><img src="https://velog.velcdn.com/images/kong-al/post/68f851bd-d989-4690-b590-ad737dbc05e1/image.png" alt="">tomom</p>
<p> 이 때부터는 톰캣 오류를 해결하는 방법을 찾기 시작했고 해결책은 간단했다.
 내부 접근법은 위에서 작성했으므로 생략하였다.</p>
<pre><code>docker exec -it tomom /bin/bash
mv webapps webapps2
mv webapps.dist/ webapps
exit</code></pre><p> 위에서 부터 한줄씩 입력해주었다. 
 여러 글들을 찾아 보았지만 아직 저 오류의 원인은 알지못하였고 해결방법만 돌아다닐 뿐이여서 아쉬웠다.
 하나씩 입력하고 재접속 해보면 이렇게 귀여운 톰캣이 그려져있는 홈페이지가 나온다!</p>
<p> <img src="https://velog.velcdn.com/images/kong-al/post/33527393-083b-4e24-9e39-5ef1a98ce68e/image.png" alt=""></p>
<p>톰캣 서버오류를 해결했으므로 war파일을 톰캣서버가 돌아가고있는 컨테이너로 복사해주었다.</p>
<pre><code>docker cp [복사할 파일이 있는 경로] tomtom:/usr/local/tomcat/webapps</code></pre><p>윈도우 cmd창에 내가 복사하기 원하는 파일은 드래그로 가져다 놓으면 파일의 현재 경로를 알려준다 !
(파워쉘은 안됨 ㅎ)</p>
<p>파일을 복사한 후 </p>
<pre><code>docker exec -it tomom /bin/bash
ls
cd webapps
ls
cd ROOT
ls</code></pre><p>순차적으로 명령어를 입력하여 제대로 ROOT.war 파일이 들어간것을 확인할 수 있다!
<img src="https://velog.velcdn.com/images/kong-al/post/63a18cc5-4c63-41b6-8b18-71f004bdcdea/image.png" alt=""></p>
<p>완료하고 잠시후 새로고침해보면 톰캣사이트에서 내가 넣은 파일로 변경된 것을 확인 할 수있다!</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[프로그래머스LV1 - 최소직사각형]]></title>
            <link>https://velog.io/@kong-al/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4LV1-%EC%B5%9C%EC%86%8C%EC%A7%81%EC%82%AC%EA%B0%81%ED%98%95</link>
            <guid>https://velog.io/@kong-al/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4LV1-%EC%B5%9C%EC%86%8C%EC%A7%81%EC%82%AC%EA%B0%81%ED%98%95</guid>
            <pubDate>Sun, 16 Oct 2022 13:53:42 GMT</pubDate>
            <description><![CDATA[<h2 id="221015-d-78">22.10.15 D-78</h2>
<h2 id="프로그래머스lv1---최소직사각형">프로그래머스LV1 - 최소직사각형</h2>
<p><img src="https://velog.velcdn.com/images/kong-al/post/c54cb2f4-3a81-4c16-8cd7-4ac679e42a78/image.png" alt=""></p>
<p>[ 답안 ]</p>
<pre><code class="language-java">class Solution {
    public int solution(int[][] sizes) {
        int answer = 0 ;
        int max_w = 0; 
        int max_h = 0; 

        for(int i = 0 ; i &lt; sizes.length; i++){ 
            if(sizes[i][0] &lt; sizes[i][1]){
                int a = sizes[i][0];
                sizes[i][0] = sizes[i][1];
                sizes[i][1] = a;
            }
            if(max_w &lt; sizes[i][0]) max_w = sizes[i][0]; 
            if(max_h &lt; sizes[i][1]) max_h = sizes[i][1];
        }

        answer = max_w * max_h; 
        return answer;


}}</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[프로그래머스LV1 - 이상한 문자 만들기]]></title>
            <link>https://velog.io/@kong-al/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4LV1-%EC%9D%B4%EC%83%81%ED%95%9C-%EB%AC%B8%EC%9E%90-%EB%A7%8C%EB%93%A4%EA%B8%B0</link>
            <guid>https://velog.io/@kong-al/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4LV1-%EC%9D%B4%EC%83%81%ED%95%9C-%EB%AC%B8%EC%9E%90-%EB%A7%8C%EB%93%A4%EA%B8%B0</guid>
            <pubDate>Sun, 16 Oct 2022 13:24:36 GMT</pubDate>
            <description><![CDATA[<h2 id="221015-d-78">22.10.15 D-78</h2>
<h2 id="프로그래머스lv1---이상한-문자-만들기">프로그래머스LV1 - 이상한 문자 만들기</h2>
<p><img src="https://velog.velcdn.com/images/kong-al/post/34069479-7810-43fe-965a-b96251f8e0d0/image.png" alt=""></p>
<p>[ 답안 ]</p>
<pre><code class="language-java">class Solution {
    public String solution(String s) {
        String answer = &quot;&quot;;
        String[] str = s.split(&quot;&quot;);

        int cnt = 0;
        for(int i=0; i&lt;str.length; i++) {
            if(str[i].equals(&quot; &quot;)) {
                cnt = 0;
            } else if(cnt % 2 == 0) {
                str[i] = str[i].toUpperCase();
                cnt++;
            } else if(cnt % 2 != 0) {
                str[i] = str[i].toLowerCase();
                cnt++;
            }
            answer += str[i];
        } 

        return answer;
    }
}</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[프로그래머스LV1 - 행렬의 덧셈]]></title>
            <link>https://velog.io/@kong-al/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4LV1-%ED%96%89%EB%A0%AC%EC%9D%98-%EB%8D%A7%EC%85%88</link>
            <guid>https://velog.io/@kong-al/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4LV1-%ED%96%89%EB%A0%AC%EC%9D%98-%EB%8D%A7%EC%85%88</guid>
            <pubDate>Fri, 14 Oct 2022 08:24:35 GMT</pubDate>
            <description><![CDATA[<h2 id="221014-d-79">22.10.14 D-79</h2>
<h2 id="프로그래머스lv1---행렬의-덧셈">프로그래머스LV1 - 행렬의 덧셈</h2>
<p><img src="https://velog.velcdn.com/images/kong-al/post/72e6d75d-bba1-4a18-8b18-77ece6b27c81/image.png" alt=""></p>
<p>[ 답안 ]</p>
<pre><code class="language-java">class Solution {
    public int[][] solution(int[][] arr1, int[][] arr2) {

        for(int i = 0; i &lt; arr1.length; i++){
            for(int j = 0; j &lt;arr1[0].length; j++){
              arr1[i][j] += arr2[i][j];  
            }
        }
        return arr1;
    }
}</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[프로그래머스LV1 - 콜라츠 추측]]></title>
            <link>https://velog.io/@kong-al/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4LV1-%EC%BD%9C%EB%9D%BC%EC%B8%A0-%EC%B6%94%EC%B8%A1</link>
            <guid>https://velog.io/@kong-al/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4LV1-%EC%BD%9C%EB%9D%BC%EC%B8%A0-%EC%B6%94%EC%B8%A1</guid>
            <pubDate>Thu, 13 Oct 2022 08:29:12 GMT</pubDate>
            <description><![CDATA[<h2 id="프로그래머스lv1---콜라츠-추측">프로그래머스LV1 - 콜라츠 추측</h2>
<p><img src="https://velog.velcdn.com/images/kong-al/post/83562bb9-e15a-49fc-9f0a-9ae5163852b5/image.png" alt=""></p>
<p>[ 답안 ]</p>
<pre><code class="language-java">class Solution {
        public long solution(long num) {
            long answer = 0;
            while(num &gt; 1){
                num =(num%2==0)?num/2:num*3+1;
                answer++;
                if(answer &gt; 500) {
                    answer = -1;
                    break;
                }
            }
            return answer;
        }
    }</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[프로그래머스LV1 - 음양 더하기]]></title>
            <link>https://velog.io/@kong-al/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4LV1-%EC%9D%8C%EC%96%91-%EB%8D%94%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@kong-al/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4LV1-%EC%9D%8C%EC%96%91-%EB%8D%94%ED%95%98%EA%B8%B0</guid>
            <pubDate>Thu, 13 Oct 2022 08:04:46 GMT</pubDate>
            <description><![CDATA[<h2 id="프로그래머스lv1---음양-더하기">프로그래머스LV1 - 음양 더하기</h2>
<p><img src="https://velog.velcdn.com/images/kong-al/post/65c75fc5-6b0e-4e97-ae68-50043cff705b/image.png" alt=""></p>
<p>[ 답안 ]</p>
<pre><code class="language-java">class Solution {
        public int solution(int[] absolutes, boolean[] signs) {
            int answer = 0;
            String buho = &quot;&quot;;
            for(int i = 0 ; i &lt; absolutes.length;i++){
                buho = (signs[i])? &quot;+&quot; : &quot;-&quot; ;
                answer += Integer.parseInt(buho+absolutes[i]);
            }
            return answer;
        }
    }</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[프로그래머스LV1 - 없는 숫자 더하기]]></title>
            <link>https://velog.io/@kong-al/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4LV1-%EC%95%BD%EC%88%98%EC%9D%98-%EA%B0%9C%EC%88%98%EC%99%80-%EB%8D%A7%EC%85%88-jrs5edzc</link>
            <guid>https://velog.io/@kong-al/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4LV1-%EC%95%BD%EC%88%98%EC%9D%98-%EA%B0%9C%EC%88%98%EC%99%80-%EB%8D%A7%EC%85%88-jrs5edzc</guid>
            <pubDate>Thu, 13 Oct 2022 07:43:57 GMT</pubDate>
            <description><![CDATA[<h2 id="프로그래머스lv1---없는-숫자-더하기">프로그래머스LV1 - 없는 숫자 더하기</h2>
<p><img src="https://velog.velcdn.com/images/kong-al/post/2ee46d21-e4f8-4e8f-a82b-393bb09682df/image.png" alt=""></p>
<p>[ 답안 ]</p>
<pre><code class="language-java">class Solution {
    public int solution(int[] numbers) {
        int answer = 45;
        for(int i = 0 ; i &lt; numbers.length;i++){
            answer -= numbers[i];
        }
        return answer;    
    }
}</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[프로그래머스LV1 - 약수의 개수와 덧셈]]></title>
            <link>https://velog.io/@kong-al/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4LV1-%EC%95%BD%EC%88%98%EC%9D%98-%EA%B0%9C%EC%88%98%EC%99%80-%EB%8D%A7%EC%85%88</link>
            <guid>https://velog.io/@kong-al/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4LV1-%EC%95%BD%EC%88%98%EC%9D%98-%EA%B0%9C%EC%88%98%EC%99%80-%EB%8D%A7%EC%85%88</guid>
            <pubDate>Thu, 13 Oct 2022 07:36:08 GMT</pubDate>
            <description><![CDATA[<h2 id="221013-d-80">22.10.13 D-80</h2>
<h2 id="프로그래머스lv1---약수의-개수와-덧셈">프로그래머스LV1 - 약수의 개수와 덧셈</h2>
<p><img src="https://velog.velcdn.com/images/kong-al/post/fa901194-a117-4c76-9189-d2c7a1dfc8be/image.png" alt=""></p>
<p>[ 답안 ]</p>
<pre><code class="language-java">class Solution {
        public int solution(int left, int right) {
            int answer=0;
            // 반복문으로 
            for(int i=left; i&lt;=right; i++){
                int cnt=0;
                for(int j=1; j&lt;=i; j++){
                    if(i%j==0) {cnt++;}
                }
                answer = (cnt%2==0)? answer+i : answer-i;

            }
            return answer;
        }
    }</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[프로그래머스LV1 - 내적]]></title>
            <link>https://velog.io/@kong-al/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4LV1-%EB%82%B4%EC%A0%81</link>
            <guid>https://velog.io/@kong-al/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4LV1-%EB%82%B4%EC%A0%81</guid>
            <pubDate>Wed, 12 Oct 2022 11:59:05 GMT</pubDate>
            <description><![CDATA[<h2 id="20221012">2022.10.12</h2>
<h2 id="프로그래머스lv1---내적">프로그래머스LV1 - 내적</h2>
<p><img src="https://velog.velcdn.com/images/kong-al/post/ca52c025-3329-4341-a71b-bee0c2723cb9/image.png" alt=""></p>
<p>[ 답안 ]</p>
<pre><code class="language-java">class Solution {
     public int solution(int[] a, int[] b) {
         int answer = 0;
         for(int i = 0 ; i&lt;a.length;i++) {
              answer += a[i]*b[i];
        }
        return answer;
    }
}</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[프로그래머스LV1 - 부족한 금액 계산하기
]]></title>
            <link>https://velog.io/@kong-al/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4LV1-%EB%B6%80%EC%A1%B1%ED%95%9C-%EA%B8%88%EC%95%A1-%EA%B3%84%EC%82%B0%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@kong-al/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4LV1-%EB%B6%80%EC%A1%B1%ED%95%9C-%EA%B8%88%EC%95%A1-%EA%B3%84%EC%82%B0%ED%95%98%EA%B8%B0</guid>
            <pubDate>Wed, 12 Oct 2022 11:37:45 GMT</pubDate>
            <description><![CDATA[<h2 id="프로그래머스lv1---부족한-금액-계산하기">프로그래머스LV1 - 부족한 금액 계산하기</h2>
<p><img src="https://velog.velcdn.com/images/kong-al/post/055dc283-6a39-4308-9cdb-4bb615d50e6c/image.png" alt=""></p>
<p>[ 답안 ]</p>
<pre><code class="language-java">class Solution {
        // money의 범위가 int를 벗어나므로 long으로 받아온다.
        public long solution(long price, long money, long count) {
            long answer = 0;
            for(int i = 1 ; i &lt;= count ; i++) {
                money -= price*i;
            }
            if(money &lt; 0 ) {
                answer = Math.abs(money);
            }else {
                answer = 0 ;
            }
            return answer;
        }
    }</code></pre>
<p>삼항연산자를 이용한 풀이</p>
<pre><code class="language-java">class Solution {
     public long solution(long price, long money, long count) {
         long answer = 0;
         for(int i = 1 ; i &lt;= count ; i++) {
            money -= price*i;
         }
         answer=(money &lt; 0)? Math.abs(money): 0 ;
         return answer;
     }
}</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[프로그래머스LV2 - 최솟값 만들기
]]></title>
            <link>https://velog.io/@kong-al/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4LV2-%EC%B5%9C%EC%86%9F%EA%B0%92-%EB%A7%8C%EB%93%A4%EA%B8%B0</link>
            <guid>https://velog.io/@kong-al/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4LV2-%EC%B5%9C%EC%86%9F%EA%B0%92-%EB%A7%8C%EB%93%A4%EA%B8%B0</guid>
            <pubDate>Wed, 12 Oct 2022 11:26:25 GMT</pubDate>
            <description><![CDATA[<h2 id="프로그래머스lv2---최솟값-만들기">프로그래머스LV2 - 최솟값 만들기</h2>
<p><img src="https://velog.velcdn.com/images/kong-al/post/1638fcd2-496c-40b0-9134-270e3c79da28/image.png" alt=""></p>
<p>[ 답안 ]</p>
<pre><code class="language-java">import java.util.Arrays;    
class Solution{
        public int solution(int []A, int []B){
        int answer = 0;
            // 배열 오름차순 정렬
            Arrays.sort(A);
            Arrays.sort(B);
            // B배열을 B1배열에 역순으로 넣어 내림차순으로 정렬
            int[] B1 = new int[A.length];
            for(int i =0; i &lt; B.length;i++) {
                B1[i] = B[(B.length-1)-i];
            }
            // 오름차순으로 정렬된A배열과 내림차순으로 정렬된B배열의
            // 같은 인덱스값을 곱해서 answer에 순차적으로 더해줌
            for(int i =0; i &lt; B.length;i++) {
                answer += A[i]*B1[i];
            }
            return answer;
        }
    }</code></pre>
<p>내림차순으로 정렬할 필요가 없다는것을 깨닫게됨</p>
<pre><code class="language-java">class Solution{
        public int solution(int []A, int []B){
        int answer = 0;
            Arrays.sort(A);
            Arrays.sort(B);
            for(int i =0; i &lt; B.length;i++) {
                answer += A[i]*B[(B.length-1)-i];
            }
            System.out.println(answer);
            return answer;
        }
    }</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[프로그래머스LV1 - 직사각형 별찍기]]></title>
            <link>https://velog.io/@kong-al/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4LV1-%EC%A7%81%EC%82%AC%EA%B0%81%ED%98%95-%EB%B3%84%EC%B0%8D%EA%B8%B0</link>
            <guid>https://velog.io/@kong-al/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4LV1-%EC%A7%81%EC%82%AC%EA%B0%81%ED%98%95-%EB%B3%84%EC%B0%8D%EA%B8%B0</guid>
            <pubDate>Tue, 11 Oct 2022 13:05:57 GMT</pubDate>
            <description><![CDATA[<h2 id="프로그래머스lv1---직사각형-별찍기">프로그래머스LV1 - 직사각형 별찍기</h2>
<p><img src="https://velog.velcdn.com/images/kong-al/post/7e6bc4c8-1b8a-417d-a0c5-0e37cc8ccec3/image.png" alt=""></p>
<p>[ 답안 ]</p>
<pre><code class="language-java">class Solution {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int a = sc.nextInt();
        int b = sc.nextInt();

        for(int i = 0 ; i &lt; b ; i++){
            for(int j =0 ; j &lt; a ; j++){
                System.out.print(&quot;*&quot;);
            }
            System.out.println();
        }
    }
}</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[프로그래머스LV1 - 문자열 내림차순으로 배치하기]]></title>
            <link>https://velog.io/@kong-al/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4LV1-%EB%AC%B8%EC%9E%90%EC%97%B4-%EB%82%B4%EB%A6%BC%EC%B0%A8%EC%88%9C%EC%9C%BC%EB%A1%9C-%EB%B0%B0%EC%B9%98%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@kong-al/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4LV1-%EB%AC%B8%EC%9E%90%EC%97%B4-%EB%82%B4%EB%A6%BC%EC%B0%A8%EC%88%9C%EC%9C%BC%EB%A1%9C-%EB%B0%B0%EC%B9%98%ED%95%98%EA%B8%B0</guid>
            <pubDate>Tue, 11 Oct 2022 12:58:18 GMT</pubDate>
            <description><![CDATA[<h2 id="프로그래머스lv1---문자열-내림차순으로-배치하기">프로그래머스LV1 - 문자열 내림차순으로 배치하기</h2>
<p><img src="https://velog.velcdn.com/images/kong-al/post/50037457-5c55-43de-b9d9-63bffc6f3e84/image.png" alt=""></p>
<p>[ 답안 ]</p>
<pre><code class="language-java">import java.util.Arrays;

class Solution {
    public String solution(String s) {
        String answer = &quot;&quot;;
        char[] string = s.toCharArray();
        Arrays.sort(string);
        for(int i = string.length-1  ; i &gt;= 0 ; i--){
            answer+= string[i];
        }
        return answer;
    }
}</code></pre>
<p>오름차순으로 정리한걸 역순으로 넣어 내침차순으로 바꿨다. </p>
<p>re</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[프로그래머스LV1 - 가운데 글자 가져오기]]></title>
            <link>https://velog.io/@kong-al/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4LV1-%EA%B0%80%EC%9A%B4%EB%8D%B0-%EA%B8%80%EC%9E%90-%EA%B0%80%EC%A0%B8%EC%98%A4%EA%B8%B0</link>
            <guid>https://velog.io/@kong-al/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4LV1-%EA%B0%80%EC%9A%B4%EB%8D%B0-%EA%B8%80%EC%9E%90-%EA%B0%80%EC%A0%B8%EC%98%A4%EA%B8%B0</guid>
            <pubDate>Tue, 11 Oct 2022 12:49:50 GMT</pubDate>
            <description><![CDATA[<h2 id="221008-d-85">22.10.08 D-85</h2>
<h2 id="프로그래머스lv1---가운데-글자-가져오기">프로그래머스LV1 - 가운데 글자 가져오기</h2>
<p><img src="https://velog.velcdn.com/images/kong-al/post/3d26985a-f79d-4e5f-a88d-0ac19e0357b2/image.png" alt=""></p>
<p>[ 답안 ]</p>
<pre><code class="language-java">class Solution {
    public String solution(String s) {
        String answer = &quot;&quot;;
        if(s.length() % 2 == 0){
            answer = s.substring(s.length()/2 - 1, s.length()/2 + 1);
        }else { 
            answer = s.substring(s.length()/2, s.length()/2 + 1);
        }
        return answer;
    }
}</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[프로그래머스LV1 - 수박수박수박수박수박수?
]]></title>
            <link>https://velog.io/@kong-al/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4LV1-%EC%88%98%EB%B0%95%EC%88%98%EB%B0%95%EC%88%98%EB%B0%95%EC%88%98%EB%B0%95%EC%88%98%EB%B0%95%EC%88%98</link>
            <guid>https://velog.io/@kong-al/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4LV1-%EC%88%98%EB%B0%95%EC%88%98%EB%B0%95%EC%88%98%EB%B0%95%EC%88%98%EB%B0%95%EC%88%98%EB%B0%95%EC%88%98</guid>
            <pubDate>Tue, 11 Oct 2022 12:43:55 GMT</pubDate>
            <description><![CDATA[<h2 id="프로그래머스lv1---수박수박수박수박수박수">프로그래머스LV1 - 수박수박수박수박수박수?</h2>
<p><img src="https://velog.velcdn.com/images/kong-al/post/92828d1d-4813-4cf3-8f5b-16985c358c21/image.png" alt=""></p>
<p>[ 답안 ]</p>
<pre><code class="language-java">class Solution {
    public String solution(int n) {
        String answer = &quot;&quot;;
        for(int i = 0 ; i &lt; n ; i++){
           answer+= (i%2==0)?&quot;수&quot;:&quot;박&quot;;           
        }
        return answer;
    }
}</code></pre>
]]></description>
        </item>
    </channel>
</rss>