<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>데브스퀘어의 프로그래밍 블로그</title>
    <link>https://devsquare.tistory.com/</link>
    <description></description>
    <language>ko</language>
    <pubDate>Wed, 12 Aug 2026 03:24:28 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>몽실KUN</managingEditor>
    <item>
      <title>Google PubSub</title>
      <link>https://devsquare.tistory.com/42</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://cloud.google.com/pubsub/docs/spring&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://cloud.google.com/pubsub/docs/spring&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1644372519922&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Spring 애플리케이션에서 Pub/Sub 사용 &amp;nbsp;|&amp;nbsp; Google Cloud&quot; data-og-description=&quot;의견 보내기 Spring 애플리케이션에서 Pub/Sub 사용 이 페이지에서는 Spring Framework로 빌드된 자바 애플리케이션에서 Pub/Sub를 사용하는 방법을 설명합니다. Spring Cloud GCP에는 Spring Framework를 사용하여 &quot; data-og-host=&quot;cloud.google.com&quot; data-og-source-url=&quot;https://cloud.google.com/pubsub/docs/spring&quot; data-og-url=&quot;https://cloud.google.com/pubsub/docs/spring?hl=ko&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/KF4h7/hyNlsu6pQJ/rvkVadKvivCe995d9Ndqpk/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630&quot;&gt;&lt;a href=&quot;https://cloud.google.com/pubsub/docs/spring&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://cloud.google.com/pubsub/docs/spring&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/KF4h7/hyNlsu6pQJ/rvkVadKvivCe995d9Ndqpk/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Spring 애플리케이션에서 Pub/Sub 사용 &amp;nbsp;|&amp;nbsp; Google Cloud&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;의견 보내기 Spring 애플리케이션에서 Pub/Sub 사용 이 페이지에서는 Spring Framework로 빌드된 자바 애플리케이션에서 Pub/Sub를 사용하는 방법을 설명합니다. Spring Cloud GCP에는 Spring Framework를 사용하여&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;cloud.google.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/GoogleCloudPlatform/spring-cloud-gcp/tree/main/spring-cloud-gcp-samples/spring-cloud-gcp-integration-pubsub-sample&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://github.com/GoogleCloudPlatform/spring-cloud-gcp/tree/main/spring-cloud-gcp-samples/spring-cloud-gcp-integration-pubsub-sample&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1644372372217&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;object&quot; data-og-title=&quot;GitHub - GoogleCloudPlatform/spring-cloud-gcp: New home for Spring Cloud GCP development starting with version 2.0.&quot; data-og-description=&quot;New home for Spring Cloud GCP development starting with version 2.0. - GitHub - GoogleCloudPlatform/spring-cloud-gcp: New home for Spring Cloud GCP development starting with version 2.0.&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/GoogleCloudPlatform/spring-cloud-gcp/tree/main/spring-cloud-gcp-samples/spring-cloud-gcp-integration-pubsub-sample&quot; data-og-url=&quot;https://github.com/GoogleCloudPlatform/spring-cloud-gcp&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/b67Hvt/hyNmC3Yb8L/nnBz65JDbuHEVOtjO6ULMK/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600&quot;&gt;&lt;a href=&quot;https://github.com/GoogleCloudPlatform/spring-cloud-gcp/tree/main/spring-cloud-gcp-samples/spring-cloud-gcp-integration-pubsub-sample&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/GoogleCloudPlatform/spring-cloud-gcp/tree/main/spring-cloud-gcp-samples/spring-cloud-gcp-integration-pubsub-sample&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/b67Hvt/hyNmC3Yb8L/nnBz65JDbuHEVOtjO6ULMK/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;GitHub - GoogleCloudPlatform/spring-cloud-gcp: New home for Spring Cloud GCP development starting with version 2.0.&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;New home for Spring Cloud GCP development starting with version 2.0. - GitHub - GoogleCloudPlatform/spring-cloud-gcp: New home for Spring Cloud GCP development starting with version 2.0.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1) auth json 파일&amp;nbsp;&lt;/b&gt;&lt;br /&gt;&amp;nbsp;공식 가이드에는 환경변수를 잡는 것으로 되어 있던데 굳이 그럴 필요 없이 classpath에 위치시켜 주면 된다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;application.yml&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1644372939483&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;spring:
  cloud:
    gcp:
      credentials:
        location: classpath:/integrated-log.json
      project-id: integrated-log
      topic: jsonrpc-test-topic&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;integrated-log.json&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1644373141263&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;{
	&quot;type&quot;: &quot;service_account&quot;,
	&quot;project_id&quot;: &quot;integrated-log&quot;,
	&quot;private_key_id&quot;: &quot;*********&quot;,
	&quot;private_key&quot;: &quot;*********&quot;,
	&quot;client_email&quot;: &quot;*********@*******.com&quot;,
	&quot;client_id&quot;: &quot;*********&quot;,
	&quot;auth_uri&quot;: &quot;https://accounts.google.com/o/oauth2/auth&quot;,
	&quot;token_uri&quot;: &quot;https://oauth2.googleapis.com/token&quot;,
	&quot;auth_provider_x509_cert_url&quot;: &quot;https://www.googleapis.com/oauth2/v1/certs&quot;,
	&quot;client_x509_cert_url&quot;: &quot;https://www.googleapis.com/robot/v1/metadata/x509/*********%40*********.com&quot;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;참조&lt;br /&gt;&lt;a href=&quot;https://velog.io/@caesars000/Spring-Boot%EC%97%90%EC%84%9C-Google-Cloud-Pub-%ED%99%9C%EC%9A%A9-%EC%98%88%EC%A0%9C&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://velog.io/@caesars000/Spring-Boot%EC%97%90%EC%84%9C-Google-Cloud-Pub-%ED%99%9C%EC%9A%A9-%EC%98%88%EC%A0%9C&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1644372896049&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;Spring Boot에서 Google Cloud Pub 활용 예제&quot; data-og-description=&quot;해당 글에서는 스프링 부트 환경에서 Google Cloud Pub 예제 코드를 소개합니다. 발행만 하고 구독을 하지 않기에 Sub를 제외했습니다.해당 링크(https://cloud.google.com/docs/authentication/getting-start&quot; data-og-host=&quot;velog.io&quot; data-og-source-url=&quot;https://velog.io/@caesars000/Spring-Boot%EC%97%90%EC%84%9C-Google-Cloud-Pub-%ED%99%9C%EC%9A%A9-%EC%98%88%EC%A0%9C&quot; data-og-url=&quot;https://velog.io/@caesars000/Spring-Boot에서-Google-Cloud-Pub-활용-예제&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/y6pGJ/hyNlpFaSrB/VMX3vblPo4yyCVjlqS89k1/img.png?width=346&amp;amp;height=146&amp;amp;face=0_0_346_146,https://scrap.kakaocdn.net/dn/ypZVX/hyNllW4WOH/LkguofdfItO49VJmiXnJ90/img.png?width=346&amp;amp;height=146&amp;amp;face=0_0_346_146&quot;&gt;&lt;a href=&quot;https://velog.io/@caesars000/Spring-Boot%EC%97%90%EC%84%9C-Google-Cloud-Pub-%ED%99%9C%EC%9A%A9-%EC%98%88%EC%A0%9C&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://velog.io/@caesars000/Spring-Boot%EC%97%90%EC%84%9C-Google-Cloud-Pub-%ED%99%9C%EC%9A%A9-%EC%98%88%EC%A0%9C&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/y6pGJ/hyNlpFaSrB/VMX3vblPo4yyCVjlqS89k1/img.png?width=346&amp;amp;height=146&amp;amp;face=0_0_346_146,https://scrap.kakaocdn.net/dn/ypZVX/hyNllW4WOH/LkguofdfItO49VJmiXnJ90/img.png?width=346&amp;amp;height=146&amp;amp;face=0_0_346_146');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Spring Boot에서 Google Cloud Pub 활용 예제&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;해당 글에서는 스프링 부트 환경에서 Google Cloud Pub 예제 코드를 소개합니다. 발행만 하고 구독을 하지 않기에 Sub를 제외했습니다.해당 링크(https://cloud.google.com/docs/authentication/getting-start&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;velog.io&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2) 수신자(receiver)&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;전반적인 내용은 예제와 같다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;ReceiverConfig&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1644373212725&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;@Configuration
public class ReceiverConfig 
{	
	Logger logger = LoggerFactory.getLogger(getClass());
	@Bean
	public MessageChannel inputMessageChannel()
	{
		return new PublishSubscribeChannel();
	}
	
	
	
	@Bean
	public PubSubInboundChannelAdapter inboundChannelAdapter(
		@Qualifier(&quot;inputMessageChannel&quot;) MessageChannel messageChannel,
		PubSubTemplate pubsubTemplate
	)
	{
		PubSubInboundChannelAdapter adapter = new PubSubInboundChannelAdapter(pubsubTemplate, &quot;jsonrpc-test-subscription&quot;);
		adapter.setOutputChannel(messageChannel);
		adapter.setAckMode(AckMode.MANUAL);
		adapter.setPayloadType(String.class);
		return adapter;
	}
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;ReceiverComponent&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1644373935244&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;@Component
public class ReceiverComponent 
{
	Logger logger = LoggerFactory.getLogger(this.getClass());
	@ServiceActivator(inputChannel = &quot;inputMessageChannel&quot;)
	public void messageReceiver
	(
		String payload,
		@Header( GcpPubSubHeaders.ORIGINAL_MESSAGE) BasicAcknowledgeablePubsubMessage message
	)
	{
		logger.info(&quot;message arrived! payload: &quot; + payload);
		message.ack();
	}

}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;3) 발신자(Sender)&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;SenderConfig&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1644373997676&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;@Configuration
public class SenderConfig 
{
	Logger logger = LoggerFactory.getLogger(getClass());
	@Bean
	@ServiceActivator(inputChannel = &quot;pubsubOutputChannel&quot;)
	public MessageHandler messageSender(PubSubTemplate pubsubTemplate)
	{
		PubSubMessageHandler adapter = new PubSubMessageHandler(pubsubTemplate, &quot;jsonrpc-test-topic&quot;);
		 adapter.setSuccessCallback(
			      ((ackId, message) -&amp;gt;
			          logger.info(&quot;Message was sent via the outbound channel adapter to topic-two!&quot;)));

			  adapter.setFailureCallback(
			      (cause, message) -&amp;gt; logger.info(&quot;Error sending &quot; + message + &quot; due to &quot; + cause));
		
		return adapter;
	}
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;SchedulerComponent&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1644374421965&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;@Component
public class SchedulerComponent 
{

	Logger logger = LoggerFactory.getLogger(getClass());
	@Autowired
	PubSubOutboundGateway gateway;
	
	@Scheduled(fixedDelay = 60000)
	public void sendMessage()
	{
		logger.info(&quot;test&quot;);
		gateway.sendToPubSub(&quot;test&quot;);
	}
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>GCP/PubSub</category>
      <category>Cloud</category>
      <category>GCP</category>
      <category>google</category>
      <category>Platform</category>
      <category>Pubsub</category>
      <author>몽실KUN</author>
      <guid isPermaLink="true">https://devsquare.tistory.com/42</guid>
      <comments>https://devsquare.tistory.com/42#entry42comment</comments>
      <pubDate>Wed, 9 Feb 2022 11:41:05 +0900</pubDate>
    </item>
    <item>
      <title>Apache James + AWS EC2 메일 서버 구축</title>
      <link>https://devsquare.tistory.com/41</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://james.apache.org/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://james.apache.org/&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1625034442556&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Apache James&quot; data-og-description=&quot;About James stands for Java Apache Mail Enterprise Server! It has a modular architecture based on a rich set of modern and efficient components which provides at the end complete, stable, secure and extendable Mail Servers running on the JVM. Create your o&quot; data-og-host=&quot;james.apache.org&quot; data-og-source-url=&quot;https://james.apache.org/&quot; data-og-url=&quot;https://james.apache.org/&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://james.apache.org/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://james.apache.org/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Apache James&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;About James stands for Java Apache Mail Enterprise Server! It has a modular architecture based on a rich set of modern and efficient components which provides at the end complete, stable, secure and extendable Mail Servers running on the JVM. Create your o&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;james.apache.org&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;메일 서버 구축을 테스트할 일이 생겨서 이런저런 자료를 찾던 중, Apache James를 찾게 되었다. 글 작성 당시의 최신 버전은 apache-james-3.6.0-app.zip 이다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://james.apache.org/server/quick-start.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://james.apache.org/server/quick-start.html&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1625034707622&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Apache James Project &amp;ndash; Apache James Server 3 - Quick Start&quot; data-og-description=&quot;Quick Start The goal of the document is to allow anyone to start with James binary Spring distribution as an operational mail server. For more complete ways of deploying James server please refer to the James installation guide Step 0: Requirements #######&quot; data-og-host=&quot;james.apache.org&quot; data-og-source-url=&quot;https://james.apache.org/server/quick-start.html&quot; data-og-url=&quot;https://james.apache.org/server/quick-start.html&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://james.apache.org/server/quick-start.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://james.apache.org/server/quick-start.html&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Apache James Project &amp;ndash; Apache James Server 3 - Quick Start&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Quick Start The goal of the document is to allow anyone to start with James binary Spring distribution as an operational mail server. For more complete ways of deploying James server please refer to the James installation guide Step 0: Requirements #######&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;james.apache.org&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다운로드 받아서 압축을 푼다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(경로는 /usr/local/server/james)&lt;/p&gt;
&lt;pre id=&quot;code_1625035925925&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ wget https://mirror.navercorp.com/apache/james/server/3.6.0/james-server-app-3.6.0-app.zip
$ unzip james-server-app-3.6.0-app.zip&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 각각의 설정 파일을 수정해준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1) domainlist.xml&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;- defualtDomain을 사용할 도메인으로 바꿔준다.&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1625036100273&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;domainlist class=&quot;org.apache.james.domainlist.jpa.JPADomainList&quot;&amp;gt;
   &amp;lt;autodetect&amp;gt;false&amp;lt;/autodetect&amp;gt;
   &amp;lt;autodetectIP&amp;gt;false&amp;lt;/autodetectIP&amp;gt;
   &amp;lt;defaultDomain&amp;gt;사용할 도메인&amp;lt;/defaultDomain&amp;gt;
&amp;lt;/domainlist&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2) smtpserver.xml&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;- authRequired: 메일을 보내기 위해서는 인증을 해야 한다. (오픈 릴레이를 막기 위해서 필요하다.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;- verifyIdentity: 발신인을 임의 수정 못하게 하기 위한 설정&lt;/p&gt;
&lt;pre id=&quot;code_1625036376625&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;authRequired&amp;gt;true&amp;lt;/authRequired&amp;gt;
&amp;lt;verifyIdentity&amp;gt;true&amp;lt;/verifyIdentity&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;3) mailetcontainer.xml (중요)&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;- 외부로 메일을 발송하기 위해서는 아래 구문을 찾아서 주석처리해줘야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;- 이것이 활성화된 상태에서는 메일을 보내더라도 relaying denied 가 발생하게 된다.&lt;/p&gt;
&lt;pre id=&quot;code_1625036839832&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;        &amp;lt;!--
       &amp;lt;mailet match=&quot;RemoteAddrNotInNetwork=127.0.0.1&quot; class=&quot;ToProcessor&quot;&amp;gt;
          &amp;lt;processor&amp;gt;relay-denied&amp;lt;/processor&amp;gt;
          &amp;lt;notice&amp;gt;550 - Requested action not taken: relaying denied&amp;lt;/notice&amp;gt;
       &amp;lt;/mailet&amp;gt;
        --&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이어서 james 서버를 기동하고, 도메인과 사용자계정을 생성해준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;도메인, 계정 등록은 1번씩만 해두면 된다.&lt;/p&gt;
&lt;pre id=&quot;code_1625037411121&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ sh james start
$ sh james-cli.sh adddomain 사용할도메인
$ sh james.cli.sh adduser 사용자@사용할도메인 패스워드&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 Route53 에서 호스트 세팅을 하자&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;1175&quot; data-origin-height=&quot;441&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bLQG0M/btq8v9oa7bi/2KDE3ZfR38DPQIpKTk6Dk0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bLQG0M/btq8v9oa7bi/2KDE3ZfR38DPQIpKTk6Dk0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bLQG0M/btq8v9oa7bi/2KDE3ZfR38DPQIpKTk6Dk0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbLQG0M%2Fbtq8v9oa7bi%2F2KDE3ZfR38DPQIpKTk6Dk0%2Fimg.png&quot; data-origin-width=&quot;1175&quot; data-origin-height=&quot;441&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 중요한 것은 MX 유형의 레코드를 잡아야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가령 mydomain.com 이란 호스트를 이용할거면 아래와 같이 MX 레코드와 A 레코드를 설정해주어야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;mydomain.com MX 10 mail.mydomain.com&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;mail.mydomain.com A (서버의 고정 IP, AWS의 경우 Elastic IP)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;레코드 셋이 잘 세팅 되었는지 확인은 아래에서 하면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://mxtoolbox.com/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://mxtoolbox.com/&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1625038495103&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;MX Lookup Tool - Check your DNS MX Records online - MxToolbox&quot; data-og-description=&quot;&quot; data-og-host=&quot;mxtoolbox.com&quot; data-og-source-url=&quot;https://mxtoolbox.com/&quot; data-og-url=&quot;http://mxtoolbox.com/default.aspx&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/gDr37/hyKKMVAeY6/bbS2dt1d43ALFM5DqgwzK0/img.png?width=843&amp;amp;height=455&amp;amp;face=0_0_843_455&quot;&gt;&lt;a href=&quot;https://mxtoolbox.com/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://mxtoolbox.com/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/gDr37/hyKKMVAeY6/bbS2dt1d43ALFM5DqgwzK0/img.png?width=843&amp;amp;height=455&amp;amp;face=0_0_843_455');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;MX Lookup Tool - Check your DNS MX Records online - MxToolbox&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;mxtoolbox.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;1591&quot; data-origin-height=&quot;701&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/3WdCA/btq8uKbC4rO/LxLPTxCojA9PLL2ynyf0YK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/3WdCA/btq8uKbC4rO/LxLPTxCojA9PLL2ynyf0YK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/3WdCA/btq8uKbC4rO/LxLPTxCojA9PLL2ynyf0YK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F3WdCA%2Fbtq8uKbC4rO%2FLxLPTxCojA9PLL2ynyf0YK%2Fimg.png&quot; data-origin-width=&quot;1591&quot; data-origin-height=&quot;701&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이메일서버를 테스트 하면 아래와 같다&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;970&quot; data-origin-height=&quot;608&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ckfXJI/btq8v8bJ2P6/kpONBuOJRjJi1ypLijVS9k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ckfXJI/btq8v8bJ2P6/kpONBuOJRjJi1ypLijVS9k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ckfXJI/btq8v8bJ2P6/kpONBuOJRjJi1ypLijVS9k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FckfXJI%2Fbtq8v8bJ2P6%2FkpONBuOJRjJi1ypLijVS9k%2Fimg.png&quot; data-origin-width=&quot;970&quot; data-origin-height=&quot;608&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AWS EC2에서 25번 포트로 SMTP를 이용하여 메일을 발송하려면 RDNS 제한을 풀어달라고 요청을 보내야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://console.aws.amazon.com/support/contacts?#/rdns-limits&quot;&gt;https://console.aws.amazon.com/support/contacts?#/rdns-limits&lt;/a&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure id=&quot;og_1625043082375&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;https://console.aws.amazon.com/support/contacts?#/rdns-limits&quot; data-og-description=&quot;&quot; data-og-host=&quot;console.aws.amazon.com&quot; data-og-source-url=&quot;https://console.aws.amazon.com/support/contacts?#/rdns-limits&quot; data-og-url=&quot;https://console.aws.amazon.com/support/contacts?#/rdns-limits&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://console.aws.amazon.com/support/contacts?#/rdns-limits&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://console.aws.amazon.com/support/contacts?#/rdns-limits&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;https://console.aws.amazon.com/support/contacts?#/rdns-limits&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;console.aws.amazon.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;811&quot; data-origin-height=&quot;850&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b7tHfn/btq8vfinxU8/95Jv2vm0hklaBRY4QLICGK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b7tHfn/btq8vfinxU8/95Jv2vm0hklaBRY4QLICGK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b7tHfn/btq8vfinxU8/95Jv2vm0hklaBRY4QLICGK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb7tHfn%2Fbtq8vfinxU8%2F95Jv2vm0hklaBRY4QLICGK%2Fimg.png&quot; data-origin-width=&quot;811&quot; data-origin-height=&quot;850&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래와 같이 telnet에서 커맨드로 테스트 할 수 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1625042104447&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;220 ip-172-*** JAMES SMTP Server Server (JAMES SMTP Server ) ready
HELO mydomain.com
250 ip-172-*** Hello mydomain.com [61.***.***.***])

