해당 라이브러리는 말이 필요 없다.

적용 방법은 아래와 같으며, 간단하게 날짜에 관한 문제를 거의 모든걸 해결해준다.

document.addEventListener("DOMContentLoaded", function(){
	var nowMoment = moment(new Data());
	nowMoment.format('YYYY-MM-DD hh:mm:ss');       // 2020-06-09 16:43:22

	// Add day 
	nowMoment.add(1, 'days').format('YYYY-MM-DD');   // 2020-06-10
  // Add Month 
	nowMoment.add(1, 'months').format('YYYY-MM-DD');  // 2020-07-10
  // Add Year
	nowMoment.add(1, 'years').format('YYYY-MM-DD');  // 2021-07-10

  // first Month Date
	nowMoment.startOf('month').format('YYYY-MM-DD');  // 2021-07-01
  // end Month Date
	nowMoment.endOf('month').format('YYYY-MM-DD');  // 2021-07-31

});

 

 

IDE에 Spring Boot 설치 및 설정 관련 사항은 별도 설명 없이 프로젝트 생성 부터 설명이 진행한다.

 

1. Spring Boot 프로젝트 생성하여 아래와 같은 Dependencies를 추가 한다.

* JDBC API
* Spring Data JPA
* Spring Data JDBC
* Rest Repositories
* Rest Repositories HAL Browser

2. Depdependency 내용

Gradle - Build.gradle 

plugins {
	id 'org.springframework.boot' version '2.2.4.RELEASE'
	id 'io.spring.dependency-management' version '1.0.9.RELEASE'
	id 'java'
}

group = 'com.demo'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '1.8'

configurations {
	compileOnly {
		extendsFrom annotationProcessor
	}
}

repositories {
	mavenCentral()
}

dependencies {
	implementation 'org.springframework.boot:spring-boot-starter-data-jdbc'
	implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
	implementation 'org.springframework.boot:spring-boot-starter-data-rest'
	implementation 'org.springframework.data:spring-data-rest-hal-browser'
	compile 'mysql:mysql-connector-java'
	compileOnly 'org.projectlombok:lombok'
	annotationProcessor 'org.projectlombok:lombok'
	testImplementation('org.springframework.boot:spring-boot-starter-test') {
		exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
	}
}

test {
	useJUnitPlatform()
}

maven - Pom.xml

	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-data-jdbc</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-data-jpa</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-data-rest</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-jdbc</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.data</groupId>
			<artifactId>spring-data-rest-hal-explorer</artifactId>
		</dependency>

		<dependency>
			<groupId>org.postgresql</groupId>
			<artifactId>postgresql</artifactId>
			<scope>runtime</scope>
		</dependency>
		<dependency>
			<groupId>org.projectlombok</groupId>
			<artifactId>lombok</artifactId>
			<optional>true</optional>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
			<exclusions>
				<exclusion>
					<groupId>org.junit.vintage</groupId>
					<artifactId>junit-vintage-engine</artifactId>
				</exclusion>
			</exclusions>
		</dependency>
	</dependencies>

3. 기본 게시판 Entity 내용

/* com.demo.back.entity>Board.java */ 
package com.demo.back.entity;

import java.time.LocalDate;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;

@Entity
public class Board {
	
	@Id
	@GeneratedValue
	private Long seq;
	
	@Column
	private String title;
	
	@Column
	private String context;
	
	@Column
	private LocalDate uptDt;
	
	@Column
	private LocalDate regDt;

	.... getter & setter ...
}

4. 레파지토리 연계 리소스

/* com.demo.back.repository > BoardRepository.java */

package com.demo.back.repository;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.rest.core.annotation.RepositoryRestResource;

import com.demo.back.entity.Board;

@RepositoryRestResource(collectionResourceRel = "board", path = "board")
public interface BoardRepository extends JpaRepository<Board, Long>{
}

5. application 설정 파일

/* src/main/resources/application.properties */

server.port=8000

spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/simpleBoard?serverTimezone=UTC&characterEncoding=UTF-8
spring.datasource.username=simpleBoard
spring.datasource.password=simple

spring.data.rest.base-path=/api
spring.data.rest.default-page-size=10

spring.jpa.hibernate.ddl-auto=create-drop
spring.jpa.show-sql=true

6. 외부에서 접근 가능 하게 Header 정보 변경

/* com.demo.back.common > CORSFilter.java */
package com.demo.back.common;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletResponse;

import org.springframework.stereotype.Component;

@Component
public class CORSFilter implements Filter {
	
	@Override
	public void init(FilterConfig fileterConfig) throws ServletException {
		// TODO Auto-generated method stub
	}

