Spring Boot (10)

ysh·2023년 7월 28일
0

Spring Boot

목록 보기
44/53

h2

application.yml

spring:
  thymeleaf:
    cache: false # 이전 데이터 캐싱되어 수정 안될 수 있음
  datasource:
    url: jdbc:h2:mem:testdb;MODE=MySQL;DB_CLOSE_DELAY=-1 # memory에 저장 속도는 빠른데 서버 재시작 시 데이터 날아감
    driverClassName: org.h2.Driver # 인터넷 검색
    username: sa
    password:
  h2:
    console:
      enabled: true # 자체 콘솔 존재
      path: /h2
  sql:
    init: # 서버가 켜질 때 들어갈 데이터
      encoding: UTF-8
#      schema-locations: classpath:h2/schema.sql
      dataLocations: classpath:sql/data.sql
      mode: always
  jpa: 
    defer-datasource-initialization: true # 위의 init에서의 데이터가 들어갈 때까지 기다림
    open-in-view: false # 트랜잭션 범위 밖에서 영속성 컨텍스트를 유지할지 여부
    database-platform: org.hibernate.dialect.H2Dialect # 어느 형식의 DB를 쓸 지 결정
    hibernate: # 
      ddl-auto: create # create-drop, update, validate, none / # 
      naming: # 이름 전략
        physical-strategy: org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
        implicit-strategy: org.hibernate.boot.model.naming.ImplicitNamingStrategyLegacyJpaImpl
    show-sql: true # sql 보이게
    properties:
      hibernate:
        format_sql: true # sql 정렬 설정
        use_sql_comments: true
  servlet:
    multipart:
      max-request-size: 10MB
      max-file-size: 10MB

h2 DB 접근

http://localhost:8080/h2


Controller에서 String으로 View 반환

@GetMapping("/auth/login")
    public ModelAndView login() {
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.setViewName("auth/login");
        return modelAndView;
    }

    @GetMapping("/auth/login")
    public String login(Model model) {
        // model.addAttribute("dto", "hong");
        return "auth/login";
    }

익셉션 핸들러

runtimeException 상속한 오류 클래스 작성

package com.example.my.common.exception;

public class BadRequestException extends RuntimeException {

    public BadRequestException(String message) {
        super(message);
    }

    public BadRequestException() {
        super("잘못된 요청입니다.");
    }
}

익셉션 핸들러로 오류 클래스를 조작

package com.example.my.common.exception.handler;

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

import com.example.my.common.dto.ResponseDTO;
import com.example.my.common.exception.BadRequestException;

@RestControllerAdvice
public class RestExceptionHandler {

    @ExceptionHandler(BadRequestException.class)
    public ResponseEntity<?> handleBadRequestException(Exception exception){
        return new ResponseEntity<>(
            ResponseDTO.builder()
            .code(1)
            .message(exception.getMessage())
            .build(),
            HttpStatus.BAD_REQUEST);
    }
}

유효성 검사 시 작성한 에러 던져주기

if (dto.getUser().getId() == null ||
                dto.getUser().getId().equals("") ||
                dto.getUser().getPassword() == null ||
                dto.getUser().getPassword().equals("")) {

            throw new BadRequestException("아이디나 비밀번호를 정확히 입력해주세요.");
        }

Req객체(입력값)에 유효성 검사(@Valid)

@Valid

: 유효성 검사할 객체에 @Valid

@PostMapping("/join")
    public ResponseEntity<?> join(@Valid @RequestBody ReqJoinDTO dto) {
        // 서비스에서 회원가입하기
        return authServiceApiV1.join(dto);
    }

ReqJoinDTO

package com.example.my.domain.auth.dto;

import jakarta.validation.Valid;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Pattern;
import jakarta.validation.constraints.Size;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

@NoArgsConstructor
@AllArgsConstructor
@Getter
public class ReqJoinDTO {

    @Valid
    @NotNull(message = "유저 정보를 입력해주세요.")
    private User user;
    
    @NoArgsConstructor
    @AllArgsConstructor
    @Builder
    @Getter
    public static class User {

        @NotBlank(message = "아이디를 입력해주세요.") // 오로지 문자열
        @Size(min = 4, message = "아이디는 4자 이상")
        private String id;

        @NotBlank(message = "비밀번호를 입력해주세요")
        @Pattern(regexp = "^(?=.*[a-zA-Z])(?=.*\\d)(?=.*[@#$%^&+=!])(?!.*\\s).{8,16}$", message = "비밀번호는 8~16자 영문 대 소문자, 숫자, 특수문자를 사용하세요.")
        private String password;
    }

}

참고

https://dev-coco.tistory.com/123

BindException

: @Valid에서 조건에 맞지 않을 시 반환하는
MethodArgumentNotValidException 오류의 상위개체

익셉션 핸들러

@ExceptionHandler(BindException.class)
    public ResponseEntity<?> handleBindException(BindException bindException) {

        // 오류 목록을 담기 위한 Map 생성
        HashMap<String, String> errorMap = new HashMap<>();

        // BindException 안의 BindingResult(오류 상세 정보)필드에서
        // FieldErrors()로 BindingResult의 errors의 정보를 FieldError객체 리스트로 반환
        for (FieldError fieldError : bindException.getBindingResult().getFieldErrors()) {
            // Map의 키를 필드 이름, 밸류를 Message로 담아
            errorMap.put(fieldError.getField(), fieldError.getDefaultMessage());
        }

        // 응답 시 Map을 데이터에 넣어 반환
        // 프론트엔드에서 Map 데이터를 받아 오류를 다 뿌려줄 수 있다.
        return new ResponseEntity<>(
            ResponseDTO.builder()
            .code(1)
            .message("입력값을 확인해주세요.")
            .data(errorMap)
            .build(),
            HttpStatus.BAD_REQUEST
        );
    }
profile
유승한

0개의 댓글