SpringBoot를 본격적으로 배우기 시작하여 처음 알게 된 기능과 기법에 대해 정리해 보았다.
자바에서 클래스를 생성하면 보통 게터,세터 등의 메서드를 직접 타이핑으로 추가 해주거나 IntelliJ 내장 기능인 generate를 사용하여 생성하는 경우가 많다.
이를 lombok을 통해 단순하고 쉽게 만들 수 있다.
아래 예시 코드를 보면 따로 getter,setter 매서드를 생성해주지 않고 어노테이션@Getter,@Setter를 추가만 해주었음에도 getId(),setTitle()등의 매서드를 자동으로 추가시켜 준다.
@Getter
@Setter
@NoArgsConstructor
public class Post {
private Long id;
private String title;
}
@NoArgsConstructor 의 역할은 아래 코드와 같이 기본 생성자와 모든 필드를 파라미터로 가진 오버로딩된 생성자를 만들어 준다.
public Post(){
}
public Post(Long id,String title){
this.id = id;
this.title = title;
}
여러개의 API를 처리하기 위해 만들어진 기능!
1.주로 유사한 성격의 API를 하나의 Controller로 관리
2.매서드 이름도 자유롭게 설정 가능.(단, 클래스 내의 중복메서드는 불가)
다음은 과제로 작성한 코드 중 일부인데 이처럼 post,get,put 등등의 다양한 api를 묶어서 관리할 수 있게 해준다.
@RequestMapping 을 사용하여 각 api를 호출할 때 중복되는 경로를 생략할 수도 있다!!
아래 코드에서는 post요청 경로가 원래는 @PostMapping("/api/posts") 라는 뜻이다.
@RestController
@RequestMapping("/api")
public class PostController {
private final Map<Long, Post> postList = new HashMap<>();
//게시물 작성하기
@PostMapping("/posts")
public PostResponseDto createPost(@RequestBody PostRequestDto requestDto) {
Post post = new Post(requestDto);
Long maxId = !postList.isEmpty() ? Collections.max(postList.keySet()) + 1 : 1;
post.setId(maxId);
//DB 저장
postList.put(post.getId(), post);
//Entity -> ResponseDto
return new PostResponseDto(post);
}
//게시글 목록 조회하기
@GetMapping("/posts")
public List<PostResponseDto> getPosts() {
return postList.values().stream()
.map(PostResponseDto::new).toList();
}
//id로 게시글 조회
@GetMapping("/post/{id}")
public Post getPost(@PathVariable Long id) {
if (postList.containsKey(id)) {
return postList.get(id);
} else {
throw new IllegalArgumentException("선택한 게시글은 존재하지 않습니다.");
}
}
//게시글 수정
@PutMapping("/posts/{id}")
public Post updatePost(@PathVariable Long id, @RequestBody PostRequestDto requestDto) {
//포스트 DB에 존재 하는지 확인
if (postList.containsKey(id)) {
Post post = postList.get(id);
//게시글 수정 매서드
if (post.getPassword().equals(requestDto.getPassword())) {
post.update(requestDto);
return post;
} else
throw new IllegalArgumentException("비밀번호가 틀렸습니다.");
} else {
throw new IllegalArgumentException("선택한 게시글은 존재하지 않습니다.");
}
}
}
POST http://localhost:8080/turtle/request/form/model
@PostMappint("/form/model")
@ResponseBody
public String turtleRequestBodyForm(@ModelAttribute Turtle turtle){
return String.format("I'm @ModelAttribute.<br> (id = %s, age = %d)",turtle.id,turtle.age);
}
html의 form 태그를 사용하여 POST 방식으로 요청을 보낼 수 있다.
이때 해당 데이터는 HTTP Body에 id=turtle&age=25 등의 형태로 서버에 전달된다.
해당 데이터를 Java의 객체 형태로 받으려면 @ModelAttribute 어노테이션을 사용한 후 Body 데이터를 받아올 객체를 선언해야 한다.
GET http://localhost:8080/turtle/request/form/param/model?id=turtle&age=25
처리해야 하는 데이터가 많아질수록 @RequestParam 으로 하나씩 받아오는데 무리가 있다.
이때 @ModelAttribute 을 사용하여 파라미터에 선언한 Turtle객체가 생성되고, 오버로딩된 생성자 혹은 Setter 매서드를 통해 요청된 id & age의 값이 담긴다.
참고로 @ModelAttribute과 @RequestParam는 생략이 가능하다. Spring에서는 파라미터가 SimpleValueType (int,Integer,Date등의 타입)이라면 @RequestParam으로 간주하고 아니라면 @ModelAttribute가 생략되었다고 판단한다.
HTTP Body에 JSON 데이터를 담아 서버에 전달할 때 해당 Body데이터를 Java의 객체로 전달 받을 수 있다.
POST http://localhost:8080/turtle/request/form/json
@PostMapping("/form/json")
@ResponseBody
public String turtlePostRequestJson(@RequestBody Turtle turtle){
return String.format("I'm @RequestBody.<br> (id = %s, age = %d)",turtle.id,turtle.age);
}
HTTP Body에 {"id":"turtle","age":"25"} 형태로 데이터가 전달되었을 때 @RequestBody 어노테이션을 사용하여 데이터를 객체 형태로 받을 수 있다.
이처럼 데이터를 Java의 객체로 받아올때는 해당 객체의 필드에 setter,getter 매서드 또는 오버로딩된 생성자가 필요하다.