본문 바로가기

국비필기노트/Spring

Spring_Spring의 Http요청 파라미터

JSP의 Servlet같은 경우는 매개변수로 HttpServletRequest를 메서드로 만들어서 파라미터를 설정하는 번거로운 방법을 진행해야했는데  스프링은 단순하게 처리가 가능하며 방법도 다양하다. 

 

 

*RequestParamController.java

 

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
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
package com.koreait.core.web.basic.request;
 
import java.io.IOException;
import java.util.Map;
 
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
 
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
 
import com.koreait.core.web.basic.dto.HelloData;
 
@Controller
public class RequestParamController {
 
    
        //버전1
        @RequestMapping("/request-param-v1")
        public void requestParamv1(HttpServletRequest request, HttpServletResponse response) 
throws IOException {
            String username = request.getParameter("username");
            int age = Integer.parseInt(request.getParameter("age"));
            
            System.out.println("username:" + username);
            System.out.println("age:" + age);
            response.getWriter().write("v1");
        }
        
        
        //버전2
        @ResponseBody
        @RequestMapping("/request-param-v2")
        public String requestParamv2(@RequestParam("username"String memberName,
                                     @RequestParam("age"int memberAge){
            
            System.out.println("username:" + memberName);
            System.out.println("age:" + memberAge);
        
            return "v2";
        }
        
        //버전3
        @ResponseBody
        @RequestMapping("/request-param-v3")
        public String requestParamv3(@RequestParam String username,
                                     @RequestParam int age){
            
            System.out.println("username:" + username);
            System.out.println("age:" + age);
        
            return "v3";
        }
        
        //버전4
        @ResponseBody
        @RequestMapping("/request-param-v4")
        public String requestParamv4(String username,int age){
            
            System.out.println("username:" + username);
            System.out.println("age:" + age);
        
            return "v4";
        }
        
        //버전5
        @ResponseBody
        @RequestMapping("/request-param-required")
        public String requestParamvRequired(@RequestParam(required = trueString username,
                                            @RequestParam(required = false) Integer age){
            
            System.out.println("username:" + username);
            System.out.println("age:" + age);
        
            return "Required";
        }
        
        //버전6
        @ResponseBody
        @RequestMapping("/request-param-default")
        public String requestParamvDefault(@RequestParam(required = true, defaultValue="guest"String username,
                                            @RequestParam(required = false, defaultValue="-1"int age){
            
            System.out.println("username:" + username);
            System.out.println("age:" + age);
        
            return "Default";
        }
        

        //버전7
        @ResponseBody
        @RequestMapping("/request-param-map")
        public String requestParamvMap(@RequestParam Map<String,Object> paramMap){
                                        
            System.out.println("username:" + paramMap.get("username"));
            System.out.println("age:" + paramMap.get("age"));
        
            return "Map";
        }
        
        //버전8
        //사용전
//        @ResponseBody
//        @RequestMapping("/request-param-v7")
//        public String modelAttrubuteV1(@RequestParam String username, @RequestParam int age) {
//            
//            HelloData helloData = new HelloData();
//            helloData.setUsername(username);
//            helloData.setAge(age);
//            
//            System.out.println("username: " + helloData.getUsername());
//            System.out.println("age: " + helloData.getAge());
//            
//            return "model-v7";
//        }
        
        //사용후
        @ResponseBody
        @RequestMapping("/request-param-v7")
        public String modelAttrubuteV1(@ModelAttribute HelloData helloData) {
                    
            System.out.println("username: " + helloData.getUsername());
            System.out.println("age: " + helloData.getAge());
            
            return "model-v7";
        }
        
                
}
 
cs
 
 
 

[버전1]

point 1. RequestParamController.java

 

Http처리를 위한 java파일을 따로 생성하고 역시 컨트롤러이기에 어노테이션을 붙혀준다.

point 2. @RequestMapping

get방식,post방식을 구분하지않고 뒤의 url이면 모든 매핑에 대한 요청을 해당 어노테이션이 붙은 메서드로 데이터를 가지고온다. 

point3. HttpServlet의 설정 간소화

 

HttpServletRequest를 받고싶다면 매개변수에 선언만 해주면 가지고 싶은 객체를 스프링이 알아서 담아준다. JSP에서 진행했던 Http를 위한 번거로운 작업들을 모두 생략해주는 것이다. 

 

point4. return이 없는 메서드

 

response에다가 "ok"라는 단어를 붙혀서 데이터를 던져주는 코드이다. 

 

return 이라는 반환타입이 없고 응답에 값을 직접 집어넣으면 스프링은 view를 조회하지않는다. 

스트링타입의 view가 있는 위치를 던져만 주면 viewresolver가 알아서 찾아왔는데 개발자가 응답메시지를 직접적으로 요청값을 넣고 반환타입이 설정하지 않으면 view조회 없이 단순히 응답결과를 화면에 출력해주게된다. 

 

[버전2]

point 1. @ ResponseBody

View조회를 무시하고 Http message Body에 직접 내용을 할당한다.

즉, 버전1의 response.getWriter()의 역할을 하는 어노테이션이다. 

차이점이 있다면 해당 어노테이션은 return값으로 데이터를 출력시키기때문에 void메서드에서는 사용이 불가능하다.

point 2. HttpServletResponse의 생략

 

 

기존에는 HttpServletRequest와  HttpServletResponse를 세트로 반드시 매개변수로 가져와야만했다. 

그런데 구현해야할 내용을 @ResponseBody로 처리를 하여 HttpServletResponse가 필요가 없다면 이를 지워줄 수 있다. 

 

JSP Servlet에서는 HttpServletRequest와  HttpServletResponse를 받아오는 그 자체를 강제 하고 개발자가 여러 클래스를 생성하여 이를 수정하고 값을 받아왔는데 스프링은 이러한 모든 작업을 백단에서 알아서 진행하기 때문에 선택적으로 매개변수를 받아올 수 있는 것이다. 

 

point 3. 선택적 매개변수

 

 

우리는 데이터를 받아올 때 지금까지 모든 Request를 통채로 받아왔다. 그러나 지금은 username과 age만 필요한 상황이다. 이 2가지를 위해 Request를 덩어리로 받아오는 것은 불필요하다. 

 

그래서 스프링은 @RequestParam을 통해서 username과 age만 특정하여 두가지만 받아오는 것을 가능하게하였다. 즉, ver1의 파란박스의 역할을 ver2에선 매개변수를 받아오면서 바로 처리를 해버리는 것이다.

 

 

[버전3]

 

 

ver2까지는 받아오는 request의 값과 이를 할당하는 변수 명이 username과 memberName으로 서로 달랐다. 그러나 이러한 변수명은 통일하는 것이 보통이며 스프링은 request로 받아오는 변수명과 그 값이 할당되는 변수명이 동일하다면 생략이 가능하게끔하여 코드를 몹시 간결하게 하였다.

 

 

[버전4]

 

 

String, int, Integer...등의 단순 타입이면 @RequestParam도 생략이 가능하다. 

그러나 너무 많은 것이 생략이 되어버리면 추후에 유지보수가 힘들 수 있기에 크게 권장되는 부분은 아니다.

 

 

[버전5]

 

 

username은 필수이고 age는 필수가 아닌 것으로 조절을 해주고 싶을 떄 defaultValue를 사용한다.

age가 Integer인 이유는 age는 필수값이 아니기에 null이 들어가야하는데 int는 null값이 들어올 수 없기에 Integer로 처리를 해주었다.

 

true면 필수적으로 파라미터값이 입력이 되어야하는 것이고 false면 생략이 가능하다.

 

프론트단에서 js로 검사를 마친 데이터를 다시 컨트롤러에서 체크를 한번 더 해야하는 이유는 명확하다.

 

예를들어 프론트단에서 컨트롤러로 데이터를 보낼 때 어떠한 데이터 손실이 있다면? 이런 오류는 아무도 예측할 수 없다. 그렇기에 최대한의 예방장치는 모두 해두어야한다. 

이렇게 촘촘하게 매개변수를 작성하면 최소한 홍길동에서 이순신으로 이름이 변경되는건 막진 못하더라도 홍길동이란 이름이 프론트단에서 백단으로 넘어올 때 소멸되는 데이터 손실 오류는 잡아낼 수 있기 때문에 이런 매개변수 작성법이 필수적이다. 

 

[버전6]

 

 

어떠한 기본값을 넣어주고 싶을 때는 defaultValue를 사용한다. 

빈 문자일 경우에는 기본값으로 username이 "guest", age가 -1이 되나 값을 넣어주면 해당 값이 파라미터로 넘어온다. 

 

[버전7]

 

파라미터를 Map으로도 받아올 수 있다.

 

[버전8]

 

*HelloData.java

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
package com.koreait.core.web.basic.dto;
 
import lombok.Getter;
import lombok.Setter;
 
//@Setter @Getter
public class HelloData {
    
    private String username;
    private int age;
    
        
}
 
cs

 

현재 실무에서 가장 많이 사용하고 있는 방법이다. 

우선 HelloData로 username과 age의 DTO를 만들어준다(lombok라이브러리를 사용하여 getter&setter를 생략해주었다.).

 

그리고 받아오는 매개변수를 @ModelAttribute를 사용해 helloData를 거치고 오는 것을 자동화할 수 있으며, 매개변수를 받아옴과 동시에 set을 진행하기때문에 기존의 파란박스는 사용의미가 없어져 생략이 가능하다.

 

 

@RequestParam과 @ModelAttribute를 무분별하게 생략할 경우 혼란이 발생할 수 있다. 

그래서 생략을 할 때 무엇을 생략할 것인지에 대한 기준을 정하는 것이 좋다.

 

  • @RequestParam: String, int, Integer같은 단순타입
  • @ModelAttribute: 나머지