ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [포스코x코딩온] API 만들기(Get, Post, Axios 사용법)
    [포스코x코딩온] 웹개발자 풀스택 부트캠프8기 2023. 11. 1. 11:24
    728x90

    API(Get, Post)

    GET 방식

    • Get method의 URL을 받을 때는 Controller에서 @GetMapping(url)을 이용해야 한다.
    @GetMapping(url주소)
    public String 함수이름() {
    	return 템플릿 파일 명;
    }

    (get) ?key=value

    • ?key=value 형태로 url이 넘어올 때 Controller에서 받는 방법은 @RequestParam 이용하기
    @GetMapping(url주소)
    public String 함수이름(@RequestParam(value="key") String key){
    	return 템플릿 파일명;
    }
    • 이때, key라는 변수에 ?key=value로 넘어온 value 값이 들어간다.
    • @RequestParam에 required값을 설정하면 없어도 실행된다.

    (get) ~/{value}

    • ~/{value} 형태로 url이 넘어올 때 Controller에서 받는 방법은 @PathVariable 이용하기
    @GetMapping(url주소/{value})
    public String 함수이름(@PathVariable String value){
    	return 템플릿 파일명;
    }
    • 이때, value 라는 변수에 url로 넘어온 값이 담긴다.
    • 만약, 이름을 다르게 설정하고 싶으면
    @GetMapping(url주소/{value}/{value2})
    public String 함수이름(@PathVariable String value, @PathVariable("value2") String abc){
    	return 템플릿 파일명;
    }
    • value2 위치에 넘어온 값이 abc라는 변수에 담기게 된다.

    • Controller.java
        @GetMapping("/introduce/{name}")
        public String introduce(@PathVariable String name, Model model){
            model.addAttribute("name", name);
            return "practice";
        }
        @GetMapping("/introduce2")
        public String introduce2(@RequestParam String name, @RequestParam String age, Model model){
            model.addAttribute("name", name);
            model.addAttribute("age",age);
            return  "practice";
        }
    • practice.html
    <!DOCTYPE html>
    <html lang="en" xmlns:th="http://www.thymeleaf.org">
    <head>
        <meta charset="UTF-8">
        <title>practice</title>
    </head>
    <body>
    <p th:text="'내 이름은 ' + ${name}">.</p>
    <p th:text="'내 나이는 ' + ${age}">.</p>
    </body>
    </html>


    POST 방식

    • Post method의 URL을 받을 때는 Controller에서 @PostMapping(url)을 이용해야 한다.
    @PostMapping(url주소)
    public String 함수이름(){
    	return 템플릿 파일명;
    }

    • Controller.java
    package codingon.kdt.kdt8.controller;
    
    import org.springframework.stereotype.Controller;
    import org.springframework.ui.Model;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.PathVariable;
    import org.springframework.web.bind.annotation.PostMapping;
    import org.springframework.web.bind.annotation.RequestParam;
    
    @Controller
    public class PracticeController {
        @GetMapping("/practice")
        public String main(){
            return "practice_form_request_231031";
        }
        @PostMapping("/post/signup")
        public  String signup(@RequestParam String name, @RequestParam String gender,
        @RequestParam String year,@RequestParam String month,@RequestParam String day,
        @RequestParam String hobby, Model model){
            model.addAttribute("name",name);
            model.addAttribute("gender", gender);
            model.addAttribute("year", year);
            model.addAttribute("month",month);
            model.addAttribute("day", day);
            model.addAttribute("hobby", hobby);
            return "practice_form_post_231031";
        }
    }
    • practice_form_request_231031.html
      • 사용자 값을 입력 받는 곳. (/practice일 때 열리는 곳)
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    <div>
        <form action="/post/signup" method="post">
        <p>이름<input type="text" name="name"></p>
        <br>
        <p>성별<input type="radio" value="남자" name="gender">남자 <input type="radio" value="여자" name="gender">여자</p>
        <br>
        <p>생년월일
            <select name="year">
                <option>1990</option>
                <option>1992</option>
                <option>1993</option>
                <option>1994</option>
                <option>1995</option>
                <option>1996</option>
                <option>1997</option>
                <option>1998</option>
                <option>1999</option>
                <option>2000</option>
        </select>년
        <select name="month">
            <option>1</option>
            <option>2</option>
            <option>3</option>
            <option>4</option>
            <option>5</option>
            <option>6</option>
            <option>7</option>
            <option>8</option>
            <option>9</option>
            <option>10</option>
            <option>11</option>
            <option>12</option>
        </select>월
        <select name="day">
            <option>1</option>
            <option>2</option>
            <option>3</option>
            <option>4</option>
            <option>5</option>
            <option>6</option>
            <option>7</option>
            <option>8</option>
            <option>9</option>
            <option>10</option>
            <option>11</option>
            <option>12</option>
            <option>13</option>
            <option>14</option>
            <option>15</option>
            <option>16</option>
            <option>17</option>
            <option>18</option>
            <option>19</option>
            <option>20</option>
            <option>21</option>
            <option>22</option>
            <option>23</option>
            <option>24</option>
            <option>25</option>
            <option>26</option>
            <option>27</option>
            <option>28</option>
            <option>29</option>
            <option>30</option>
        </select>일</p>
        <br>
        <p>관심사<input type="checkbox" value="여행" name="hobby">여행
            <input type="checkbox" value="패션" name="hobby">패션
            <input type="checkbox" value="음식" name="hobby">음식</p>
        <br>
        <button type="submit">회원가입</button>
        </form>
    </div>
    </body>
    </html>
    • practice_form_post_231031.html
    <!DOCTYPE html>
    <html lang="en" xmlns:th="http://www.thymeleaf.org">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    <p th:text="'이름: ' + ${name}"></p>
    <p th:text="'성별: ' + ${gender}"></p>
    <p th:text="'생년월일: ' + ${year} + '-'+ ${month}+ '-' + ${day}"></p>
    <p th:text="'관심사: ' + ${hobby}"></p>
    </body>
    </html>


    API로 이용하기

    • 앞에서 배운 방식으로 return을 이용해 Template view를 무조건 불러왔다.
    • 하지만, API로만 데이터를 전달할 수도 있다.
    • @ResponseBody를 이용하면 된다.
    @GetMapping("response-string")
    @ResponseBody
    public String getString(@RequestParam("name") String name){return "hello" + name;}
    • Node.js에서의 res.send()와 동일하다고 생각해도 된다.

    DTO 이용하기

    • request.html
    <h2>DTO 이용하기</h2>
    <div style="display: flex">
        <form action="/dto/response1" method="get" style="margin-right: 20px;">
            <h3>Get - DTO</h3>
            이름 : <input type="text" name="name">
            <br>
            나이 : <input type="text" name="age">
            <br>
            <button type="submit">GET 전송</button>
        </form>
        <form action="/dto/response2" method="post" style="margin-right: 20px;">
            <h3>Post - DTO</h3>
            이름 : <input type="text" name="name">
            <br>
            나이 : <input type="text" name="age">
            <br>
            <button type="submit">Post 전송 ( RequestBody x )</button>
        </form>
        <form action="/dto/response3" method="post" style="margin-right: 20px;">
            <h3>Post - DTO</h3>
            이름 : <input type="text" name="name">
            <br>
            나이 : <input type="text" name="age">
            <br>
            <button type="submit">Post 전송 ( RequestBody O )</button>
        </form>
    </div>
    • UserDTO.java
      • get, set 함수를 만들어줘야 한다.
    package codingon.kdt.kdt8.dto;
    
    
    public class UserDTO {
        private String name;
        private String age;
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public String getAge() {
            return age;
        }
    
        public void setAge(String age) {
            this.age = age;
        }
    
    }
    • MainController.java
      • @RequestBody를 사용했을 때만 오류가 발생한다.
      • @RequestBody는 json 이나 xml 데이터 형식을 읽기 때문이다.
      • 즉, 일반 폼 Get 방식 DTO(@ModelAttribute)로 전송을 해야한다.
        @GetMapping("/dto/response1")
        @ResponseBody
        public String dtoAPI1(@ModelAttribute UserDTO userDTO){
            //ModelAttribute: html 폼 데이터를 컨트롤러로 전달할 때 사용. get이나 post 전송에서 사용
            String msg = userDTO.getName() +" "+ userDTO.getAge()+"!!!!";
            return msg;
        }
        //일반 폼 Get 방식 - DTO(@ModelAttribute) 전송 가능
        //일반 폼 Get 방식 - DTO(@RequestBody) 오류 발생
    
        @PostMapping("/dto/response2")
        @ResponseBody
        public String dtoAPI2(UserDTO userDTO){
            String msg = userDTO.getName() + " " + userDTO.getAge() + "!!!";
            return msg;
        }
        @PostMapping("/dto/response3")
        @ResponseBody
        public String dtoAPI3( @RequestBody UserDTO userDTO){
            //RequestBody : json 또는 xml 데이터 형식을 읽는다.(axios)
            //일반 폼 전송 시 데이터 형식은 기본값으로 x-www-form-urlencoded
            String msg = userDTO.getName() + " " + userDTO.getAge() + "!!!";
            return msg;
        }

    Axios-DTO 이용하기

    • request.html
    <script>
        function dtoResponse1() {
            var form = document.getElementById('form_dto1');
            axios.get(`/axios/response1?name=${form.name.value}&age=${form.age.value}`)
            .then((res)=>{
                console.log( res );
                console.log( 'dtoResponse1 : ', res.data );
            });
        }
        function dtoResponse2() {
            var form = document.getElementById('form_dto1');
            axios.get(`/axios/response2?name=${form.name.value}&age=${form.age.value}`)
            .then((res)=>{
                console.log( res );
                console.log( 'dtoResponse2 : ', res.data );
            });
        }
        function dtoResponse3() {
            var form = document.getElementById('form_dto2');
            axios.post(`/axios/response3`, {name: form.name.value, age: form.age.value})
            .then((res)=>{
                console.log( res );
                console.log( 'dtoResponse3 : ', res.data );
            });
        }
        function dtoResponse4() {
            var form = document.getElementById('form_dto2');
            axios.post(`/axios/response4`, {name: form.name.value, age: form.age.value})
            .then((res)=>{
                console.log( res );
                console.log( 'dtoResponse1 : ', res.data );
            });
        }
        function dtoResponse5() {
            var form = document.getElementById('form_dto2');
            axios.post(`/axios/response5`, {name: form.name.value, age: form.age.value})
            .then((res)=>{
                console.log( res );
                console.log( 'dtoResponse5 : ', res.data );
            });
        }
    </script>
    
    <br>
    <hr>
    <h2>DTO 이용하기 - axios</h2>
    <div style="display: flex">
        <form action="/axios/response1" method="get" style="margin-right: 20px;" id="form_dto1">
            이름 : <input type="text" name="name">
            <br>
            나이 : <input type="text" name="age">
            <br>
            <button type="button" onclick="dtoResponse1();">GET ( 일반 ) - axios</button>
            <button type="button" onclick="dtoResponse2();">Get ( DTO ) - axios</button>
        </form>
        <form action="/axios/response3" method="post" style="margin-right: 20px;" id="form_dto2">
            <h3>Post ( 일반 ) - axios</h3>
            이름 : <input type="text" name="name">
            <br>
            나이 : <input type="text" name="age">
            <br>
            <button type="button" onclick="dtoResponse3();">Post ( 일반 ) - axios</button>
            <button type="button" onclick="dtoResponse4();">Post ( DTO ) - axios ( RequestBody X )</button>
            <button type="button" onclick="dtoResponse5();">Post ( DTO ) - axios ( RequestBody O )</button>
        </form>
    </div>
    • MainController.java
      • axios로 값을 전달하게 되면 파라미터로 값이 들어오지 않는다. 이 상태에서 @RequestParam으로 값을 전달 받으면 required의 기본값이 true이기 때문에 오류가 발생한다.
        @GetMapping("/axios/response1")
        @ResponseBody
        public String axiosResponse1(@RequestParam String name, @RequestParam String age){
            String msg = "이름: " + name + ", 나이: " + age;
            return msg;
        }
    
        @GetMapping("/axios/response2")
        @ResponseBody
        public String axiosResponse2(UserDTO userDTO){
            String msg = "이름: " + userDTO.getName() + ", 나이: "+ userDTO.getAge();
            return msg;
        }
    
        @PostMapping("/axios/response3")
        @ResponseBody
        //@RequstParam required 기본값이 true
        //axios로 값을 전달하게 될 경우 파라미터로 값이 들어오지 않는다.(Post로 보냈을 때)
        //값이 들어오지 않는데, @RequestParasm의 required가 기본값이 true이기 때문에 오류
        public String axiosResponse3(@RequestParam String name, @RequestParam String age){
            String msg = "이름: " + name + ", 나이: "+ age;
            return  msg;
    
        }
    
        @PostMapping("/axios/response4")
        @ResponseBody
        public String axiosResponse4(UserDTO userDTO){
            String msg = "이름:" + userDTO.getName() + ", 나이: "+ userDTO.getAge();
            return msg;
        }
    
        @PostMapping("/axios/response5")
        @ResponseBody
        public String axiosResponse5(@RequestBody UserDTO userDTO){
            String msg = "이름:" + userDTO.getName() + ", 나이: "+ userDTO.getAge();
            return msg;
        }
        //@RequestParam @ModelAttribute : 매개변수(파라미터)로 전달된 친구들을 변환
        //@RequestBody: json 형태의 데이터 (데이터)

    VO 이용하기

    • request.html
    <h2>VO 이용하기</h2>
    <div style="display: flex">
        <form action="/vo/response1" method="get" style="margin-right: 20px;">
            <h3>Get - VO</h3>
            이름 : <input type="text" name="name">
            <br>
            나이 : <input type="text" name="age">
            <br>
            <button type="submit">GET 전송</button>
        </form>
        <form action="/vo/response2" method="post" style="margin-right: 20px;">
            <h3>Post - VO</h3>
            이름 : <input type="text" name="name">
            <br>
            나이 : <input type="text" name="age">
            <br>
            <button type="submit">Post 전송 ( RequestBody x )</button>
        </form>
        <form action="/vo/response3" method="post" style="margin-right: 20px;">
            <h3>Post - VO</h3>
            이름 : <input type="text" name="name">
            <br>
            나이 : <input type="text" name="age">
            <br>
            <button type="submit">Post 전송 ( RequestBody O )</button>
        </form>
    </div>
    • UserVO.java
      • VO의 경우에는 set 함수를 만들지 않는다.
    package codingon.kdt.kdt8.vo;
    
    public class UserVO {
        private String name;
        private String age;
    
        public String getName() {
            return name;
        }
    
        public String getAge() {
            return age;
        }
    }
    • MainController.java
      • set함수를 만들지 않음으로 null값이 발생한다.
        @GetMapping("/vo/response1")
        @ResponseBody
        public String voAPI1(UserVO userVO){
            String msg = userVO.getName() + " " + userVO.getAge() + "!!!";
            return msg;
        }

    Axios-VO 이용하기

    • request.html
    <script>
        function voResponse1() {
            var form = document.getElementById('form_vo1');
            axios.get(`/axios/vo/response1?name=${form.name.value}&age=${form.age.value}`)
            .then((res)=>{
                console.log( res );
                console.log( 'dtoResponse1 : ', res.data );
            });
        }
        function voResponse2() {
            var form = document.getElementById('form_vo1');
            axios.get(`/axios/vo/response2?name=${form.name.value}&age=${form.age.value}`)
            .then((res)=>{
                console.log( res );
                console.log( 'voResponse2 : ', res.data );
            });
        }
        function voResponse3() {
            var form = document.getElementById('form_vo2');
            axios.post(`/axios/vo/response3`, {name: form.name.value, age: form.age.value})
            .then((res)=>{
                console.log( res );
                console.log( 'voResponse3 : ', res.data );
            });
        }
        function voResponse4() {
            var form = document.getElementById('form_vo2');
            axios.post(`/axios/vo/response4`, {name: form.name.value, age: form.age.value})
            .then((res)=>{
                console.log( res );
                console.log( 'voResponse4 : ', res.data );
            });
        }
        function voResponse5() {
            var form = document.getElementById('form_vo2');
            axios.post(`/axios/vo/response5`, {name: form.name.value, age: form.age.value})
            .then((res)=>{
                console.log( res );
                console.log( 'voResponse5 : ', res.data  );
            });
        }
    </script>
    
    <br>
    <hr>
    <h2>VO 이용하기 - axios</h2>
    <div style="display: flex">
        <form id="form_vo1" style="margin-right: 20px;">
            <h3>Get ( 일반 ) - axios</h3>
            이름 : <input type="text" name="name">
            <br>
            나이 : <input type="text" name="age">
            <br>
            <button type="button" onclick="voResponse1();">GET ( 일반 ) - axios</button>
            <button type="button" onclick="voResponse2();">Get ( VO ) - axios</button>
        </form>
        <form id="form_vo2" style="margin-right: 20px;">
            <h3>Post ( 일반 ) - axios</h3>
            이름 : <input type="text" name="name">
            <br>
            나이 : <input type="text" name="age">
            <br>
            <button type="button" onclick="voResponse3();">Post ( 일반 ) - axios</button>
            <button type="button" onclick="voResponse4();">Post ( VO ) - axios ( RequestBody X )</button>
            <button type="button" onclick="voResponse5();">Post ( VO ) - axios ( RequestBody O )</button>
        </form>
    </div>
    • MainController.java
      • @RequestBody로 값을 전달하면 userVO에 setter 함수가 없어도 값이 들어간다.(필드에 내장된 set 함수를 실행한다.)
    @PostMapping("/axios/vo/response4")
        @ResponseBody
        public String axiosVoResponse4(UserVO userVO){
            String msg = "이름: "+ userVO.getName() + ", 나이: "+ userVO.getAge();
            return msg;
        }
    
        @PostMapping("/axios/vo/response5")
        @ResponseBody
        public String axiosVoResponse5(@RequestBody UserVO userVO){
            //@RequestBody로 값을 전달할때 userVO에 setter 함수가 없어도 값이 들어간다.
            //@RequestBody는 setter 함수 실행이 아니라 각각의 필드(변수)에 직접적으로 값을 주입하면서 매핑
            //@ModelAttribute가 setter 함수를 실행해 값을 넣어준다면
            //@RequestBody는 각각의 필드(변수)에 직접적으로 값을 주입한다. 필드에 내장된 set 함수를 실행
            String msg = "이름: "+ userVO.getName() + ", 나이: "+ userVO.getAge();
            return msg;
        }

    총 정리

    1. 일반 폼 전송 시
      • RequestParam : Get과 Body 둘 다 가능
      • ParamVariable : Get만 가능
    2. DTO 이용 - 일반 폼 전송
      • Get 전송 가능
      • Post 전송 - RequestBody가 없을 경우 가능
      • Post 전송 - RequestBody가 있을 경우 실패
    3. VO 이용 - 일반 폼 전송
      • Get 전송 Null
      • Post 전송 - RequestBody가 없을 경우 Null
      • Post 전송 - RequestBody가 있을 경우 실패
    4. Axios 이용 - DTO
      • Get 일반 : 가능
      • Get DTO : 가능
      • Post 일반 : 실패
      • Post DTO - RequestBody가 없을 경우 : Null
      • Post DTO - RequestBody가 있을 경우 : 가능
    5. Axios 이용 - VO
      • Get 일반 : 가능
      • Get DTO : 가능
      • Post 일반 : 실패
      • Post DTO - RequestBody가 없을 경우 : Null
      • Post DTO - RequestBody가 있을 경우 : 가능

    @RequestBody

    • View에서 Controller로 값을 전달할 때 HTTP Body 안에 JSON을 VO에 매핑시켜주는 Spring Annotation
    • IntroduceVO에는 Setter이 없음에도 값이 할당된다.
    728x90
Designed by Tistory.