들어가며

앞서 JSP 태그 종류를 살펴보았고, 이번 포스팅에서는 각각의 태그의 쓰임을 좀 더 자세히 살펴본다.  

https://0306-0903.tistory.com/118

 

8. JSP(Java Server Page) (2)

JSP 내장 객체 JSP 내장 객체란? JSP에서 기본적으로 제공하는 객체들로 request, response, out 등 Scriptlet tag와 Expression tag에서 사용할 수 있도록 암시적으로 선언 된 객체를 뜻한다. JSP 내장 객체의 종류

0306-0903.tistory.com

 

 

 

  • 프로젝트 하위 web/WEB-INF/index.html 에 다음과 같이 작성한다. 
  • <a href=""></a> 내에 작성하는 것은 해당 jsp 파일 경로를 매핑하는 것이다. 
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>jsp</title>
</head>
<body>
	<h1 align="center">JSP</h1>
	<ul>
		<li><a href="jsp/1_simpleJspStates.jsp">JSP 기본 문법</a></li>
		<li><a href="jsp/2_pageDirective.jsp">page 지시자 태그</a></li>
		<li><a href="jsp/3_includeDirective.jsp">include 지시자 태그</a></li>
		<li><a href="jsp/4_request.jsp">jsp를 이용한 응답 처리(forward)</a></li>
	</ul>
</body>
</html>

 

 

  • 매핑한대로 해당 경로아래에 .jsp파일을 만든다.

 

 

  • 위와 같이 경로와 파일명을 작성하면 다음과같은 .jsp 파일이 생성된다. 
  • <title></title> 사이에 페이지 제목을 작성한다. 
  • <% %> 스크립틀릿 태그 안에는 자바코드를 작성할 수 있다. 

 

  • 스크립틀릿 안에 다음과같은 자바 코드를 작성하면 에러가 생긴다. 왜일까? import 가 안되었기 때문이다. 

 

 

 

 


page <지시자 태그>에서 사용 가능한 속성 


<%@&nbsp; &nbsp;%> 바로 이것! 이것이 페이지 지시자 태그

  • 여러가지 있지만 현재 알고 있어야 하는 속성은 크게 많지는 않다.
  1. errorPage : 현재 페이지에서 Exception이 발생하게 되면 속성 값에 설정한 jsp 경로로 exception을 던진다.
  2. isErrorPage : 현재 페이지가 Exception을 처리할 페이지인 경우 true로 지정한다. 기본 값은 false이다. true일시 내장객체 Exception을 사용할 수 있게된다. 
  3. import : java.lang 패키지 이외의 클래스를 현 jsp 파일에서 사용할 때 import 속성에 정의하게 되면 import 선언부를 작성하는 것과 같다.

  • 또한 지시자 태그는 page 지시자 태그, include 지시자 태그, taglib 지시자 태그가 있다.
  1. page 지시자 태그 : 현 jsp 페이지에 대한 설정을 하는 지시자 태그
  2. include 지시자 태그 : 다른 jsp 파일을 포함하기 위해 사용하는 지시자 태그
  3. taglib : xml 문법 기반의 라이브러리인 JSTL을 이용하기 위해 선언하는 지시자 태그

 

 

* 지시자 태그1. import 

  • 지시자 태그 내 import 태그를 사용해 주니 자바 코드작성이 가능한 스크립틀릿 <%%> 내에 에러줄이 사라졌음을 확인할 수 있다. 임포트 처리가 완료 된 것이다. 

 

 

  • 화면으로 돌아가 페이지 지시자 태그를 눌렀을때 스크립틀릿 코드가 돌았기에 콘솔창에 날짜와 관련된 부분이 적히는 것을 확인할 수 있다. 

 

 

 

  • 만약 임포트 할 경로가 두개 이상이라면 다음과 같이 콤마를 찍고 import=" " 내에 작성하면 된다.

 

 

 

* 지시자 태그2. errorPage

  • 에러페이지라는 속성을 테스트 해본다.
  • 현재 페이지에서 Exception이 발생하게 되면 속성 값에 설정한 jsp 경로로 exception을 던진다.
  • 같은 경로 내에 errorPage.jsp 를 만들어 본다. 

 

"같은 경로 내"

 

 

 

  • 같은 경로내 에러페이지.jsp 파일을 만들었다면 다시 지시자 태그내에 isErrorPage="true"를 작성해준다. 
  • 현재 페이지가 Exception을 처리할 페이지인 경우 true로 지정한다.
  • 에러에대한 속성을 다루는 페이지로서 true 라는 뜻
  • 즉, 에러페이지가 아닌 페이지의 기본 값은 false이다. (기본은 에러페이지가 아닐테니까)

 

  • 이와같이 isErrorPage="true" 로 놓았을때 얻을 수 있는 효과는 
  • exception 이라는 내장객체를 사용할 수 있게 된다는 점이다. 
  • 즉 jsp 내에 그저 exception 이라고 썼을때, 존재하게 되는 어떤 내장 객체가 있는데 이를 이용하여
  • (1) getName통해 '이름'을 알아옴으로서 어떤 에러가 발생했는지 알 수 있고
  • (2) getMassage를 통해 오류 메세지를 얻어올 수도 있다. 

 

즉 ,

  • (1) isErrorPage="true" 설정을 통해서
  • (2) exception  내장 객체의 사용이 가능해지므로
  • (3) exception과 관련된 데이터(getName,getMessage)를 얻어올 수 있다.

 

 

 

그렇다면,

  • 이렇게 가져온 변수값 (exceptionType, exceptionMessage)을 expression 태그를 통해서 화면에 출력해보도록한다.
  • 앞서 jsp 태그를 공부하면서 값을 화면에 출력하기 위해선 expression 태그, 즉 표현 태그를 사용할 수 있음을 알았다.

 

익스프레션 태그를 통해, 가져온 에러 정보를 담은 변수를 화면에 출력해보도록 한다.

 

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8" isErrorPage="true"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>errorPage</title>
</head>
<body>
	<%
		String exceptionType = exception.getClass().getName();
		String exceptionMessage = exception.getMessage();
	%>
	
	<h1 align="center"><%= exceptionType %></h1>
	<h1 align="center"><%= exceptionMessage %></h1>
