더미 데이터 update (Feat. Get요청/Post요청 데이터 형태)

myeonji·2022년 2월 15일
0

📍 Get 요청

📍 Post, Put, Delete 요청

  • Body에 데이터를 담아 보낸다.
  • x-www-form-urlencoded(form 태그를 만들어 전송) 일 때도 get처럼 key=value의 데이터 형태를 가진다.
  • form 태그 method="post" 로 하면 되지만, form 태그 같은 경우는 Get 요청과 Post 요청 밖에 할 수 없다. (Put과 Delete 불가능)
  • 따라서 데이터 형태는 json으로 통일하는 것이 좋다.
  • 이번 프로젝트 : 자바스크립트로 ajax 요청 + 데이터는 json으로 통일

Post가 x-www-form-urlencoded(form 태그를 만들어 데이터 전송) 으로 데이터를 담아 보낸다는 예시로 전략을 살펴보면, 데이터는 key=value 형태이다.

💡 스프링 컨트롤러의 파싱 전략 1 - 변수에 파싱

  • 스프링 컨트롤러는 key=value 데이터를 자동으로 파싱하여 변수에 담아준다.
PostMapping("/test")
public String test(String username, String email){
    return "test";
}

💡 스프링 컨트롤러의 파싱 전략 2 - 오브젝트로 파싱

  • 스프링 컨트롤러는 key=value 형태의 데이터를 오브젝트로 파싱해서 받아준다.
  • ⭐ 이 전략에서 주의할 점 : 해당 오브젝트에 setter가 있어야 한다.
PostMapping("/test")
public String test(User user){
    return "test";
}

🔥 key=value가 아닌 데이터 파싱 방법

  • json이나 일반 text 데이터 등등..
  • @RequestBody 어노테이션 사용
  • @RequestBody 어노테이션을 붙이면 MessageConverter가 작동하게 되는데 메세지를 컨버팅 할 때 기본 전략은 json이다.
{
    "username":"yj",
    "password":"123"
}

위의 형태가 json 데이터이다.
이런 형태는 스프링이 파싱해서 오브젝트로 받지 못한다.

따라서 @RequestBdoy를 붙여 MessageConverter 클래스를 구현한 Jackson 라이브러리가 동작하면 json 데이터를 자바 오브젝트로 파싱할 수 있게 된다.

PostMapping("/test")
public String home(@RequestBody User user){
    return "test";
}

본론 !!

업데이트(수정)을 하고자 한다.

	// email과 password만 수정 가능하도록 함
    // 기존의 email, password 불러오기
    @PutMapping("/dummy/user/{id}")
    public User updateUser(@PathVariable int id, @RequestBody User requestUser) { // json 데이터로 받기 위해 @RequestBdoy 사용 (<-> key=value 데이터는 @RequestBody 사용 X)
        // json 데이터 요청 -> Java Object : 스프링의 MessageConverter의 Jackson 라이브러리가 반환해서 받아줌.
        System.out.println("id:"+id);
        System.out.println("password:"+requestUser.getPassword());
        System.out.println("email:"+requestUser.getEmail());

        requestUser.setId(id);

        userRepository.save(requestUser); // save -> 만약 id가 이미 있다면 업데이트 역할을 함
        return null;
    }

이렇게 보내면 에러가 뜬다.

username이 null 값이라는 에러! User Entity에서 username을 notnull로 지정해놨는데,
password와 email만 수정했으므로 현재 requestUser에는 id, password, email만 들어가있는 상태가 되는 것이다.

🎃 방법 1

    // email과 password만 수정 가능하도록 함
    // 기존의 email, password 불러오기
    @PutMapping("/dummy/user/{id}")
    public User updateUser(@PathVariable int id, @RequestBody User requestUser) { // json 데이터로 받기 위해 @RequestBdoy 사용 (<-> key=value 데이터는 @RequestBody 사용 X)
        // json 데이터 요청 -> Java Object : 스프링의 MessageConverter의 Jackson 라이브러리가 반환해서 받아줌.
        System.out.println("id:"+id);
        System.out.println("password:"+requestUser.getPassword());
        System.out.println("email:"+requestUser.getEmail());

        User user = userRepository.findById(id).orElseThrow(()->{
            return new IllegalArgumentException("수정에 실패하였습니다.");
        });
        user.setPassword(requestUser.getPassword());
        user.setEmail(requestUser.getEmail());

        userRepository.save(user); // save -> 만약 id가 이미 있다면 업데이트 역할을 함
        return null;
    }

컨트롤러를 고쳐보았다.

id로 기존의 User 객체를 불러오고, 그 객체에 받아온 requestUser를 set 하는 방식을 사용했다.
그러면 기존의 User는 null이 없으므로 정상적인 수정이 가능할 것이다.

< save 함수의 역할 >

  • 역할 1. id를 전달하지 않으면 insert,
  • 역할 2. id를 전달하였는데 해당 id에 대한 데이터가 있으면 update,
  • 역할 3. id를 전달하였는데 해당 id에 대한 데이터가 없으면 insert

🎃 방법 2

    // email과 password만 수정 가능하도록 함
    // 기존의 email, password 불러오기
    @Transactional
    @PutMapping("/dummy/user/{id}")
    public User updateUser(@PathVariable int id, @RequestBody User requestUser) { // json 데이터로 받기 위해 @RequestBdoy 사용 (<-> key=value 데이터는 @RequestBody 사용 X)
        // json 데이터 요청 -> Java Object : 스프링의 MessageConverter의 Jackson 라이브러리가 반환해서 받아줌.
        System.out.println("id:"+id);
        System.out.println("password:"+requestUser.getPassword());
        System.out.println("email:"+requestUser.getEmail());

        User user = userRepository.findById(id).orElseThrow(()->{
            return new IllegalArgumentException("수정에 실패하였습니다.");
        });
        user.setPassword(requestUser.getPassword());
        user.setEmail(requestUser.getEmail());

        return null;
    }

save를 하지 않고 @Transactional 어노테이션을 추가하였다.
-> 정상 작동한다 !!

이 방법을 더티 체킹 이라고 한다.

0개의 댓글