Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Spring Core] 이동호 미션 제출합니다. #264

Open
wants to merge 21 commits into
base: plusultracode
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 20 commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
06583e5
Docs: readme 작성
PlusUltraCode May 12, 2024
fbdc5c1
feat: 1단계 화면 추가
PlusUltraCode May 12, 2024
0c9f3db
feat: 2단계 예약 조회 추가
PlusUltraCode May 12, 2024
2c704f1
feat: 3단계 예약 추가/취소 추가
PlusUltraCode May 12, 2024
6443dcd
feat: 4단계 예외처리 추가
PlusUltraCode May 12, 2024
2207bf3
Update README.md
PlusUltraCode May 12, 2024
1f39026
Merge remote-tracking branch 'origin/main'
PlusUltraCode May 13, 2024
e903bef
refactor: 모든코드 리펙토링
PlusUltraCode May 19, 2024
098b99c
feat : 6단계 gradle, schema, DB 설정 완료
PlusUltraCode May 20, 2024
6cb8adc
feat : 6단계 데이터 조회 완료
PlusUltraCode May 20, 2024
cf79545
feat : 7단계 데이터 추가/삭제 완료
PlusUltraCode May 20, 2024
a5aa063
Update README.md
PlusUltraCode May 20, 2024
1f92290
feat : DAO => ReservationRepository 및 Impl 로 대체 + Serivce 객체 구현
PlusUltraCode May 26, 2024
6ea0ac4
feat : KeyHolder 반영 완료.
PlusUltraCode May 26, 2024
89ae934
refractor : 리펙토링 완료.
PlusUltraCode May 26, 2024
9f0e681
Merge remote-tracking branch 'origin/main2' into main2
PlusUltraCode May 26, 2024
90ea520
feat : 8단계 시간관리 완료
PlusUltraCode May 26, 2024
7e002f3
feat : 9 완료 및 10 계층화 완료
PlusUltraCode May 27, 2024
0be43a7
feat : convention 수정
PlusUltraCode May 27, 2024
c859908
feat : testing 완료
PlusUltraCode May 27, 2024
6c59295
refator : 오류 해결 및 코드리뷰 반영 완료!!
PlusUltraCode Jun 3, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 38 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
*** 1단계 화면 생성 ***

controller, model, exception 패키지 생성

[gradle 첨가]
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'


**** 2단계 화면 조회 ****

1. exception 패키지에 예외 처리 record (Date, Id, Name, Time) 생성
2. model 패키지에 Reservation 객체 그햔
3. controller 패키지에 ReservationController 만든 후 페이지 요청(/reservation) 및 목록 조회(/reservations) 구현

*****3단계 정보 생성 및 삭제 *****

1. 생성관련 메소드는 PostMapping을 이용할 것.
2. 삭제관련 메소드는 DeleteMapping을 이용할 것.

****4단계 예외 처리 ******
전역적으로 다루는 예외 함수를 이용하여 특정 원하는 오류값을 리턴할 계획


****5단계 데이터베이스 적용하기 ******

gradle , h2 , 스키마 파일 넣기

****6단계 데이터베이스 조회하기 ******
1. Getmapping(/reservations) 를 했을 때 해당 데이터 베이스에 있는 자료들이 화면에 보여야 된다.
그러면 해당 함수에 데이터 베이스 전체를 불러오는 List를 선언해서 리턴해줘야 겠다.

2. 데이터 베이스를 관리할 entity를 새로 만들자 db 패키지 안에 ReservationEntity
3. 직접적으로 db와 소통을 하기 위한 객체가 필요하다. Service 패키지 안에 Update 및 Query 과 관련된 객체 생성
4. 해당 객체의 맞게 함수 만들기.

****7단계 데이터베이스 적용하기 ******
위에 구현해 놨던 함수에 delete 및 insert와 해당 id를 건내줄 경우 해당 튜플을 반환해주는 함수를 구현해보자.
11 changes: 10 additions & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,20 @@ repositories {
}

dependencies {
implementation 'org.springframework.boot:spring-boot-starter-validation'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'

implementation 'org.springframework.boot:spring-boot-starter'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation 'io.rest-assured:rest-assured:5.3.1'
// https://mvnrepository.com/artifact/org.projectlombok/lombok
compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
implementation 'org.springframework.boot:spring-boot-starter-jdbc'
runtimeOnly 'com.h2database:h2'
}