</body>
</html>

 

 

 

  • 그런데 한가지 문제는 작성한 오류 메세지를 확인하려면 오류가 나야하는데 있다. 
  • 앞서 작성한 pageDirective 라는 이름의 jsp 파일을 열었을때 오류가 발생하도록 해야한다. 
  • 작성하던 페이지로 돌아가 일부러 오류 발생을 시켜본다. 
Runtime Error가 발생할 코드를 작성하여 errorPage, isErrorPage 속성을 테스트한다.

null 인 상태인데 0번째 인덱스의 문자를 달라는 코드이니 에러가 발생한다.

 

 

 

  • 화면으로 돌아가 pageDirective.jsp 페이지에서 새로고침을 누르면 에러가 발생하여 에러페이지로 넘어간다.
  • 즉 다음과같은 에러 메세지를 확인할 수 있다. 
  • 첫번째줄은 exceptionType이며 두번째줄은 exceptionMessage이다. 

 

 

 

 

 

'Programming > Servlet&JSP' 카테고리의 다른 글

jsp 액션태그  (0) 2023.04.03
JSP 태그 종류와 사용법(2)  (0) 2023.03.30
10. EL & JSTL (2)  (0) 2022.03.08
10. EL & JSTL (1)  (0) 2022.03.08
9. JSP Action Tag  (0) 2022.03.08

 

현상


쿼리를 짠 후 서버를 올렸더니 여러단락의 에러가 떴다. 그 중 주된 에러메세지는 다음과 같다. 

: Error parsing Mapper XML, Parsing error was found in mapping 

Caused by: org.apache.ibatis.builder.BuilderException: Error parsing Mapper XML. The location is...

 

 

 

 

해결방법


차례로 콘솔을 살펴보니 쿼리중 다음과 같은 오타가 눈에 띄었다. 구글링 해보니 주로 괄호를 잘못 사용한 경우에 많이 발생하는 에러임을 알 수 있었다. 콘솔에 뜨지않는다면 다시 쿼리를 꼼꼼히 들여다보는 수 밖에 없다.  

 #{RPSV_NM]

Caused by: org.apache.ibatis.builder.BuilderException: Parsing  error was found in mapping #{RPSV_NM]

 

 

 

 

 

 

 

 

 

 

 

 

 

REST(Representational Safe Transfer)


데이터를 주고 받는 방식의 아키텍처 (디자인 패턴)

 


HTTP URI를 통한 자원의 명시


  • url?category=novel 와 같은 쿼리 스트링 방식이 아니라 url/category/novel 과 같은 방식 사용
  • 대문자 사용 지양
  •  _ 대신 - 사용
  •  URL 마지막에 / 사용하지 않음
  •  행위를 포함하지 않음(insert, update, delete)
  •  가급적 명사 사용(동사 사용 지양)

 

 

HTTP Method(Get, Post, Put, Delete)로 해당 자원을 제어하는 행위를 표현


  • GET - Read(Select) : URL/1
  • POST - Create(Insert) : URL
  • PUT - Update : URL/1
  • DELETE - Delete : URL/1

 

 


Restful 서비스(API)


  • REST 아키텍처를 준수하는 서비스
  • RESTful 서비스에서는 Controller에서 요청 받은 내용을 처리하고 데이터를 가공해서 처리 결과를 "특정 플랫폼"에 적합한 형태의 View로 만들어서 응답하지 않고 데이터만 처리하거나 응답 데이터가 있다면 JSON/XML로 응답한다. (View와는 무관하다)
  • 즉, 클라이언트는 규칙에 맞게 작업을 요청하면 되고 서버는 어떤 플랫폼에서 어떻게 사용할 것인지를 신경쓰지 않고 요청 받은 데이터만 처리하고 응답하면 된다.
  • 클라이언트는 받은 데이터를 알아서 가공해서 사용한다. 즉, 멀티 플랫폼에서 사용 가능하다.
  • 이러한 특성으로, 사용자 플랫폼과 view에 상관하지 않고 요청한 데이터만 응답해주는 오픈 API에서 Restful한 서비스 방식을 많이 사용한다.
  • 어플리케이션의 복잡도 증가로 인해 서비스별 독립적 구축과 운영이 필요해지면서 많이 활용되고 있다.

 

 

 

전체 프로젝트 파일 구조


 

 

 

 

프로젝트 코드


 

 

Chap03RestApiApplication

package com.greedy.rest.config;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class Chap03RestApiApplication {

	public static void main(String[] args) {
		SpringApplication.run(Chap03RestApiApplication.class, args);
	}

}

 

 

 

ContextConfiguration

package com.greedy.rest.config;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

@Configuration
@ComponentScan("com.greedy.rest")
public class ContextConfiguration {

}

 

 

 

MyBatisConfiguration

package com.greedy.rest.config;


import org.apache.ibatis.annotations.Mapper;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Configuration;

@Configuration
@MapperScan(basePackages="com.greedy.rest", annotationClass = Mapper.class)
public class MyBatisConfiguration {

}

 

 

 

 

 

 

 

BookController

package com.greedy.rest.controller;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import com.greedy.rest.model.dto.BookDTO;
import com.greedy.rest.model.service.BookService;

import lombok.extern.slf4j.Slf4j;

@Slf4j
@RestController
/* @Controller + @ResponseBody
 * => 모든 메소드에 @ResponseBody가 적용되므로 메소드별로 명시할 필요가 없음
 * => @RestController의 용도는 JSON/XML 등의 형식으로 데이터를 반환하는 것
 * */
public class BookController {
	
	private BookService bookService;
	
	@Autowired
	public BookController(BookService bookService) {
		this.bookService = bookService;
	}
	
//	@GetMapping("/book/category/{category}")
//	public List<BookDTO> selectBookByCategory(@PathVariable String category){
//		
//		log.debug("조회 요청 category : {}", category);
//		
//		return bookService.selectBookByCategory(category);
//	}
	
