시작하기

원하는 프로젝트 명으로 설정 및 JAVA, Gradle,, JDK, Jar 파일을 설정한다.

의존성 설정에서 Spring 웹 어플리케이션 개발을 위한 Spring Web을 선택

controller 패키지를 생성하고 controller 역할을 수행할 클래스를 생성한다.
class에 @RestController, @RquestMapping 어노테이션을 추가한다.
@RestController: 해당 클래스를 REST API를 처리하는 컨트롤러로 설정
@RequestMapping : 클라이언트 요청을 받을 URI를 지정
ex) http://localhost:8080/api
추가로 해당 컨트롤러에서 GET방식으로 클라이언트 요청을 처리할 메소드를 생성
@GetMapping : 해당 메소드는 GET 처리 및 URI 지정
ex) GET http://localhost:8080/api/hello251
GET API
package com.example.hello.controller;
import com.example.hello.dto.UserRequest;
import org.springframework.web.bind.annotation.*;
import java.util.Map;
@RestController
@RequestMapping("/api/get")
public class GetApiController {
@GetMapping(path = "/hello") // http://localhost:port/api/get/hello
public String hello() {
return "GET HELLO";
}
@RequestMapping(path = "/hi", method = RequestMethod.GET) // GET http://localhost:port/api/get/hi
public String hi(){
return "hi";
}
// http://localhost:port/api/get/path-variable/{name}
@GetMapping("/path-variable/{name}")
public String pathVariable(@PathVariable(name="name") String pathName){
System.out.println("PathVariable : "+pathName);
return pathName;
}
// http://localhost:port/api/get/query-param?user=jun&email=jun@gmail.com&age=21
@GetMapping(path = "/query-param")
public String queryParam(@RequestParam Map<String,String> queryParams)
{
StringBuilder sb = new StringBuilder();
queryParams.entrySet().forEach( entry -> {
System.out.println(entry.getKey() + "=" + entry.getValue()+"\n");
sb.append(entry.getKey() + "=" + entry.getValue()+"\n");
});
return sb.toString();
}
@GetMapping(path = "/query-param2")
public String queryParam2(
@RequestParam String name,
@RequestParam String email,
@RequestParam int age
){
System.out.println(name + " " + age + " " + email);
return name + " " + age + " " + email;
}
@GetMapping(path = "/query-param3")
public String queryParam3(UserRequest userRequest){
System.out.println(userRequest.getName() + " " + userRequest.getAge() + " " + userRequest.getEmail());
return userRequest.toString();
}
}
controller로 사용할 클래스을 생성한다. 이 후 @RestController, @RequestMapping 어노테이션을 추가
1. @GetMapping
메소드에 @GetMapping를 추가하면 해당 메소드는 GET 방식으로 요청을 받는다.
인자의 기본값은 path이며, path = “stringValue” 사용 시 명시적으로 설정 가능
2. @RequestMapping
메소드에 @RequestMapping를 추가 시 모든 방식의 메소드로 요청을 받을 수 있음
필요에 따라 인자로 method = RequestMethod.GET 와 같이 사용할 **HTTP Method**를 직접 지정할 수 있다.
3. PathVariable
URI에서 변화 하는 값은 PathVariable로 지정하여 한 URI로 처리가 가능하다. 맵핑 어노테이션에서@GetMapping("/path-variable/{name}") 와 같이 **({)대괄호**로 감싸주면 PathVariable로 지정이 된다.
일반적으로 URI의 지정한 PathVariable와 메소드 안에서 사용할 변수명이 동일하게끔 사용하지만, 필요에 따라 @PathVariable(name="name") String pathName 와 같이 어노테이션 name 속성에 PathVariable을 지정하면 다른 변수명으로 사용이 가능하다.
4. QueryParam
URI중 ? 뒤에 key=value의 쌍을 말한다. 여러 개 일 경우 &를 구분자로 사용한다.
1. @RequestParam와 Map<String,String>을 이용하여 임의의 쿼리 파라미터를 받을 수 있다.
2. @RequestParam를 각각 지정하여 지정한 쿼리 파라미터만을 받을 수 있다.
3. DTO 클래스를 만들어 파싱할 쿼리 파라미터 관리할 수 있다. 이 때는 @RequestParam를 사용하지 않는다.
DTO(Data Transfer Object)는 프로세스 간 데이터를 전달하는 객체를 의미합니다. Spring에서는 주로 Controller와 Client 간의 데이터 교환을 위해 사용됩니다.
DTO의 특징:
- 순수하게 데이터를 저장하고 전달하는 목적으로만 사용
- 비즈니스 로직을 포함하지 않고 getter/setter 메서드만 포함
- 계층간 데이터 전달을 위한 객체로써 데이터 은닉과 캡슐화를 위해 사용
위 예제에서 UserRequest 클래스는 클라이언트로부터 받은 name, email, age 데이터를 담아 전달하는 DTO 역할을 수행합니다.
package com.example.hello.dto;
public class UserRequest {
private String name;
private String email;
private int age;
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "UserRequest{" +
"name='" + name + '\'' +
", email='" + email + '\'' +
", age=" + age +
'}';
}
}
POST API
JSON
JSON(JavaScript Object Notation)은 데이터를 쉽게 교환하고 저장하기 위한 텍스트 기반의 데이터 교환 표준입니다. 이는 자바스크립트의 객체 표기법에서 파생된 부분 집합으로, 인간이 읽고 쓰기 쉽고 기계가 분석하고 생성하기도 쉬운 경량 데이터 교환 형식입니다
JSON 구조
JSON 데이터는 **키-값 쌍**으로 구성되며, 중괄호 **`{}`**로 둘러싸여 표현됩니다. 여러 데이터는 쉼표 **`,`**로 구분됩니다
JSON 데이터 타입
JSON에서 사용할 수 있는 기본 데이터 타입은 다음과 같습니다:
- 숫자(number): 정수 또는 부동소수점 숫자로, 큰 따옴표 없이 사용됩니다.
- 문자열(string): 큰 따옴표로 묶여 사용됩니다.
- 불리언(boolean): true 또는 false로 표현됩니다.
- 객체(object): 중괄호 `{}`로 묶여 사용됩니다.
- 배열(array): 대괄호 `[]`로 묶여 사용됩니다.
- NULL: null로 표현됩니다
JSON 객체 예시
{
"name": "John",
"age": 30,
"city": "New York"
}
ObjectMapper
ObjectMapper는 Jackson 라이브러리의 핵심 클래스로, Java 객체와 JSON 간의 변환을 담당합니다. 이 클래스는 직렬화와 역직렬화 두 가지 주요 기능을 제공합니다.
1. 직렬화 (Serialization)
- Java 객체를 JSON으로 변환: `writeValueAsString()` 메서드를 사용하여 Java 객체를 JSON 문자열로 변환합니다. 이 과정은 객체의 필드를 JSON의 키-값 쌍으로 매핑합니다
2. 역직렬화 (Deserialization)
- JSON을 Java 객체로 변환: `readValue()` 메서드를 사용하여 JSON 문자열을 Java 객체로 변환합니다. 이 과정은 JSON의 키-값 쌍을 Java 객체의 필드로 매핑합니다. 기본 생성자를 통해 객체를 생성한 후, 리플렉션을 사용하여 필드에 값을 할당합니다
ObjectMapper를 사용하여 Java 객체를 JSON으로 변환할 때, 기본적으로는 camelCase로 변환됩니다.
동작 과정
1. JSON 파싱: JSON 데이터를 파싱하여 키-값 쌍을 추출합니다.
2. 객체 생성: 기본 생성자를 통해 빈 Java 객체를 생성합니다.
3. 리플렉션 사용: 리플렉션을 통해 객체의 필드를 탐색하고, JSON의 키와 일치하는 필드에 값을 할당합니다
4. 결과 반환: 완성된 Java 객체를 반환합니다.
package com.example.post.controller;
import com.example.post.dto.PostRequestDto;
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;
import java.util.Map;
@RestController
@RequestMapping("/api")
public class PostApiController {
@PostMapping("/post")
public void post(@RequestBody Map<String, Object> requestData) {
requestData.forEach((key, value) ->
System.out.println("key: " + key + " value: " + value));
}
@PostMapping("/post2")
public void post(@RequestBody PostRequestDto requestDto) {
System.out.println("requestDto: " + requestDto);
}
}
// 예제
{
"account" : "user1",
"email" : "jun@gmail.com",
"address" : "경기도 OO시",
"password" : "abcd",
"phone_number" : "010-1111-2222"
}
기본적으로 RequestBody를 파싱하기 위하여 @RequestBody 어노테이션을 추가해야한다.
1. Map<String, Object>
메소드에 @PostMapping를 추가하면 해당 메소드는 POST 방식으로 요청을 받는다.
JSON타입의 RequestBody를 파싱하기 위해 Map<String, Object>를 사용할 수 있다.
2. DTO 클래스
데이터 클래스를 만들어 RequestBody를 파싱할 데이터를 지정할 수 있다.
JSON 형태의 RequestBody를 ObjectMapper가 DTO 객체로 변환 할 때 JAVA 클래스 변수명은 카멜 케이스로 JSON은 스네이크 케이스로 되어 있어 제대로 동작하지 경우에는 @JsonProperty 어노테이션을 사용하여 변수와 매칭될 JSON Key값을 직접 지정할 수 있다.
package com.example.post.dto;
import com.fasterxml.jackson.annotation.JsonProperty;
public class PostRequestDto {
private String account;
private String email;
private String address;
private String password;
@JsonProperty("phone_number")
private String phoneNumber;
public String getAccount() {
return account;
}
public void setAccount(String account) {
this.account = account;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getPhoneNumber() {
return phoneNumber;
}
public void setPhoneNumber(String phoneNumber) {
this.phoneNumber = phoneNumber;
}
@Override
public String toString() {
return "PostRequestDto{" +
"account='" + account + '\'' +
", email='" + email + '\'' +
", address='" + address + '\'' +
", password='" + password + '\'' +
", phoneNumber='" + phoneNumber + '\'' +
'}';
}
}
PUT API
POST API와 방식이 유사하다.
package com.example.put.controller;
import com.example.put.dto.PutRequestDto;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/api")
public class PutApiController {
@PutMapping("/put")
public PutRequestDto put(@RequestBody PutRequestDto requestDto)
{
System.out.println(requestDto);
return requestDto;
}
}
package com.example.put.dto;
import com.fasterxml.jackson.databind.PropertyNamingStrategies;
import com.fasterxml.jackson.databind.annotation.JsonNaming;
@JsonNaming(value = PropertyNamingStrategies.SnakeCaseStrategy.class)
public class CarDto {
private String name;
private String carNumber;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getCarNumber() {
return carNumber;
}
public void setCarNumber(String carNumber) {
this.carNumber = carNumber;
}
@Override
public String toString() {
return "CarDto{" +
"name='" + name + '\'' +
", carNumber='" + carNumber + '\'' +
'}';
}
}
package com.example.put.dto;
import com.fasterxml.jackson.databind.PropertyNamingStrategies;
import com.fasterxml.jackson.databind.annotation.JsonNaming;
import java.util.List;
@JsonNaming(value = PropertyNamingStrategies.SnakeCaseStrategy.class)
public class PutRequestDto {
private String name;
private int age;
private List<CarDto> carList;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public List<CarDto> getCarList() {
return carList;
}
public void setCarList(List<CarDto> carList) {
this.carList = carList;
}
@Override
public String toString() {
return "PostRequestDto{" +
"name='" + name + '\'' +
", age=" + age +
", carList=" + carList +
'}';
}
}
{
"name":"jun",
"age" : 20,
"car_list": [
{
"name" : "BMW",
"car_number": "11가 1234"
},
{
"name" : "A4",
"car_number": "22가 3456"
}
]
}
DELETE API
삭제와 관련된 API 이며, 키 값이 제한적이기 때문에 보통 DTO 클래스를 따로 생성하진 않는다.
이미 삭제가 되어 있더라도 200 OK를 응답으로 내려준다.
package com.example.delete.controller;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/api")
public class DeleteApiController {
@DeleteMapping("/delete/{userId}")
public void delete(@PathVariable String userId, @RequestParam String account) {
System.out.println(userId);
System.out.println(account);
}
}'Spring' 카테고리의 다른 글
| ObjectMapper (0) | 2025.03.18 |
|---|---|
| Response 내려주기 (0) | 2025.03.18 |
| Decorator pattern(데코레이터 패턴) (0) | 2021.04.18 |
| Proxy pattern(프록시 패턴) (0) | 2021.04.16 |
| Adapter pattern(어댑터 패턴) (0) | 2021.04.16 |