2022/02/28 스프링 부트 시작하기

김석진·2022년 2월 28일
0

스프링입문

목록 보기
3/5

스프링 부트를 통해서 Controller를 통해서 원하는 내용을 내려줄 수 있다.
@RequestController 는 해당 클래스는 RESTAPI를 처리하는 컨트롤러라는 것을 알려주는 Annotation이고
@RequestMapping을 통해 URI를 지정하는 Annotation이다
@GetMapping

GET API

@GetMapping

@GetMapping(path="")를 통해서 주소를 명시적으로 알려주는 방법이 있다.

과거에는 @RequestMapping("")이런 방식으로 사용을 했었는데 이방식은 GET/POST/PUT/DELTE 를 모두 사용할 수 있어서 속성으로 지정을 해줘야한다

ex)
@RequestMapping(path="/hi",method = RequestMethod.GET)
이런식으로 하면 주소는 http://localhost:8080/hi 라는 주소를 GET method를 사용하겠다 라는 의미이다.

Path Variable를 사용하기

예를 들어 변화하는 값들을 주소에 받을 예정이다
http://localhost:8080/api/get/path-variable/{name}
어떤 사용자의 이름이 변화할 수 있기 때문에 Path Variable로 받을 수 있다.

    // http://localhost:8080/api/get/path-variable/{name}
    @GetMapping("/path-variable/{name}")
    public String pathVariable(@PathVariable String name){
        System.out.println("PathVariable : "+name);
        return name;
    }

Method의 파라미터에 받으려는 변화하는 값을 @PathVariable로 선언을 해주면된다.
주의할 점은 @GetMapping안에 중괄호({})안의 변수명과 @PathVariable로 선언한 변수명이 동일해야한다.
개발을 하면서 변수명이 달라질 수 있고 변수명을 같게 하지 않을 수도 있다.
그런경우 @PathVariable(name="")을 통해서 동일하게 세팅을 할 수 있다


    @GetMapping("/path-variable/{name}")
    public String pathVariable(@PathVariable(name="name") String pathName){
        System.out.println("PathVariable : "+pathName);
        return pathName;
    }

QueryParameter 받아보기

QueryParameter는 검색을 할 때 여러가지 매개변수인자를 이야기하는것이다.
주로 검색할 때 사용하는 것이다

형식

?key=value&key2=value2

@GetMapping(path = "query-param")
    public String queryParam(@RequestParam Map<String, String> queryParam) {
        StringBuilder sb=new StringBuilder();
        queryParam.entrySet().forEach(entry ->
                {
                    System.out.println(entry.getKey());
                    System.out.println(entry.getValue());
                    System.out.println();
                sb.append(entry.getKey()+"="+entry.getValue()+"\n");
            }
    );
    return sb.toString();
}
이렇게 매개변수에 queryParameter를 사용할 경우 @RequestParam이라는 애노테이션을 추가를 해야 제대로 들어감을 알 수 있다.
Map으로 매개변수를 queryParameter를 받을때는 어떤값이 들어올지몰라 하나하나 지정을 해야한다.

### QueryParameter를 이용해 명확히 값을 명시적으로 지정해서 GET하는 방법

@GetMapping("query-param2")
public String queryParam2(
@RequestParam String name,
@RequestParam String email,
@RequestParam int age
) {
System.out.println(name);
System.out.println(email);
System.out.println(age);
return name +" "+ email +" "+ age;
}

여기서도 문제가 생긴다. 변수가 지정이 되어 있을경우는 상관이없다
하지만 변수가 계속 추가가 된다면?이라는 문제점이 발생한다
Spring에서는 DTO형태로 매핑할 수 있도록 해준다

### QueryParameter를 DTO형태로 매핑하는 방법(현업에서도 자주 사용)
dto 패키지에 UserRequest라는 객체를 생성한다

public class UserRequest {

private String name;
private String email;
private int age;

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}

public String getEmail() {
    return email;
}

public void setEmail(String email) {
    this.email = email;
}

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 +
            '}';
}

}


    @GetMapping("query-param3")
    public String queryParam(UserRequest userRequest) {

        System.out.println(userRequest.getName());
        System.out.println(userRequest.getEmail());
        System.out.println(userRequest.getAge());

        return userRequest.toString();
    }

여기서는 @RequestParam이라는 애노테이션을 사용하지 않는다.
Spring에서 주소에 나오는 ?key=value&key2=value2에서 key와 value를 해당 객체에서 변수와 이름매칭을 해주게 된다.
이렇게 사용하면 변수가 추가된다거나 그럴때 객체에 들어가는 변수들을 추가하면 된다는 점에서 편리하게 수정이 가능하다.

POST API

JSON의 기본구조