	/* ResponseEntity : 개발자가 직접 결과 데이터와 HTTP 상태 코드를 
    제어할 수 있는 클래스로
	 * 결과 데이터가 예외적인 상황에 대해서 세밀한 제어를 할 수 있다.
	 * */
	@GetMapping("/book/category/{category}")
	public ResponseEntity<Map<String, Object>> 
    selectBookByCategory(@PathVariable String category){
		
		log.debug("조회 요청 category : {}", category);
		
		List<BookDTO> bookList = bookService.selectBookByCategory(category);
		
		Map<String, Object> result = new HashMap<>();
		result.put("data", bookList);
		
		if(bookList.isEmpty()) {
			result.put("data", "no data");
			result.put("message", "check your category");
		}
		
		return ResponseEntity.ok(result);
	}
	
	@PostMapping("/book")
	public ResponseEntity<Map<String, String>> insertBook(@RequestBody BookDTO book){
		
		log.debug("입력 요청 book : {}", book);
		
		String message = bookService.insertBook(book)
        		> 0 ? "book registration success" : "book registration failed";
		
		Map<String, String> result = new HashMap<>();
		result.put("message", message);
		
		return ResponseEntity.ok(result);
	}
	
	@PutMapping("/book/{id}")
	public ResponseEntity<Map<String, String>> 
    			updateBook(@PathVariable int id, @RequestBody BookDTO book){
		
		log.debug("수정 요청 id : {}", id);
		log.debug("수정 요청 book : {}", book);
		
		book.setId(id);
		
		String message = bookService.updateBook(book)
        		> 0 ? "book modification success" : "check your book id";
		
		Map<String, String> result = new HashMap<>();
		result.put("message", message);
		
		return ResponseEntity.ok(result);
	}
	
	@DeleteMapping("/book/{id}")
	public ResponseEntity<Map<String, String>> deleteBook(@PathVariable int id) {
		
		log.debug("삭제 요청 id : {}", id);
		
		String message = bookService.deleteBook(id)
        			> 0 ? "book deletion success" : "check your book id";
		
		Map<String, String> result = new HashMap<>();
		result.put("message", message);
		
		return ResponseEntity.ok(result);
	}
	
	/* 도서 아이디 전달 받아 해당 도서 정보 응답하는 기능 구현하기 */
	@GetMapping("/book/{id}")
	public ResponseEntity<Map<String, Object>> selectBookByid(@PathVariable int id) {
		
		log.debug("조회 요청 id : {}", id);
		
		BookDTO book = bookService.selectBookByid(id);
		
		Map<String, Object> result = new HashMap<>();
		result.put("data", book);
		
		if(book == null) {
			result.put("data", "no data");
			result.put("message", "check your book id");
		}
		
		return ResponseEntity.ok(result);
	}
	
	
	
	
	
}

 

 

 

 

interface BookMapper

package com.greedy.rest.model.dao;

import java.util.List;

import org.apache.ibatis.annotations.Mapper;

import com.greedy.rest.model.dto.BookDTO;

@Mapper
public interface BookMapper {

	List<BookDTO> selectBookByCategory(String category);

	int insertBook(BookDTO book);

	int updateBook(BookDTO book);

	int deleteBook(int id);

	BookDTO selectBookByid(int id);

}

 

 

 

BookDTO

package com.greedy.rest.model.dto;

import lombok.Data;

@Data
public class BookDTO {
	
	private int id;
	private String title;
	private String author;
	private String publisher;
	private String category;
	
}

 

 

interface BookService

package com.greedy.rest.model.service;

import java.util.List;

import com.greedy.rest.model.dto.BookDTO;

public interface BookService {

	List<BookDTO> selectBookByCategory(String category);

	int insertBook(BookDTO book);

	int updateBook(BookDTO book);

	int deleteBook(int id);

	BookDTO selectBookByid(int id);
	
	

}

 

 

 

BookServiceImpl implements BookService

package com.greedy.rest.model.service;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.greedy.rest.model.dao.BookMapper;
import com.greedy.rest.model.dto.BookDTO;

@Service
@Transactional
public class BookServiceImpl implements BookService {
	
	private BookMapper bookMapper;
	
	@Autowired
	public BookServiceImpl(BookMapper bookMapper) {
		this.bookMapper = bookMapper;
	}

	@Override
	public List<BookDTO> selectBookByCategory(String category) {
		return bookMapper.selectBookByCategory(category);
	}

	@Override
	public int insertBook(BookDTO book) {
		return bookMapper.insertBook(book);
	}

	@Override
	public int updateBook(BookDTO book) {
		return bookMapper.updateBook(book);
	}

	@Override
	public int deleteBook(int id) {
		return bookMapper.deleteBook(id);
	}

	@Override
	public BookDTO selectBookByid(int id) {
		return bookMapper.selectBookByid(id);
	}

}

 

 

 

 

 

 