	@Override
	public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletResponse response = (HttpServletResponse) servletResponse;
        response.setHeader("Access-Control-Allow-Origin", "*");
        response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
        response.setHeader("Access-Control-Max-Age", "3600");
        response.setHeader("Access-Control-Allow-Headers", "*");
        filterChain.doFilter(servletRequest, servletResponse);
    }
	
	@Override
	public void destroy() {
		
	}
}

7. 구동 후 http://localhost:8000/api/ 접속 하면 위 Dependencies 했던 Rest Repositories HAL Browser 가 실행하여 테스트 할 수 있습니다.

IDE 도구는 Visual Studio Code 로 작업 진행하고 IDE에 사용 되는 Vue 관련 플로그 인은 별도 설명은 생략 한다.

1. Vue Js 앱 생성 과정

# vue-cli 설치
$ npm install -g @vue/cli
# vue 앱 생성
$ vue create simple-board
$ cd simple-board
# vuetify 추가 설치
$ vue add vuetify
# 설치 진행중 질문 사항
✔  Successfully installed plugin: vue-cli-plugin-vuetify

? Choose a preset: Configure (advanced)
? Use a pre-made template? (will replace App.vue and HelloWorld.vue) Yes
? Use custom theme? No
? Use custom properties (CSS variables)? No
? Select icon font Material Icons
? Use fonts as a dependency (for Electron or offline)? Yes
? Use a-la-carte components? No
? Use babel/polyfill? Yes
? Select locale Korean
# 기본 vueJS 앱 서버 실행
$ npm run serve
# 성공시 아래와 같은 메시지 확인과 주소 접근시 페이지 확인 가능.
DONE  Compiled successfully in 5252ms                                                                                                                                                       10:45:31 AM

  App running at:
  - Local:   http://localhost:8080/
  - Network: http://192.168.1.179:8080/

  Note that the development build is not optimized.
  To create a production build, run npm run build.

2. 앱 생성 후 기본 주요 디렉토리 구조

├─node_modules             
├─public    
├─src
│  ├─App.vue
│  ├─main.js 
│  ├─assets
│  ├─components
│  │  └─HelloWorld.vue
│  └─plugins
│	  └─vuetify.js
├─babel.config.js
├─package-lock.json
├─package.json
└─README.md

3. Router 설치

# vuex 및 vue-router 설치
$ npm install --save-dev vue-router vuex

4. Router 적용

/* ## -- src/main.js 변경 사항 */
import Vue from 'vue'
import App from './App.vue'
import vuetify from './plugins/vuetify'
import router from './router'
import '@babel/polyfill'
import 'roboto-fontface/css/roboto/roboto-fontface.css'
import 'material-design-icons-iconfont/dist/material-design-icons.css'

Vue.config.productionTip = false

new Vue({
  vuetify,
  router,
  render: h => h(App)
}).$mount('#app')


/* ## -- src/router 폴더 생성 후 index.js 내용 */
import Vue from 'vue'
import Router from 'vue-router'
import BoardList from '@/components/BoardList'

Vue.use(Router)

export default new Router({
  routes: [
    {
      path: '/',
      name: 'BoardList',
      component: BoardList
    }
  ]
})

*/ ## -- src/App.vue 변경 내용 */
<template>
  <div id="app">
    <v-app-bar>
        Simple Board
    </v-app-bar>
    <router-view/>
  </div>
</template>

<script>
export default {
  name: 'App'
};
</script>

5. 게시판 목록 / 상세 / 작성 라우터 설정

/* axios 설치 */
$ npm install --save-dev axios

/* ## src/router/index.js 내용 변경 */
import Vue from 'vue'
import Router from 'vue-router'
import BoardList from '@/components/BoardList'
import BoardView from '@/components/BoardView'
import BoardWriter from '@/components/BoardWriter'

Vue.use(Router)

export default new Router({
  routes: [
    {
      path: '/',
      name: 'BoardList',
      component: BoardList
    },
    {
      path: '/view/:seq',
      name: 'BoardView',
      component: BoardView
    },
    {
      path: '/writer',
      name: 'BoardWriter',
      component: BoardWriter
    }
  ]
})

6. 각 게시판 목록 / 상세 / 작성 컨포넌트 파일 생성 및 내용

/* ## BoardList.vue 내용 */
<template>
  <v-container>
    <v-data-table
      :headers="headers"
      :items="desserts"
      :items-per-page="5"
      class="elevation-1"
      @click:row="rowClick"
    >
    </v-data-table>
    <v-row>
      <v-btn outlined color="blue" @click="writeClick" > 작성 </v-btn>
    </v-row>
  </v-container>
</template>

<script>
import axios from 'axios'