JSON에서는 string,number,boolean,object,array형태가 올 수 있다.
JSON에서는 Snake case 단어의 구분마다 언더바(_) 를 사용하는 방법과 CamelCase를 사용하는방법을 사용한다

{
	"key": "value"
}

예제

{
	"phone_number" :"010-1111-2222"		//String
    "age" : 10,							//number
    "isAgree" : false,					//boolean
    "user" : {
    		"email" : "steve@gmail.com"
            "password" : "1234"
            },							//object
    "user_list" : [{},{},{},{}]			//array      
    		
}

POST 구현해보기

@RestController
@RequestMapping("/api/post")
public class PostApiController {

    @PostMapping()
    public void post(@RequestBody Map<String, Object> requestData) {

        requestData.forEach((key, value) -> {
            System.out.println("key : " + key);
            System.out.println("value : " + value);
        });
    }
}

POST의 경우에는 매개변수에 GET과 다르게 @RequestBody를 선언해 줘야 값들을 받을 수 있다.


값은 잘 들어옴을 알 수 있지만 어떤 값을 보낼지 다 알아야하므로 Map으로 받기는 애매한 상황이다.
값을 받을 수 있도록 DTO를 작성을 한다.

DTO를 작성하고 이를 이용한 POST 방식사용해보기

DTO

public class PostRequestDto {

    private String account;
    private String email;
    private String address;
    private String password;

    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;
    }

    @Override
    public String toString() {
        return "PostRequestDto{" +
                "account='" + account + '\'' +
                ", email='" + email + '\'' +
                ", address='" + address + '\'' +
                ", password='" + password + '\'' +
                '}';
    }
}

controller

@RestController
@RequestMapping("/api/post")
public class PostApiController {

    @PostMapping()
    public void post(@RequestBody PostRequestDto postRequestDto) {
        System.out.println(postRequestDto);
    }
}

결과


제대로 값이 객체를 통해서 들어온것을 확인할 수 있다.

PUT API

PUT

name,age(String)으로 받을예정이고 Car(array)로 받을예정이다.

{
	"name" : "steve"	,
    "age"  : "20" ,
    "car_list" : [
    	{
        	"name" : "BMW",
            "car_number" : "11가 1234"
        },
        {
            "name" : "A4",
            "car_number" : "22가 1234"
        }
        ]
   }

}

예제코드

dto

public class CarDto {

    private String name;
    @JsonProperty("car_number")
    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 + '\'' +
                '}';
    }
}
@JsonNaming(value = PropertyNamingStrategy.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 "PutRequestDto{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", carList=" + carList +
                '}';
    }
}

controller

@RestController
@RequestMapping("/api/put")
public class PutApiController {

    @PutMapping()
    public void put(@RequestBody PutRequestDto putRequestDto){
        System.out.println(putRequestDto);
    }
}

결과


DELETE API

DELETE

@RestController
@RequestMapping("/api/delete")
public class DeleteApiController {

    @DeleteMapping("/{userId}")
    public void delete(
            @PathVariable String userId,
            @RequestParam String account) {
        System.out.println(userId);
        System.out.println(account);
    }
}

실행결과

100
user100

Response 내려주기 및 모범사례

@RestController
@RequestMapping("/api")
public class ApiController {

    @GetMapping("/text")
    public String text(@RequestParam String account) {
        return account;

    }
}

을 실행시켜서 Query Parameter에 account(key), user100(value)를 추가하여 GET을 구동시키면 body에 Text형태의 user100이 response로 받아오게 되어있다
이렇게 사용하는 경우는 실무에서 거의 없을 것이다

제일 많이 사용하는 방법은 JSON이다

  //JSON
    @PostMapping("/json")
    public User json(@RequestBody User user) {
        return user;
    }

이렇게 해서

이렇게 실행을 시켜봤다 이결과 request body에 있는 값들을 obejct mapper가 object로 변형시켜 method 를 실행시키고 object가 리턴되어 object mapper를 통해
결과는 JSON 형태의 Response를 받을 수 있었다.

@Controller

@RestController와 다르게 @Controller 애노테이션은 HTML 리소스를 찾아 return 해주는 Controller이다.
여기서 반환값의 자료형을 String으로 한다면 자동으로 resource에 있는 html을 찾아가게되는데 이때 JSON을 어떻게 내려줄것인가? -> 해답은 ResponseEntity를 쓰는 방법과 @ResponseBody애노테이션을 이용한 방법이 있다.
@ResponseBody 애노테이션은 객체 자체를 리턴했을 때 리소스를 찾지않고 ResponseBody를 만들어서 내리겠다는 애노테이션이다.

    @ResponseBody
    @GetMapping("/user")
    public User user() {

        var user = new User();
        user.setName("steve");
        user.setAddress("패스트캠퍼스");
        return user;
    }

실행 결과

profile
주니어 개발자 되고싶어요

0개의 댓글