BookMapper.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.greedy.rest.model.dao.BookMapper">
	
	<resultMap id="bookResultMap" type="com.greedy.rest.model.dto.BookDTO">
		<id property="id" column="BOOK_ID"/>
		<result property="title" column="BOOK_TITLE"/>
		<result property="author" column="BOOK_AUTHOR"/>
		<result property="publisher" column="BOOK_PUBLISHER"/>
		<result property="category" column="BOOK_CATEGORY"/>
	</resultMap>
	
	<select id="selectBookByCategory" resultMap="bookResultMap">
		SELECT
		       BOOK_ID
		     , BOOK_TITLE
		     , BOOK_AUTHOR
		     , BOOK_PUBLISHER
		     , BOOK_CATEGORY
		  FROM TBL_BOOK
		 WHERE BOOK_CATEGORY = #{ category }
	</select>
	
	<insert id="insertBook">
		INSERT
		  INTO TBL_BOOK
		(
		  BOOK_ID
		, BOOK_TITLE
		, BOOK_AUTHOR
		, BOOK_PUBLISHER
		, BOOK_CATEGORY
		)
		VALUES
		(
		  SEQ_BOOK_ID.NEXTVAL
		, #{ title }
		, #{ author }
		, #{ publisher }
		, #{ category }
		)
	</insert>
	
	<update id="updateBook">
		UPDATE
	           TBL_BOOK
	       SET BOOK_TITLE = #{ title }
	       	 , BOOK_AUTHOR = #{ author }
	       	 , BOOK_PUBLISHER = #{ publisher }
	       	 , BOOK_CATEGORY = #{ category }
	     WHERE BOOK_ID = #{ id }
	</update>
	
	<delete id="deleteBook">
		DELETE
		  FROM TBL_BOOK
		 WHERE BOOK_ID = #{ id }
	</delete>
	
	<select id="selectBookByid" resultMap="bookResultMap">
		SELECT
		       BOOK_ID
		     , BOOK_TITLE
		     , BOOK_AUTHOR
		     , BOOK_PUBLISHER
		     , BOOK_CATEGORY
		  FROM TBL_BOOK
		 WHERE BOOK_ID = #{id}	
	</select>
	
	
	
	


</mapper>

 

 

 

index.html

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>rest api</title>
</head>
<body>
	<h1>REST API</h1>

</body>
</html>

 

 

 

application.yml

# server port config
server:
  port: 8001
  
# datasource config
spring:
  datasource:
    driver-class-name: oracle.jdbc.driver.OracleDriver
    url : jdbc:oracle:thin:@localhost:1521:xe
    username :
    password :
    
# mybatis config
mybatis:
  mapper-locations: mappers/**/*.xml

# logging level
logging:
  level:
    '[com.greedy.rest]': debug

 

 

 

 

 

 

 

 

 

 

 

'Programming > Spring Framework' 카테고리의 다른 글

Spring-Boot-Crud (2) : Thymeleaf  (0) 2022.05.09
Spring-Boot-Crud (1)  (0) 2022.05.09
Spring Security (2)  (0) 2022.04.25
Spring Security (1)  (0) 2022.04.25
Spring Boot 초기 설정  (0) 2022.04.20

 

 

 

 

Thymeleaf


타임리프는 스프링 부트에서 공식적으로 지원하는 뷰 템플릿으로 JSP와 달리 html 확장자를 가지고 있어 JSP처럼 Servlet이 문서를 표현하는 방식이 아니므로 서버 없이 동작 가능하다.

 

 

 

템플릿 엔진(Template Engine)


데이터와 이 데이터를 표현할 템플릿을 결합해주는 도구로 스프링 부트가 지원하는 템플릿 엔진은 Thymeleaf, Freemarker, Mustache, Groovy가 있다.

 

 


타임리프의 문법 적용


스프링 부트의 templates 폴더 하위html 확장자를 쓰고 xmlns:th 네임스페이스를 추가하고 타임리프 문법을 사용할 수 있다.

 

 


타임리프의 장점


  • natural templates를 제공 : HTML의 기본 구조를 그대로 사용하며 HTML 파일을 직접 열어도 동작한다.
  • 개발 시 디자인과 개발이 분리 되어 작업 효율이 좋다.
  • WAS를 통하지 않고 파일을 웹 브라우저를 통해 열 수 있어서 퍼블리셔와 협업이 용이하다.

 

 


타임리프의 단점


  •  jsp 태그 라이브러리와 custom 태그 들을 사용할 수 없어 기존 JSP 코드를 재사용할 수 없다.
  • 기존 태그를 유지하며 속성으로 템플릿 구문을 넣는데 있어 어느 정도 한계가 있고 자바스크립트의 도움이 필요할 수 있다.

 

 

 

 

 

 

프로젝트 전체 파일구조


 

 

 

 

 

 

 

프로젝트 코드 


 

 

 

 

 

Chap02ThymeleafApplication

package com.greedy.thymeleaf.config;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class Chap02ThymeleafApplication {

	public static void main(String[] args) {
		SpringApplication.run(Chap02ThymeleafApplication.class, args);
	}

}

 

 

ContextConfiguration

package com.greedy.thymeleaf.config;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

@Configuration
@ComponentScan(basePackages = "com.greedy.thymeleaf")
public class ContextConfiguration {

}

 

 

ModelAndView expression(ModelAndView mv)

package com.greedy.thymeleaf.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

import com.greedy.thymeleaf.model.dto.MemberDTO;

@Controller
@RequestMapping("/lecture")
public class LectureController {

	@GetMapping("expression")
	public ModelAndView expression(ModelAndView mv) {
		
		mv.addObject("member", new MemberDTO("유관순", 16, '여', "서울시 서대문구"));
		
		mv.setViewName("/lecture/expression");
		
		return mv;
	}
	
	
}

 

 

MemberDTO

package com.greedy.thymeleaf.model.dto;

import lombok.AllArgsConstructor;
import lombok.Data;

@Data
@AllArgsConstructor
public class MemberDTO {
	
	private String name;
	private int age;
	private char gender;
	private String address;

}

 

 

 

 

 

index.html

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>index</title>
</head>
<body>
<h1 align="center">Thymeleaf</h1>

<button onclick="location.href='/lecture/expression?title=표현식&no=5&no=6'">
   표현식</button>
	
	
	
	
</body>
</html>

 

 

 

expression.html

<!DOCTYPE html>

<!-- 
xmlns:th
: 타임리프의 th 속성을 사용하기 위한 네임스페이스로 html 태그의 속성으로 작성한다.
 -->
 
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	
	<h1 align="center">표현식</h1>
    
	<h2>주석</h2>
	<!-- 
		주석의 종류
		parser-level 주석
		: 정적 페이지에서 주석으로 있다가 thymeleaf가 처리 될 때 제거되어
        클라이언트에게 노출되지 않는 주석
		
		prototype-only 주석
		: 정적 페이지에 주석으로 있다가 thymeleaf 처리 후에 
        화면에 보여지게 되는 주석
	 -->
     
	 <ul>
	 	<li>parser-level 주석</li>
	 	<!--/* 주석내용 */-->
	 	<li>prototype-only 주석</li>
	 	<!--/*/ 주석내용 /*/-->
	 </ul>
	 
	 <h2>표현식1 - 변수 표현식 ${...}</h2>
	 <p th:text="${ param.title }"></p>
	 <p th:text="${ param.no[0] }"></p>
	 <p th:text="${ param.no[1] }"></p>
     