export default {
  name: 'BoardList',
  created() {
    this.fetch()
  },
  methods: {
    fetch() {
      console.log('fetch list')
      axios.get('http://localhost:8000/api/board/list')
      .then((response) => {
        console.log(response)
      })
      .catch((error) => {
        console.log(error)
      })
    },
    writeClick() {
      this.$router.push('/writer')
    },
    rowClick(item) {
      this.$router.push('/view/' + item.seq)
    }
  },
  data () {
      return {
        headers: [
          {
            text: 'Number',
            align: 'left',
            sortable: false,
            value: 'number',
          },
          { text: 'Title', value: 'title' },
          { text: 'Reg Date', value: 'regDt' }
        ],
        desserts: [],
      }
    }
};
</script>

/* ## BoardWrite.vue 파일 내용 */
<template>
  <v-form>
    <v-container>
      <v-row>
        제목
      </v-row>
      <v-row>
        <v-text-field
          :counter="50"
          label="제목"
          name="title"
          required
          v-model="title"
          maxlength="50"
        ></v-text-field>
      </v-row>
      <v-row>
        내용 
      </v-row>
      <v-row>
        <v-textarea
          filled
          name="context"
          hint="내용을 입력해주세요."
          v-model="context"
          :counter="1000"
          maxlength="1000"
        ></v-textarea>
      </v-row>
      <v-row>
        <v-btn block outlined color="blue" @click="writeClick"> 등록 </v-btn>
      </v-row>
    </v-container>
  </v-form>    
</template>

<script>
import axios from 'axios'

export default {
  name: 'BoardWriter',
  methods: {
    writeClick() {
      if(this.$route.params.seq) {
        axios.put('http://localhost:8000/api/board', this.$data)
        .then((response) => {
          console.log(response)
          this.$router.push('/')
        })
        .catch((error) => {
          console.log(error)
        })
      } else {
        this.$data.regDt = this.getNowDate()
        this.$data.uptDt = this.getNowDate()
        axios.post('http://localhost:8000/api/board', this.$data)
        .then((response) => {
          console.log(response)
          this.$router.push('/')
        })
        .catch((error) => {
          console.log(error)
        })
      }
    },
    getNowDate() {
      var nowDate = new Date()
      var year = nowDate.getFullYear().toString()
      var month = (nowDate.getMonth() + 1).toString()
      var day = nowDate.getDate().toString()

      return year + "-" + (month[1] ? month : "0" + month[0]) + "-" + (day[1] ? day : "0" + day[0])
    }
  },
  data () {
    return {
      title : '',
      context: '',
      uptDt: '',
      regDt: ''
    }
  }
}
</script>


/* ## BoardView.vue 파일 내용 */
<template>
  <v-form>
    <v-container>
      <v-row>
        제목
      </v-row>
      <v-row>
        {{ title }}
      </v-row>
      <v-row>
        내용 
      </v-row>
      <v-row>
        {{ context }}
      </v-row>
      <v-row>
        <v-btn block outlined color="blue" @click="listClick"> 목록 </v-btn>
      </v-row>
    </v-container>
  </v-form>    
</template>

<script>
import axios from 'axios'

export default {
  name: 'BoardView',
  created() {
    this.fetch()
  },
  methods: {
    fetch() {
      axios.get('http://localhost:8000/api/board/' + this.$$router.params.seq)
      .then((response) => {
        console.log(response)
      })
      .catch((error) => {
        console.log(error)
      })
    },
    listClick() {
      this.$router.push('/')
    },
    deleteClick() {
      if(this.$data.seq) {
        axios.delete('http://localhost:8000/api/board/' + this.$data.seq)
        .then((response) => {
          console.log(response)
          this.$router.push('/')
        })
        .catch((error) => {
          console.log(error)
        })
      }
    }
  },
  data () {
    return {
      title : "",
      context: ""
    }
  }
}
</script>

'Javascript' 카테고리의 다른 글

날짜 라이브러리 moment JS  (1) 2020.06.10
Vue Js 설치  (0) 2019.10.01
자바스크립트(Javascript)에서 GET 파라메타 함수  (0) 2018.09.10
jQuery 웹 페이지 로드 테스트  (0) 2018.09.06
jQuery Template 사용.  (0) 2018.09.04

설치 환경

Docker Install

# 기존 docker 관련 삭제
$ yum remove docker docker-client docker-client-latest docker-common docker-latest docker-latest-logrotate docker logrotate docker-engine
# 설치 과정 및 실행 시 필요 유틸 설치
$ yum install -y yum-utils device-mapper-persistent-data lvm2
# yum 레파지토리 추가
$ yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
# docker-ce 및 관련 유틸 설정
$ yum install -y docker-ce docker-ce-cli containerd.io
# 서비스 시작 등록
$ systemctl enabled docker

Docker 허브 이미지 다운로드