AUTH LOGIN
334 VXNl****
YWRt****
334 UGFz****
dGVz****
235 Authentication Successful

MAIL FROM: &amp;lt;admin@mydomain.com&amp;gt;
250 2.1.0 Sender &amp;lt;admin@mydomain.com&amp;gt; OK
RCPT TO: &amp;lt;****@naver.com&amp;gt;
250 2.1.5 Recipient &amp;lt;****@naver.com&amp;gt; OK

DATA
354 Ok Send data ending with &amp;lt;CRLF&amp;gt;.&amp;lt;CRLF&amp;gt;
SUBJECT: TEST MAIL
FROM: &amp;lt;admin@mydomain.com&amp;gt;
TO: &amp;lt;****@naver.com&amp;gt;

mail test
.
250 2.6.0 Message received&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;발송하면 실제로 외부 메일 (네이버)로 발송이 되게 된다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;847&quot; data-origin-height=&quot;386&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cI3FKd/btq8v2JB4et/c9trpSqEGRs1y8jrzez2X0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cI3FKd/btq8v2JB4et/c9trpSqEGRs1y8jrzez2X0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cI3FKd/btq8v2JB4et/c9trpSqEGRs1y8jrzez2X0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcI3FKd%2Fbtq8v2JB4et%2Fc9trpSqEGRs1y8jrzez2X0%2Fimg.png&quot; data-origin-width=&quot;847&quot; data-origin-height=&quot;386&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;썬더버드를 이용한 메일 테스트도 가능하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.thunderbird.net/ko/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.thunderbird.net/ko/&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1625042259666&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Thunderbird &amp;mdash; 이메일을 더 쉽게 사용하세요.&quot; data-og-description=&quot;Thunderbird는 메일을 더 쉽게 사용할 수 있는 무료 프로그램입니다. 더 많은 기능을 만나보세요!&quot; data-og-host=&quot;www.thunderbird.net&quot; data-og-source-url=&quot;https://www.thunderbird.net/ko/&quot; data-og-url=&quot;https://www.thunderbird.net/ko/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/doweOe/hyKI1mz5ne/kXvwSmnNS5GlX8bSkO8In0/img.png?width=256&amp;amp;height=256&amp;amp;face=0_0_256_256&quot;&gt;&lt;a href=&quot;https://www.thunderbird.net/ko/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.thunderbird.net/ko/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/doweOe/hyKI1mz5ne/kXvwSmnNS5GlX8bSkO8In0/img.png?width=256&amp;amp;height=256&amp;amp;face=0_0_256_256');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Thunderbird &amp;mdash; 이메일을 더 쉽게 사용하세요.&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Thunderbird는 메일을 더 쉽게 사용할 수 있는 무료 프로그램입니다. 더 많은 기능을 만나보세요!&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.thunderbird.net&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;1373&quot; data-origin-height=&quot;753&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/m8cAq/btq8vgIsLP7/VokpZ7yKDo6kxVWGjKcrW0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/m8cAq/btq8vgIsLP7/VokpZ7yKDo6kxVWGjKcrW0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/m8cAq/btq8vgIsLP7/VokpZ7yKDo6kxVWGjKcrW0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fm8cAq%2Fbtq8vgIsLP7%2FVokpZ7yKDo6kxVWGjKcrW0%2Fimg.png&quot; data-origin-width=&quot;1373&quot; data-origin-height=&quot;753&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;당연한 이야기지만, SMTP와 IMAP, POP3 등의 포트는 AWS 보안 설정에서 허용해줘야 정상적으로 메일을 송/수신 할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Server/Spring Boots</category>
      <category>apache james</category>
      <category>Email</category>
      <category>Mail Server</category>
      <category>smtp</category>
      <category>메일 서버</category>
      <author>몽실KUN</author>
      <guid isPermaLink="true">https://devsquare.tistory.com/41</guid>
      <comments>https://devsquare.tistory.com/41#entry41comment</comments>
      <pubDate>Wed, 30 Jun 2021 18:04:31 +0900</pubDate>
    </item>
    <item>
      <title>Spring Security + CustomAuthenticationFilter 만들기</title>
      <link>https://devsquare.tistory.com/40</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;참조자료&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://derekpark.tistory.com/101&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://derekpark.tistory.com/101&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1622101591461&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;spring security custom filter 인증 구현&quot; data-og-description=&quot;http request 에서 custom filter 를 적용하여 특정 header 에 토큰을 담고 해당 토큰이 유효하면 인증된 요청이 되게끔 구현하고 싶었다. 스프링 사이트에서 표시된 이미지다. 솔직히 스프링에 대해서 제&quot; data-og-host=&quot;derekpark.tistory.com&quot; data-og-source-url=&quot;https://derekpark.tistory.com/101&quot; data-og-url=&quot;https://derekpark.tistory.com/101&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/8B7k6/hyKlhKiTMW/ofxBMGN8K8kelwf001S4Xk/img.png?width=800&amp;amp;height=600&amp;amp;face=0_0_800_600,https://scrap.kakaocdn.net/dn/cNPc0L/hyKms4yTk7/TSDR6kwoxcKmnaHRkqMymK/img.png?width=800&amp;amp;height=600&amp;amp;face=0_0_800_600,https://scrap.kakaocdn.net/dn/cBKtND/hyKmy4Lper/lsqFppOpnFqV23s7HKvtC1/img.png?width=820&amp;amp;height=615&amp;amp;face=0_0_820_615&quot;&gt;&lt;a href=&quot;https://derekpark.tistory.com/101&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://derekpark.tistory.com/101&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/8B7k6/hyKlhKiTMW/ofxBMGN8K8kelwf001S4Xk/img.png?width=800&amp;amp;height=600&amp;amp;face=0_0_800_600,https://scrap.kakaocdn.net/dn/cNPc0L/hyKms4yTk7/TSDR6kwoxcKmnaHRkqMymK/img.png?width=800&amp;amp;height=600&amp;amp;face=0_0_800_600,https://scrap.kakaocdn.net/dn/cBKtND/hyKmy4Lper/lsqFppOpnFqV23s7HKvtC1/img.png?width=820&amp;amp;height=615&amp;amp;face=0_0_820_615');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;spring security custom filter 인증 구현&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;http request 에서 custom filter 를 적용하여 특정 header 에 토큰을 담고 해당 토큰이 유효하면 인증된 요청이 되게끔 구현하고 싶었다. 스프링 사이트에서 표시된 이미지다. 솔직히 스프링에 대해서 제&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;derekpark.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://imbf.github.io/spring/2020/06/29/Spring-Security-with-JWT.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://imbf.github.io/spring/2020/06/29/Spring-Security-with-JWT.html&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1622101601093&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Spring Security + JWT를 통해 프로젝트에 인증 구현하기&quot; data-og-description=&quot;Spring Security와 JWT를 활용해서 프로젝트에 인증을 어떻게 구현했는지에 대해서 포스팅 하려고 한다.&quot; data-og-host=&quot;imbf.github.io&quot; data-og-source-url=&quot;https://imbf.github.io/spring/2020/06/29/Spring-Security-with-JWT.html&quot; data-og-url=&quot;https://imbf.github.io/spring/2020/06/29/Spring-Security-with-JWT.html&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/b6ZKEt/hyKmxSk6sl/i7oVSnKTKJUUzP8CwPAVDk/img.png?width=486&amp;amp;height=361&amp;amp;face=0_0_486_361,https://scrap.kakaocdn.net/dn/029c6/hyKmHAFv1y/t4yAAVk6eJJJApKP1TPEd1/img.png?width=486&amp;amp;height=361&amp;amp;face=0_0_486_361,https://scrap.kakaocdn.net/dn/bKXmz2/hyKlmSoLQ6/Vk09TUHsjBQgeVtEp6DWjK/img.png?width=2688&amp;amp;height=1824&amp;amp;face=0_0_2688_1824&quot;&gt;&lt;a href=&quot;https://imbf.github.io/spring/2020/06/29/Spring-Security-with-JWT.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://imbf.github.io/spring/2020/06/29/Spring-Security-with-JWT.html&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/b6ZKEt/hyKmxSk6sl/i7oVSnKTKJUUzP8CwPAVDk/img.png?width=486&amp;amp;height=361&amp;amp;face=0_0_486_361,https://scrap.kakaocdn.net/dn/029c6/hyKmHAFv1y/t4yAAVk6eJJJApKP1TPEd1/img.png?width=486&amp;amp;height=361&amp;amp;face=0_0_486_361,https://scrap.kakaocdn.net/dn/bKXmz2/hyKlmSoLQ6/Vk09TUHsjBQgeVtEp6DWjK/img.png?width=2688&amp;amp;height=1824&amp;amp;face=0_0_2688_1824');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Spring Security + JWT를 통해 프로젝트에 인증 구현하기&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Spring Security와 JWT를 활용해서 프로젝트에 인증을 어떻게 구현했는지에 대해서 포스팅 하려고 한다.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;imbf.github.io&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://stackoverflow.com/questions/38341114/spring-security-cookie-jwt-authentication&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://stackoverflow.com/questions/38341114/spring-security-cookie-jwt-authentication&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1622101652860&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Spring Security Cookie + JWT authentication&quot; data-og-description=&quot;I must say I am very confused about the entire model and I need help gluing all the floating pieces together. I am not doing Spring REST, just plain WebMVC controllers. My mission: I want a form ...&quot; data-og-host=&quot;stackoverflow.com&quot; data-og-source-url=&quot;https://stackoverflow.com/questions/38341114/spring-security-cookie-jwt-authentication&quot; data-og-url=&quot;https://stackoverflow.com/questions/38341114/spring-security-cookie-jwt-authentication&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/xijVL/hyKljBm92T/AeDWLOEFgO0YON1cy1Kte1/img.png?width=316&amp;amp;height=316&amp;amp;face=0_0_316_316&quot;&gt;&lt;a href=&quot;https://stackoverflow.com/questions/38341114/spring-security-cookie-jwt-authentication&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://stackoverflow.com/questions/38341114/spring-security-cookie-jwt-authentication&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/xijVL/hyKljBm92T/AeDWLOEFgO0YON1cy1Kte1/img.png?width=316&amp;amp;height=316&amp;amp;face=0_0_316_316');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Spring Security Cookie + JWT authentication&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;I must say I am very confused about the entire model and I need help gluing all the floating pieces together. I am not doing Spring REST, just plain WebMVC controllers. My mission: I want a form ...&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;stackoverflow.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://stackoverflow.com/questions/34233856/spring-security-authenticationmanager-must-be-specified-for-custom-filter&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://stackoverflow.com/questions/34233856/spring-security-authenticationmanager-must-be-specified-for-custom-filter&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1622101659404&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Spring Security authenticationmanager must be specified - for custom filter&quot; data-og-description=&quot;I&amp;rsquo;m trying to create a custom username password authentication filter since I need to validate passwords from two different sources. I&amp;rsquo;m using Spring Boot 1.2.1 and Java configuration. The error ...&quot; data-og-host=&quot;stackoverflow.com&quot; data-og-source-url=&quot;https://stackoverflow.com/questions/34233856/spring-security-authenticationmanager-must-be-specified-for-custom-filter&quot; data-og-url=&quot;https://stackoverflow.com/questions/34233856/spring-security-authenticationmanager-must-be-specified-for-custom-filter&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/wDtLH/hyKmGBJmqe/kH3AQrHBdV5Y0lpgNFXOM0/img.png?width=316&amp;amp;height=316&amp;amp;face=0_0_316_316&quot;&gt;&lt;a href=&quot;https://stackoverflow.com/questions/34233856/spring-security-authenticationmanager-must-be-specified-for-custom-filter&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://stackoverflow.com/questions/34233856/spring-security-authenticationmanager-must-be-specified-for-custom-filter&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/wDtLH/hyKmGBJmqe/kH3AQrHBdV5Y0lpgNFXOM0/img.png?width=316&amp;amp;height=316&amp;amp;face=0_0_316_316');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Spring Security authenticationmanager must be specified - for custom filter&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;I&amp;rsquo;m trying to create a custom username password authentication filter since I need to validate passwords from two different sources. I&amp;rsquo;m using Spring Boot 1.2.1 and Java configuration. The error ...&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;stackoverflow.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;독립된 A사이트에서 로그인을 하면 쿠키를 굽는다. 이 때 별도의 B사이트에서 A사이트의 쿠키 정보를 가지고 인증을 처리하는 작업을 좀 더 스마트하게 하고 싶었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;820&quot; data-origin-height=&quot;615&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/sX9Hc/btq5R2e6eqK/E5uaoYQiuKKnxZy5YKwGzK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/sX9Hc/btq5R2e6eqK/E5uaoYQiuKKnxZy5YKwGzK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/sX9Hc/btq5R2e6eqK/E5uaoYQiuKKnxZy5YKwGzK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FsX9Hc%2Fbtq5R2e6eqK%2FE5uaoYQiuKKnxZy5YKwGzK%2Fimg.png&quot; data-origin-width=&quot;820&quot; data-origin-height=&quot;615&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;스프링 시큐리티의 인증 아키텍처. 시간 날 때 한 번 찬찬히 파보며 공부해야겠다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;CookieAuthFilter&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;쿠키에서 특정 값이 있는 경우, 이를 처리하는 필터이다&lt;/p&gt;
