관리 메뉴

bright jazz music

3. React에서 axios 사용하기(POST) 테스트 본문

Framework/ReactJs

3. React에서 axios 사용하기(POST) 테스트

bright jazz music 2023. 5. 22. 10:13

처음 화면
[데이터 보내기] 클릭 후 화면

1. App.js 작성

import axios from "axios";
import { useState, useEffect } from "react";

function NameAndAge(props) {
  if (props.data !== null) {
    // 입력받은 props.data 에서 직접 값을 가져오는 경우
    const name = props.data.name;
    const age = props.data.age;
    console.log("##name: " + name + ", ##age: " + age);
    console.log(
      typeof props.data.age,
      ": props.data.age와 그 값을 입력받은 age 모두 number 타입이다. "
    );

    console.log("#");

    //  props.data의 값들을 JSON.stringfy() 하는 경우. number 타입이 string 타입으로 바뀐다.
    const jsonName = JSON.stringify(props.data.name);
    const jsonAge = JSON.stringify(props.data.age);
    console.log("##jsonName: " + jsonName + ", ##jsonAge: " + jsonAge);
    console.log(
      typeof JSON.stringify(props.data.age),
      ": JSON.stringfy(props.data.age)와 그 값을 입력받은 jsonAge 모두 string 타입이다. "
    );
    console.log("#");

    // props.data의 값들을 Obect.values() 하는 경우. string, int 타입들이 모두 object 타입으로 바뀐다.
    const objectName = Object.values(props.data.name);
    const objectAge = Object.values(props.data.age);
    console.log("##objectName: " + objectName + ", ##objectAge: " + objectAge);
    console.log(
      typeof Object.values(props.data.age),
      ": Object.values(props.data.age)와 그 값을 입력받은 objectAge 모두 object 타입이다. string 타입에 대해서는 캐릭터를 나눠 표시하지만 number나 단일 값에 대해서는 value가 없기 때문에 값이 없다."
    );
    console.log("#");

    return (
      <div>
        <p>받은 데이터 name: {name}</p>
        <p>받은 데이터 age: {age}</p>

        <p>받은 데이터 jsonName: {jsonName}</p>
        <p>받은 데이터 jsonAge: {jsonAge}</p>

        <p>받은 데이터 objectName: {objectName}</p>
        <p>받은 데이터 objectAge: {objectAge}</p>
      </div>
    );
  }
}

function App() {
  const [data, setData] = useState(null);

  const sendData = () => {
    const requestData = { name: "John", age: 25 };
    axios
      .post("http://localhost:8080/axios/post", requestData)
      .then((response) => {
        console.log("###response.data ", response.data);
        setData(response.data);
      })
      .catch((error) => {
        console.error(error);
      });
  };

  return (
    <div>
      <button onClick={sendData}>데이터 보내기</button>
      {/* 에러발생: Objects are not valid as a React child (found: object with keys {name, age}). If you meant to render a collection of children, use an array instead. 
      객체를 JSX에서 직접 렌더링 하려고 할 때 발생하는 오류. 

      1. JSON.stringfy를 사용하여 객체를 문자열로 변환하여 출력할 수 있다. 또는
      2. Object.value() 를 사용하여 객체의 값을 배열로 변환한 후 출력할 수 있다. 이는 객체의 특성 속성을 렌더링해야 하는 경우 사용된다. */}

      {/* <p>받은 데이터: {data}</p> */}

      <p>받은 데이터: {JSON.stringify(data)}</p>

      {/* 아래와 같이 객체의 존재 여부를 확인하지 않고 표시하는 코드를 써버리면 
      Cannot convert undefined or null to object
      TypeError: Cannot convert undefined or null to object 에러가 발생한다.
      
      이는 undefined 또는 null 값을 객체로 변환하려고 할 때 발생한다.
      Object.keys(), Object.values(), Object.entries() 등의 메소드느 undefined 또는 null을 인자로 받지 않기 때문이다.

      이 경우 위처럼 if문을 사용하여 undefine 또는 null을 체크하고 값을 넣거나,
      또는 undefined 또는 null을 대체할 기본 객체를 만들어 놓는 방법을 사용하여 해결할 수 있다.
      
      <p>받은 데이터 name: {Object.values(data.name)}</p>
      <p>받은 데이터 age: {Object.values(data.age)}</p> */}

      <NameAndAge data={data}></NameAndAge>
    </div>
  );
}

export default App;

 

2. ReactAxiosPostController.java 작성

package com.project.base.controller;

import lombok.Builder;
import lombok.Data;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

@CrossOrigin(origins = "http://localhost:3000" )
@RequestMapping("/axios")
@RestController
public class ReactAxiosPostController {

    @PostMapping("/post")
//    public ResponseEntity<TestPerson> postTest(@RequestBody TestPerson reqData) {
    public TestPerson postTest(@RequestBody TestPerson reqData) {
        TestPerson testPerson = TestPerson.builder()
                .name(reqData.getName()+" OK!")
                .age(reqData.getAge() + 10)
                .build();
        System.out.println("###testPerson" + testPerson);

//        return ResponseEntity.status(HttpStatus.OK).body(testPerson);
        return testPerson;
    }

}

@Data
@Builder
class TestPerson{
    private String name;
    private int age;
}

 

4. ResponseEntity를 사용하여 응답하는 경우

위에서는 반환 시 TestPerson 객체를 직접 반환하였다.

이번에는 응답 타입과 반환부에 ResponseEntity<>를 사용하여 테스트한다.

package com.project.base.controller;

import lombok.Builder;
import lombok.Data;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

@CrossOrigin(origins = "http://localhost:3000" )
@RequestMapping("/axios")
@RestController
public class ReactAxiosPostController {

    @PostMapping("/post")
    public ResponseEntity<TestPerson> postTest(@RequestBody TestPerson reqData) {
//    public TestPerson postTest(@RequestBody TestPerson reqData) {
        TestPerson testPerson = TestPerson.builder()
                .name(reqData.getName()+" OK!")
                .age(reqData.getAge() + 10)
                .build();
        System.out.println("###testPerson" + testPerson);

        return ResponseEntity.status(HttpStatus.OK).body(testPerson);
//        return ResponseEntity.status(HttpStatus.NOT_FOUND).body(testPerson);
//        return ResponseEntity.status(HttpStatus.FORBIDDEN).body(testPerson);
//        return ResponseEntity.status(HttpStatus.SERVICE_UNAVAILABLE).body(testPerson);
//        return testPerson;
    }

}

@Data
@Builder
class TestPerson{
    private String name;
    private int age;
}

 

return ResponseEntity.status(HttpStatus.OK).body(testPerson); 인 경우 200코드로 기록되며 데이터가 화면에 표시된다.

 

 

백엔드 서버에서 HttpStatus.NOT_FOUND 를 반환했을 경우 404코드가 표시되며, 데이터가 화면에 표시되지 않는다. 물론 응답 바디에는 {"name":"John OK!","age":35}가 포함되어 있다.

 

HttpStatus.FORBIDDEN으로 설정한 경우 403코드가 표시된다. 데이터는 표시되지 않는다.&nbsp;물론 응답 바디에는 {"name":"John OK!","age":35}가 포함되어 있다.

 

HttpStatus.SERVICE_UNAVAILABLE 로 설정한 경우, 503 코드가 표시된다. 데이터는 표시되지 않는다.&nbsp;물론 응답 바디에는 {"name":"John OK!","age":35}가 포함되어 있다.

Comments