<!-- <p th:text="${ param.no[2] }"></p>

 		parameter로 넘어온 경우는 param, session attribute일 경우는 session,
 		model에 담겨 온 경우는 따로 적지 않음(request라고 적으면 에러)
 		파라미터가 존재하지 않으면 무시하지 않고 에러 발생함
 -->	 
	 
     
     
	 <h2>표현식2 - 메세지 표현식 #{...}</h2>
	 <!-- resources 폴더 하위에 messages.properties 
     라는 외부 리소스를 읽어온다. -->
	 <p th:text="#{ message.first }"></p>
	 <p th:text="#{ message.second(everyone) }"></p>
	
	<h3>표현식3 - 링크 표현식 @{...}</h3>
	<a th:href="@{/}">메인으로</a>
	<a th:href="@{/(name=${member.name},age=${member.age})}">Test1</a>
	<a th:href="@{/{name}/{age}(name=${member.name},age=${member.age})}">Test2</a>
	<a th:href="@{/{name}(name=${member.name},age=${member.age})}">Test3</a>
	
	
	
	
</body>
</html>

 

 

application.yml

server:
  port: 8001

 

 

messages.properties

message.first=hello world
message.second=hello {0}

 

 

 

 


 

 

 

 

 

 

Chap02ThymeleafApplicationTests

package com.greedy.thymeleaf;

import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
class Chap02ThymeleafApplicationTests {

	@Test
	void contextLoads() {
	}

}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

'Programming > Spring Framework' 카테고리의 다른 글

Spring-Boot-Crud (3) : REST API  (0) 2022.05.09
Spring-Boot-Crud (1)  (0) 2022.05.09
Spring Security (2)  (0) 2022.04.25
Spring Security (1)  (0) 2022.04.25
Spring Boot 초기 설정  (0) 2022.04.20

 

 

 

 

 

 

 

Spring-Boot-Crud (1)


CRUD를 테스트 해 볼 프로젝트를 만든다. 파일 구조는 다음과 같다. 

 

 

 

 

 

 

Chap01BootCrudApplication


  • 프로그램 시작, 시동이 되는 파일로 생각한다.
  • @SpringBootApplication 은 통합적 처리가 가능한 어노테이션이다. 
package com.greedy.crud.config;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class Chap01BootCrudApplication {

	public static void main(String[] args) {
		SpringApplication.run(Chap01BootCrudApplication.class, args);
	}

}

 

 

ContextConfiguration 

package com.greedy.crud.config;

public class ContextConfiguration {

}

 

 

 

MybatisConfig


  • 설정 파일을 넣을 config 패키지 하위에 작성하도록 한다. 
  • Chap01BootCrudApplication은 기본 시작되는 클래스이므로 이곳에 직접 작성하는 것보다 MybatisConfig 클래스를 따로 작성하여 필요한 설정 파일등을 추가하는 것이 좋다. 
  • MapperScan에 있어서 "com.greedy.crud"까지만 작성하게 될 경우 crud 하위의 모든 인터페이스를 대상으로 매퍼로 간주되고 구현체를 생성해달라는 의미가 된다. 매퍼가 아닌 인터페이스는 따로 건들지 않도록 세부 작성이 필요하다. 
  • 모든 인터페이스를 모두 매퍼로 설정할 것은 아니기 때문이다.  
package com.greedy.crud.config;

import org.apache.ibatis.annotations.Mapper;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Configuration;

@Configuration
@MapperScan(basePackages
= "com.greedy.crud", annotationClass = Mapper.class)
public class MybatisConfig {

}

 

 

 

MenuController 

package com.greedy.crud.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

import com.greedy.crud.model.service.MenuService;

@Controller
@RequestMapping("/menu")
public class MenuController {

	
	private MenuService menuService;
	
	@Autowired
	public MenuController(MenuService menuservice) {
		this.menuService = menuService;
	}

	
	
}

 

 

 

interface MenuMapper


  • @Mapper는 인터페이스를 위한 mark이다. 
  • dao에 해당하는 것을 직접 만들지 않아도 된다. 마이바티스 스프링에서 매퍼 스캔기능 이용시 인터페이스만 만들어 놓고 mapper.xml을 만들었을때, 중간에 자동으로 호출해주는 구현체는 프록시를 이용해 자동생성 될 것이다. 
  • 그러므로 이와같이 @Mapper 를 통해 crud하위의 매퍼를 스캔 해 프록시로 MenuMapperImpl.java 를 생성하는 작업까지는 된 것이다. 
  • 여기서 추가로 -Impl이 호출할 대상이 어떤 경로에 있는지 매퍼를 등록하는 설정이 필요하다. 이를 application.yml에 작성하도록 한다. 
package com.greedy.crud.model.dao;

import org.apache.ibatis.annotations.Mapper;

@Mapper
public interface MenuMapper {

}

 

 

 

 

Lombok


  • DTO/VP 클래스의 constructor, getter/setter, toString 등을 어노테이션을 통해 자동 작성해 줄 수 있는 기능을 가진다. 
  • 필드 수정 후 해당 코드에 대한 수정작업이 필요 없다는 장점이 있다.
  • 편리하지만 구조와 무관한게 남용될 수 있어 프로젝트에 따라 사용하지않는 경우도 있음에 유의한다.
  • 팀 프로젝트에서 활용 시 모든 팀원이 해당 라이브러리를 설치한 환경에서 사용해야 한다. 

 

 

Lombok 설치 방법 :


  1. 의존성 추가 후 라이브러리 설치
  2. 해당 jar 파일이 위치한 폴더에서 cmd 창으로 -java lombok-버전.jar 실행
  3. sts.exe 선택해서 install / update 후 sts 재부팅

 

 

 

