[포스코x코딩온] 웹개발자 풀스택 부트캠프8기
[포스코x코딩온] API 만들기(Get, Post, Axios 사용법)
항상 발전하는 개발자
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;
}
총 정리
- 일반 폼 전송 시
- RequestParam : Get과 Body 둘 다 가능
- ParamVariable : Get만 가능
- DTO 이용 - 일반 폼 전송
- Get 전송 가능
- Post 전송 - RequestBody가 없을 경우 가능
- Post 전송 - RequestBody가 있을 경우 실패
- VO 이용 - 일반 폼 전송
- Get 전송 Null
- Post 전송 - RequestBody가 없을 경우 Null
- Post 전송 - RequestBody가 있을 경우 실패
- Axios 이용 - DTO
- Get 일반 : 가능
- Get DTO : 가능
- Post 일반 : 실패
- Post DTO - RequestBody가 없을 경우 : Null
- Post DTO - RequestBody가 있을 경우 : 가능
- 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