test {
useJUnitPlatform()
}
}
3 changes: 3 additions & 0 deletions src/main/java/roomescape/RoomescapeApplication.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
package roomescape;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.jdbc.core.JdbcTemplate;

@SpringBootApplication
public class RoomescapeApplication {
Expand Down
29 changes: 29 additions & 0 deletions src/main/java/roomescape/controller/GlobalExceptionHandler.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package roomescape.controller;

import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;

import java.time.format.DateTimeParseException;

@ControllerAdvice
public class GlobalExceptionHandler {

@ExceptionHandler
public ResponseEntity<Void> notFoundExceptionHandler(NotFoundException error) {
System.out.println(error.getMessage());
return ResponseEntity.notFound().build();
}

@ExceptionHandler
public ResponseEntity<Void> illegalArgumentsExceptionHandler(IllegalArgumentException error) {
System.out.println(error.getMessage());
return ResponseEntity.badRequest().build();
}

@ExceptionHandler
public ResponseEntity<Void> dateTimeParseExceptionHandler(DateTimeParseException error) {
System.out.println(error.getMessage());
return ResponseEntity.badRequest().build();
}
}
13 changes: 13 additions & 0 deletions src/main/java/roomescape/controller/HomeController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package roomescape.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;

@Controller
public class HomeController {

@GetMapping("/")
public String homePage() {
return "home";
}
}
7 changes: 7 additions & 0 deletions src/main/java/roomescape/controller/NotFoundException.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package roomescape.controller;

public class NotFoundException extends RuntimeException {
public NotFoundException(String errormessage) {
super(errormessage);
}
}
64 changes: 64 additions & 0 deletions src/main/java/roomescape/controller/ReservationController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
package roomescape.controller;

import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import roomescape.model.Reservation;

import java.net.URI;
import java.time.LocalDate;
import java.time.LocalTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicLong;

@Controller
public class ReservationController {

private final List<Reservation> reservations = new ArrayList<>();
private final AtomicLong index = new AtomicLong(1);

@GetMapping(value = "/reservation")
public String reservation() {
return "reservation";
}

@GetMapping(value = "/reservations")
public ResponseEntity<List<Reservation>> reservations() {
HttpHeaders headers = new HttpHeaders();
if (reservations.isEmpty())
return new ResponseEntity<>(Arrays.asList(), headers, HttpStatus.OK);

headers.setContentType(MediaType.APPLICATION_JSON);
return new ResponseEntity<>(reservations, headers, HttpStatus.OK);
}

@PostMapping(value = "/reservations")
public ResponseEntity<Reservation> create(@RequestBody Reservation reservation) {

System.out.println("\n생성 : " + reservation + "\n\n");
Reservation newReservation = Reservation.toEntity(reservation, index.getAndIncrement());
reservations.add(newReservation);

HttpHeaders headers = new HttpHeaders();
headers.setLocation(URI.create("/reservations/" + Long.toString(newReservation.getId())));
headers.setContentType(MediaType.APPLICATION_JSON);
return ResponseEntity.status(HttpStatus.CREATED).headers(headers).body(newReservation);
}

@DeleteMapping(value = "/reservations/{id}")
public ResponseEntity<Void> delete(@PathVariable long id) {
Reservation reservation = reservations.stream()
.filter(it -> Objects.equals(it.getId(), id))
.findFirst()
.orElseThrow(IllegalArgumentException::new);
reservations.remove(reservation);

return ResponseEntity.noContent().build();
}
}
33 changes: 33 additions & 0 deletions src/main/java/roomescape/exception/GlobalExceptionHandler.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package roomescape.exception;

import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;

@ControllerAdvice
public class GlobalExceptionHandler {

@ExceptionHandler(RuntimeException.class)
public ResponseEntity<Void> runTimeExceptionHandler(RuntimeException error) {

System.out.println(error.getMessage());
return ResponseEntity.status(HttpStatus.BAD_REQUEST).build();

}

@ExceptionHandler(IllegalArgumentException.class)
public ResponseEntity<Void> illegalArgumentsExceptionHandler(IllegalArgumentException error) {

System.out.println(error.getMessage());
return ResponseEntity.status(HttpStatus.BAD_REQUEST).build();
}

@ExceptionHandler(MethodArgumentNotValidException.class)
public ResponseEntity<Void> methodArgumentNotValidExceptionHandler(MethodArgumentNotValidException error) {

System.out.println(error.getMessage());
return ResponseEntity.status(HttpStatus.BAD_REQUEST).build();
}
}
30 changes: 30 additions & 0 deletions src/main/java/roomescape/model/Exception.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package roomescape.model;





import java.time.LocalDate;
import java.time.LocalTime;
import java.util.Objects;

public class Exception {

public static LocalDate validateDateIsNotNull(LocalDate date){
if(Objects.isNull(date))
throw new IllegalArgumentException("올바르지 않은 날짜 형식입니다.");
return date;
}

public static LocalTime validateTimeIsNotNull(LocalTime time){
if(Objects.isNull(time))
throw new IllegalArgumentException("올바르지 않은 시간 형식입니다.");
return time;
}

public static String validateNameIsNotNull(String name){
if(Objects.isNull(name))
throw new IllegalArgumentException("올바르지 않은 이름 형식입니다.");
return name;
}
}
33 changes: 33 additions & 0 deletions src/main/java/roomescape/model/Reservation.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package roomescape.model;


import lombok.*;

import java.time.LocalDate;
import java.time.LocalTime;

@Data
@NoArgsConstructor
@Getter
public class Reservation {

private Long id;
private String name;
private LocalDate date;
private LocalTime time;

public Reservation(Long id, String name, LocalDate date, LocalTime time) {
this.id = id;
this.name = Exception.validateNameIsNotNull(name);
this.date = Exception.validateDateIsNotNull(date);
this.time = Exception.validateTimeIsNotNull(time);
}

public static Reservation toEntity(Reservation reservation, Long id){
return new Reservation(id,
reservation.name,
reservation.date,
reservation.time
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package roomescape.reservation.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;

@Controller
public class HomeApiController {

@GetMapping("/")
public String home() {
return "home";
}

}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

저는 @GetMapping(value = "/reservations"), @PostMapping(value = "/reservations"), @DeleteMapping(value = "/reservations/{id}") 부분에서 "/reservations"가 중복되는걸 줄여주고 싶어서
@controller 어노테이션 위에 RequestMapping("/reservations")를 적어주었습니다.

이렇게 하면 중복되는 부분은 제거되어
@GetMapping(value = "/reservations") -> @GetMapping
@PostMapping(value = "/reservations") -> @PostMapping
@DeleteMapping(value = "/reservations/{id}") -> @DeleteMapping("/{id})
조금 더 간결하게 짤 수 있었던 거 같아요.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@RequsetMapping("/reservaations")를 사용하니
해당 클래스 안에 있는 @GetMapping @PostMapping에
중복되는 "/reservations"을 없앨 수 있게 되었습니다.

감사합니다 ^^

Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package roomescape.reservation.controller;


import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import roomescape.reservation.dto.ReservationRequest;
import roomescape.reservation.dto.ReservationResponse;
import roomescape.reservation.service.ReservationService;

import javax.net.ssl.SSLEngineResult;
import java.net.URI;
import java.util.List;

@RestController
@RequiredArgsConstructor
public class ReservationApiController {

private final ReservationService reservationService;

@GetMapping("/reservations")
public ResponseEntity<List<ReservationResponse>> reservations() {
List<ReservationResponse> responseList = reservationService.findAllReservations();

return ResponseEntity
.status(HttpStatus.OK)
.body(responseList);
}

@PostMapping("/reservations")
public ResponseEntity<ReservationResponse> addReservation(
@Valid
@RequestBody ReservationRequest reservationRequest
) {

ReservationResponse response = reservationService.addReservation(reservationRequest);

return ResponseEntity.created(URI.create("/reservations/" + response.getId()))
.body(response);
}

@DeleteMapping("/reservations/{id}")
public ResponseEntity<Void> deleteReservation(
@PathVariable Long id
) {
reservationService.cancelReservation(id);

return ResponseEntity.noContent()
.build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package roomescape.reservation.controller;


import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;

@Controller
public class ReservationController {

@GetMapping("/reservation")
public String reservation() {
return "new-reservation";
}
}
15 changes: 15 additions & 0 deletions src/main/java/roomescape/reservation/db/ReservationEntity.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package roomescape.reservation.db;

import lombok.Builder;
import lombok.Data;
import roomescape.time.db.TimeEntity;

@Data
@Builder
public class ReservationEntity {
private Long id;
private String name;
private String date;
private TimeEntity timeEntity;

}
Loading