DevLog ๐ถ
[HTTP] GET vs POST, GET์ body ๊ฐ์ ๊ฐ์ง๋ฉด ์ ๋ ๊น? ๋ณธ๋ฌธ
๐ฑ ๋ค์ด๊ฐ๊ธฐ ์
์คํฐ๋๋ฅผ ์งํํ๋ฉด์, GET ์์ฒญ๊ณผ POST ์์ฒญ์ ์ฐจ์ด๊ฐ ๋จ์ํ '์๋ฏธ๋ก ์ '์ผ๋ก๋ง ์ฐจ์ด๊ฐ ์๋ ๊ฑด์ง ๊ถ๊ธํด์ ์ฐพ์๋ณด๊ฒ ๋์๋ค.
์ต๊ด์ ์ผ๋ก ๋๋ ๋ฆฌ์์ค ๋ฑ๋ก ์ POST๋ฅผ, ๊ทธ๋ฆฌ๊ณ ์กฐํ ์ GET์ ์ฌ์ฉํ์๋ค.
ํ์ง๋ง ๋ฆฌ์์ค ๋ฑ๋ก ์์๋ GET์ ์ฌ์ฉํ๋ ๊ฒ์ด ๋ฌธ๋ฒ์ ์ผ๋ก๋ ์ ๋๋ ๊ฑด์ง, ์๋๋ฉด ๊ด์ต์ ์ผ๋ก ์ฌ์ฉํ์ง ์๋ ๊ฒ์ธ์ง๋ ๊ถ๊ธํด์ ์ฐพ์๋ณด์๋ค. ๊ทธ๋ฆฌ๊ณ ๋ช ๊ฐ์ง ์์ฒญ๋ค์ ์ค์ตํด๊ฐ๋ฉฐ ์ด๋ ์ ๋ ์๊ฐ์ ์ ๋ฆฌํด๋์๋ค.
(์์ด ์๋ฌธ์ ๋ํ ๋ฒ์ญ์ ํ๋ค ๋ณด๋ ๋ค์ ์๋ฏธ์ ์ฐจ์ด๊ฐ ์์ ์๋ ์์ต๋๋ค ๐ฅฒ)
โ๏ธ GET
The GET method requests that the target resource transfer a representation of its state.
GET requests should only retrieve data and should have no other effect.
GET ๋ฉ์๋๋ ํ๊ฒ ๋ฆฌ์์ค๊ฐ ํด๋น ๋ฆฌ์์ค์ ์ํ๋ฅผ ํํํ๋ ๊ฒ์ ์ ์กํ๋๋ก ์์ฒญํ๋ ๊ฒ์ด๋ค.
GET ์์ฒญ์ ๋ฐ์ดํฐ๋ฅผ ๊ฒ์ํด์ผ ํ๋ฉฐ, ๋ค๋ฅธ ๋ถ์์ ํจ๊ณผ๊ฐ ๋ํ๋์ง ์๋๋ก ํด์ผ ํ๋ค.
์ฌ๊ธฐ์ 'retrieve data'๋ผ๋ ํํ์ด ์ฐ์๋๋ฐ, ์ด๋ DBMS์์ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ค๋ ๊ฒ์ ์๋ฏธํ๋ค.
= ๋ฐ์ดํฐ๋ฅผ ์ด๋ ํ ์ฟผ๋ฆฌ๋ฅผ ํตํด์ ๊ฐ์ ธ์ค๋ ํ์๋ฅผ ์๋ฏธํ๋ค.
๋ฆฌ์์ค์ ๋ณ๊ฒฝ ์์ด ๊ฒ์์ ํ ๋๋ URL์ ํตํด '๊ฒ์'ํ๋ GET ์์ฒญ์ด ๋ ์ ์ฉํ๋ค.
W3C (๊ตญ์ ์น ํ์ค ๊ธฐ๊ตฌ)์์๋ ๋ค์๊ณผ ๊ฐ์ด GET์ ์ ์ํ์๋ค.
Use GET if:
The interaction is more like a question. (i.e, it is a safe operation such as a query, read operation, or lookup)
๋ง์ฝ '์ง๋ฌธํ๋ ๊ฒ์ฒ๋ผ' ์ด๋ ํ ๊ฒ์ ๋ฌผ์ด๋ณผ ๋, read ์ฐ์ฐ์ ํ ๋ GET์ ์ฌ์ฉํ๋ผ๊ณ ํ์๋ค.
๊ทธ๋ฆฌ๊ณ , URI์ ์ด์ฉํด์ ์ ๋ณด๋ฅผ ์์ฒญํ๋ผ๊ณ ๋งํ๊ณ ์๋ค.
๊ธฐ๋ณธ์ ์ผ๋ก ์น ์ํคํ
์ฒ๋ RFC2396์ ์ํด ์ ์๋ URI๋ก ์์๋๋ค. Web์ Web๋ผ๋ฆฌ ์๋ก ์ฐธ์กฐํ๊ณ , ์ค๋ช
ํ๊ณ , ์ ๊ทผํ๊ณ , ๊ณต์ ํ ์ ์๋๋ก URI์ ๊ท์น์ ๋ฐ๋ฅด๊ฒ ๋๋๋ฐ, ๋ฆฌ์์ค์ ๋ํ URI๋ linking, bookmarking, caching ๋ฑ ๋ค์ํ ์ด์ ์ ์ค๋ค๊ณ ์๊ฐํ๋ค.
์ฌ๊ธฐ์ 'URI addressability'๋ผ๋ ๋จ์ด๋ฅผ ์๊ฐํ๋๋ฐ, ์ด๋ ํด๋ผ์ด์ธํธ๊ฐ ํน์ ํ์
์ ์ํธ์์ฉ์ ์ํํ๊ธฐ ์ํด์๋ URI๋ก๋ ์ถฉ๋ถํ๋ค๊ณ ๋งํ๋ค. ์ฆ, URI๋ง์ผ๋ก๋ ํต์ ํ๊ธฐ ์ถฉ๋ถํ๋ค๋ ์๊ฒฌ์ด๋ค. (๋ฌผ๋ก , ๋๋ ๋์ํ์ง ์๋๋ค ๐
)
By convention, when GET method is used, all information required to identify the resource is encoded in the URI
๋ํ, HTTP/1.1์์ GET์ ๊ฒ์ ์ด์ธ์ ๋์์ ์ํํ๋๋ก ํ์ง ์๋ ๊ฒ์ด ์ข๋ค๊ณ ์๊ฐํ๊ณ ์๋ค.
์ ์ด์ GET ์์ฒญ ์์ฒด๋ฅผ '์์ ํ ๋ฉ์๋'๋ผ๊ณ ํ๋จํ๋๋ฐ, ์์์ ๋จ์ํ ์ฝ๊ธฐ๋ง ํ๋ ๊ฒ์ด๊ธฐ ๋๋ฌธ์ ์๋ฒ์ ์ํฅ์ ๋ผ์น์ง ์๊ธฐ ๋๋ฌธ์ด๋ค.
ํ์ง๋ง, GET ์์ฒญ์ ๊ฒฝ์ฐ ๊ฒฐ๊ณผ์ ์ผ๋ก ํ์ํ ๋ชจ๋ ์ ๋ณด๊ฐ URI์ ๋ค์ด๊ฐ๊ธฐ ๋๋ฌธ์, ๋ณด์์ ์ธ ์ธก๋ฉด์์ ์๊ฐํด๋ณด์์ ๋ body์์ ๋ฐ์ดํฐ๋ฅผ ์ ๊ณตํ๋๋ก 'GET with BODY'๋ผ๋ ๊ฒ์ด ๋
ผ์๋๊ธฐ๋ ํ์๋๋ฐ ๊ธฐ๊ฐ๋์๋ค๊ณ ํ๋ค. (๋ฌผ๋ก ๊ณผ๊ฑฐ๋ค)
๊ทธ๋์ ์ด์ ๋ํด์ ๋ ์ฌ๋ฌ ๊ฐ์ง๋ฅผ ์ฐพ์๋ณด์๋ค.
๋ก์ด ํ๋ฉ์ด๋ผ๋ ์ฌ๋์ 'GET with BODY'์ ๋ํด์ ๋ค์๊ณผ ๊ฐ์ ์๊ฒฌ์ ๋จ๊ฒผ๋ค.
Yes. In other words, any HTTP request message is allowed to contain a message body, and thus must parse messages with that in mind. Server semantics for GET, however, are restricted such that a body, if any, has no semantic meaning to the request. The requirements on parsing are separate from the requirements on method semantics.
So, yes, you can send a body with GET, and no, it is never useful to do so.
This is part of the layered design of HTTP/1.1 that will become clear again once the spec is partitioned (work in progress).
๋ชจ๋ HTTP ์์ฒญ ๋ฉ์์ง๋ ๊ธฐ๋ณธ์ ์ผ๋ก message body๊ฐ ํฌํจ๋ ์ ์๋ค.
ํ์ง๋ง, 'GET'์ ๋ํด ์๋ฏธ๋ก ์ ์ธ ๊ด์ ์ผ๋ก ๋ณด์์ ๋, body๊ฐ ์๋ ๊ฒฝ์ฐ ์์ฒญ์ ๋ํด์ ๋ณ๋ค๋ฅธ ์๋ฏธ๊ฐ ์๋๋ก ์ ํ๋๋ค.
๊ทธ๋์ GET์ผ๋ก body๋ฅผ ๋ด์ ๋ณด๋ผ ์๋ ์์ง๋ง, ์ฌ์ค์ ์ข์ง ์์ ์ค๊ณ๋ผ๊ณ ๋งํ๋ค. (HTTP/1.1 ๊ธฐ์ค)
์ค์ ๋ก, HTTP/1.1 spec์ ๊ฐ๋ฉด ๋ค์๊ณผ ๊ฐ์ด ์ ์๋์ด ์๋ค.
The GET method means retrieve whatever information ([...]) is identified by the Request-URI
๊ฒฐ๊ณผ์ ์ผ๋ก GET ๋ฉ์๋๋ Request-URI๋ฅผ ํตํด ์๋ณ๋๋ ์ ๋ณด๋ฅผ ๊ฒ์ํ๋ ๊ฒ์ ์๋ฏธํ๋ค๋ ๊ฒ์ด๋ค.
ํ์ง๋ง, 2014๋
๋ถํฐ HTTP/1.1์ ๊ธฐ๋ณธ ์คํ์ด์๋ RFC2616์ด ์ ๊ฑฐ๋๊ณ , RFC 7230-7237๋ก ๋์ฒด๋์๋ค.
๊ธฐ์กด์ ์กด์ฌํ๋ "the message-body SHOULD be ignored when handling the request" ๋ผ๋ ๋ฌธ๊ตฌ๊ฐ ์ ๊ฑฐ๋๊ณ , ๋ค์๊ณผ ๊ฐ์ ๋ฌธ๊ตฌ๊ฐ ์ถ๊ฐ๋์๋ค.
๐ฑ Request message framing is independent of method semantics, even if the method doesn't define any use for a message body.
์์ฒญ ๋ฉ์์ง์ ๋ํ ํ๋ ์์ ์ด์ method์ ์๋ฏธ๋ก ์ ๊ด์ ๊ณผ ๋
๋ฆฝ์ ์ด๋ฉฐ, ํด๋น ๋ฉ์๋๊ฐ message body์ ๋ํด ์ ์ํ์ง ์๋๋ผ๋ ์๊ด์๋ค๋ผ๊ณ ๋์ ์๋ค. ๋ํ ์์ ์ธ๊ธํ๋ The GET method means retrieve whatever information ([...]) is identified by the Request-URI ์ ๋ํ ๋ถ๋ถ๋ ์ ๊ฑฐ๋์๊ธฐ ๋๋ฌธ์, ๊ฒฐ๊ณผ์ ์ผ๋ก ์๊ฐํด๋ณธ๋ค๋ฉด ์๋ฏธ๋ก ์ ๊ด์ ์์ ๋ณด์์ ๋๋ GET ์์ฒญ์ request body๊ฐ ๋ค์ด๊ฐ๋ ์๊ด์ด ์๋ค๋ ๊ฒ์ด๋ค.
ํ์ง๋ง, ์๊ด์ ์๋ค๋ง body๊ฐ ํน๋ณํ ์๋ฏธ๋ฅผ ๊ฐ์ง๋ ๊ฒ์ ์๋๋ค. RFC7231์์๋ ๋ค์๊ณผ ๊ฐ์ด ์ ์๋์ด ์๋ค.
A payload within a GET request message has no defined semantics;
sending a payload body on a GET request might cause some existing implementations to reject the request.
GET ์์ฒญ์ request message์๋ ์ ์๋ ์๋ฏธ๊ฐ ์๊ธฐ ๋๋ฌธ์, GET ์์ฒญ์ body๋ฅผ ๋ฃ์์ ๊ฒฝ์ฐ ๊ธฐ์กด์ ๊ตฌํ์ฒด์์๋ ์์ฒญ์ ๊ฑฐ๋ถํ ์๋ ์๋ค๋ ๊ฒ์ด๋ค.
์ค์ ๋ก ES์์๋ GET ์์ฒญ์์ body๋ฅผ ํ์ฉํ๋ ๊ฒฝ์ฐ๋ ์๋ค.
์ฌ๊ธฐ์๋ ๋ง์ฐฌ๊ฐ์ง๋ก RFC 7231์ ๋ด์ฉ์ ์ธ๊ธํ๋ฉฐ, GET with body๋ฅผ ํตํด ๊ฒ์ํ๋ ๊ฒ์ ์ ํธํ๋ค๊ณ ํ๋ค ๐
๊ทธ๋์ ๊ฒฐ๊ณผ์ ์ผ๋ก ๋๋ ์ด๋ ๊ฒ ๊ฒฐ๋ก ๋ด๋ ธ๋ค.
body์ ๋ฃ์ ์๋ ์๊ณ , ์ด๊ฒ ์ ์๋ ์ฌํญ์์๋ ์๋ฐ๋๋ ๊ฒ์ด ์๋๋ค.
๋ค๋ง, ๊ธฐ์กด์๋ ๊ธ์ง๊ฐ ๋์๋ ๊ฒ ์ผ๋ฐ์ ์ด๊ธฐ ๋๋ฌธ์ ๊ธฐ์กด ๊ตฌํ์ฒด๋ค์ ๊ฒฝ์ฐ body๋ฅผ ๋ด์ GET์ ๋ณด๋ด๋ฉด ๊ฑฐ์ ๋นํ ์๊ฐ ์๊ธฐ ๋๋ฌธ์ ์ ์คํ๊ฒ ์ฌ์ฉํ ํ์๊ฐ ์๋ค. (๋ํ, ํต์์ ์ผ๋ก ์ฌ๋๋ค์ด ์๊ฐํ๋ ๊ด๋
์ด ์๊ธฐ ๋๋ฌธ์ ์ฌ๋งํ๋ฉด ๋ฆฌ์์ค์ ์์ฒญ์ผ๋ก๋ง ์ฌ์ฉํ๋ ค๊ณ ํ๋ค)
โ๏ธ POST
The POST method requests that the target resource process the representation enclosed in the request according to the semantics of the target resource.
POST๋ ํ๊ฒ ๋ฆฌ์์ค๊ฐ ์์ฒญ์ ํํ๋ ๊ฒ์ ํ๊ฒ ๋ฆฌ์์ค์ ์๋ฏธ์ ๋ฐ๋ผ์ ์ฒ๋ฆฌํ๋ ๊ฒ์ ์๋ฏธํ๋ค.
RFC7231์์๋ ๋ค์๊ณผ ๊ฐ์ ์ํฉ์์ ์ฌ์ฉํ๋ผ๊ณ ๋งํ๋ค.
1. HTML form์ ์
๋ ฅํ ํ๋์ ๊ฐ๋ค์ ๋ํ ๋ฐ์ดํฐ๋ฅผ ์ ๊ณตํ ๋
2. ๊ฒ์ํ, ๋ฉ์ผ๋ง, ๋ธ๋ก๊ทธ ๊ฐ์ ๊ธ ๊ด๋ จ ๋ฉ์์ง๋ฅผ ์์ฑํ ๋
3. origin ์๋ฒ์์ ์๋ณ๋์ง ์์ ์๋ก์ด ๋ฆฌ์์ค๋ฅผ ์์ฑํ๋ ๊ฒฝ์ฐ
4. ์ด๋ฏธ ์กด์ฌํ๋ ๋ฆฌ์์ค์ ๋ํด์ ๋ง๋ถ์ผ ๋
์ ์๊ฐํด๋ณด๋ฉด, ๋ชจ๋ ๋ค '๋ฐ์ดํฐ๋ฅผ ์ ์กํ๋ค'๋ผ๋ ๊ด์ ์์ ์ฌ์ฉํ ์ ์๋ค.
POST ๋ฐฉ์์ ๊ฒฝ์ฐ request body ๊ฐ์ ๋ฐ์ดํฐ๋ฅผ ๋ฃ์ด์ ๋ณด๋ด๋ ๊ฒ์ด ์ผ๋ฐ์ ์ด๋ค.
ํ์ง๋ง, POST ๋ฐฉ์์ด๋๋ผ๋ ๋ฐ์ดํฐ ๊ฒ์์์ ์ฌ์ฉํ ์ ์๋ค.
๊ฒ์ ์กฐ๊ฑด์ด ๋งค์ฐ ๊น๋ค๋ก์์ URL์ ๋ถ์ฌ์ง ๋ฐ์ดํฐ๊ฐ ๋ง์์ง ๊ฒฝ์ฐ, POST๋ฅผ ๊ณ ๋ คํ ์ ์๋ค.
๊ธฐ๋ณธ์ ์ผ๋ก ๋ธ๋ผ์ฐ์ ๋ ์ฒ๋ฆฌํ ์ ์๋ URL์ ๊ธธ์ด๊ฐ ์ ํ์ด ์์ผ๋ฉฐ, ๋ณดํต ํ๋ผ๋ฏธํฐ๋ก ๋์ด๊ฐ ๊ฐ๋ค์ ์ธ์ฝ๋ฉ ์ ๊ธ์์๊ฐ ๋ ๋์ด๋๊ธฐ ๋๋ฌธ์ ๋ ์ฃผ์ํด์ผ ํ๋ค. Apache HTTP ์๋ฒ๋ ์ต๋ 4000์, Microsoft Internet Explorer๋ ์ต๋ 2048์๋ฅผ ์ฒ๋ฆฌํ ์ ์๋ค.
๋ํ, ์ฌ์ฉ์์ ์ด๋ฆ์ด๋ ๋น๋ฐ๋ฒํธ ๊ฐ์ ์ ๋ณด ๊ฐ์ด ๋ฏผ๊ฐํ ์ ๋ณด๋ URL๋ก ๋ณด๋ด์ง ์๋ ๊ฒ์ด ์ข๋ค.
HTTPS๋ฅผ ์ฌ์ฉํ๋๋ผ๋ ๋ธ๋ผ์ฐ์ ๊ธฐ๋ก์ด๋ ์น ์๋ฒ ๋ก๊ทธ์ ์ ์ฒด URL์ด ํฌํจ๋ ์ ์๊ธฐ ๋๋ฌธ์ ์ด๋ฐ ๊ฒฝ์ฐ ๋ณดํต POST๋ฅผ ์ฌ์ฉํ๋ค.
(๋จ, URL์ ๋ฐ์ดํฐ๊ฐ ๋
ธ์ถ๋์ง ์์์ผ๋ก ๋ณด์์ฑ์ ์ฆ๊ฐํ์ง๋ง ์บ์ฑ์ ๋์ง ์๋๋ค๋ ๊ฒ์ด ํน์ง์ด๋ค)
โ๏ธ GET with URI
๐ฑ GET - query Parameter
๋ง์ฝ GET ํตํด ๋ฆฌ์์ค๋ฅผ ๋ฑ๋กํ๊ณ ์ถ๋ค๋ฉด ์ฟผ๋ฆฌ ํ๋ผ๋ฏธํฐ๋ฅผ ํ์ฉํ ์ ์๋ค.
์ค์ต์ ์ํด ๊ฐ๋จํ html์ ๊ตฌ์ฑํ์๋ค.
๊ทธ๋ฅ ์ด๋ฆ์ด๋ ๋์ด ๋ฃ๊ณ ์ ์ถํ ์ ์๋ form์ด๋ค.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="/test" method="get">
์ด๋ฆ: <label>
<input type="text" name="name"/>
</label>
๋์ด: <label>
<input type="text" name="age"/>
</label>
์ ์ถํ๊ธฐ: <input type="submit", value="submit">
</form>
</body>
</html>
๊ทธ๋ฆฌ๊ณ , ์ด์ ๋์ํ๋ ์ปจํธ๋กค๋ฌ๋ฅผ ๋ง๋ค์ด๋ณด์.
@RestController
public class Controller {
@GetMapping("/test")
public void test(@RequestParam("name") String name, @RequestParam("age") int age) {
System.out.println("name = " + name);
System.out.println("age = " + age);
}
}
์ ๋ง ๊ฐ๋จํ ์ปจํธ๋กค๋ฌ์ด๋ค.
์ด์ ์์ฒญ์ ๋ ๋ ค๋ณด์. ์ด๋ค ์์ผ๋ก ๋์ํ๊ฒ ๋ ๊น?
submit์ ๋๋ฅด๋ฉด ์์ ๊ฐ์ด name๊ณผ age๋ผ๋ ์ฟผ๋ฆฌ ํ๋ผ๋ฏธํฐ๊ฐ ๋ถ์ ๊ฒ์ ํ์ธํ ์ ์๋ค.
๋ํ, ๊ฐ์ ๋ํ ๋ฐ์ธ๋ฉ ์ญ์ ์ ๋ ๊ฒ์ ๋ณผ ์ ์๋ค.
๐ฑ POST - query parameter
๋ง์ฝ, Post๋ก ์์ฒญ์ ๋ฐ๊พธ๋ฉด ์ด๋ป๊ฒ ๋ ๊น?
html ํ์ผ์ method ๋ถ๋ถ์ post๋ก ๋ฐ๊พธ๊ณ , ์ปจํธ๋กค๋ฌ ์ญ์ @PostMapping์ ํ์ฉํ๋๋ก ๋ฐ๊พธ์ด๋ณด์.
@PostMapping("/test")
public void test(@RequestParam("name") String name, @RequestParam("age") int age) {
System.out.println("name = " + name);
System.out.println("age = " + age);
}
์ด๋ฒ์๋ ์ ์ถํ๋๋ผ๋ ๋ณ๋ค๋ฅธ ์ฟผ๋ฆฌ ํ๋ผ๋ฏธํฐ๊ฐ ๋ถ์ง ์๊ฒ ๋๋ค.
ํ์ง๋ง ๊ฐ์ ๋ํ ๋ฐ์ธ๋ฉ์ ๊ฒฝ์ฐ ์ ๋๋ ๊ฒ์ ํ์ธํ ์ ์๋ค. ์ด ๊ฐ๋ค์ ์ด๋์ ์ ์ฅ๋ ๊ฑธ๊น?
์ฐ์ , request์ content-type์ ๋ณด๋ฉด x-www-form-urlencoded ํ์ ์ผ๋ก ์ง์ ๋ ๊ฒ์ ๋ณผ ์ ์๋ค.
๊ทธ๋ฆฌ๊ณ ํ์ด๋ก๋๋ฅผ ๋ณด๋ฉด ์์ ๊ฐ์ด form data๋ก ์ค์ ๋ ๊ฒ์ ํ์ธํ ์ ์๋ค!
application/x-www-form-urlencoded์ ๊ฒฝ์ฐ POST ์์ฒญ์ผ๋ก ์ฟผ๋ฆฌ ํ๋ผ๋ฏธํฐ๋ฅผ ์ฌ์ฉํ ๋ ์ ์ก๋๋ ํ์
์ด๋ผ๊ณ ๋ณผ ์ ์๋ค.
๊ทธ๋ ๋ค๊ณ ํด์ ์ฟผ๋ฆฌ ํ๋ผ๋ฏธํฐ๋ก ๋ณด๋ด๋ ๊ฒ๊ณผ ๋์ผํ ๊ฒ์ ์๋๋ค.
๋จ์ง, body ๊ฐ์ ์์ฒญ์ผ๋ก ๋ฃ์ ๋ content-type์ด application/x-www-form-urlencoded์ธ ๊ฒ๋ฟ์ด๋ค.
์ค์ ๋ก ์ค๋ํซ ๊ฐ์ ๊ฒฝ์ฐ๋ ์์ ๊ฐ์ด body ๊ฐ์ key-value ํ์์ผ๋ก ์ ์ก๋๋ค. ๐
์ฆ, POST๋ก๋ request parameter๋ฅผ ํตํด ๋ฐ์ดํฐ๋ฅผ ์ ๋ฌํ ์ ์๋ค๋ ๊ฒ์ด ํ์ธ๋์๋ค.
๐ฑ POST - multipart/form-data
ํ์ง๋ง ์๊น form ํ๊ทธ๋ฅผ ํ์ฉํ์ ๋๋ multipart/form-data๋ก ๊ฐ์ด ๋์ด๊ฐ์๋ค.
๊ทธ๋ฌ๋ฉด multipart/form-data๋ก ๋ณด๋ธ ์์ฒญ์ @RequestParam์ผ๋ก ๋ฐ์ ์ ์๋ค๋ ๊ฒ์ผ๊น?
๊ถ๊ธํ๊ธฐ ๋๋ฌธ์ ๋ฐ๋ก ํด๋ณด์๋ค.
์ค... ๋ฐ์ธ๋ฉ์ด ๋งค์ฐ ์ ๋๋ค! body ๊ฐ์ผ๋ก ๋ด๊ธด multipart/form-data๋ @RequestParam์ผ๋ก ๋ฐ์ ์ ์๋ค๋ ์ฌ์ค์ ๊นจ๋ฌ์๋ค.
์ค์ ๋ก ๊ณต์ ๋ฌธ์๋ฅผ ๊ฐ๋ณด๋๊น, @RequestParam์ ๋ค์๊ณผ ๊ฐ์ด ์์ฑ๋์ด ์์๋ค.
In Spring MVC, "request parameters" map to query parameters, form data, and parts in multipart requests. This is because the Servlet API combines query parameters and form data into a single map called "parameters", and that includes automatic parsing of the request body.
Spring MVC์์ ๋งํ๋ web request parameter๋, ์ฟผ๋ฆฌ ํ๋ผ๋ฏธํฐ์, form-data, multipart request์์ ๊ฐ๊ฐ์ part ๋ฐ์ดํฐ๋ค์ด ๋งคํ๋๋ค๊ณ ํ๋ค. ์ด์ ๋? ์๋ธ๋ฆฟ API๊ฐ ์ฟผ๋ฆฌ ํ๋ผ๋ฏธํฐ์ form data๋ฅผ "parameters"๋ผ๊ณ ๋ถ๋ฆฌ๋ ๋จ์ผ map์ผ๋ก ๊ฒฐํฉํ๊ณ , request body์ ์๋ ๊ตฌ๋ฌธ ๋ถ์์ ํฌํจํ๊ธฐ ๋๋ฌธ์ด๋ค! (์ด ๋ถ๋ถ์ ์ฒ์ ์์์ ์์ฒญ ๋๋๋ค.)
๐ฑ POST - query parameter with form data
๊ทธ๋ ๋ค๋ฉด, form data์ ์ฟผ๋ฆฌ ํ๋ผ๋ฏธํฐ๋ฅผ ๋์์ ๋ฃ์ผ๋ฉด ์ด๋ป๊ฒ ์์ฒญ์ด ์ฌ๊น? ์ด๊ฒ๋ ๊ถ๊ธํด์ ์คํํด๋ณด์๋ค.
1. form data์ query parameter๋ก ๋ฐ๋ ๊ฐ์ ์ด๋ฆ์ด ๋ค๋ฅผ ๋
์์ ๊ฐ์ด ์์ฒญ์ ๋ณด๋ด๋ณด์๋ค.
๋ฐ์ธ๋ฉ๋ ๋งค์ฐ ์ ๋์๋ค. ๊ทธ๋ ๋ค๋ฉด, GET ์์ฒญ์ผ๋ก ๋ณด๋์ ๋๋ ์ด๋ป๊ฒ ๋์ฌ๊น?
๋น์ฐํ ๋์ง ์๋๋ค. GET ์์ฒญ์์๋ name, age, name2, age2 ๋ชจ๋ ๋ค ์ฟผ๋ฆฌ ํ๋ผ๋ฏธํฐ๋ก ๋ค์ด์ค๊ธฐ๋ฅผ ์์ํ๊ณ ์๊ธฐ ๋๋ฌธ์ด๋ค.
2. form data์ query parameter๋ก ๋ฐ๋ ๊ฐ์ ์ด๋ฆ์ด ๊ฐ์ ๋
์์ฒญ์ ํ ๋ฒ ๋ ๋ ค๋ณด์.
๊ต์ฅํ ์ ๊ธฐํ ๊ฒฐ๊ณผ๊ฐ ๋์๋ค! name์ ๊ฒฝ์ฐ ,์ผ๋ก ๊ตฌ๋ถ๋ ๊ฒฐ๊ณผ๊ฐ ๋์์ง๋ง, age์ ๊ฒฝ์ฐ ํ๋ผ๋ฏธํฐ๋ก ๋๊ธด ๊ฐ๋ง ๋ค์ด๊ฐ๊ธฐ ๋๋ฌธ์ด๋ค.
์์ธ์ง ๊ถ๊ธํด์ ๊น๋ณด๋ ค๊ณ ํ๋๋ฐ, ์ด๊ฑฐ๋ ์ฝ๋ ๋ ๋ฒจ๋ก ๋ค์ด๊ฐ์ผ ํ ๊ฒ ๊ฐ์์ ์ฐ์ ๋ค์ ํฌ์คํ
์์ ์์๋ณด๊ณ ์ ํ๋ค.
๋ง์ฝ GET์ผ๋ก ์์ฒญํ๋ค๋ฉด ์ด๋ป๊ฒ ๋ ๊น?
body์ ๋ค์ด์๋ ๊ฐ์ ๋ฌด์๋๊ณ , ์ฟผ๋ฆฌ ํ๋ผ๋ฏธํฐ์ ๊ฐ๋ง ๋ฐ๋๋ค.
๐ฑ ํ์ผ ์ ๋ก๋์ request parameter
๊ทธ๋ ๋ค๋ฉด, ํ์ผ ์ ๋ก๋ ๊ธฐ๋ฅ์ ํ๊ธฐ ์ํด form tag๋ฅผ ์ฌ์ฉํ๋ค๋ฉด ์ ์์ ์ผ๋ก ์์ฒญ์ด ๊ฐ๊น?
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="/test" method="post">
ํ์ผ: <input type="file" name="file">
์ ์ถํ๊ธฐ: <input type="submit" value="submit">
</form>
</body>
</html>
์๊น์ ๋น์ทํ์ง๋ง ๋งค์ฐ ์ฌํํ ํ์ผ ์ ๋ก๋ html์ ๋ง๋ค์๋ค.
@RestController
public class Controller {
@PostMapping("/test")
public void test(@RequestParam("file") MultipartFile file) {
System.out.println(file.getOriginalFilename());
}
}
Get ์์ฒญ์ ํตํด์ ํ์ผ์ ๋ฐ์๋ณด์.
ํ์ผ ์
๋ก๋ ์ ๋ค์๊ณผ ๊ฐ์ ์ค๋ฅ๊ฐ ๋ฐ์ํ๋ค. ํ์ผ์ ๊ฒฝ์ฐ GET ์์ฒญ์ผ๋ก ๋ฐ์ ์ ์๋ ๊ฒ์ด๋ค.
POST๋ก ๋ณ๊ฒฝํด๋ณด์.
์ฌ์ ํ ์ค๋ฅ๊ฐ ๋ฐ์ํ๋ค.
์์ ๋งํ๋ ๊ฒ์ฒ๋ผ, POST์์ @requestParam์ ์ธ ๊ฒฝ์ฐ application/x-www-form-urlencoded ๋ฐฉ์์ผ๋ก ๋ฐ๋๋ค.
ํ์ง๋ง ํ์ผ ๊ฐ์ ๋ฐ์ด๋๋ฆฌ ๋ฐ์ดํฐ๋ฅผ ์ฐ๋ฆฌ๊ฐ ์ธ์ฝ๋ฉํ ์ ์์๊น? ์๋๋ค.
The content type "application/x-www-form-urlencoded" is inefficient for sending large quantities of binary data or text containing non-ASCII characters. The content type "multipart/form-data" should be used for submitting forms that contain files, non-ASCII data, and binary data.
์ ์ด์ W3C์ ๋ฐ๋ฅด๋ฉด application/x-www-form-urlencoded์ ๊ฒฝ์ฐ, ๊ฐ๋จํ ํ
์คํธ๋ ASCII ํ์์ผ๋ก ๋ฐ์ดํฐ๋ฅผ ๋ณด๋ด๋ ๊ฒ์ด๋ผ๊ณ ์ ์ํ๊ธฐ ๋๋ฌธ์ด๋ค. ๋ํ ๋ฐ์ด๋๋ฆฌ ๊ฐ์ ๊ฒฝ์ฐ ์ฌ์ฉ์ด ๋ถ๊ฐ๋ฅํ๋ค.
๊ทธ๋์ ํ์ผ ์
๋ก๋ ์ ๋ฐ๊ณ ์ถ๋ค๋ฉด multipart/form-data๋ฅผ ํ์ฉํด์ผ ํ๋ค.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="/test" method="post" enctype="multipart/form-data">
ํ์ผ: <input type="file" name="file">
์ ์ถํ๊ธฐ: <input type="submit" value="submit">
</form>
</body>
</html>
form ํ๊ทธ์ enctype์์ multipart/form-data๋ก ๋ณ๊ฒฝํ์.
๊ทธ๋ฆฌ๊ณ ๋ค์ ์์ฒญ์ ๋ณด๋ด๋ฉด ์์ ๊ฐ์ด ์๋ณธ ํ์ผ๋ช
์ด ์ ๋จ๋ ๊ฒ์ ๋ณผ ์ ์๋ค.
์ค์ ๋ก Request Header์ ๊ฐ์ ๋ณด๋๋ผ๋ multipart/form-data ํํ๋ก ์ ์ ๋ฌ๋๋ ๊ฒ์ ๋ณผ ์ ์๋ค.
@RestController
public class Controller {
@PostMapping("/test")
public void test(@RequestBody MultipartFile file) {
System.out.println(file.getOriginalFilename());
}
// @PostMapping("/test")
public void test(@RequestPart MultipartFile file) {
System.out.println(file.getOriginalFilename());
}
}
@RequestParam์ด ์๋๋๋ผ๋ @RequestBody, @RequestPart๋ฅผ ํ์ฉํ์ฌ multipart/form-data ํํ์ ๋ฐ์ดํฐ๋ฅผ ๋ฐ์ ์ ์๋ค.
'โ๏ธ > CS' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[MySQL] ํธ๋์ญ์ ๊ฒฉ๋ฆฌ ์์ค์ ์ฟผ๋ฆฌ๋ฅผ ํตํด ์ง์ ํ ์คํธํด๋ณด๊ธฐ (0) | 2023.06.21 |
---|---|
[Web] JWT๋ฅผ ํตํ ์ธ์ฆ ๊ณผ์ ์์๋ณด๊ธฐ (0) | 2023.05.14 |
[Web] ์ธ์ฆ๊ณผ ์ธ๊ฐ๋? - ์ฟ ํค์ ์ธ์ ์ ๋ํด์ ์์๋ณด์! (2) | 2023.05.03 |
[MSA] MicroService, SoA (0) | 2022.10.20 |