&lt;pre id=&quot;code_1622103050266&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;@Component
public class CookieAuthFilter extends GenericFilterBean     
{
	@Autowired
	AtomSessionComponent sessionComponent;
    
	@Override
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
			throws IOException, ServletException 
	{
		boolean result = sessionComponent.validateAtomSession((HttpServletRequest) request);
		if(!result)
		{
			chain.doFilter(request, response);
			return;
		}
		CookieAuthenticationToken cookie = null;
		Map&amp;lt;String, Object&amp;gt; map = null;
		try 
		{
			map = sessionComponent.getUserInfoFromCookie((HttpServletRequest) request);
		} 
		catch 
		(InvalidKeyException | NumberFormatException | NoSuchAlgorithmException | NoSuchPaddingException
		| InvalidAlgorithmParameterException | UnsupportedEncodingException | IllegalBlockSizeException
		| BadPaddingException e) 
		{
			chain.doFilter(request, response);
			return;
		}
		cookie = new CookieAuthenticationToken(map, true);
		SecurityContextHolder.getContext().setAuthentication(cookie);
		chain.doFilter(request, response);
	}
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;CookieAuthenticationToken&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1622106056999&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public class CookieAuthenticationToken extends AbstractAuthenticationToken 
{
	private Object credentials;
	private static final long serialVersionUID = -5333188013042870764L;
	
	public CookieAuthenticationToken()
	{
		super(null);
	}
	public CookieAuthenticationToken(Map&amp;lt;String, Object&amp;gt; map, boolean isAuthenticated)
	{
		super( new ArrayList&amp;lt;GrantedAuthority&amp;gt;());	
		CookieUserDetails userDetails = new CookieUserDetails();
		userDetails.setUsername(String.valueOf(map.get(&quot;user_id&quot;)));
		setDetails(userDetails);
		this.credentials = null;
		setAuthenticated(isAuthenticated);
	}
	
	public CookieAuthenticationToken(Collection&amp;lt;? extends GrantedAuthority&amp;gt; authorities) 
	{
		super(authorities);
	}

	@Override
	public Object getCredentials() 
	{
		return credentials;
	}

	@Override
	public Object getPrincipal() 
	{
		return ((CookieUserDetails)getDetails()).getUsername();
	}
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;WebSecurityConfig&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1622106167171&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter
{
	@Autowired
	AESComponent aesComponent;

	@Autowired
	AtomSessionComponent atomComponent;
	
	@Autowired
	CookieAuthFilter cookieAuthFilter;
	
	@Override
	protected void configure(HttpSecurity http) throws Exception
	{
		 http.csrf().disable()
	        .authorizeRequests()
	        	.antMatchers(&quot;/&quot;, &quot;/login&quot;, &quot;/register&quot;).permitAll()
	        .anyRequest().authenticated() .and()
	        .formLogin()
	        	.loginPage(&quot;/login&quot;) .permitAll().and().logout() .permitAll()
	        .and()
	        	.addFilterBefore(cookieAuthFilter, BasicAuthenticationFilter .class);
	}

	@Bean
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception 
    {
        return super.authenticationManagerBean();
    }	
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;WebSecurityConfig&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Server/Spring Boots</category>
      <category>Authentication</category>
      <category>Security</category>
      <category>Spring</category>
      <category>스프링</category>
      <category>시큐리티</category>
      <category>인증</category>
      <author>몽실KUN</author>
      <guid isPermaLink="true">https://devsquare.tistory.com/40</guid>
      <comments>https://devsquare.tistory.com/40#entry40comment</comments>
      <pubDate>Thu, 27 May 2021 18:03:54 +0900</pubDate>
    </item>
    <item>
      <title>프로그래머를 지망하는 비전공자를 위한 취업 안내서 -1-</title>
      <link>https://devsquare.tistory.com/39</link>
      <description>&lt;p&gt;&amp;nbsp;사실 이런 포스트는 예전부터 쓰려고 했었습니다. 그러나 이게 또 경우에 따라서는 민감한 주제이기 때문에 벌통을 건들이는 꼴이 될 수도 있어 망설였었습니다. 하지만 오픈카톡 채팅방에서 웹개발자를 지망하는 사람들의 질문과 사례를 보다보니 느끼는 바가 있어 조심스레 글을 작성합니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-filename=&quot;sub01_7_img2.jpg&quot; data-origin-width=&quot;445&quot; data-origin-height=&quot;296&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bQd0Ut/btq2YSkBCEP/vOYSJzfROJrXjK43twNWTk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bQd0Ut/btq2YSkBCEP/vOYSJzfROJrXjK43twNWTk/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bQd0Ut/btq2YSkBCEP/vOYSJzfROJrXjK43twNWTk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbQd0Ut%2Fbtq2YSkBCEP%2FvOYSJzfROJrXjK43twNWTk%2Fimg.jpg&quot; data-filename=&quot;sub01_7_img2.jpg&quot; data-origin-width=&quot;445&quot; data-origin-height=&quot;296&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;작은 불빛이 누군가에게는 어두운 밤바다를 안내하는 한 줄기의 등대불이 될 수 있기 때문에, 저 또한 다른 분에게 보탬이 되고자 글을 씁니다. 그렇다고 제가 뭐 명문대를 나오고 대단한 대기업에서 일하는 뛰어난 사람은 아닙니다. 그저 평범하게 대학교에서 컴퓨터공학을 전공하고, 평범하게 IT기업체에서 개발을 하면서 나름대로 느꼈던 것들을 소소하게 팁으로 남기고자 합니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;왜 비전공자들이 프로그래머를 지원할까?&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;이 문제의 답에 대해 고민을 했습니다. 결론적으로는 &lt;b&gt;&quot;경기 불황으로 인한 취업난&quot;&lt;/b&gt;, &lt;b&gt;&quot;회사 업무에 대한 염증&quot;&lt;/b&gt;, &lt;b&gt;&quot;미래에 대한 불확실성&quot;&lt;/b&gt; 등이 주된 이유인 것 같습니다. 정말 개발이 좋아서, 재밌어서 진로를 도중에 변경하신 분들은 10명 중에 1명? 정도이지 싶습니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;왜, 현업 전공자들이 비전공자가 개발자를 지망한다면 뜯어 말릴까?&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;여러가지 이유가 있겠지만, 편향된 정보를 바탕으로 내린 결정이 가장 큰 이유입니다. 학원 수업 6개월이 과연 취업하는데 충분한가? 냉정하게 이야기하면 NO입니다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;그렇다고 학원 무용론을 말하자는 것은 아닙니다. 수준 낮은 강사를 돌려막기하는 일부 비양심적인 학원을 빼고 보면, 대다수의 학원에서 높은 취업률 (70-80%)을 보이고 있습니다. 심지어는 전공자들도 졸업하기 전에 학원 와서 프레임워크를 배우기도 합니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;네, 눈치가 빠른 분이라면 여기서 감을 채셨을 수도 있습니다. 대학 전공도 취업하는데 충분치 않아요. 컴퓨터공학 전공했다고 무조건 뽑아주는 시대는 정말 15년 전 2000년대 초중반 IT버블 때 이야기입니다. 대학교 전공도 충분하지 않아요. 그렇기 때문에 학원 교육 또한 불충분하다고 말하는 겁니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-filename=&quot;19113-1-7556.jpg&quot; data-origin-width=&quot;461&quot; data-origin-height=&quot;250&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dmiXgo/btq2NqJ9a1D/4KZlW6NyzidllpChTtmLP1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dmiXgo/btq2NqJ9a1D/4KZlW6NyzidllpChTtmLP1/img.jpg&quot; data-alt=&quot;밴드 오브 브라더스&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dmiXgo/btq2NqJ9a1D/4KZlW6NyzidllpChTtmLP1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdmiXgo%2Fbtq2NqJ9a1D%2F4KZlW6NyzidllpChTtmLP1%2Fimg.jpg&quot; data-filename=&quot;19113-1-7556.jpg&quot; data-origin-width=&quot;461&quot; data-origin-height=&quot;250&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;밴드 오브 브라더스&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;현업 개발자들, 특히 전공자들이 보기에 학원의 이러한 모습은 흡사 밴드 오브 브라더스와 비슷하다고 봅니다. 훈련소 나오자마자 그대로 전선에 투입하는 것처럼, 학원 커리큘럼을 이수하자마자 산업전선에 갈아넣는 것이지요.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;대부분의 학원들이 상담할 때하는 레퍼토리가 있습니다. 학원 취업률이 대학교 컴공과 취업률보다 높다구요. 네 맞는 말입니다. 학교마다 차이는 있겠지만 인서울 중하위권이 60-70%이고 학원이 70-80% 나와요. 근데 이는 같은 개발자라고 해도 지원하는 분야나 규모가 다르기 때문입니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;학원의 개발자 취업률은 중소기업체에서 캐리하고 있다.&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;학원 수료생의 대부분은 &lt;b&gt;SI/솔루션/ERP 등의 업무를 하는 중소기업체&lt;/b&gt;에 취업을 합니다. 정말 특출나게 실력이 뛰어나지 않는 한 10명 중에 8명은 이렇게 현업 개발자의 삶을 시작합니다. 여기서 받는 현실은 정말 상상과 다릅니다. &lt;b&gt;네카라쿠배&lt;/b&gt;로 잘 알려진 국내 대형 IT 기업의 근로조건과 복지를 기대하고 갔다가 열악한 산업전선의 최전방에서 만신창이가 되어서 와들와들 떠는게 현실입니다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;전공자 졸업 3년 후 개발자 비율은 30%, 학원은?&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;전공자 기준으로 100명이 졸업한다고 했을 때, 3년 후에 이들 중에서 개발자를 하고 있을 확률은 대략 30% 정도입니다. 대학원 진학 등 혹은 취업 실패 등도 있거니와 개발자가 아닌 다른 IT 기술분야 (DBA / 인프라 / 기술영업 / 기술기획 / 데이터분석 등)로 지원하는 경우, 전혀 관련없는 별개 분야로 취업하는 경우도 있습니다. 대략 많아야 졸업자들 중에서 40-50% 정도만이 개발자가 되고, 이들 중에서 3분의 1 가량은 중도에 다른 IT분야로 전환합니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;그러면 학원 출신은 어떨까요? 명확한 통계는 본적이 없지만 아마 대동소이할 걸로 생각합니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;사실 전공자든 비전공자든 대부분의 인력풀이 신입-1,2,3년차에 몰려 있다가 경력 3년 이상 (4년 차 이상) 되면 훅 줄어드는 것을 체감합니다. 채용공고를 내면 이력서 들어오는 갯수가 연차에 따라서 자릿수가 달라지기도 합니다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;기나긴 서론, 그래서 하고 싶은 말이 도대체 뭔데?&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;이제 와서 학원 취소하고 다른 것을 알아보라는 무책임한 말은 하지 않겠습니다. 다만 이 바닥이 전공자들도 버티고 살아남기 위해서 부단히 노력해야 한다는 점과 함께, 어떻게 해야 보다 좋은 조건에서 스타트를 끊을 수 있는지, 어떻게 해야 3년이란 시간 동안 커리어관리 하면서 살아남을 수 있는지 노하우와 팁을 소소하게 적고자 합니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>취업 관련/비전공자</category>
      <category>개발자</category>
      <category>비전공자</category>
      <category>취업</category>
      <category>프로그래머</category>
      <category>학원</category>
      <author>몽실KUN</author>
      <guid isPermaLink="true">https://devsquare.tistory.com/39</guid>
      <comments>https://devsquare.tistory.com/39#entry39comment</comments>
      <pubDate>Mon, 19 Apr 2021 03:33:25 +0900</pubDate>
    </item>
    <item>
      <title>Cloud SQL 에서 Bigquery로 데이터 이동</title>
      <link>https://devsquare.tistory.com/38</link>
      <description>&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://stackoverflow.com/questions/47624181/best-way-to-import-google-cloud-sql-data-into-bigquery&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;stackoverflow.com/questions/47624181/best-way-to-import-google-cloud-sql-data-into-bigquery&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1611132066100&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Best way to import Google Cloud SQL data into BigQuery&quot; data-og-description=&quot;I have a database in a Cloud SQL instance. I would like to copy its content into BigQuery in order to perform analysis. It is not a requirement for me to continuously update the BigQuery dataset. I...&quot; data-og-host=&quot;stackoverflow.com&quot; data-og-source-url=&quot;https://stackoverflow.com/questions/47624181/best-way-to-import-google-cloud-sql-data-into-bigquery&quot; data-og-url=&quot;https://stackoverflow.com/questions/47624181/best-way-to-import-google-cloud-sql-data-into-bigquery&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/daADSs/hyIZTJ6tHO/zaxQoWQSAiqNKkRgshryF0/img.png?width=316&amp;amp;height=316&amp;amp;face=0_0_316_316&quot;&gt;&lt;a href=&quot;https://stackoverflow.com/questions/47624181/best-way-to-import-google-cloud-sql-data-into-bigquery&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://stackoverflow.com/questions/47624181/best-way-to-import-google-cloud-sql-data-into-bigquery&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/daADSs/hyIZTJ6tHO/zaxQoWQSAiqNKkRgshryF0/img.png?width=316&amp;amp;height=316&amp;amp;face=0_0_316_316');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot;&gt;Best way to import Google Cloud SQL data into BigQuery&lt;/p&gt;
&lt;p class=&quot;og-desc&quot;&gt;I have a database in a Cloud SQL instance. I would like to copy its content into BigQuery in order to perform analysis. It is not a requirement for me to continuously update the BigQuery dataset. I...&lt;/p&gt;
&lt;p class=&quot;og-host&quot;&gt;stackoverflow.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p&gt;&lt;a href=&quot;https://cloud.google.com/bigquery/docs/cloud-sql-federated-queries&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;cloud.google.com/bigquery/docs/cloud-sql-federated-queries&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1611132934750&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Cloud SQL 통합 쿼리 &amp;nbsp;|&amp;nbsp; BigQuery &amp;nbsp;|&amp;nbsp; Google Cloud&quot; data-og-description=&quot;이 페이지에서는 통합 쿼리를 사용하여 BigQuery 및 Cloud SQL의 데이터를 쿼리하는 방법을 설명합니다. 개요 데이터는 많은 위치에 흩어져 있는 경우가 많습니다. 고객 테이블은 BigQuery에, 판매 테이&quot; data-og-host=&quot;cloud.google.com&quot; data-og-source-url=&quot;https://cloud.google.com/bigquery/docs/cloud-sql-federated-queries&quot; data-og-url=&quot;https://cloud.google.com/bigquery/docs/cloud-sql-federated-queries?hl=ko&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/Aeqx5/hyI1inZvd3/ap9BdPGzbUwZe2mGrIYsS0/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/chIixY/hyI1b3tpIi/ICuRFFRW2Dk4Hfy8pz8Fn0/img.png?width=572&amp;amp;height=645&amp;amp;face=0_0_572_645,https://scrap.kakaocdn.net/dn/bLLHGR/hyIZ1Bo9WT/cSLgw6FvVZRVtFsrT8EI50/img.png?width=485&amp;amp;height=256&amp;amp;face=0_0_485_256&quot;&gt;&lt;a href=&quot;https://cloud.google.com/bigquery/docs/cloud-sql-federated-queries&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://cloud.google.com/bigquery/docs/cloud-sql-federated-queries&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/Aeqx5/hyI1inZvd3/ap9BdPGzbUwZe2mGrIYsS0/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/chIixY/hyI1b3tpIi/ICuRFFRW2Dk4Hfy8pz8Fn0/img.png?width=572&amp;amp;height=645&amp;amp;face=0_0_572_645,https://scrap.kakaocdn.net/dn/bLLHGR/hyIZ1Bo9WT/cSLgw6FvVZRVtFsrT8EI50/img.png?width=485&amp;amp;height=256&amp;amp;face=0_0_485_256');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot;&gt;Cloud SQL 통합 쿼리 &amp;nbsp;|&amp;nbsp; BigQuery &amp;nbsp;|&amp;nbsp; Google Cloud&lt;/p&gt;
&lt;p class=&quot;og-desc&quot;&gt;이 페이지에서는 통합 쿼리를 사용하여 BigQuery 및 Cloud SQL의 데이터를 쿼리하는 방법을 설명합니다. 개요 데이터는 많은 위치에 흩어져 있는 경우가 많습니다. 고객 테이블은 BigQuery에, 판매 테이&lt;/p&gt;
&lt;p class=&quot;og-host&quot;&gt;cloud.google.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;우선 cloud SQL 통합쿼리의 가이드 라인을 살펴보면 아래와 같은 형태로 SQL 구문을 쓸 수 있다&lt;/p&gt;
&lt;pre id=&quot;code_1611133745460&quot; class=&quot;sql&quot; style=&quot;display: block; overflow: auto; padding: 15px; color: #383a42; background: #f6f7f8; font-size: 14px; border-radius: 3px; font-family: Menlo, Consolas, Monaco, monospace; border: 1px solid #dddddd; margin: 20px auto 0px; cursor: default; z-index: 1; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-thickness: initial; text-decoration-style: initial; text-decoration-color: initial;&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;select * from 
EXTERNAL_QUERY(
'(프로젝트명).(리전명).(클라우드SQL명)',
'select * from (테이블명) where log_date between DATE_ADD(date(NOW()), INTERVAL -1 day) and date(now());'
);&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;이때 외부 연결을 최초 1회 등록을 해주어야 한다&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/V2gnk/btqUeVX2a9U/TFWJd4Ch940uMtBICZKz3K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/V2gnk/btqUeVX2a9U/TFWJd4Ch940uMtBICZKz3K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/V2gnk/btqUeVX2a9U/TFWJd4Ch940uMtBICZKz3K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FV2gnk%2FbtqUeVX2a9U%2FTFWJd4Ch940uMtBICZKz3K%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;빅쿼리 창에서 데이터 추가 &amp;gt; 외부 데이터 소스를 선택하면 추가할 수 있다&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bAIylK/btqT90y2H6D/i2cTdt0Dkxe0Zmluz79321/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bAIylK/btqT90y2H6D/i2cTdt0Dkxe0Zmluz79321/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bAIylK/btqT90y2H6D/i2cTdt0Dkxe0Zmluz79321/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbAIylK%2FbtqT90y2H6D%2Fi2cTdt0Dkxe0Zmluz79321%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&lt;b&gt;연결ID&lt;/b&gt;: 외부 연결을 구분할 ID 값이다&lt;/p&gt;
&lt;p&gt;&lt;b&gt;연결위치&lt;/b&gt;: 연결이 있을 리전을 선택한다. 살짝 아리송하다. 다행히 우리 회사는 sql과 bigquery 모두 도쿄리전을 쓰고 있기 때문에 연결위치도 도쿄리전을 선택했다.&lt;br /&gt;&lt;b&gt;Clould SQL 인스턴스 ID&lt;/b&gt;: clould SQL 탭에서 해당 인스턴스의 전체경로 ID를 가져오면 된다.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;데이터베이스 이름&lt;/b&gt;: 데이터를 가져오고자 하는 데이터베이스 이름입니다.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;데이터베이스 사용자 이름&lt;/b&gt;: 데이터를 불러올 때 쓰일 DB 서비스 계정&lt;/p&gt;
&lt;p&gt;&lt;b&gt;데이터베이스 비밀번호&lt;/b&gt;: DB 서비스 계정의 비밀번호&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;이렇게 세팅하면 된다.&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bGec89/btqT6G9h0DA/E1UNgKuXcff8z0tTREQM81/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bGec89/btqT6G9h0DA/E1UNgKuXcff8z0tTREQM81/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bGec89/btqT6G9h0DA/E1UNgKuXcff8z0tTREQM81/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbGec89%2FbtqT6G9h0DA%2FE1UNgKuXcff8z0tTREQM81%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;어제자 데이터를 불러오는 쿼리 실행결과. 잘 불러온다&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;데이터를 빅쿼리에 넣는 방법은 크게 2가지 방법이 있다.&lt;br /&gt;&lt;b&gt;1) 수동으로 쿼리를 날리고, 쿼리 결과를 bigquery 테이블에 저장&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;2) 예약 쿼리를 실행&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;우선 첫번째 방법을 먼저 살펴보면...&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/o1Xkd/btqT3toOlY7/pt3360Ewg2DoD9LoYvxBKk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/o1Xkd/btqT3toOlY7/pt3360Ewg2DoD9LoYvxBKk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/o1Xkd/btqT3toOlY7/pt3360Ewg2DoD9LoYvxBKk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fo1Xkd%2FbtqT3toOlY7%2Fpt3360Ewg2DoD9LoYvxBKk%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;더보기에서 쿼리 세팅을 보면... 아래와 같은 설정탭이 나온다&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-filename=&quot;img.png&quot; data-origin-width=&quot;535&quot; data-origin-height=&quot;833&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Gl6Uj/btq2RkIZTDZ/L8zFvFgyvmGPhhjYW4gBGK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Gl6Uj/btq2RkIZTDZ/L8zFvFgyvmGPhhjYW4gBGK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Gl6Uj/btq2RkIZTDZ/L8zFvFgyvmGPhhjYW4gBGK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FGl6Uj%2Fbtq2RkIZTDZ%2FL8zFvFgyvmGPhhjYW4gBGK%2Fimg.png&quot; data-filename=&quot;img.png&quot; data-origin-width=&quot;535&quot; data-origin-height=&quot;833&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;반면 두번째 방법은 쿼리 예약을 거는 것이다&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/XSCTv/btqUfZeS2RJ/bKznUcxUsCA1WnkZxBAM01/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/XSCTv/btqUfZeS2RJ/bKznUcxUsCA1WnkZxBAM01/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/XSCTv/btqUfZeS2RJ/bKznUcxUsCA1WnkZxBAM01/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FXSCTv%2FbtqUfZeS2RJ%2FbKznUcxUsCA1WnkZxBAM01%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;예약된 쿼리 탭에서 설정된 쿼리를 볼 수 있다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;예약된 쿼리 만들기를 하면 쿼리를 등록할 수 있는데, 예약 걸고자 하는 쿼리를 작성한 후 일정을 등록하면 된다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b3jV4T/btqT8JdlHmP/56cnoIVNWeuflq2hKUwFe1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b3jV4T/btqT8JdlHmP/56cnoIVNWeuflq2hKUwFe1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b3jV4T/btqT8JdlHmP/56cnoIVNWeuflq2hKUwFe1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb3jV4T%2FbtqT8JdlHmP%2F56cnoIVNWeuflq2hKUwFe1%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;일정에서 새로 예약된 커리 만들기를 클릭한 다음 아래와 같은 탭에서 그 정보를 입력하자.&lt;/p&gt;
&lt;p&gt;다 입력 후 예약을 걸면 예약된 쿼리가 등록이 되고 정해진 시간에 수행하는 것을 알 수 있다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-filename=&quot;img (1).png&quot; data-origin-width=&quot;543&quot; data-origin-height=&quot;915&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/nsi98/btq2NUEhRP3/kszEnaITURPKzkxgnjzREk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/nsi98/btq2NUEhRP3/kszEnaITURPKzkxgnjzREk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/nsi98/btq2NUEhRP3/kszEnaITURPKzkxgnjzREk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fnsi98%2Fbtq2NUEhRP3%2FkszEnaITURPKzkxgnjzREk%2Fimg.png&quot; data-filename=&quot;img (1).png&quot; data-origin-width=&quot;543&quot; data-origin-height=&quot;915&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>Database/Bigquery</category>
      <category>bigquery</category>
      <category>Cloud SQL</category>
      <category>GCP</category>
      <category>query</category>
      <category>scheduled query</category>
      <category>SQL</category>
      <category>마이그레이션</category>
      <author>몽실KUN</author>
      <guid isPermaLink="true">https://devsquare.tistory.com/38</guid>
      <comments>https://devsquare.tistory.com/38#entry38comment</comments>
      <pubDate>Wed, 20 Jan 2021 19:11:38 +0900</pubDate>
    </item>
    <item>
      <title>Spring Boot Maven Multi Module 개발환경 설정하기</title>
      <link>https://devsquare.tistory.com/36</link>
      <description>&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://spring.io/guides/gs/multi-module/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;spring.io/guides/gs/multi-module/&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1605085717309&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Creating a Multi Module Project&quot; data-og-description=&quot;this guide is designed to get you productive as quickly as possible and using the latest Spring project releases and techniques as recommended by the Spring team&quot; data-og-host=&quot;spring.io&quot; data-og-source-url=&quot;https://spring.io/guides/gs/multi-module/&quot; data-og-url=&quot;https://spring.io/guides/gs/multi-module/&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://spring.io/guides/gs/multi-module/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://spring.io/guides/gs/multi-module/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot;&gt;Creating a Multi Module Project&lt;/p&gt;
&lt;p class=&quot;og-desc&quot;&gt;this guide is designed to get you productive as quickly as possible and using the latest Spring project releases and techniques as recommended by the Spring team&lt;/p&gt;
&lt;p class=&quot;og-host&quot;&gt;spring.io&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p&gt;멀티 모듈 프로젝트로 개발하게 되면 여러가지 장점이 있다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;공통의 모듈을 한 곳에서 관리함으로써 중복되는 소스 코드를 최소화하게 되며, 이에 따라 개발 할 때는 자신이 개발해야 하는 부분에 좀 더 촛점을 둘 수 있다. 장점에 대한 소개는 제쳐두고, 환경 세팅에 대해 고민해봤다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p&gt;&lt;b&gt;1. maven parent project의 생성&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/clcX65/btqNf7RMzuz/c8ZeBzk201J8yDtZPqpLMk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/clcX65/btqNf7RMzuz/c8ZeBzk201J8yDtZPqpLMk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/clcX65/btqNf7RMzuz/c8ZeBzk201J8yDtZPqpLMk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FclcX65%2FbtqNf7RMzuz%2Fc8ZeBzk201J8yDtZPqpLMk%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;아래는 jt-root의 pom.xml 파일이다.&lt;/p&gt;
&lt;pre id=&quot;code_1605086137346&quot; class=&quot;html xml&quot; style=&quot;display: block; overflow: auto; padding: 15px; color: #383a42; background: #f6f7f8; font-size: 14px; border-radius: 3px; font-family: Menlo, Consolas, Monaco, monospace; border: 1px solid #dddddd; margin: 20px auto 0px; cursor: default; z-index: 1; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;project xmlns=&quot;http://maven.apache.org/POM/4.0.0&quot; 
xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot; 
xsi:schemaLocation=&quot;http://maven.apache.org/POM/4.0.0 
https://maven.apache.org/xsd/maven-4.0.0.xsd&quot;&amp;gt;
  &amp;lt;modelVersion&amp;gt;4.0.0&amp;lt;/modelVersion&amp;gt;
  &amp;lt;groupId&amp;gt;com.****&amp;lt;/groupId&amp;gt;
  &amp;lt;artifactId&amp;gt;jt-root&amp;lt;/artifactId&amp;gt;
  &amp;lt;version&amp;gt;0.0.1-SNAPSHOT&amp;lt;/version&amp;gt;
  &amp;lt;packaging&amp;gt;pom&amp;lt;/packaging&amp;gt;
  &amp;lt;modules&amp;gt;
  	&amp;lt;module&amp;gt;****-backoffice&amp;lt;/module&amp;gt;
  	&amp;lt;module&amp;gt;****-backoffice-api&amp;lt;/module&amp;gt;
  	&amp;lt;module&amp;gt;****-backoffice-core&amp;lt;/module&amp;gt;
  &amp;lt;/modules&amp;gt;
&amp;lt;/project&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;root 혹은 parent의 maven project는 packaging을 pom으로 갖는다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/biIfVW/btqNe66TTF0/2Ilc9ge5DVCNusKJMOvQt1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/biIfVW/btqNe66TTF0/2Ilc9ge5DVCNusKJMOvQt1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/biIfVW/btqNe66TTF0/2Ilc9ge5DVCNusKJMOvQt1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbiIfVW%2FbtqNe66TTF0%2F2Ilc9ge5DVCNusKJMOvQt1%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;생성시에는 Maven Project로 생성할 수 있다.&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/AaqY5/btqNfrbTULN/KwwGapJR4rkPbY1OuIBLWk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/AaqY5/btqNfrbTULN/KwwGapJR4rkPbY1OuIBLWk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/AaqY5/btqNfrbTULN/KwwGapJR4rkPbY1OuIBLWk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FAaqY5%2FbtqNfrbTULN%2FKwwGapJR4rkPbY1OuIBLWk%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;simple project를 체크해주자. (보다 간편하게 프로젝트를 생성할 수 있다.)&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kNWO7/btqNcFPw4Hf/DS9jTBQ4QV88LaBKnXWGE0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kNWO7/btqNcFPw4Hf/DS9jTBQ4QV88LaBKnXWGE0/img.png&quot; data-alt=&quot;packaging은 pom으로 선택해주자.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kNWO7/btqNcFPw4Hf/DS9jTBQ4QV88LaBKnXWGE0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FkNWO7%2FbtqNcFPw4Hf%2FDS9jTBQ4QV88LaBKnXWGE0%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;packaging은 pom으로 선택해주자.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p&gt;&lt;b&gt;2. 하위 프로젝트(Maven Module Project)의 생성&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;크게 생성하는 방법은 두가지다. 첫번째 방법은 Maven Module로 생성하는 것이다.&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dLjSI1/btqM9qlv16C/ZpgoyHcep2hud0ot7ggUGK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dLjSI1/btqM9qlv16C/ZpgoyHcep2hud0ot7ggUGK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dLjSI1/btqM9qlv16C/ZpgoyHcep2hud0ot7ggUGK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdLjSI1%2FbtqM9qlv16C%2FZpgoyHcep2hud0ot7ggUGK%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;가장 표준적인 방법이지만 이 방법으로는 깡통 자바 메이븐 프로젝트가 하위프로젝트로 생성이 되므로, 만약 Spring Boot를 하위 프로젝트로 만들고자 하는 경우 수동으로 Spring boot 프로젝트처럼 세팅을 해주어야 한다. (pom.xml, application.properties 등)&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bqojtg/btqM9O7xs38/JgOJRKqkYMkQxAPb04ehp0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bqojtg/btqM9O7xs38/JgOJRKqkYMkQxAPb04ehp0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bqojtg/btqM9O7xs38/JgOJRKqkYMkQxAPb04ehp0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbqojtg%2FbtqM9O7xs38%2FJgOJRKqkYMkQxAPb04ehp0%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;두번째 방법은 Spring Starter Project로 생성하는 것이다.&amp;nbsp;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/tyZxC/btqNf7xycGV/KnW10KMXBu3JFmKwDGc5pk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/tyZxC/btqNf7xycGV/KnW10KMXBu3JFmKwDGc5pk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/tyZxC/btqNf7xycGV/KnW10KMXBu3JFmKwDGc5pk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FtyZxC%2FbtqNf7xycGV%2FKnW10KMXBu3JFmKwDGc5pk%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;이 방법으로 할 경우에는 default location이 아닌 parent project의 하위 경로에 생성을 하여야 한다. 그리고 parent project에 module로 등록을 해야 한다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p&gt;api를 만들기 위해서 mybatis - mysql 를 이용하여 db에서 data를 가져오는 mapper와 service를 생성한다. 이 때 api 프로젝트가 아니라 core 프로젝트에 넣는다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;공식 가이드를 보면 알겠지만, library 프로젝트 (내가 세팅한 환경에서는 core 프로젝트) 또한 스프링 부트 프로젝트이다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1605087941850&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&amp;gt;
&amp;lt;project xmlns=&quot;http://maven.apache.org/POM/4.0.0&quot; 
xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
	xsi:schemaLocation=&quot;http://maven.apache.org/POM/4.0.0 
    https://maven.apache.org/xsd/maven-4.0.0.xsd&quot;&amp;gt;
	&amp;lt;modelVersion&amp;gt;4.0.0&amp;lt;/modelVersion&amp;gt;
	&amp;lt;parent&amp;gt;
		&amp;lt;groupId&amp;gt;org.springframework.boot&amp;lt;/groupId&amp;gt;
		&amp;lt;artifactId&amp;gt;spring-boot-starter-parent&amp;lt;/artifactId&amp;gt;
		&amp;lt;version&amp;gt;2.3.2.RELEASE&amp;lt;/version&amp;gt;
		&amp;lt;relativePath/&amp;gt; &amp;lt;!-- lookup parent from repository --&amp;gt;
	&amp;lt;/parent&amp;gt;
	&amp;lt;groupId&amp;gt;com.example&amp;lt;/groupId&amp;gt;
	&amp;lt;artifactId&amp;gt;multi-module-library&amp;lt;/artifactId&amp;gt;
	&amp;lt;version&amp;gt;0.0.1-SNAPSHOT&amp;lt;/version&amp;gt;
	&amp;lt;name&amp;gt;multi-module-library&amp;lt;/name&amp;gt;
	&amp;lt;description&amp;gt;Demo project for Spring Boot&amp;lt;/description&amp;gt;

