[Spring Boot] 요청 데이터 처리 방법

k·2024년 2월 6일

spring boot

목록 보기
3/4

클라이언트에서 여러 방법으로 서버에 요청 데이터를 보낼 수 있다. 그러한 방식을 어떤 식으로 서버 내에서 받을 수 있는지에 대해서 간략하게 말해보려고 한다.

Query string을 통한 요청

먼저, Query string을 간단하게 무엇인지 먼저 간단하게 설명하려고 한다. 아래의 url을 먼저 보자.

http://localhost:8080/api/test?a=1

위를 보면 /api/test url로 서버에 요청하고, ?(물음표) 구분자를 통해서 쿼리 스트링을 추가 할 수 있다.

a=1은 key=value로 대응시킬 수 있으며, 서버에서는 key를 통해 value에 접근할 수 있다.

또한, 여러개의 쿼리스트링을 붙이고 싶다면, &(엔퍼센트)를 넣어서 구분하여 붙일 수 있다. 아래는 그 예시이다.

?a=1&b=2

그럼 이제 스프링 내에서 어떻게 쿼리스트링을 처리할 수 있는지 보자.

1. "?a=1" 처리 방법 (기본)

@RestController
@RequestMapping("/")
class TestController{
	public String getValueInQueryString(@RequestParam String a){
		return a;
	}
}

별다른 옵션을 주지않고 @RequestParam 을 선언하여 사용하게 되면, 변수명과 쿼리스트링 key대응되면, 해당 쿼리스트링의 value가 값으로 담기게 된다.

2. "?a=1" 처리 방법 - Key 를 명시적으로 선언

@RestController
@RequestMapping("/")
class TestController{
	public String getValueInQueryString(@RequestParam(name="a") String queryString){
		return queryString;
	}
}

이는 name 이라는 option을 "a"로 둬서, a에 해당하는 쿼리스트링 value를 queryString 변수에 담기게 한다.

3. "?a=1&b=2" 처리 방법 - 여러개의 쿼리스트링 처리

@RestController
@RequestMapping("/")
class TestController{
	public String getValueInQueryString(@RequestParam(name="a") String param1,@RequestParam(name="b") String param2){
    	
       //param1 과 param2를 사용하면 됨
        return "multiple querystring";
	}
}

위 처럼하면 a와 b 쿼리스트링이 param1, param2 에 대응되서 사용 할 수 있게 된다.

4. 경로가 존재하지 않을 때 - 기본 값 설정

이는 원하던 쿼리스트링이 있었는데, 이를 찾지 못했을 때, 이를 극복하기 위해서 사용된다.

기본값을 설정하여 오류가 생기지 않도록 하는 것이 주목적이다.

@RestController
@RequestMapping("/")
class TestController{
	public String getValueInQueryString(@RequestParam(name="a", defaultValue="hi") String param1){
    	
       	return param1;
	}
}

만약에, "a"가 존재하지 않으면, default Value가 a에 들어가게 된다.

즉, a="hi"가 된다. param1에는 hi가 들어가 있다.

?b=1을 보내게 되면, 이 또한 a가 없는 것이기 때문에, default Value가 param1에 들어오게 된다.

굳이 왜 이렇게 쓰는거야?

실제로 대응되는 key가 없으면 Bad Request로 간주하여 코드 내에 의도하지않은 결과를 초래할 수 있다.

이를 통해 코드 내에 오류를 방지하고 안정화 시킬 수 있다.

경로 변수를 통한 요청

먼저, 경로 변수(Path Variable)에 대해서 간단하게 설명하려 한다. 아래의 url을 보자.

http://localhost:8080/api/test/1234

엥? 별다른거 없어 보이는데?

그렇다. 경로변수는 그냥 url 상으로 보면 딱히 이상한 점을 발견하지 못한다.

이는 경로 상에 변수가 들어있기 때문이다.

/api/test/{variable}

위의 형태를 보면 1234가 경로 변수인 것을 한 눈에 알아 볼 수 있을 것이다.

경로 변수를 스프링 내에서 어떻게 처리할 수 있는지 보자.

1. /exam/hello 처리 (기본)


@RestController
@RequestMapping("/api")
class TestController{
	
    @GetMapping("/exam/{test}")
    public String getParam(@PathVariable String test){
        return test;
	}
    
}

test 변수에는 hello가 대응되어서 들어가게 된다.

2. /exam/hello1/hello2 - 여러개의 경로 변수가 있을 때

@RestController
@RequestMapping("/api")
class TestController{
	
    @GetMapping("/exam/{arg1}/{arg2}")
    public String getParam(@PathVariable(name="arg1") String a, @PathVariable(name="arg2") String b){
		//여기서 각 arg1, arg2에 대한 처리 작업을 하면된다.
		return "multiple test";
	}
    
}

명시적으로 arg1, arg2 를 지정하여 맵핑하여 여러개의 경로 변수일 때 위와 같이 처리 가능하다.

3. 경로가 존재하지 않을 때 - 기본 값 설정

위에 query String을 설명할 때 사용법과 비슷하기 때문에 추가적인 설명은 생략한다.

defaultValue를 운용하면 된다.

사용되는 경우만 말해주자면, /exam 에 요청을 했는데, /exam/{test} 에 맵핑 되어 컨트롤러가 진행되게 되었을 때 사용하면 된다.

이를 통해 예상치 못한 결과나 오류들을 사전에 방지하고 안정성을 확보할 수 있게 된다.

Body와 Header를 통한 요청

아마 가장 흔하게 많이 사용 되는 요청 방식이 아닐까 생각된다.

  • body를 통한 요청

    import lombok.Data;
    
    @Data
    public class MyDto {
        private String name;
        private int age;
    }

    먼저 @Data 어노테이션을 통해서 Dto를 만들어야한다.

    @Data, Dto에 대한 설명은 추후 블로그에 올라갈 예정이라서 생략하겠다.

    간단하게 생각해서 Dto라는 틀에 맞춰서 데이터를 받겠다. 정도로 생각하면 좋을 것 같다.

    DTO를 사용해서 본격적으로 body를 통한 요청을 받아보겠다.

    @RestController
    @RequestMapping("/api")
    public class MyController {
    
        @PostMapping("/example")
        public String example(@RequestBody MyDto myDto) {
            // 클라이언트로부터 전달된 JSON을 MyDto 객체로 변환하여 사용
            return "Received data: " + myDto.toString();
        }
    }

    아래와 같이 데이터를 보내면, @Requestbody 어노테이션이 있는 곳과 매칭이 되고, 해당 Dto 에 맞게 값이 들어간다.

    {
        "name":"kang",
        "age":25
    }
  • 헤더를 통한 요청

    @RestController
    @RequestMapping("/api")
    public class MyController {
    
        @GetMapping("/example")
        public String example(@RequestHeader("User-Agent") String userAgent) {
            // User-Agent 헤더 값을 사용
            return "User-Agent: " + userAgent;
        }
    }
    

    이미 존재하는 header에 접근하여 값을 가져와서 사용했다.

    인증에 관련된 게시글을 올릴 때, 추가적인 설명을 포함하겠다.

profile
You must do the things you think you cannot do

0개의 댓글