본문 바로가기
Spring Framework

Spring boot REST API 개발 - Dto 클래스로 입력 값 제한하기

by 자유코딩 2019. 1. 11.

컨트롤러에서는 입력 값을 받아들인다.

 

우리는 보통 모델 클래스를 만들고 그것을 insert 한다.

 

아래와 같은 Model 클래스가 있다고 해보자.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
package com.example.api.events;
 
import lombok.*;
 
import javax.persistence.*;
import java.time.LocalDateTime;
 
//@Data data 애너테이션을 사용하는 것은 권하지 않는다.
//아래 작성된 EqualsAndHashCode 에서 of 값으로 id 속성을 쓰고 있다.
//그런데 Data 애너테이션을 쓰면 of 를 모든 속성에 대해서 사용 한 것처럼 된다. 이러면 스택오버플로우가 발생할 여지가 있다고 한다.
@Builder @NoArgsConstructor @AllArgsConstructor
@Getter @Setter @EqualsAndHashCode(of = "id"// 애너테이션이 굉장히 많은데. 원래 Lombok 의 애너테이션을 제외한 다른 애너테이션들은 메타 애너테이션을 활용해서 줄일 수 있다.
//롬복의 애너테이션들은 아직 줄일 수 있는 방법이 없다. 이렇게 다 작성해야 한다.
@Entity
public class Event {
    @Id @GeneratedValue
    private Integer id;
    private String name;
    private String description;
    private LocalDateTime beginEnrollmentDateTime;
    private LocalDateTime closeEnrollmentDateTime;
    private LocalDateTime beginEventDateTime;
    private LocalDateTime endEventDateTime;
    private String location; // location 값이 없다면 온라인 모임
    private int basePrice; // optional
    private int maxPrice; // optional
    private int limitOfEnrollment;
    private boolean offline;
    private boolean free;
    @Enumerated(EnumType.STRING) // 기본 타입은 EnumType.Ordinal 인데 String 으로 바꿔주는 것이 좋다.
    private EventStatus eventStatus; // Enum 클래스 안의 데이터의 순서가 바뀌게 되면 데이터에 문제가 생긴다.
    //그래서 순서가 바뀌어도 문제 되지 않는 String 을 사용한다.
 
}
 
cs

 

컨트롤러에 값을 보낼때는 이렇게 할 것이다.

 

1
2
3
4
5
@PostMapping
    public ResponseEntity createEvent(@RequestBody Event Event ){ 
        ....
        ...
    }
cs

 

자 그런데 만약에 임의로 id 값을 보낸다거나 하면.

 

id 컬럼은 자동 증가인데. 사용자가 id 를 임의로 바꾸게 되어서 혼란을 가져 올 수 있다.

 

이렇게 컬럼의 모든 값을 받으면 안되고 입력 값을 제한해야 한다.

 

그럴때 Dto 클래스를 사용한다.

 

그리고 Dto 클래스를 원본 클래스로 변환하게 된다.

 

아래와 같이 작성한다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@Builder @NoArgsConstructor @AllArgsConstructor
@Getter @Setter
public class EventDto {
    private String name;
    private String description;
    private LocalDateTime beginEnrollmentDateTime;
    private LocalDateTime closeEnrollmentDateTime;
    private LocalDateTime beginEventDateTime;
    private LocalDateTime endEventDateTime;
    private String location; // location 값이 없다면 온라인 모임
    private int basePrice; // optional
    private int maxPrice; // optional
    private int limitOfEnrollment;
}
 
cs

 

1
2
3
4
5
6
7
8
9
10
11
12
13
@PostMapping
    public ResponseEntity createEvent(@RequestBody EventDto eventDto){ // 모델매퍼를 활용해서 EventDTO 를 Event 로 바꾼다.
//        Event event = Event.builder() 1. ModelMapper 를 사용하지 않는 방법
//                .name(eventDto.getName())
//                .description(eventDto.getDescription())
        //ModelMapper 를 사용하는 방법
        Event event = modelMapper.map(eventDto , Event.class); // 위에 사용하지 않는 방법은 많은 값을 입력한다. //ModelMapper 를 사용하면 이 1줄로 들어온 모든 값을 1세팅 할 수 있다.
 
        Event newEvent = this.eventRepository.save(event);
        URI createUri = linkTo(EventController.class).slash(newEvent.getId()).toUri();
        event.setId(10);
        return ResponseEntity.created(createUri).body(event);
    }
cs

 

이렇게 원본 클래스의 필드를 일부 가지고 있는 Dto 클래스를 만든다.

 

그리고 ModelMapper 를 사용하거나 객체를 생성해서 변환한다.

이렇게 하면 효과적으로 입력 필드를 제한 할 수 있다.

 

댓글