	&amp;lt;properties&amp;gt;
		&amp;lt;java.version&amp;gt;1.8&amp;lt;/java.version&amp;gt;
	&amp;lt;/properties&amp;gt;

	&amp;lt;dependencies&amp;gt;
		&amp;lt;dependency&amp;gt;
			&amp;lt;groupId&amp;gt;org.springframework.boot&amp;lt;/groupId&amp;gt;
			&amp;lt;artifactId&amp;gt;spring-boot-starter&amp;lt;/artifactId&amp;gt;
		&amp;lt;/dependency&amp;gt;

		&amp;lt;dependency&amp;gt;
			&amp;lt;groupId&amp;gt;org.springframework.boot&amp;lt;/groupId&amp;gt;
			&amp;lt;artifactId&amp;gt;spring-boot-starter-test&amp;lt;/artifactId&amp;gt;
			&amp;lt;scope&amp;gt;test&amp;lt;/scope&amp;gt;
			&amp;lt;exclusions&amp;gt;
				&amp;lt;exclusion&amp;gt;
					&amp;lt;groupId&amp;gt;org.junit.vintage&amp;lt;/groupId&amp;gt;
					&amp;lt;artifactId&amp;gt;junit-vintage-engine&amp;lt;/artifactId&amp;gt;
				&amp;lt;/exclusion&amp;gt;
			&amp;lt;/exclusions&amp;gt;
		&amp;lt;/dependency&amp;gt;
	&amp;lt;/dependencies&amp;gt;