# 원하는 패키지는 docker Hub에 존재.
$ docker pull centos:7

Docker 실행 및 옵션

# bash 명령어를 실행 할 수 있게 변경.
$ docker run -it centos:7 bash  
# 컨테이너의 포트와 외부 포트 연결
$ docker run -it -d --name devGuide -p 10088:80 -p 18080:8080 -p 19090:9090 -p 10080:11080 -p 6100:6100 centos:7 
# 컨테이너 디렉토리와 로컬 디렉토리 연결.
$ docker run -it -v /srv/apm:/app centos:7 

Docker 컨테이너&이미지 관리

# 이미지 목록 출력
$ docker images 
# 이미지 삭제
$ docker rmi [이미지ID] 
# 현재 실행 중인 컨테이너 목록 출력
$ docker ps 
# 모든 컨테이너 목록 출력
$ docker ps -a 
# 컨테이너 삭제
$ docker rm [컨테이너ID] 
# 컨테이너 이름 변경
$ docker rename devGuide dev
# 이미지 태그명(복제) 변경
$ docker tag centos:7.1 centos:7 
# 이미지 삭제
$ docker rmi centos:7
# 로컬 이미지 저장소에 현재 컨테이너 상태를 이미지로 등록.
$ docker commit [CONTAINER ID] [Repository]:[TAG]

참고 사항

1. docker run -t -i
- [Ctrl + P] + [Ctrl + Q]로 컨테이너에서 빠져나오게 되면 컨테이너를 현재 상태 그대로 두고 외부로 빠져나올 수 있다.
2. docker run -i
- [Ctrl + P] + [Ctrl + Q]로 컨테이너에서 빠져나올 수 없다. 이 것은 stdin을 붕괴시킬 것이다.
3. docker run
- [Ctrl + P] + [Ctrl + Q]로 컨테이너에서 빠져나올 수 없다.
- SIGKILL 시그널로 도커 컨테이너를 죽일 수 있다.

* 참고 블로그 : http://egloos.zum.com/sstories/v/9731853

 

사전 Apache + Tomcat 설치

Apache 설치

https://dollvin.tistory.com/56

 

Apache 소스 설치 - centOS 7

사용자 변경 및 아파치 소스 다운로드 $ cd /usr/local/src/ $ wget https://archive.apache.org/dist/httpd/httpd-2.4.33.tar.gz $ wget https://archive.apache.org/dist/apr/apr-1.6.3.tar.bz2 $ wget https://..

dollvin.tistory.com

Tomcat 설치

https://dollvin.tistory.com/57

 

Tomcat 설치 - centOS 7

1. 자바(openJDK 1.8) 설치 $ su - root $ yum list | grep java # 설치(1.8) 버전 있는지 확인. $ yum install -y java-1.8.0-openjdk-devel.x86_64 2. Java 설치 확인 및 위치 확인 # 설치 체크 $ java -version..

dollvin.tistory.com

1. tomcat connector 소스 다운로드 및 압축 해제

$ su - root 
$ cd /usr/local/src 
$ wget http://apache.tt.co.kr/tomcat/tomcat-connectors/jk/tomcat-connectors-1.2.46-src.tar.gz 
$ tar xvf ./tomcat-connectors-1.2.46-src.tar.gz 


2. 소스 파일 컴파일

$ cd ./tomcat-connectors-1.2.46-src/native 
$ ./configure --with-apxs=/home/testUser/apache_2.4.33/bin/apxs 
$ make && make install 


3. 아파치(apache) 설정 변경 - httpd.conf

# httpd.conf 
.... 
LoadModule jk_module modules/mod_jk.so 
.... 
Include conf/mod_jk.conf 


4. mod_jk 설정 파일 

JkWorkersFile "/home/testUser/apache_2.4.33/conf/workers.properties" 
JkLogFile "/home/testUser/apache_2.4.33/logs/mod_jk.log" 
JkLogLevel info 
JkLogStampFormat "[%a %b %d %H:%M:%S %Y]" 
JkOptions +ForwardkeySize +ForwardURICompat -ForwardDirectories 
JkRequestLogFormat "%w %V %T" 
jkMount /* worker_tomcat 

     
5. [workers.properties] 프로퍼티 파일 

workers.tomcat_home=/home/testUser/tomcat85/ 
workers.java_home="/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.232.b09-0.el7_7.x86_64" 
worker.list=worker_tomcat 
 
worker.worker_tomcat.port=8009 
worker.worker_tomcat.host=localhost 
worker.worker_tomcat.type=ajp13 


6. 아파치 재구동 및 아파치 포트 접속 시 Tomcat 소스 출력 확인

$ /home/testUser/apache_2.4.33/bin/httpd -k restart

+ Recent posts