From 15088ebb4e95b7c4c37ebb4cabbe83d8f772bae1 Mon Sep 17 00:00:00 2001 From: pci2676 Date: Tue, 26 Mar 2019 01:28:20 +0900 Subject: [PATCH 1/3] =?UTF-8?q?1=EC=A3=BC=EC=B0=A8=20=EC=8A=A4=ED=84=B0?= =?UTF-8?q?=EB=94=94=20=EB=82=B4=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. 환경설정 2. 기본적인 Spring RestFul 구조 학습 3. 스프링 빈 기초 학습 4. 어노테이션 학습 --- build.gradle | 6 ++- .../SpringbootstudyApplication.java | 6 +-- .../controller/TestController.java | 51 +++++++++++++++++++ .../controller/UserController.java | 49 ++++++++++++++++++ .../springbootstudy/dto/UserReqDto.java | 9 ++++ .../springbootstudy/dto/UserResDto.java | 13 +++++ .../springbootstudy/service/UserService.java | 15 ++++++ .../SpringbootstudyApplicationTests.java | 6 +-- 8 files changed, 147 insertions(+), 8 deletions(-) create mode 100644 src/main/java/org/dailystudio/springbootstudy/controller/TestController.java create mode 100644 src/main/java/org/dailystudio/springbootstudy/controller/UserController.java create mode 100644 src/main/java/org/dailystudio/springbootstudy/dto/UserReqDto.java create mode 100644 src/main/java/org/dailystudio/springbootstudy/dto/UserResDto.java create mode 100644 src/main/java/org/dailystudio/springbootstudy/service/UserService.java diff --git a/build.gradle b/build.gradle index 3f2652e..dc1bc18 100644 --- a/build.gradle +++ b/build.gradle @@ -3,6 +3,8 @@ plugins { id 'java' } +apply plugin: 'java' +apply plugin: 'org.springframework.boot' apply plugin: 'io.spring.dependency-management' group = 'org.dailystudio' @@ -21,7 +23,7 @@ repositories { dependencies { implementation 'org.springframework.boot:spring-boot-starter-web' - compileOnly 'org.projectlombok:lombok' - annotationProcessor 'org.projectlombok:lombok' + compileOnly 'org.projectlombok:lombok:+' + annotationProcessor 'org.projectlombok:lombok:+' testImplementation 'org.springframework.boot:spring-boot-starter-test' } diff --git a/src/main/java/org/dailystudio/springbootstudy/SpringbootstudyApplication.java b/src/main/java/org/dailystudio/springbootstudy/SpringbootstudyApplication.java index 574a96e..44a039e 100644 --- a/src/main/java/org/dailystudio/springbootstudy/SpringbootstudyApplication.java +++ b/src/main/java/org/dailystudio/springbootstudy/SpringbootstudyApplication.java @@ -6,8 +6,8 @@ @SpringBootApplication public class SpringbootstudyApplication { - public static void main(String[] args) { - SpringApplication.run(SpringbootstudyApplication.class, args); - } + public static void main(String[] args) { + SpringApplication.run(SpringbootstudyApplication.class, args); + } } diff --git a/src/main/java/org/dailystudio/springbootstudy/controller/TestController.java b/src/main/java/org/dailystudio/springbootstudy/controller/TestController.java new file mode 100644 index 0000000..e88c41d --- /dev/null +++ b/src/main/java/org/dailystudio/springbootstudy/controller/TestController.java @@ -0,0 +1,51 @@ +package org.dailystudio.springbootstudy.controller; + +import org.dailystudio.springbootstudy.dto.UserReqDto; +import org.springframework.web.bind.annotation.*; + +@RestController +@RequestMapping("api/test") +public class TestController { + + @GetMapping + public String test() { + String str = "hello world"; + return str; + } + + @GetMapping("/get") + public String me() { + return "me"; + } + + @GetMapping("/path/{parameter}") + public String parameter(@PathVariable("parameter") String output) { + return output; + } + + @PostMapping("/post") + public String postTest0() { + return "post"; + } + + @PostMapping("/post/{name}") + public String postTest1(@PathVariable("name") String output) { + return output; + } + + @PostMapping("/post/instance/user") + public String postTest2(@RequestBody UserReqDto user) { + String output = user.getName() + user.getNumber(); + return output; + } + + @DeleteMapping("/delete") + public String deleteTest() { + return "delete"; + } + + @PutMapping + public String putTest() { + return "put"; + } +} diff --git a/src/main/java/org/dailystudio/springbootstudy/controller/UserController.java b/src/main/java/org/dailystudio/springbootstudy/controller/UserController.java new file mode 100644 index 0000000..59069b7 --- /dev/null +++ b/src/main/java/org/dailystudio/springbootstudy/controller/UserController.java @@ -0,0 +1,49 @@ +package org.dailystudio.springbootstudy.controller; + +import lombok.RequiredArgsConstructor; +import org.dailystudio.springbootstudy.dto.UserReqDto; +import org.dailystudio.springbootstudy.dto.UserResDto; +import org.dailystudio.springbootstudy.service.UserService; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/* +RestFul한 API란 무엇인가? +하나의 URI는 반드시 그에 상응하는 데이터를 나타내는 구조이다. + +예를 들어 +/api/user/1/name 로 접근하는 경우 +'1번' '유저'의 '이름' 대한 데이터를 나타낸다. + +@RestController = @Controller + @ResponseBody 이다. +기존에 @Controller를 사용했을 때는 뷰를 반환하였지만 +@RestController를 사용하면 데이터만 반환하게 된다. +이러한 데이터는 JSON형태로 반환된다. + +우리는 RestFul API를 구현할 때 반환값으로 ResponseEntity를 이용할 것이다. +ResponseEntity를 이용하게 되면 +서버에서 직접 + +1. 상태코드 --> OK(200), NOT_FOUND(404)... +2. HttpHeader --> Content-type : JSON(application/json)... +3. 응답 메세지 --> 요청에 대한 응답 값 + +를 지정해서 클라이언트에게 보내줄 수 있다. + */ +@RestController +@RequestMapping("api/user") +@RequiredArgsConstructor +public class UserController { + + private final UserService userService; + + @PostMapping + public ResponseEntity getUserName(@RequestBody UserReqDto userReqDto) { + //UserReqDto userReqDto = userService.getUserInfo(userReqDto); + //return ResponseEntity.ok().body(userReqDto); + return ResponseEntity.ok().body(userService.getUserInfo(userReqDto)); + } +} diff --git a/src/main/java/org/dailystudio/springbootstudy/dto/UserReqDto.java b/src/main/java/org/dailystudio/springbootstudy/dto/UserReqDto.java new file mode 100644 index 0000000..1423821 --- /dev/null +++ b/src/main/java/org/dailystudio/springbootstudy/dto/UserReqDto.java @@ -0,0 +1,9 @@ +package org.dailystudio.springbootstudy.dto; + +import lombok.Getter; + +@Getter +public class UserReqDto { + private String name; + private Integer number; +} diff --git a/src/main/java/org/dailystudio/springbootstudy/dto/UserResDto.java b/src/main/java/org/dailystudio/springbootstudy/dto/UserResDto.java new file mode 100644 index 0000000..88dc11c --- /dev/null +++ b/src/main/java/org/dailystudio/springbootstudy/dto/UserResDto.java @@ -0,0 +1,13 @@ +package org.dailystudio.springbootstudy.dto; + +import lombok.Getter; + +@Getter +public class UserResDto { + private String name; + + public UserResDto(UserReqDto userReqDto) { + this.name = userReqDto.getName(); + } + +} diff --git a/src/main/java/org/dailystudio/springbootstudy/service/UserService.java b/src/main/java/org/dailystudio/springbootstudy/service/UserService.java new file mode 100644 index 0000000..35544a9 --- /dev/null +++ b/src/main/java/org/dailystudio/springbootstudy/service/UserService.java @@ -0,0 +1,15 @@ +package org.dailystudio.springbootstudy.service; + +import org.dailystudio.springbootstudy.dto.UserReqDto; +import org.dailystudio.springbootstudy.dto.UserResDto; +import org.springframework.stereotype.Service; + +@Service +public class UserService { + + public UserResDto getUserInfo(UserReqDto userReqDto) { + UserResDto userResDto = new UserResDto(userReqDto); + return userResDto; + } + +} diff --git a/src/test/java/org/dailystudio/springbootstudy/SpringbootstudyApplicationTests.java b/src/test/java/org/dailystudio/springbootstudy/SpringbootstudyApplicationTests.java index 1cbed09..71a1031 100644 --- a/src/test/java/org/dailystudio/springbootstudy/SpringbootstudyApplicationTests.java +++ b/src/test/java/org/dailystudio/springbootstudy/SpringbootstudyApplicationTests.java @@ -9,8 +9,8 @@ @SpringBootTest public class SpringbootstudyApplicationTests { - @Test - public void contextLoads() { - } + @Test + public void contextLoads() { + } } From d3821172d74b10e91d55719280d4237cfdb3db80 Mon Sep 17 00:00:00 2001 From: pci2676 Date: Thu, 28 Mar 2019 17:21:36 +0900 Subject: [PATCH 2/3] =?UTF-8?q?requestParam=20=EB=82=B4=EC=9A=A9=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../springbootstudy/controller/TestController.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/dailystudio/springbootstudy/controller/TestController.java b/src/main/java/org/dailystudio/springbootstudy/controller/TestController.java index e88c41d..ac93731 100644 --- a/src/main/java/org/dailystudio/springbootstudy/controller/TestController.java +++ b/src/main/java/org/dailystudio/springbootstudy/controller/TestController.java @@ -19,10 +19,15 @@ public String me() { } @GetMapping("/path/{parameter}") - public String parameter(@PathVariable("parameter") String output) { + public String pathVariable(@PathVariable("parameter") String output) { return output; } + @GetMapping("/path") + public String parameter(@RequestParam("no") String number) { + return "번호는" + number; + } + @PostMapping("/post") public String postTest0() { return "post"; From 9e50fcb0120dd1a99244c91de9ac3fce783a2de6 Mon Sep 17 00:00:00 2001 From: pci2676 Date: Sun, 26 May 2019 23:08:42 +0900 Subject: [PATCH 3/3] using cache --- build.gradle | 10 +++- .../springbootstudy/config/CacheConfig.java | 9 +++ .../controller/TestController.java | 56 ------------------ .../controller/UserController.java | 49 ---------------- .../springbootstudy/domain/Board.java | 28 +++++++++ .../springbootstudy/dto/UserReqDto.java | 9 --- .../springbootstudy/dto/UserResDto.java | 13 ----- .../repository/BoardRepository.java | 7 +++ .../springbootstudy/service/BoardService.java | 38 +++++++++++++ .../springbootstudy/service/UserService.java | 15 ----- src/main/resources/application.properties | 6 +- .../service/BoardServiceTest.java | 57 +++++++++++++++++++ 12 files changed, 153 insertions(+), 144 deletions(-) create mode 100644 src/main/java/org/dailystudio/springbootstudy/config/CacheConfig.java delete mode 100644 src/main/java/org/dailystudio/springbootstudy/controller/TestController.java delete mode 100644 src/main/java/org/dailystudio/springbootstudy/controller/UserController.java create mode 100644 src/main/java/org/dailystudio/springbootstudy/domain/Board.java delete mode 100644 src/main/java/org/dailystudio/springbootstudy/dto/UserReqDto.java delete mode 100644 src/main/java/org/dailystudio/springbootstudy/dto/UserResDto.java create mode 100644 src/main/java/org/dailystudio/springbootstudy/repository/BoardRepository.java create mode 100644 src/main/java/org/dailystudio/springbootstudy/service/BoardService.java delete mode 100644 src/main/java/org/dailystudio/springbootstudy/service/UserService.java create mode 100644 src/test/java/org/dailystudio/springbootstudy/service/BoardServiceTest.java diff --git a/build.gradle b/build.gradle index dc1bc18..511219f 100644 --- a/build.gradle +++ b/build.gradle @@ -22,8 +22,16 @@ repositories { } dependencies { + compile('org.springframework.boot:spring-boot-starter-cache') + testCompile('org.springframework.boot:spring-boot-starter-test') + + implementation 'org.springframework.boot:spring-boot-starter-data-jpa' + compile('com.h2database:h2') + + testCompile('org.assertj:assertj-core:3.9.0') + implementation 'org.springframework.boot:spring-boot-starter-web' - compileOnly 'org.projectlombok:lombok:+' + compile 'org.projectlombok:lombok:+' annotationProcessor 'org.projectlombok:lombok:+' testImplementation 'org.springframework.boot:spring-boot-starter-test' } diff --git a/src/main/java/org/dailystudio/springbootstudy/config/CacheConfig.java b/src/main/java/org/dailystudio/springbootstudy/config/CacheConfig.java new file mode 100644 index 0000000..20fbaa6 --- /dev/null +++ b/src/main/java/org/dailystudio/springbootstudy/config/CacheConfig.java @@ -0,0 +1,9 @@ +package org.dailystudio.springbootstudy.config; + +import org.springframework.cache.annotation.EnableCaching; +import org.springframework.context.annotation.Configuration; + +@Configuration +@EnableCaching +public class CacheConfig { +} diff --git a/src/main/java/org/dailystudio/springbootstudy/controller/TestController.java b/src/main/java/org/dailystudio/springbootstudy/controller/TestController.java deleted file mode 100644 index ac93731..0000000 --- a/src/main/java/org/dailystudio/springbootstudy/controller/TestController.java +++ /dev/null @@ -1,56 +0,0 @@ -package org.dailystudio.springbootstudy.controller; - -import org.dailystudio.springbootstudy.dto.UserReqDto; -import org.springframework.web.bind.annotation.*; - -@RestController -@RequestMapping("api/test") -public class TestController { - - @GetMapping - public String test() { - String str = "hello world"; - return str; - } - - @GetMapping("/get") - public String me() { - return "me"; - } - - @GetMapping("/path/{parameter}") - public String pathVariable(@PathVariable("parameter") String output) { - return output; - } - - @GetMapping("/path") - public String parameter(@RequestParam("no") String number) { - return "번호는" + number; - } - - @PostMapping("/post") - public String postTest0() { - return "post"; - } - - @PostMapping("/post/{name}") - public String postTest1(@PathVariable("name") String output) { - return output; - } - - @PostMapping("/post/instance/user") - public String postTest2(@RequestBody UserReqDto user) { - String output = user.getName() + user.getNumber(); - return output; - } - - @DeleteMapping("/delete") - public String deleteTest() { - return "delete"; - } - - @PutMapping - public String putTest() { - return "put"; - } -} diff --git a/src/main/java/org/dailystudio/springbootstudy/controller/UserController.java b/src/main/java/org/dailystudio/springbootstudy/controller/UserController.java deleted file mode 100644 index 59069b7..0000000 --- a/src/main/java/org/dailystudio/springbootstudy/controller/UserController.java +++ /dev/null @@ -1,49 +0,0 @@ -package org.dailystudio.springbootstudy.controller; - -import lombok.RequiredArgsConstructor; -import org.dailystudio.springbootstudy.dto.UserReqDto; -import org.dailystudio.springbootstudy.dto.UserResDto; -import org.dailystudio.springbootstudy.service.UserService; -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; - -/* -RestFul한 API란 무엇인가? -하나의 URI는 반드시 그에 상응하는 데이터를 나타내는 구조이다. - -예를 들어 -/api/user/1/name 로 접근하는 경우 -'1번' '유저'의 '이름' 대한 데이터를 나타낸다. - -@RestController = @Controller + @ResponseBody 이다. -기존에 @Controller를 사용했을 때는 뷰를 반환하였지만 -@RestController를 사용하면 데이터만 반환하게 된다. -이러한 데이터는 JSON형태로 반환된다. - -우리는 RestFul API를 구현할 때 반환값으로 ResponseEntity를 이용할 것이다. -ResponseEntity를 이용하게 되면 -서버에서 직접 - -1. 상태코드 --> OK(200), NOT_FOUND(404)... -2. HttpHeader --> Content-type : JSON(application/json)... -3. 응답 메세지 --> 요청에 대한 응답 값 - -를 지정해서 클라이언트에게 보내줄 수 있다. - */ -@RestController -@RequestMapping("api/user") -@RequiredArgsConstructor -public class UserController { - - private final UserService userService; - - @PostMapping - public ResponseEntity getUserName(@RequestBody UserReqDto userReqDto) { - //UserReqDto userReqDto = userService.getUserInfo(userReqDto); - //return ResponseEntity.ok().body(userReqDto); - return ResponseEntity.ok().body(userService.getUserInfo(userReqDto)); - } -} diff --git a/src/main/java/org/dailystudio/springbootstudy/domain/Board.java b/src/main/java/org/dailystudio/springbootstudy/domain/Board.java new file mode 100644 index 0000000..a0d13bf --- /dev/null +++ b/src/main/java/org/dailystudio/springbootstudy/domain/Board.java @@ -0,0 +1,28 @@ +package org.dailystudio.springbootstudy.domain; + +import lombok.NoArgsConstructor; + +import javax.persistence.*; +import javax.validation.constraints.NotNull; + +@Entity +@Table(name = "BOARD") +@NoArgsConstructor +public class Board { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @Column + @NotNull + private String content; + + public String getContent() { + return content; + } + + public Board(@NotNull String content) { + this.content = content; + } +} diff --git a/src/main/java/org/dailystudio/springbootstudy/dto/UserReqDto.java b/src/main/java/org/dailystudio/springbootstudy/dto/UserReqDto.java deleted file mode 100644 index 1423821..0000000 --- a/src/main/java/org/dailystudio/springbootstudy/dto/UserReqDto.java +++ /dev/null @@ -1,9 +0,0 @@ -package org.dailystudio.springbootstudy.dto; - -import lombok.Getter; - -@Getter -public class UserReqDto { - private String name; - private Integer number; -} diff --git a/src/main/java/org/dailystudio/springbootstudy/dto/UserResDto.java b/src/main/java/org/dailystudio/springbootstudy/dto/UserResDto.java deleted file mode 100644 index 88dc11c..0000000 --- a/src/main/java/org/dailystudio/springbootstudy/dto/UserResDto.java +++ /dev/null @@ -1,13 +0,0 @@ -package org.dailystudio.springbootstudy.dto; - -import lombok.Getter; - -@Getter -public class UserResDto { - private String name; - - public UserResDto(UserReqDto userReqDto) { - this.name = userReqDto.getName(); - } - -} diff --git a/src/main/java/org/dailystudio/springbootstudy/repository/BoardRepository.java b/src/main/java/org/dailystudio/springbootstudy/repository/BoardRepository.java new file mode 100644 index 0000000..1333ebf --- /dev/null +++ b/src/main/java/org/dailystudio/springbootstudy/repository/BoardRepository.java @@ -0,0 +1,7 @@ +package org.dailystudio.springbootstudy.repository; + +import org.dailystudio.springbootstudy.domain.Board; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface BoardRepository extends JpaRepository { +} diff --git a/src/main/java/org/dailystudio/springbootstudy/service/BoardService.java b/src/main/java/org/dailystudio/springbootstudy/service/BoardService.java new file mode 100644 index 0000000..22d3518 --- /dev/null +++ b/src/main/java/org/dailystudio/springbootstudy/service/BoardService.java @@ -0,0 +1,38 @@ +package org.dailystudio.springbootstudy.service; + +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.dailystudio.springbootstudy.domain.Board; +import org.dailystudio.springbootstudy.repository.BoardRepository; +import org.springframework.cache.annotation.CacheEvict; +import org.springframework.cache.annotation.Cacheable; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.stream.Collectors; + +@Service +@Slf4j +@RequiredArgsConstructor +public class BoardService { + + private final BoardRepository boardRepository; + + @CacheEvict(value = "contents", allEntries = true) + public void saveContent(String content) { + Board board = new Board(content); + boardRepository.save(board); + } + + @Cacheable(value = "contents") + public List fetchContents() { + logCache(); + return boardRepository.findAll().stream() + .map(Board::getContent) + .collect(Collectors.toList()); + } + + private void logCache() { + log.info("new cache."); + } +} diff --git a/src/main/java/org/dailystudio/springbootstudy/service/UserService.java b/src/main/java/org/dailystudio/springbootstudy/service/UserService.java deleted file mode 100644 index 35544a9..0000000 --- a/src/main/java/org/dailystudio/springbootstudy/service/UserService.java +++ /dev/null @@ -1,15 +0,0 @@ -package org.dailystudio.springbootstudy.service; - -import org.dailystudio.springbootstudy.dto.UserReqDto; -import org.dailystudio.springbootstudy.dto.UserResDto; -import org.springframework.stereotype.Service; - -@Service -public class UserService { - - public UserResDto getUserInfo(UserReqDto userReqDto) { - UserResDto userResDto = new UserResDto(userReqDto); - return userResDto; - } - -} diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 8b13789..5046899 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -1 +1,5 @@ - +spring.h2.console.path=/h2 +spring.datasource.url=jdbc:h2:~/ds;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE +spring.jpa.database-platform=org.hibernate.dialect.H2Dialect +spring.h2.console.enabled=true +spring.jpa.hibernate.ddl-auto=create-drop diff --git a/src/test/java/org/dailystudio/springbootstudy/service/BoardServiceTest.java b/src/test/java/org/dailystudio/springbootstudy/service/BoardServiceTest.java new file mode 100644 index 0000000..7b1b20a --- /dev/null +++ b/src/test/java/org/dailystudio/springbootstudy/service/BoardServiceTest.java @@ -0,0 +1,57 @@ +package org.dailystudio.springbootstudy.service; + +import lombok.extern.slf4j.Slf4j; +import org.junit.After; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; + +@Slf4j +@RunWith(SpringRunner.class) +@SpringBootTest +public class BoardServiceTest { + + private static final String DEFAULT_CONTENT = "default"; + + @Autowired + private BoardService boardService; + + private List contents; + + @After + public void tearDown() throws Exception { + log.info(contents.toString()); + } + + @Test + public void 캐시0() { + boardService.saveContent(DEFAULT_CONTENT); + contents = boardService.fetchContents(); + } + + @Test + public void 캐시1() { + contents = boardService.fetchContents(); + } + + @Test + public void 캐시2() { + contents = boardService.fetchContents(); + } + + @Test + public void 캐시3() { + boardService.saveContent("캐시3"); + contents = boardService.fetchContents(); + } + + @Test + public void 캐시4() { + contents = boardService.fetchContents(); + } +} \ No newline at end of file