	&amp;lt;build&amp;gt;
		&amp;lt;plugins&amp;gt;
			&amp;lt;plugin&amp;gt;
				&amp;lt;groupId&amp;gt;org.springframework.boot&amp;lt;/groupId&amp;gt;
				&amp;lt;artifactId&amp;gt;spring-boot-maven-plugin&amp;lt;/artifactId&amp;gt;
			&amp;lt;/plugin&amp;gt;
		&amp;lt;/plugins&amp;gt;
	&amp;lt;/build&amp;gt;

&amp;lt;/project&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;즉, library 프로젝트는 독립으로 돌아갈 수 있는 프로젝트인 셈.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/brwRRv/btqNgsuHIJ5/mgyII6TqT3SoMokE1RzT6K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/brwRRv/btqNgsuHIJ5/mgyII6TqT3SoMokE1RzT6K/img.png&quot; data-alt=&quot;Core project의 구성&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/brwRRv/btqNgsuHIJ5/mgyII6TqT3SoMokE1RzT6K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbrwRRv%2FbtqNgsuHIJ5%2FmgyII6TqT3SoMokE1RzT6K%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Core project의 구성&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;이렇게 구성하면 mapper와 service, xml 파일, 심지어는 controller 까지도 core에 두고 개발이 가능하다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/veS0q/btqNaF3CQsm/337FHFPOj64oMsFO6Og0l0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/veS0q/btqNaF3CQsm/337FHFPOj64oMsFO6Og0l0/img.png&quot; data-alt=&quot;api 서버의 구성&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/veS0q/btqNaF3CQsm/337FHFPOj64oMsFO6Og0l0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FveS0q%2FbtqNaF3CQsm%2F337FHFPOj64oMsFO6Og0l0%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;api 서버의 구성&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1605089279518&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;@SpringBootTest
@ContextConfiguration(classes=****BackofficeApiApplication.class)
public class ClickPaidServiceTest 
{
	Logger logger = LoggerFactory.getLogger(ClickPaidServiceTest.class);
	