MenuDTO


  • @Data는 위 주석처리된 모든 어노테이션을 한번에 생성할 수 있다. 
  • 단, @AllArgsConstructor는 제외이다. 
  • 편리하기는 하지만 최소한의 필요한 것들만 추가하는 방향으로 롬복을 사용하는 것이 바람직하다.
  • @Data를 만능키로 사용하지 않도록 한다.
package com.greedy.crud.model.dto;

import lombok.Data;
import lombok.NoArgsConstructor;


//@NoArgsConstructor
//@AllArgsConstructor
//@Getter
//@Setter
//@ToString
//@EqualsAndHashCode
@Data //매개변수 생성자를 제외하고 위의 내용을 한번에 처리할 수 있는 어노테이션
public class MenuDTO {

	
	private int code;
	private String name;
	private int place;
	private int categoryCode;
	private String orderableStatus;
	
	
	
}

 

 

 

MenuService

package com.greedy.crud.model.service;

public class MenuService {

}

 

 

 

MenuServiceImpl


원칙대로라면 인터페이스를 구현해야하지만 확인이 목적이므로 편의를 위해 빈 클래스를 만들어준다. 

 

package com.greedy.crud.model.service;

public class MenuServiceImpl {

}

 

 

 

 

 

 

 

 

MenuMapper.xml


  • dtd를 작성하기위해 다음과같은 경로를 참고할 수 있다.
  • 이클립스 메뉴의 help - marcket place - mybatis 검색 후 - mybatis 1.25 설치
  • mapper는 dtd를 필요로 하고 위 방법으로 좀 더 손쉽게 작성할 수 있다. 
  • namespace에는 인터페이스 지정이 필요하다.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.greedy.crud.model.dao.MenuMapper"></mapper>

 

 

 

list.html

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>

</body>
</html>

 

 

regist.html

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>

</body>
</html>

 

 

 

application.yml


  • 매퍼 설정을 통해 MenuMapper.java 와 MenuMapper.xml 두가지가 인식되어 연결될 수 있다. 
  • /**/ : 하위에 경로가 얼마든지 있어도 상관없음을 나타냄 
  • /*.xml : *은 파일에 대한 패턴을 의미하며, 여기에서 패턴은 .xml에 해당한다. 
#server port config

server:
  port: 8001
  
 #oracle driver config
spring:
  datasource:
    url: jdbc:oracle:thin:@localhost:1521:xe
    driver-class-name: oracle.jdbc.driver.OracleDriver
    username:
    password: 
    
    
 # mybatis config
mybatis:
  mapper-locations: mappers/**/*.xml

 

 

 

 

 

 

 

 

 

'Programming > Spring Framework' 카테고리의 다른 글

Spring-Boot-Crud (3) : REST API  (0) 2022.05.09
Spring-Boot-Crud (2) : Thymeleaf  (0) 2022.05.09
Spring Security (2)  (0) 2022.04.25
Spring Security (1)  (0) 2022.04.25
Spring Boot 초기 설정  (0) 2022.04.20

 

 

DockerFile 다루기

 

 

 

 

Dockerfile

 

도커 이미지를 생성할 수 있는 설정 파일
사용자가 이미지를 조합하기 위해 명령 줄에서 호출할 수 있는 모든
명령을 포함하는 텍스트 문서
완성된 이미지를 생성하기 위해 필요한 컨테이너, 패키지, 소스코드,
명령어 등을 하나의 파일에 기록
도커에서 이 파일을 읽어 자동으로 작업을 수행한 뒤 완성된 이미지
로 만들어 줌
깃과 같은 개발도구를 통해 애플리케이션의 빌드 및 배포를 자동화
할 수 있음

 

 

 

도커
이미지
생성
방법
1

 

기존 이미지로 컨테이너 생성 후 작업 완료된 컨테이너를 다시 이미
지로 생성

 

 

 

도커
이미지
생성
방법
2

 

Dockerfile로 필요한 패키지, 소스코드, 명령어 등을 작성 후 빌드

 

 

 

 

 

 

Tomcat 공식 이미지 Dockerfile 확인
Docker hub tomcat 이미지 검색 시 태그별 Dockerfile을 볼수있는
경로를 제공해 줌

 

 

 

 

 

 

 

 

 

Dockerfile
작성

 

 

컨테이너에서 수행해야 할 작업을 명시
정해진 형식과 명령어로 작성해야 함
문서 파일로 작성
한 줄에 하나의 명령어로 구성
명령어를 명시하고 뒤에 옵션을 추가
명령어는 대/소문자 상관없음(일반적으로 대문자로 표기)
위에서 아래로 한 줄씩 차례대로 실행됨
주석은 # 기호를 사용

 

 

 

 

 

 

Dockerfile
명령어

 

 

 

 

 

 

 

Dockerfile
작성
예제
① D:\DockerWeb 디렉터리 생성
② ROOT.war 파일 DockerWeb 디렉터리에 저장
③ Dockerfile 작성 후 저장

 

 

 

 

 

 

 

 

 

 

[Dockerfile]

# 베이스 이미지를 tomcat:8.5.72-jdk8로 지정
FROM tomcat:8.5.72-jdk8
# 작성자 라벨 생성
LABEL maintainer "kh<kh@iei.com>“
# 버전 라벨 생성
LABEL version="1.0“
# /usr/local/tomcat/webapps 디렉터리에 ROOT.war 파일
추가
ADD ROOT.war /usr/local/tomcat/webapps
# Timezone 환경변수를 Asia/Seoul로 변경
ENV TZ=Asia/Seoul
# 이미지에서 8080포트 사용
EXPOSE 8080
# 컨테이너 실행 시 catalina.sh 파일 자동 실행
CMD ["catalina.sh","run"]

 

 

 

 

Dockerfile
빌드
작성한 Dockerfile을 이용해 이미지를 생성하는 과정
docker build [옵션] <Dockerfile이 존재하는 디렉터리 경로>

 

 

 

 

 

 

 

 

 

 

 

