룽쓰의 개발도구

@ResponseBody와 @RequestBody는 무엇일까? 본문

개발 용어/React

@ResponseBody와 @RequestBody는 무엇일까?

디벨로퍼룽쓰 2021. 5. 18. 12:33

React를 공부하면서 가장 처음 막힌 부분이 이부분이다.

스프링부트에서는 객체라는 개념이 있는데 HTML로 이루어진 react에서는 객체라는 개념이 아니다.

물론, 일반 html에서는 객체라는 개념이 전혀 없는 것 같지만 react에서는 let user{username,password...}를 통해 객체처럼 사용할 수 있는 개념이 존재한다. 하지만 엄연히 말하면 객체는 아니다. 

리액트는 HTML

스프링은 객체

 

 

그럼 스프링부트에서 리액트로 그리고 리액트에서 스프링부트로 데이터를 넘길 때 어떻게 해야하는 것일까?

먼저, 리액트에서 스프링부트로 데이터를 넘길 때 주의해야할 점을 알아보자.

 

[ form을 통한 회원가입 데이터 전송 ]

<from style={fromContainer}>
	<TextField type="text" placeholder="please input your username" fullWidth margin="normal" name="username" value={this.state.username} onChange={this.onChange} />
	<TextField type="password" placeholder  ="plase input your password" fullWidth margin="normal" name="password" value={this.state.passowrd} onChange={this.onChange} />
	<TextField  placeholder="please input your first name" fullWidth margin="normal" name="firstName" value={this.state.firstName} onChange={this.onChange} />
	<TextField  placeholder="please input your last name" fullWidth margin="normal" name="lastName" value={this.state.lastName} onChange={this.onChange} />
	<TextField type="number" placeholder="plase input your age" fullWidth margin="normal" name="age" value={this.age} onChange={this.onChange} />                  
	<TextField type="number" placeholder="plase input your salary" fullWidth margin="normal" name="salary" value={this.state.salary} onChange={this.onChange} />
	<Button variant="contained" color="primary" onClick={this.saveUser}>Save</Button>
</from>

사용자가 데이터를 모두 입력하고 나서 Save버튼을 누르게되면 onClick안에 있는 saveUser메소드가 실행되게 된다.

 

 

[ saveUser 메소드 ]

 

   saveUser = (e) => {
        e.preventDefault();

        let user = {
            username : this.state.username,
            password : this.state.password,
            firstName : this.state.firstName,
            lastName : this.state.lastName,
            age : this.state.age,
            salary : this.state.salary
        }

        ApiService.addUser(user)
        .then(res => {
            this.setState({
                message : user.username + '님이 성공적으로 등록되었습니다.'
            })
            console.log(this.state.message);
            this.props.history.push('/users');
        })
        .catch( err =>{
            console.log('saveUser() 에러', err);
        });

    }

단계적으로 설명을 하려고 한다.

  •  1) 버튼이 눌려서 saveUser메서드가 실행된다.
  •  2) 만약 false라면 기본동작인 form의 submit을 실행하지 않는다.
  •  3) let을 통해 user를 하나 만들게되는데 그 안에서 사용할 변수들은 사용자가 넣은 변수를 집어넣게 된다. -> 결과적으로 사용자 입력값이 들어있는 user가 하나 완성된다.
  •  4) 그 user를 axios를 적용해둔 addUser메서드를 실행시킨다.

 

 

[ ApiService.addUser(user) ]

import axios from 'axios';

const USER_API_BASE_URL = "http://localhost:8080/users";

class ApiService {
    addUser(user){
        return axios.post(USER_API_BASE_URL, user);
    }
}

export default new ApiService();
  •  5) addUser는 axios.post로 http://localhost:8080/users에다가 4번에서 받은 사용자 데이터를 전달하게 된다.

 

** 핵심 **

여기서 오늘의 주제가 나온다. react에서 아무리 객체형태의 user를 전달했더라도 결국 값은 객체가 아니기 때문에 스프링부트에서 받아낼 때는 변환을 해줘야 한다.

 

[ 인텔리제이의 Controller ]

@RequestMapping("/users")
public class UserController {
  @Autowired
  UserMapper userMapper;

  @PostMapping
  void insertUser(@RequestBody UserVO user){
    userMapper.insertUser(user);
    System.out.println("유저 DB 저장 성공");
  }
}
  •  6) 스프링부트에서는 react에서 사용자가 요청한 url을 controller로 받아온다.
  •  7) 그 안에서 여러개의 매핑방식 중에 Post방식으로 값을 넘겼기 때문에 @PostMapping부분에서 받아올 수 있게 된다. 포스트매핑 아래 부분은 따로 호출해서 실행시키는 것이 아닌 react에서 넘어올 때 post라고 넘어오면 바로 실행되는 메서드다.
  •  8) 5번에서 넘겨줄 때 return axios.post(USER_API_BASE_URL, user); 부분이 있다. 즉, 이 주소값으로 데이터를 넘겨줄 예정인데 user도 같이 넘겨줄거야! 라는 말이 된다.
  •  9) 5번에서 넘겨준 user를 @RequestBody로 받아온다. html형식의 데이터를 UserVO user에 넣는 과정이다.
  •  10) 그 user객체를 통해서 insertUser 메서드를 실행시키게 된다.

 

 

사실상 @ResponseBody는 스프링부트의 객체를 다시 html로 변경시키는 방법이다. 하지만 리액트에서는 기본적으로 지원해주기 때문에 따로 @ResponseBody를 사용하지 않아도 된다.