	@Autowired
	ClickPaidService cps;
	
	@Test
	public void test()
	{
		int a = cps.selectCount(Date.valueOf(&quot;2020-10-21&quot;), 20);
		logger.info(&quot;&quot;+a);
	}
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;다만 core 프로젝트를 참조하는 다른 프로젝트에서 &lt;span style=&quot;color: #333333;&quot;&gt;JUnit을 통해 단위 테스트를 할 때는 ContextConfiguration을 통해 Application.class 를 지정해주어야 한다. 그렇지 않으면 중복되는게 있다고 에러 메세지가 뜬다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p&gt;application.properties 등 api에 중복되는 파일이 존재하는 경우, core의 파일이 아니라 api의 파일을 우선적으로 선택하여 실행한다.&lt;/p&gt;</description>
      <category>Server/Spring Boots</category>
      <category>maven</category>
      <category>multi module</category>
      <category>spring boot</category>
      <author>몽실KUN</author>
      <guid isPermaLink="true">https://devsquare.tistory.com/36</guid>
      <comments>https://devsquare.tistory.com/36#entry36comment</comments>
      <pubDate>Wed, 11 Nov 2020 19:17:28 +0900</pubDate>
    </item>
    <item>
      <title>[삽질] vue.js + spring boot 통합 환경 -1-</title>
      <link>https://devsquare.tistory.com/35</link>
      <description>&lt;p&gt;사실 vue.js와 spring boot 를 통합하는 글은 많이 있다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;그러나 대부분의 예제는 backend로 spring boot를, frontend로 node.js를 사용한다.&lt;/p&gt;
&lt;pre id=&quot;code_1605055600810&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;npm run serve&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;우선 공식 홈페이지에서 안내하는 vue.js 사용법에 대해 한 번 살펴보자.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://vuejs.org/v2/guide/installation.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;vuejs.org/v2/guide/installation.html&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1605055833575&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-og-type=&quot;article&quot; data-og-title=&quot;Installation &amp;mdash; Vue.js&quot; data-og-description=&quot;Vue.js - The Progressive JavaScript Framework&quot; data-og-host=&quot;vuejs.org&quot; data-og-source-url=&quot;https://vuejs.org/v2/guide/installation.html&quot; data-og-url=&quot;https://vuejs.org/v2/guide/installation.html&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/Q0CsT/hyIdjHZTTj/hfjFWpZLYjIYfOAzKqSEB0/img.png?width=400&amp;amp;height=400&amp;amp;face=0_0_400_400,https://scrap.kakaocdn.net/dn/qySz0/hyIdmxXkv7/qqpTDiBqUbdtYb5wF8vXIK/img.png?width=400&amp;amp;height=400&amp;amp;face=0_0_400_400&quot;&gt;&lt;a href=&quot;https://vuejs.org/v2/guide/installation.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://vuejs.org/v2/guide/installation.html&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/Q0CsT/hyIdjHZTTj/hfjFWpZLYjIYfOAzKqSEB0/img.png?width=400&amp;amp;height=400&amp;amp;face=0_0_400_400,https://scrap.kakaocdn.net/dn/qySz0/hyIdmxXkv7/qqpTDiBqUbdtYb5wF8vXIK/img.png?width=400&amp;amp;height=400&amp;amp;face=0_0_400_400');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot;&gt;Installation &amp;mdash; Vue.js&lt;/p&gt;
&lt;p class=&quot;og-desc&quot;&gt;Vue.js - The Progressive JavaScript Framework&lt;/p&gt;
&lt;p class=&quot;og-host&quot;&gt;vuejs.org&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p&gt;크게 3가지 방법 (Direct Script include / NPM / Vue CLI)가 있다. 여기서 Direct Script Include를 살펴보자&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/crb0BY/btqM63J3BJr/1VlSrhfpWfb3dKMFsjaWNK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/crb0BY/btqM63J3BJr/1VlSrhfpWfb3dKMFsjaWNK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/crb0BY/btqM63J3BJr/1VlSrhfpWfb3dKMFsjaWNK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcrb0BY%2FbtqM63J3BJr%2F1VlSrhfpWfb3dKMFsjaWNK%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;node.js 서버를 올리는 방법 외에도 기존의 js 파일을 script tag로 불러오는 것처럼 간단하게 불러올 수 있다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p&gt;우선 vue.js를 사용할 때 왜 node.js에 올려서 사용하는지 생각해보았다. 여러가지 이유가 있겠지만 가장 큰 이유는 javascript의 compile이 가능한 환경이기 때문일 것이다.&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://forum.vuejs.org/t/how-can-i-serve-vue-app-without-node-js/38801&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;forum.vuejs.org/t/how-can-i-serve-vue-app-without-node-js/38801&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1605057301977&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-og-type=&quot;website&quot; data-og-title=&quot;How can I serve Vue app without Node.js?&quot; data-og-description=&quot;Hello! I got stuck with serving Vue app on Linux-based server. I have my Vue app locally now. I&amp;rsquo;ve created it via vue-cli. Locally I use Node.js. But on server I&amp;rsquo;m going to have Apache, so I can&amp;rsquo;t serve Vue via Node.js, because of 80 port might be fo&quot; data-og-host=&quot;forum.vuejs.org&quot; data-og-source-url=&quot;https://forum.vuejs.org/t/how-can-i-serve-vue-app-without-node-js/38801&quot; data-og-url=&quot;https://forum.vuejs.org/t/how-can-i-serve-vue-app-without-node-js/38801&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/pkgeJ/hyIc9rRnMn/Pa1YXnYL6NifPhlUcPYAtK/img.png?width=400&amp;amp;height=400&amp;amp;face=0_0_400_400,https://scrap.kakaocdn.net/dn/mwfgL/hyIb0QQzvK/vOq6MKHhwJPRUjFFIA6H90/img.png?width=400&amp;amp;height=400&amp;amp;face=0_0_400_400,https://scrap.kakaocdn.net/dn/tZwu5/hyIbYlaKPK/GScp3VTR5Tp3YKdK2FsUJ0/img.png?width=400&amp;amp;height=400&amp;amp;face=0_0_400_400&quot;&gt;&lt;a href=&quot;https://forum.vuejs.org/t/how-can-i-serve-vue-app-without-node-js/38801&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://forum.vuejs.org/t/how-can-i-serve-vue-app-without-node-js/38801&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/pkgeJ/hyIc9rRnMn/Pa1YXnYL6NifPhlUcPYAtK/img.png?width=400&amp;amp;height=400&amp;amp;face=0_0_400_400,https://scrap.kakaocdn.net/dn/mwfgL/hyIb0QQzvK/vOq6MKHhwJPRUjFFIA6H90/img.png?width=400&amp;amp;height=400&amp;amp;face=0_0_400_400,https://scrap.kakaocdn.net/dn/tZwu5/hyIbYlaKPK/GScp3VTR5Tp3YKdK2FsUJ0/img.png?width=400&amp;amp;height=400&amp;amp;face=0_0_400_400');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot;&gt;How can I serve Vue app without Node.js?&lt;/p&gt;
&lt;p class=&quot;og-desc&quot;&gt;Hello! I got stuck with serving Vue app on Linux-based server. I have my Vue app locally now. I&amp;rsquo;ve created it via vue-cli. Locally I use Node.js. But on server I&amp;rsquo;m going to have Apache, so I can&amp;rsquo;t serve Vue via Node.js, because of 80 port might be fo&lt;/p&gt;
&lt;p class=&quot;og-host&quot;&gt;forum.vuejs.org&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p&gt;포럼에 올라온 답변에 따르면 vue.js의 실행에서는 node.js를 필수로 요구하지 않는다. npm을 통해 build가 된 이후에는 static file 로 컴파일이 되며 이러한 정적 리소스 파일들은 전통적인 방법처럼 이용할 수 있다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/48GUi/btqNaFnRtRH/kNwnm0X22GIbYYMbzc8N61/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/48GUi/btqNaFnRtRH/kNwnm0X22GIbYYMbzc8N61/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/48GUi/btqNaFnRtRH/kNwnm0X22GIbYYMbzc8N61/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F48GUi%2FbtqNaFnRtRH%2FkNwnm0X22GIbYYMbzc8N61%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://dev.to/arswaw/create-a-lightweight-componentized-spa-without-node-569j&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;dev.to/arswaw/create-a-lightweight-componentized-spa-without-node-569j&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1605057722520&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-og-type=&quot;article&quot; data-og-title=&quot;Use Vue to create a SPA without any Node modules&quot; data-og-description=&quot;In this guide I will show you to create a static single-page application with VueJS and ES6 Modules....&quot; data-og-host=&quot;dev.to&quot; data-og-source-url=&quot;https://dev.to/arswaw/create-a-lightweight-componentized-spa-without-node-569j&quot; data-og-url=&quot;https://dev.to/arswaw/create-a-lightweight-componentized-spa-without-node-569j&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/kUyPf/hyIbPV4893/GBYhD391J9WznDwcKloIiK/img.png?width=1128&amp;amp;height=600&amp;amp;face=86_477_124_519&quot;&gt;&lt;a href=&quot;https://dev.to/arswaw/create-a-lightweight-componentized-spa-without-node-569j&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://dev.to/arswaw/create-a-lightweight-componentized-spa-without-node-569j&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/kUyPf/hyIbPV4893/GBYhD391J9WznDwcKloIiK/img.png?width=1128&amp;amp;height=600&amp;amp;face=86_477_124_519');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot;&gt;Use Vue to create a SPA without any Node modules&lt;/p&gt;
&lt;p class=&quot;og-desc&quot;&gt;In this guide I will show you to create a static single-page application with VueJS and ES6 Modules....&lt;/p&gt;
&lt;p class=&quot;og-host&quot;&gt;dev.to&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p&gt;관련하여 튜토리얼을 하나 찾았다. 댓글을 보면 spring boot 환경에서 동작하는 것을 알 수 있다. 즉, 완전히 불가능한 접근 방법은 아닌 듯 하다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p&gt;&amp;nbsp;물론 vue.js 를 사용하는 방법 중에서 가장 범용적인 방법은 node.js에 올리는 것이다. 그러나 남들이 일반적으로 node.js를 사용한다고 해서, vue.js를 사용하기 위해 node.js를 도입하는 것은 주객이 전도되는 상황이다. 운영되는 서버를 node.js 와 tomcat에서 tomcat으로 일원화함으로써 관리포인트를 줄이자는 차원에서 vue.js를 spring boot 에 올려서 사용하는 방법에 대해 리서치를 진행할 것이다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p&gt;&lt;b&gt;왜 Javascript Compile이 필요한가?&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;사실 컴파일이 필요가 없으면&amp;nbsp; build를 할 필요도 없고, 그저 다운로드 받아서 올려서 쓰면 된다. 간혹 이거를 편법으로 생각하는 분들이 있는데, 공식 사이트에서 가이드하는 정식 사용법 중 하나인 것을 알자. vue.js는 node.js만을 위한 프레임 워크가 아니다.&lt;br /&gt;&lt;br /&gt;그럼에도 불구하고 node.js 상에서 구축을 하는 것이 여러모로 편리한데, 그 중 하나는 JSX 문법일 것이다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://vuejs.org/v2/guide/render-function.html#JSX&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;vuejs.org/v2/guide/render-function.html#JSX&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1605058776652&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-og-type=&quot;article&quot; data-og-title=&quot;Render Functions &amp;amp; JSX &amp;mdash; Vue.js&quot; data-og-description=&quot;Vue.js - The Progressive JavaScript Framework&quot; data-og-host=&quot;vuejs.org&quot; data-og-source-url=&quot;https://vuejs.org/v2/guide/render-function.html#JSX&quot; data-og-url=&quot;https://vuejs.org/v2/guide/render-function.html#JSX&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/dgK8gP/hyIbPV5KKp/av2jPNSye7cMldx74Innik/img.png?width=400&amp;amp;height=400&amp;amp;face=0_0_400_400,https://scrap.kakaocdn.net/dn/NIsYN/hyIbZEoR4z/DNkR4onV1czLkkVuIHeiC0/img.png?width=400&amp;amp;height=400&amp;amp;face=0_0_400_400&quot;&gt;&lt;a href=&quot;https://vuejs.org/v2/guide/render-function.html#JSX&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://vuejs.org/v2/guide/render-function.html#JSX&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/dgK8gP/hyIbPV5KKp/av2jPNSye7cMldx74Innik/img.png?width=400&amp;amp;height=400&amp;amp;face=0_0_400_400,https://scrap.kakaocdn.net/dn/NIsYN/hyIbZEoR4z/DNkR4onV1czLkkVuIHeiC0/img.png?width=400&amp;amp;height=400&amp;amp;face=0_0_400_400');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot;&gt;Render Functions &amp;amp; JSX &amp;mdash; Vue.js&lt;/p&gt;
&lt;p class=&quot;og-desc&quot;&gt;Vue.js - The Progressive JavaScript Framework&lt;/p&gt;
&lt;p class=&quot;og-host&quot;&gt;vuejs.org&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/vuejs/jsx&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;github.com/vuejs/jsx&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1605058781818&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-og-type=&quot;object&quot; data-og-title=&quot;vuejs/jsx&quot; data-og-description=&quot;monorepo for Babel / Vue JSX related packages. Contribute to vuejs/jsx development by creating an account on GitHub.&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/vuejs/jsx&quot; data-og-url=&quot;https://github.com/vuejs/jsx&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bp4alV/hyIdfr5JXX/GWvILbCJau6vK2CCud7VSk/img.png?width=200&amp;amp;height=200&amp;amp;face=0_0_200_200&quot;&gt;&lt;a href=&quot;https://github.com/vuejs/jsx&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/vuejs/jsx&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bp4alV/hyIdfr5JXX/GWvILbCJau6vK2CCud7VSk/img.png?width=200&amp;amp;height=200&amp;amp;face=0_0_200_200');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot;&gt;vuejs/jsx&lt;/p&gt;
&lt;p class=&quot;og-desc&quot;&gt;monorepo for Babel / Vue JSX related packages. Contribute to vuejs/jsx development by creating an account on GitHub.&lt;/p&gt;
&lt;p class=&quot;og-host&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1605058835046&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;render() {
  return &amp;lt;input
    type=&quot;email&quot;
    placeholder={this.placeholderText}
  /&amp;gt;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Jquery나 바닐라 Javascript로 개발한 사람은 위 구문을 기존 방식으로 짤 경우 소스 코드가 엄청 지저분해진다는 것을 알 것이다. JS상에서 html 태그의 원형(엄밀히 말하면 xml)을 그대로 사용할 수 있다면 코드의 가독성과 생산성이 엄청나게 증가할 것이다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;위와 같이 jsx 문법을 사용하여 작성된 스크립트를 node.js 없이 spring boot에서 static js 파일로 동작하게 개발환경을 구성하고자 한다.&lt;/p&gt;</description>
      <category>기타/vue.js</category>
      <category>node.js</category>
      <category>NPM</category>
      <category>spring boot</category>
      <category>Vue.js</category>
      <category>삽질</category>
      <category>통합</category>
      <author>몽실KUN</author>
      <guid isPermaLink="true">https://devsquare.tistory.com/35</guid>
      <comments>https://devsquare.tistory.com/35#entry35comment</comments>
      <pubDate>Wed, 11 Nov 2020 10:45:39 +0900</pubDate>
    </item>
    <item>
      <title>Spring Profile + Maven Profile + WAR파일 배포</title>
      <link>https://devsquare.tistory.com/34</link>
      <description>&lt;p&gt;Maven Profile 세팅&lt;/p&gt;
&lt;pre id=&quot;code_1603257525208&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;profiles&amp;gt;
	&amp;lt;profile&amp;gt;
		&amp;lt;id&amp;gt;dev&amp;lt;/id&amp;gt;
		&amp;lt;activation&amp;gt;
			&amp;lt;activeByDefault&amp;gt;true&amp;lt;/activeByDefault&amp;gt;
		&amp;lt;/activation&amp;gt;
		&amp;lt;properties&amp;gt;
			&amp;lt;activatedProperties&amp;gt;dev&amp;lt;/activatedProperties&amp;gt;
		&amp;lt;/properties&amp;gt;
	&amp;lt;/profile&amp;gt;
	&amp;lt;profile&amp;gt;
		&amp;lt;id&amp;gt;local&amp;lt;/id&amp;gt;
		&amp;lt;properties&amp;gt;
			&amp;lt;activatedProperties&amp;gt;local&amp;lt;/activatedProperties&amp;gt;
		&amp;lt;/properties&amp;gt;
	&amp;lt;/profile&amp;gt;
	&amp;lt;profile&amp;gt;
		&amp;lt;id&amp;gt;live&amp;lt;/id&amp;gt;
		&amp;lt;properties&amp;gt;
			&amp;lt;activatedProperties&amp;gt;live&amp;lt;/activatedProperties&amp;gt;
		&amp;lt;/properties&amp;gt;
	&amp;lt;/profile&amp;gt;
&amp;lt;/profiles&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;스프링 프로필 세팅&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/qZ4aZ/btqLpToG2Ax/FGe5FF0npD0SGq4MdOIV5k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/qZ4aZ/btqLpToG2Ax/FGe5FF0npD0SGq4MdOIV5k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/qZ4aZ/btqLpToG2Ax/FGe5FF0npD0SGq4MdOIV5k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FqZ4aZ%2FbtqLpToG2Ax%2FFGe5FF0npD0SGq4MdOIV5k%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;한가지 중요한 것은 Maven Profile이랑 Spring Profile은 다르다는 것이다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Maven Profile은 Build 시점에서 사용되는 profile이고, spring.profiles.active는 Run Time에서 쓰이는 프로필이다. 때문에 이를 JAVA_OPTS 에 넣어서 런타임 시 실행하게 하는 방법이 보통 많이 쓰이고 있다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1603259113016&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;clean package -Plocal&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;빌드 시 Maven Profile 설정&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1603342850020&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;export JAVA_OPTS=&quot;$JAVA_OPTS -Dspring.profiles.active=dev&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Runtime용 스프링 profile 설정&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;JAVA_OPTS를 수정하는 스크립트는 여러 곳에서 주입할 수 있지만, 크게 쓰이는 곳은 2곳이다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;톰캣 경로 내 bin 폴더의 setenv.sh 로 저장&lt;/li&gt;
&lt;li&gt;/etc/profile.d/ 내에 sh 파일로 저장&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;전자는 톰캣 기동 시에, 후자는 리눅스 기동 시에 해당 스크립트를 실행하게 된다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Server/Spring Boots</category>
      <category>deploy</category>
      <category>maven</category>
      <category>Profile</category>
      <category>Spring</category>
      <category>War</category>
      <author>몽실KUN</author>
      <guid isPermaLink="true">https://devsquare.tistory.com/34</guid>
      <comments>https://devsquare.tistory.com/34#entry34comment</comments>
      <pubDate>Wed, 21 Oct 2020 14:46:16 +0900</pubDate>
    </item>
    <item>
      <title>[Spring boot] Class path contains multiple SLF4J bindings 에러</title>
      <link>https://devsquare.tistory.com/33</link>
      <description>&lt;p&gt;참조&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.baeldung.com/slf4j-classpath-multiple-bindings&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;www.baeldung.com/slf4j-classpath-multiple-bindings&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1603254613522&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-og-type=&quot;article&quot; data-og-title=&quot;SLF4J Warning: Class Path Contains Multiple SLF4J Bindings | Baeldung&quot; data-og-description=&quot;Learn about the SLF4J warning &amp;quot;Class path contains multiple SLF4J bindings&amp;quot; and how to fix it&quot; data-og-host=&quot;www.baeldung.com&quot; data-og-source-url=&quot;https://www.baeldung.com/slf4j-classpath-multiple-bindings&quot; data-og-url=&quot;https://www.baeldung.com/slf4j-classpath-multiple-bindings&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/hTxU9/hyHXpBMvgV/Hyljgp2FhCbol8XWFlXPLk/img.jpg?width=952&amp;amp;height=498&amp;amp;face=0_0_952_498,https://scrap.kakaocdn.net/dn/bThZKS/hyHXiJqluY/Q0tyMwGjQvCkIxaHQUzZkk/img.jpg?width=952&amp;amp;height=498&amp;amp;face=0_0_952_498&quot;&gt;&lt;a href=&quot;https://www.baeldung.com/slf4j-classpath-multiple-bindings&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.baeldung.com/slf4j-classpath-multiple-bindings&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/hTxU9/hyHXpBMvgV/Hyljgp2FhCbol8XWFlXPLk/img.jpg?width=952&amp;amp;height=498&amp;amp;face=0_0_952_498,https://scrap.kakaocdn.net/dn/bThZKS/hyHXiJqluY/Q0tyMwGjQvCkIxaHQUzZkk/img.jpg?width=952&amp;amp;height=498&amp;amp;face=0_0_952_498');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot;&gt;SLF4J Warning: Class Path Contains Multiple SLF4J Bindings | Baeldung&lt;/p&gt;
&lt;p class=&quot;og-desc&quot;&gt;Learn about the SLF4J warning &quot;Class path contains multiple SLF4J bindings&quot; and how to fix it&lt;/p&gt;
&lt;p class=&quot;og-host&quot;&gt;www.baeldung.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p&gt;에러 로그&lt;/p&gt;
&lt;pre id=&quot;code_1603254686496&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SLF4J: Class path contains multiple SLF4J bindings.
SLF4J: Found binding in [jar:file:.../slf4j-log4j12-1.7.21.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in [jar:file:.../logback-classic-1.1.7.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation.
SLF4J: Actual binding is of type [org.slf4j.impl.Log4jLoggerFactory]&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;에러 로그에 따르면 SLF4J가 Multiple Binding이 되어 있다고 나온다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;충돌나는부분은 log4J와 logback이다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/3ZsUs/btqLq4C3Iku/CNkku0BbYlpl7ZHLQOHxvk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/3ZsUs/btqLq4C3Iku/CNkku0BbYlpl7ZHLQOHxvk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/3ZsUs/btqLq4C3Iku/CNkku0BbYlpl7ZHLQOHxvk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F3ZsUs%2FbtqLq4C3Iku%2FCNkku0BbYlpl7ZHLQOHxvk%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;우선 Spring-boot-starter-web 패키지에는 Spring-boot-starter-logging을 dependency로 참조하고 있다. 만약 여기서 Spring-boot-starter-log4j2 를 pom.xml에 추가해 넣게 되면 충돌이 일어나게 되는 것이다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://stackoverflow.com/questions/14024756/slf4j-class-path-contains-multiple-slf4j-bindings&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;stackoverflow.com/questions/14024756/slf4j-class-path-contains-multiple-slf4j-bindings&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1603255280112&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-og-type=&quot;website&quot; data-og-title=&quot;SLF4J: Class path contains multiple SLF4J bindings&quot; data-og-description=&quot;I'm getting the following error. It seems there are multiple logging frameworks bound to slf4j. Not sure how to resolve this. Any help is greatly appreciated. SLF4J: Class path contains multiple SL...&quot; data-og-host=&quot;stackoverflow.com&quot; data-og-source-url=&quot;https://stackoverflow.com/questions/14024756/slf4j-class-path-contains-multiple-slf4j-bindings&quot; data-og-url=&quot;https://stackoverflow.com/questions/14024756/slf4j-class-path-contains-multiple-slf4j-bindings&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/ehU8M2/hyHWl14pPy/vyVUxToKtKBFvPMHH2PTv0/img.png?width=316&amp;amp;height=316&amp;amp;face=0_0_316_316,https://scrap.kakaocdn.net/dn/Om01B/hyHWcKPrAG/2xEodM9YInTZQWw53hTgiK/img.png?width=982&amp;amp;height=385&amp;amp;face=0_0_982_385&quot;&gt;&lt;a href=&quot;https://stackoverflow.com/questions/14024756/slf4j-class-path-contains-multiple-slf4j-bindings&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://stackoverflow.com/questions/14024756/slf4j-class-path-contains-multiple-slf4j-bindings&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/ehU8M2/hyHWl14pPy/vyVUxToKtKBFvPMHH2PTv0/img.png?width=316&amp;amp;height=316&amp;amp;face=0_0_316_316,https://scrap.kakaocdn.net/dn/Om01B/hyHWcKPrAG/2xEodM9YInTZQWw53hTgiK/img.png?width=982&amp;amp;height=385&amp;amp;face=0_0_982_385');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot;&gt;SLF4J: Class path contains multiple SLF4J bindings&lt;/p&gt;
&lt;p class=&quot;og-desc&quot;&gt;I'm getting the following error. It seems there are multiple logging frameworks bound to slf4j. Not sure how to resolve this. Any help is greatly appreciated. SLF4J: Class path contains multiple SL...&lt;/p&gt;
&lt;p class=&quot;og-host&quot;&gt;stackoverflow.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p&gt;머 해결방법은 다양하다. Multiple Binding이 되는 부분을 지워주면 된다. 나 같은 경우는 spring-boot-starter-log4j2를 사용하기 위해서 spring-boot-starter-logging을 exclude 했다. 반대로 log4j2를 주석처리해서 dependency에서 빼도 동작한다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1603255436774&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;dependency&amp;gt;
	&amp;lt;groupId&amp;gt;org.springframework.boot&amp;lt;/groupId&amp;gt;
	&amp;lt;artifactId&amp;gt;spring-boot-starter-web&amp;lt;/artifactId&amp;gt;
	&amp;lt;exclusions&amp;gt;
		&amp;lt;exclusion&amp;gt;
			&amp;lt;groupId&amp;gt;org.springframework.boot&amp;lt;/groupId&amp;gt;
			&amp;lt;artifactId&amp;gt;spring-boot-starter-logging&amp;lt;/artifactId&amp;gt;
		&amp;lt;/exclusion&amp;gt;
	&amp;lt;/exclusions&amp;gt;
&amp;lt;/dependency&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Server/Spring Boots</category>
      <category>boot</category>
      <category>log4j</category>
      <category>multiple binding</category>
      <category>slf4j</category>
      <category>Spring</category>
      <category>멀티 바인딩</category>
      <author>몽실KUN</author>
      <guid isPermaLink="true">https://devsquare.tistory.com/33</guid>
      <comments>https://devsquare.tistory.com/33#entry33comment</comments>
      <pubDate>Wed, 21 Oct 2020 13:44:33 +0900</pubDate>
    </item>
    <item>
      <title>Session getAttribute Integer 주의사항</title>
      <link>https://devsquare.tistory.com/32</link>
      <description>&lt;p&gt;정말 생각도 못했던 버그이다.&lt;/p&gt;
&lt;p&gt;이유는 모르겠으나, 로컬 개발 환경(Windows)에서는 에러가 발생하지 않지만&lt;/p&gt;
&lt;p&gt;실서버 (Linux-Tomcat)에서는 에러가 합니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://stackoverflow.com/questions/6031278/session-attribute-access-and-converting-to-int&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;stackoverflow.com/questions/6031278/session-attribute-access-and-converting-to-int&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1602664416967&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Session attribute access and converting to int?&quot; data-og-description=&quot;I have stored user id in Session using following command in Servlet: HttpSession session = request.getSession(); session.setAttribute(&amp;quot;user&amp;quot;, user.getId()); Now, I want to access that user id from&quot; data-og-host=&quot;stackoverflow.com&quot; data-og-source-url=&quot;https://stackoverflow.com/questions/6031278/session-attribute-access-and-converting-to-int&quot; data-og-url=&quot;https://stackoverflow.com/questions/6031278/session-attribute-access-and-converting-to-int&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/cMYEZ2/hyHRP2YwKl/LeuSE7YWjVskNKGHNT8fm1/img.png?width=316&amp;amp;height=316&amp;amp;face=0_0_316_316&quot;&gt;&lt;a href=&quot;https://stackoverflow.com/questions/6031278/session-attribute-access-and-converting-to-int&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://stackoverflow.com/questions/6031278/session-attribute-access-and-converting-to-int&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/cMYEZ2/hyHRP2YwKl/LeuSE7YWjVskNKGHNT8fm1/img.png?width=316&amp;amp;height=316&amp;amp;face=0_0_316_316');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot;&gt;Session attribute access and converting to int?&lt;/p&gt;
&lt;p class=&quot;og-desc&quot;&gt;I have stored user id in Session using following command in Servlet: HttpSession session = request.getSession(); session.setAttribute(&quot;user&quot;, user.getId()); Now, I want to access that user id from&lt;/p&gt;
&lt;p class=&quot;og-host&quot;&gt;stackoverflow.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p&gt;거두절미하고 결론부터 말하자면&lt;/p&gt;
&lt;p&gt;int값을 getAttribute 할 때는 (Integer) casting을 해줘야 한다. (int casting이 아니라)&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1602665805884&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;int randValue = rand.nextInt();
String randkey = TestController.byteArrayToHex(bytes);
//=========== SET ===========
session.setAttribute(randkey, randValue);
//===========================
//=========== GET ===========
(Integer) session.getAttribute(key);
//===========================&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>integer</category>
      <category>Java</category>
      <category>SESSION</category>
      <author>몽실KUN</author>
      <guid isPermaLink="true">https://devsquare.tistory.com/32</guid>
      <comments>https://devsquare.tistory.com/32#entry32comment</comments>
      <pubDate>Wed, 14 Oct 2020 17:57:27 +0900</pubDate>
    </item>
  </channel>
</rss>