DockerFile
다루기

 

Dockerfile 빌드

> docker build –t mytomcat:1.0 d:\DockerWeb

 

 

 

 

 

 

 

 

생성된
이미지
상세
정보
보기

 

> docker inspect mytomcat:1.0

 

 

 

 

 

 

 

 

생성된
이미지로
컨테이너
실행

 

docker run -d --name myweb2 -p 81:8080 --link mydb:db mytomcat:1.0

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

'Programming > DOCKER' 카테고리의 다른 글

도커컨테이너관리하기  (0) 2022.05.03
도커 이미지 관리하기  (0) 2022.05.03
도커의 구조와 특징  (0) 2022.05.02
도커 (docker) 설치하기  (0) 2022.05.02
docker를 사용하는 이유  (0) 2022.05.02

 

 

 

 

 

도커컨테이너관리하기

 

 

도커
컨테이너

 

도커 이미지의 실행 가능한 인스턴스
개별 애플리케이션의 실행에 필요한 실행환경을 독립적으로 운용

 

 

 

 

 

앞서 지웠기 때문에 톰캣 설치부터 시작됨 

docker run -d --name myweb -p 80:8080 tomcat:8.5.72-jdk8

 

 

 

 

 

 

 

 

 

 

 

내가 가진 컨테이너 목록

docker ps -a

 

 

 

아이디로 컨테이너 조회 

docker inspect 93eac9619c8f

 

 

 

 

 

 

 

 

 

 

 

 

 

docker stop myweb

 

 

 

 

docker start myweb

 

docker restart myweb

 

 

 

 

상태 확인

 

docker stats my web

 

무한 로딩이 될 것인데 

ctrl + c 눌러서 빠져나옴 

 

 

테스트를 위해 D:test.txt를 만들

 

파일 카피 하기

docker cp d:\test.txt myweb:/root

 

 

 

컨테이너 내부 프로세스에 접근할 수 있는 명령어 exec

 

 

ls /root

를 추가로 입력하면 내부에 존재하는 파일을 볼 수 있다. 

 

test.txt 확인 가능

 

 

빠져나오기 

exit

 

 

 

 

컨테이너 삭제 

docker rm -f myweb

 

myweb 컨테이너가 사라진 모습 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

'Programming > DOCKER' 카테고리의 다른 글

DockerFile 다루기  (0) 2022.05.03
도커 이미지 관리하기  (0) 2022.05.03
도커의 구조와 특징  (0) 2022.05.02
도커 (docker) 설치하기  (0) 2022.05.02
docker를 사용하는 이유  (0) 2022.05.02

도커 이미지 관리하기

 

 

 

도커 이미지

 

컨테이너를 만들고 실행하기 위한 읽기 전용 파일(템플릿)
모든 컨테이너는 이미지 기반으로 생성됨
컨테이너 실행에 필요한 파일과 설정 값 등을 포함하고 있음

 

파일설정값을 읽기전용으로 만들어놓은것이고 

 

 

도커 이미지와 컨테이너

 

컨테이너는 필요한 파일과 설정을 이미지에서 읽기전용으로 가져다
사용하고, 변경된 사항만 컨테이너 계층에 별도 저장
하나의 이미지로 여러 컨테이너에서 사용 가능

 

 

 

 

 

도커허브 (Docker Hub)

도커에서 공식적으로 제공하고 있는 중앙 이미지 저장소
도커 계정을 가지고 있으면 누구든 이미지 업로드/다운로드가 가능
기본적인 리눅스 운영체제부터 웹서버, 데이터베이스, 각종 애플리
케이션 등의 다양한 종류의 이미지를 도커 레지스트리에서 내려 받
아 컨테이너로 생성

 

이미지를 풀받아 컨테이너로 만들어줄것을 요ㅕ청하면 

푸시하여 업로드하는 것도 가능

 

 

 

 

 

 

 

 

도커이미지이름

 

[저장소이름/]이미지이름[:태그]
-저장소 이름 생략 시 도커 허브 공식 이미지로 인식
-태그는 버전을 나타냄
-태그 생략 시 최신 버전(latest)으로 인식

 

 

 

 

이미지검색방법1

 

도커 허브 공식 홈페이지에서 검색
https://hub.docker.com/

 

 

 

 

 

 

 

 

이미지검색방법2

 

도커 엔진에서 명령어로 검색
docker search <키워드>

 

 

- NAME : [저장소이름/]이미지이름
- DESCRIPTION : 설명
- STARS : 도커 사용자로부터 즐겨찾기 된 수
- OFFICIAL : 공식 이미지
- AUTOMATED : 자동화 빌드 설정 여부

 

 

 

이미지 다운로드

 

 

다운받은
이미지
목록
조회

 

 

 

이미지세부정보 조회

image id 는 목록 중 유일하게 구분될 수 있게만 작성하면 됨

 

 

도커
이미지
추출

 

도커 이미지를 별도의 파일로 저장할 때 사용

 

 

 

 

도커
이미지
추출

 

추출된 파일을 다시 도커 내 이미지로 로드

 

 

도커
이미지
이름
추가

 

기존 이미지를 새로운 이름으로 추가

 

 

 

 

도커
이미지
삭제

 

 

 

 

 

 

 

 

 

 

 

docker pull tomcat:8.5 입력시 다운로드 시작 

 

다운로드 완료

 

 

 

내가 가진 이미지 목록 검색 

docker images

 

 

 

해당 이미지 검색

docker image inspect feecc4e7d7e2

 

 

 

 

이미지가 겹치지않는다면 앞의 세네자리만 쳐도 해당 이미지를 잘 찾아온다. 

현재 이미지가 한개밖에없으므로 fee 정도만 쳐도 이미지를 잘 찾아오는 모습이다. 

 

 

 

다른 환경에서 사용하기위해 백업용, 물리적으로 옮기기위해서는 이 이미지를 별도의 파일로 만들어놓고 저장을 할 수 도 있다. 

 

