Study/Spring

[Spring] form 태그와 JSON 형식을 이용한 요청

dev_kong 2023. 1. 4. 00:35
728x90
728x90

인텔리J 유료버전 기준으로 작성된 글 입니다
Java Version 11

 

[Spring] 스프링 부트 시작하기. Hello, World!와 이어지는 글입니다.

 

@RequestParam

회원 가입을 할 수 있는 간단한 form을 만들고,

 

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
<form method="post" action="http://localhost:8080/form">
    <ul>
        <li>
            <input type="text" name="userId" placeholder="아이디">
        </li>
        <li>
            <input type="text" name="userPw" placeholder="비밀번호">
        </li>
        <li>
            <button type="submit">제출</button>
        </li>
    </ul>
</form>
</body>
</html>

 

그리고 이 form.html을 /form 이라는 url에 get요청이 들어올 때 보여주자.

 

public class HelloController {
    @GetMapping("/")
    public String hello() {
        return "hello";
    }

    @GetMapping("/form")
    public String form() {
        return "form";
    }
}

 

이렇게 작성 해준 뒤,
서버를 한번 껐다 켜준 뒤에 localhost:8080/form 접속 해보면,

 

 

위와 같은 화면을 확인해 볼 수 있다.

 

대-충 아이디랑 비밀번호를 입력하고
제출 버튼을 갈기면,

 

 

당연하게도 에러페이지가 뜬다.

 

form태그가 submit 되면 요청이 전송 되는데,
요청 주소는 action 속성을, 요청 method는 method를 따른다.

 

즉, /form주소로 들어오는 post 요청을 받을 수 있게끔 route를 적용시켜야 한다.

 

@Controller
public class HelloController {
    @GetMapping("/")
    public String hello() {
        return "hello";
    }

    @GetMapping("/form")
    public String form() {
        return "form";
    }

    @PostMapping("/form")
    public String postForm(@RequestParam String userId, @RequestParam String userPw, Model model) {
        String message = String.format("아이디는 %s, 비밀번호는 %s 입니다.", userId, userPw);
        model.addAttribute("message", message);
        return "postForm";
    }
}

 

매우 쉽다.


Get route에는 @GetMapping 어노테이션을,
Post route에는 @PostMapping 어노테이션을 붙여주면 된다.

 

form태그를 통해 전달 된 값을 @RequestParam으로 받아서 message를 만들어주고,
message를 model을 통해 html 파일로 전달해주자.

 

model의 역할은 template engine 으로 값을 전달해주는 임시저장소의 역할을 한다.

 

return 값으로 postForm을 입력해주었으니,
postForm.html을 만들어 주면 된다.

 

<!doctype html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
    <span th:text="${message}"></span>
</body>
</html>

 

thymeleaf 를 사용하기 위해서는
항상 최상단 html 태그에 xmlns:th="..." 를 입력해주어야 한다.
또한 th:text="${...}" attribute를 통해 해당 태그의 innerHTML을 입력할 수 있다.

 

요런 식으로 만들어주고 서버를 돌려보자.

 

입력한 뒤 제출 버튼을 누르면,


위와 같은 화면이 뜨는 것을 확인 할 수 있다.

 

@RequestBody

위의 코드처럼 form태그를 이용하게 되면 HTTP header의 Content-type이 x-www-form-urlencoded로 지정 되는데,
요새는 잘 쓰여지진 않는다.

 

대세는 JSON 이다.
restAPI의 사용이 증가함에 따라, JSON 형식으로 데이터를 주고 받는게 국룰이다.

 

...
HTML 만드는게 너무 귀찮아서, 이후로는 PostMan을 이용하려고 한다.

 

이번에도 마찬가지로 post route를 적용 시킬거다.

 

@ResponseBody
@PostMapping("/jsonPost")
public String jsonPost(@RequestBody UserDto userDto) {
    String userId = userDto.getUserId();
    String userPw = userDto.getUserPw();
    return String.format("이름은 %s, 비밀번호는 %s 입니다.", userId, userPw);
}

 

/jsonPostpost 요청을 받을 수 있는 route이다.


기존의 코드와 다른 점이라면,
@ResponseBody 어노테이션이 추가됐다는 점과,
method의 인자값이 @RequestParam에서 @RequestBody로 바뀌었다는 점이다.

 

인자값에 들어간 DTO 객체는 아래와 같다.

 

public class UserDto {
    private final String userId;
    private final String userPw;

    public UserDto(String userId, String userPw) {
        this.userId = userId;
        this.userPw = userPw;
    }

    public String getUserId() {
        return userId;
    }

    public String getUserPw() {
        return userPw;
    }
}

 

JSON 형식으로 데이터를 전달 받으면,
@RequestBody로 선언된 Class(여기선 UserDto)로 생성되어 전달된다.

 

그리고 return에 들어가는 값이 Response Body에 포함되어 응답한다.

 

Postman을 통해 실행한 결과이다.

 

Response 객체를 커스텀하여 결과데이터를 던져주는 것이 더 효율적일거 같긴한데...
우선은 이 정도만 해보려고 한다.

728x90
728x90