도커 이미지 추출

 

 

docker save -o d:\\tomcat_image tomcat:8.5

 

 

 

 

 

 

 

 

백업용파일로 만들기위해 로드하기 

 

docker load -i d:\\tomcat_image

 

 

 

 

별도의 이름이나 태그걸기 

 

docker tag tomcat:8.5 mytom:1

 

 

 

 

 

존재하는 이미지 삭제하기 

 

tomcat 8.5를 태그한 삭제기에 태그가 지워짐 

docker rmi mytom:1

mytom이 지워진 모습이다. 

 

 

 

 

 

톰캣 8.5도 삭제 해보자 

docker rmi tomcat:8.5

 

잘 delete 된 모습을 확인할 수 있다. 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

'Programming > DOCKER' 카테고리의 다른 글

DockerFile 다루기  (0) 2022.05.03
도커컨테이너관리하기  (0) 2022.05.03
도커의 구조와 특징  (0) 2022.05.02
도커 (docker) 설치하기  (0) 2022.05.02
docker를 사용하는 이유  (0) 2022.05.02

 

 

 

도커의 구조와 특징

 

 

 

 

 

 

 

도커(Docker)란 ?


  • 애플리케이션을 개발/배포/실행하기 위한 플랫폼
  • 컨테이너를 사용하여 애플리케이션 및 지원 구성 요소를 개발
  • 리눅스 자체 기능을 사용하여 프로세스 단위의 격리 환경을 제공
  • 배포 용량과 시간을 단축하고, 성능 손실을 최소화 시킴

 

 

 

 

 

도커 구조


출처 : https://docs.docker.com/get-started/overview/

 

 

 

 

 

 

도커 엔진과 도커 데몬 (dockerd)


  • 도커엔진: 외부에서 Docker API 요청을 받아 Docker 객체와 서비스들을 관리컨테이너를 생성하고 관리하는 주체
  • 도커 데몬 : 도커 프로세스가 실행되어 입력 받을 준비가 된 상태

 

 

 

 

 

 

도커 클라이언트 (docker)


  • 입력된 명령어를 Docker API 형태로 도커 데몬에게 전달
  • 도커 엔진의 수행 결과를 반환 받아 사용자에게 출력

 

 

 

 

 

 

도커 레지스트리 (Registry)


  • 도커에서 사용되는 이미지들을 저장하고 공유해주는 원격 저장소
  • 공개 레지스트리(Docker Hub)와 사설 레지스트리 사용 가능

 

 

 

 

 

이식성


  • 한 번 만들어두면 어디에서든 동작하는 소프트웨어의 특성

 

 

 

 

 

 

상호 운용성


  • 여러 조직이나 시스템과 연계하여 사용할 수 있는 소프트웨어의 특성

 

 

 

 

 

 

 

'Programming > DOCKER' 카테고리의 다른 글

도커컨테이너관리하기  (0) 2022.05.03
도커 이미지 관리하기  (0) 2022.05.03
도커 (docker) 설치하기  (0) 2022.05.02
docker를 사용하는 이유  (0) 2022.05.02
STS에서 Maven build하기  (0) 2022.05.02

 

 

 

 

 

도커 설치


  • 다양한 운영체제에서 사용 가능(리눅스, 윈도우, 맥 OS X)
  • 설치 및 설정 방법은 운영체제에 따라 조금씩 다르지만, 설치된 이후 사용방법은 동일
  • 공식 홈페이지 :  https://www.docker.com/  
  • 가이드 홈페이지 :  https://docs.docker.com/   

 

 

 

 

 

 

 

 

 

 

 

Docker Desktop for Windows 설치


 

① 도커 공식 홈페이지 접속 (https://www.docker.com)

② 상단 메뉴 중 Developers 클릭

 

 

 

 

 

 

③ Download for Windows 클릭
④ 다운받은 설치 파일 실행

 

 

 

 

 

⑤ WSL2 설치 체크 후 OK
⑥ Unpacking 완료 후 윈도우 재부팅

  •  재부팅 후 잠시 기다리면 서비스 계약 변경 동의 창 팝업 됨
※ WSL2(Windows Subsystem for Linux 2) :
윈도우에서 경량 가상화 기술을 사용해 리눅스를 구동할 수 있 도록 도와주는 기능

 

 

 

 

 

 

 

 

 

 


⑦ I accept the terms 체크 후 Accept 버튼 클릭
⑧ WSL2 오류 팝업 창에서 계속 버튼 클릭

 

 

 

 

 

 

 

⑨ WSL2 설치 팝업 창에서 링크 클릭
⑩ Linux 커널 업데이트 패키지 다운로드 후 Next로 설치
⑪ WSL2 설치 팝업 창에서 Restart

 

순서에 유의하며 번호대로 설치한다. 

 

 

 

 

 

 

 

 

⑫ Docker 첫 실행 화면에서 Skip tutorial 클릭
⑬ 윈도우 명령 프롬프트(cmd) 에서 도커 버전 확인

 

 

 

 

 

 

 

 

 

  • 다음과 같이 도커 버전이 출력되면 정상 설치가 완료 된 것이다. 
  • cmd를 실행시켜 다음과같이 입력 
docker -v

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Docker Desktop for Windows 설치 오류


만일 다음과 같은 오류가 발생한다면 Windows 기능 켜기/끄기의 Hyper-V 기능을 찾아 체크한다.
만약 체크가 이미 되어 있으면 해당 기능을 삭제 및 재 설치한다.

 

 

 

 

 

 

 

 

 

 

 

 

 

  • cmd창에 다음과같이 입력하면 버전, 단축어나 도커에 대한 설명을 확인할 수 있다. 
docker -help

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

'Programming > DOCKER' 카테고리의 다른 글

도커컨테이너관리하기  (0) 2022.05.03
도커 이미지 관리하기  (0) 2022.05.03
도커의 구조와 특징  (0) 2022.05.02
docker를 사용하는 이유  (0) 2022.05.02
STS에서 Maven build하기  (0) 2022.05.02

+ Recent posts