JiwonDev

# HTTP ๋ฐ์ดํ„ฐ ์ „์†ก/์‘๋‹ต

by JiwonDev

ํ”„๋ ˆ์ž„์›Œํฌ ์—†์ด ์ˆœ์ˆ˜ ์ž๋ฐ” ์„œ๋ธ”๋ฆฟ์„ WAS์— ๋“ฑ๋กํ•˜๊ณ , ๋ฐ์ดํ„ฐ๋ฅผ ์ „์†ก ๋ฐ›์•„๋ณด์ž.

์ฐธ๊ณ ๋กœ ์ง์ ‘ ์›น๋ธŒ๋ผ์šฐ์ €๋ฅผ ๋„์›Œ ํ•˜๋‚˜ํ•˜๋‚˜ ๋ฉ”์‹œ์ง€๋ฅผ ์ž…๋ ฅํ•˜๋Š” ๋ฐฉ๋ฒ•๋„ ์žˆ์ง€๋งŒ, ๋ณดํ†ต API ํ…Œ์ŠคํŠธ๋ฅผ ์‰ฝ๊ฒŒํ•˜๋Š” ํˆด์ธ Postman์„ ๋งŽ์ด ์‚ฌ์šฉํ•œ๋‹ค. ๊ฐ„๋‹จํžˆ ๊ฐ€์ž…ํ•˜๊ณ  Workspace๋ฅผ ๋งŒ๋“ค์–ด ์ง์ ‘ HTTP ์š”์ฒญ์„ ๋ณด๋‚ผ ์ˆ˜ ์žˆ๋‹ค.

https://www.postman.com/

 

Postman | The Collaboration Platform for API Development

Postman makes API development easy. Our platform offers the tools to simplify each step of the API building process and streamlines collaboration so you can create better APIs faster.

www.postman.com

 


# HTTP ์š”์ฒญ ๋ฐ์ดํ„ฐ ์ „์†ก

HTTP์„ ํ†ตํ•ด ์š”์ฒญ ๋ฐ์ดํ„ฐ๋ฅผ ์ „์†กํ•  ๋•Œ ์•„๋ž˜์˜ 3๊ฐ€์ง€ ๋ฐฉ๋ฒ•์„ ๋ณดํ†ต ์‚ฌ์šฉํ•œ๋‹ค.

  • GET - ์ฟผ๋ฆฌ ํŒŒ๋ผ๋ฏธํ„ฐ
    jiwondev.tistory.com/?username=JIWON&age=25
    ๋ฉ”์‹œ์ง€ body์—†์ด URL์˜ ํŒŒ๋ผ๋ฉ”ํƒ€๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ํฌํ•จํ•ด์„œ ์ „๋‹ฌํ•˜๋Š” ๋ฐฉ๋ฒ•

  • POST - HTML Form ์œผ๋กœ ์ „์†ก, message body ์— ํŒŒ๋ผ๋ฉ”ํƒ€๋ฅผ ์ „๋‹ฌ
    content-type: application/x-www.form-urlencoded
    body: username=hello&age=20
  • HTTP API - message body์— ๋ฐ์ดํ„ฐ๋ฅผ ์ง์ ‘ ๋‹ด์•„์„œ ์š”์ฒญ
    json, xml, text ํ˜•์‹. ์›ํ•œ๋‹ค๋ฉด ์ด์ง„๋ฐ์ดํ„ฐ(Java ๊ฐ์ฒด ์ง๋ ฌํ™”)๋„ ๋ณด๋‚ผ ์ˆ˜ ์žˆ์œผ๋‚˜ ๋ณดํ†ต json์œผ๋กœ ์‚ฌ์šฉ 
    ๋ณดํ†ต POST, PUT, PATCH๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ „์†กํ•จ.

 


@1. HTTP GET

๋ฐ์ดํ„ฐ๋ฅผ URL์— ์ ๋Š”๋‹ค. ์ฟผ๋ฆฌ ํŒŒ๋ผ๋ฏธํ„ฐ๋Š” ? ๋ฅผ ์ด์šฉํ•˜์—ฌ ๋ณด๋‚ผ ์ˆ˜ ์žˆ๋‹ค. ๋˜‘๊ฐ™์€ ์ด๋ฆ„์˜ ํŒŒ๋ผ๋ฉ”ํƒ€๋ฅผ ์—ฌ๋Ÿฌ๋ฒˆ ๋ณด๋‚ผ ์ˆ˜ ์žˆ๋‹ค.

http://my.tistory.com/?username=hello&age=30&age=20

 

์ด๋ ‡๊ฒŒ ์ „๋‹ฌ๋ฐ›์€ ๋ฐ์ดํ„ฐ๋Š” request ๊ฐ์ฒด๋ฅผ ํ†ตํ•ด ์„œ๋ฒ„์—์„œ ๋ฐ›์•„ ์˜ฌ ์ˆ˜ ์žˆ๋‹ค.

//๋‹จ์ผ ํŒŒ๋ผ๋ฏธํ„ฐ ์กฐํšŒ (์—ฌ๋Ÿฌ ๊ฐœ๊ฐ€ ์žˆ๋‹ค๋ฉด ์ฒซ๋ฒˆ์งธ ๊ฐ’)
String username = request.getParameter("username");

//ํŒŒ๋ผ๋ฏธํ„ฐ ์ด๋ฆ„๋“ค ๋ชจ๋‘ ์กฐํšŒ
Enumeration<String> parameterNames = request.getParameterNames();

//ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ Map์œผ๋กœ ์กฐํšŒ
Map<String, String[]> parameterMap = request.getParameterMap();

//๋ณต์ˆ˜ ํŒŒ๋ผ๋ฏธํ„ฐ ์กฐํšŒ
String[] usernames = request.getParameterValues("username");

 


@2. HTTP Form (POST) ๋ฐฉ์‹

๋‹ค์Œ๊ณผ ๊ฐ™์€ HTML ํผ์„ ์ด์šฉํ•˜์—ฌ ๋ฉ”์‹œ์ง€ ๋ฐ”๋””์— ํŒŒ๋ผ๋ฉ”ํƒ€๋ฅผ ํฌํ•จํ•˜์—ฌ ์ „์†กํ•œ๋‹ค.

HTML ์ŠคํŽ™์ƒ, Form ๋ฐ์ดํ„ฐ๋Š” POST๋กœ ์ „์†กํ•˜๋Š” ๊ฒƒ๋งŒ ํ—ˆ์šฉ๋œ๋‹ค.

http://my.tistory.com/hello-form.html

์‹ค์ œ HTTP์—์„œ๋Š” ์ด๋ ‡๊ฒŒ ์ „์†ก๋œ๋‹ค. ์ด๋Š” ์›น ๋ธŒ๋ผ์šฐ์ €๊ฐ€ HTML ํผ์„ ์ฝ๊ณ  ๋งŒ๋“ค์–ด์ค€๋‹ค.

* content-type์ด ๋ญ์ฃ 

๋”๋ณด๊ธฐ

content-type์€ HTTP ๋ฉ”์‹œ์ง€ ๋ฐ”๋””์˜ ๋ฐ์ดํ„ฐ ํ˜•์‹์„ ์ง€์ •ํ•œ๋‹ค.

 

GET URL ์ฟผ๋ฆฌ ํŒŒ๋ผ๋ฏธํ„ฐ ํ˜•์‹์œผ๋กœ ํด๋ผ์ด์–ธํŠธ์—์„œ ์„œ๋ฒ„๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ์ „๋‹ฌํ•  ๋•Œ๋Š” HTTP ๋ฉ”์‹œ์ง€ ๋ฐ”๋””๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— content-type์ด ์—†๋‹ค.

 

POST HTML Form ํ˜•์‹์œผ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ์ „๋‹ฌํ•˜๋ฉด HTTP ๋ฉ”์‹œ์ง€ ๋ฐ”๋””์— ํ•ด๋‹น ๋ฐ์ดํ„ฐ๋ฅผ ํฌํ•จํ•ด์„œ ๋ณด๋‚ด๊ธฐ ๋•Œ๋ฌธ์— ๋ฐ”๋””์— ํฌํ•จ๋œ ๋ฐ์ดํ„ฐ๊ฐ€ ์–ด๋–ค ํ˜•์‹์ธ์ง€ content-type์„ ๊ผญ ์ง€์ •ํ•ด์•ผ ํ•œ๋‹ค. ์ด๋ ‡๊ฒŒ ํผ์œผ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ์ „์†กํ•˜๋Š” ํ˜•์‹์„ application/x-www-form-urlencoded ๋ผ ํ•œ๋‹ค.

<-- hello-form.html -->

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<form action="/request-param" method="post">
    username: <input name="username" type="text"/>
    age: <input name="age" type="text"/>
    <button type="submit">์ „์†ก</button>
</form>
</body>
</html>

์ฐธ๊ณ ๋กœ ์ด๋ ‡๊ฒŒ ๋ฐ›์€ ํŒŒ๋ผ๋ฉ”ํƒ€๋ฅผ ๊บผ๋‚ด๋Š” ๋ฐฉ๋ฒ•์€ @1. HTTP GET๊ณผ ๋‹ค๋ฅด์ง€ ์•Š๋‹ค. ๋ณด๋‚ด๋Š” ๋ฐฉ์‹์ด ๋‹ค๋ฅผ ๋ฟ์ด๋‹ค. ๊ทธ๋ž˜์„œ ์„œ๋ธ”๋ฆฟ์—์„œ๋Š” doGet() ๊ณผ doPost()๊ฐ™์€ ๋ฉ”์„œ๋“œ๋ฅผ ๋”ฐ๋กœ ์ œ๊ณตํ•˜์—ฌ, Service() ์—์„œ ์ฒ˜๋ฆฌํ•œ ํ›„ ์ ์ ˆํ•œ ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•ด์„œ ๊ตฌ๋ถ„ํ•œ๋‹ค. (doGet()๋“ฑ์„ ํ˜ธ์ถœํ•˜๋Š” ๊ฑด HTTPServlet ํด๋ž˜์Šค์— ์ •์˜๋˜์–ด ์žˆ๋‹ค.)

 


@3. HTTP API (json, xml, text)

POST, PUT, PATCH๋“ฑ์„ ์ด์šฉํ•ด์„œ ๋ฉ”์‹œ์ง€ ๋ฐ”๋””์— ์ง๋ ฌํ™” ๋ฐ์ดํ„ฐ(Json, XML, Text)๋ฅผ ์ง์ ‘ ๋‹ด์•„์„œ ๋ณด๋‚ธ๋‹ค.

requset์—์„œ ํŒŒ๋ผ๋ฉ”ํƒ€๋ฅผ ๊บผ๋‚ด๋Š” ๋ฐฉ์‹์ด ์•„๋‹Œ, JSON์„ ๊บผ๋‚ด ํŒŒ์‹ฑํ•˜์—ฌ ์‚ฌ์šฉํ•œ๋‹ค. ์ž๋ฐ” ๊ฐ์ฒด๋ฅผ Json์œผ๋กœ ์†์‰ฝ๊ฒŒ ์ „ํ™˜ํ•  ์ˆ˜ ์žˆ๋Š” ObjectMapper๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ํŽธ๋ฆฌํ•˜๋‹ค. ๋Œ€ํ‘œ์ ์œผ๋กœ Jackson, Gson ๋“ฑ์ด ์žˆ๋‹ค.

 

์ฐธ๊ณ ๋กœ HTML form ๋ฐ์ดํ„ฐ๋„ ์•„๋ž˜์™€ ๊ฐ™์ด ์ง์ ‘ ๋ฐ”์ดํŠธ ์ŠคํŠธ๋ฆผ์„ ์—ฐ๊ฒฐํ•ด ์ฝ์„ ์ˆ˜ ์žˆ์œผ๋‚˜ request.getParameter(...)๋กœ ์†์‰ฝ๊ฒŒ ๊บผ๋‚ด์˜ฌ ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ๊ฒƒ๋ฟ์ด๋‹ค.

 ... ์„œ๋ธ”๋ฆฟ ๊ฐ์ฒด   
    private ObjectMapper objectMapper = new ObjectMapper();

    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        
        // request์—์„œ data๋ฅผ ๊บผ๋‚ด์˜จ๋‹ค.
        ServletInputStream inputStream = req.getInputStream();
        String messageBody = StreamUtils.copyToString(inputStream, StandardCharsets.UTF_8);
        System.out.println("messageBody = " + messageBody);
        
        // objectMapper๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด json <-> Object ๋ณ€ํ™˜์„ ๊ฐ„๋‹จํ•˜๊ฒŒ ๊ฐ€๋Šฅํ•˜๋‹ค.
        HelloData helloData = objectMapper.readValue(messageBody,  HelloData.class);
        System.out.println("helloData.username = " + helloData.getUsername());
        System.out.println("helloData.age = " + helloData.getAge());
        
        // response ์ˆ˜์ • ํ›„ ๋ฐ˜ํ™˜
        resp.getWriter().write("ok");
    }
    
 ... ์ƒ๋žต

 


# HTTP ์„œ๋ฒ„ ์‘๋‹ต

์š”์ฒญ์„ ๋ฐ›์€ ์„œ๋ฒ„๋Š” [HTTP ์‘๋‹ต์ฝ”๋“œ]์™€ ํ•จ๊ป˜ ํ—ค๋”, ๋ฐ”๋””๋ฅผ ์ƒ์„ฑํ•˜์—ฌ ๋ฐ์ดํ„ฐ๋ฅผ ์ „์†กํ•œ๋‹ค.

  • 1xx(์ •๋ณด) : ์š”์ฒญ์„ ๋ฐ›์•˜์œผ๋ฉฐ ํ”„๋กœ์„ธ์Šค๋ฅผ ๊ณ„์† ์ง„ํ–‰ํ•ฉ๋‹ˆ๋‹ค.
  • 2xx(์„ฑ๊ณต) : ์š”์ฒญ์„ ์„ฑ๊ณต์ ์œผ๋กœ ๋ฐ›์•˜์œผ๋ฉฐ ์ธ์‹ํ–ˆ๊ณ  ์ˆ˜์šฉํ•˜์˜€์Šต๋‹ˆ๋‹ค.
  • 3xx(๋ฆฌ๋‹ค์ด๋ ‰์…˜) : ์š”์ฒญ ์™„๋ฃŒ๋ฅผ ์œ„ํ•ด ์ถ”๊ฐ€ ์ž‘์—… ์กฐ์น˜๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.
  • 4xx(ํด๋ผ์ด์–ธํŠธ ์˜ค๋ฅ˜) : ์š”์ฒญ์˜ ๋ฌธ๋ฒ•์ด ์ž˜๋ชป๋˜์—ˆ๊ฑฐ๋‚˜ ์š”์ฒญ์„ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.
  • 5xx(์„œ๋ฒ„ ์˜ค๋ฅ˜) : ์„œ๋ฒ„ ์‘๋‹ต์ด ์—†๊ฑฐ๋‚˜ ์„œ๋ฒ„๊ฐ€ ๋ช…๋ฐฑํžˆ ์œ ํšจํ•œ ์š”์ฒญ์— ๋Œ€ํ•œ ์ถฉ์กฑ์„ ์‹คํŒจํ–ˆ์Šต๋‹ˆ๋‹ค.

์„œ๋ธ”๋ฆฟ ์ŠคํŽ™์—์„œ๋Š” response ๋ฉ”์„œ๋“œ๋ฅผ ํ†ตํ•ด ์‘๋‹ต์„ ์†์‰ฝ๊ฒŒ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ค.

response.setStatus(HttpServletResponse.SC_OK); //์‘๋‹ต์ฝ”๋“œ 200

 //[response-headers]
 response.setHeader("Content-Type", "text/plain;charset=utf-8");
 response.setHeader("Cache-Control", "no-cache, no-store, mustrevalidate");
 response.setHeader("Pragma", "no-cache");
 response.setHeader("my-header","hello");
 
 //[Header ๋ฉ”์„œ๋“œ, ์•„๋ž˜์— ์„ค๋ช…]
 content(response);
 cookie(response);
 redirect(response);
 
 //[message body]
 PrintWriter writer = response.getWriter();
 writer.println("ok");
    private void content(HttpServletResponse response) {
        //response.setHeader("Content-Type", "text/plain;charset=utf-8")์™€ ๋™์ผ
        response.setContentType("text/plain");
        response.setCharacterEncoding("utf-8");
        
        //response.setContentLength(2); //(์ƒ๋žต์‹œ ์ž๋™ ์ƒ์„ฑ)
    }


    private void cookie(HttpServletResponse response) {
        //response.setHeader("Set-Cookie", "myCookie=good; Max-Age=600")์™€ ๋™์ผ
        Cookie cookie = new Cookie("myCookie", "good");
        cookie.setMaxAge(600); //600์ดˆ
        response.addCookie(cookie);
    }


    private void redirect(HttpServletResponse response) throws IOException {
        // ์•„๋ž˜ ๋‘ ์ฝ”๋“œ์™€ ๋™์ผํ•œ ๋™์ž‘.
        //response.setStatus(HttpServletResponse.SC_FOUND); //302
        //response.setHeader("Location", "/basic/hello-form.html");
        response.sendRedirect("/basic/hello-form.html");
    }

 

@ ์‘๋‹ต์— ๋ฐ์ดํ„ฐ ๋„ฃ๊ธฐ - HTML

์‚ฌ์‹ค ์ผ๋ฐ˜ text๋ฅผ ๋ณด๋‚ด๋Š” ๋ฐฉ์‹ (write.println)๊ณผ ํฌ๊ฒŒ ๋‹ค๋ฅผ๊ฑด ์—†๋‹ค. ๋‹ค๋งŒ content-type์„ text/html๋กœ ์ง€์ •ํ•˜๊ณ  ํƒœ๊ทธ๋ฅผ ๋ณด๋‚ธ๋‹ค๋Š” ์ ์ด ๋‹ค๋ฅผ ๋ฟ์ด๋‹ค. ์ด๋ ‡๊ฒŒ ์ž๋ฐ”์ฝ”๋“œ๋กœ HTML๋ฅผ ๋งŒ๋“ค๊ธฐ ์–ด๋ ค์›Œ ๋“ฑ์žฅํ•œ ๊ฐœ๋…์ด View ํ…œํ”Œ๋ฆฟ, ๋ฐ”๋กœ JSP์ด๋‹ค.

//Content-Type: text/html;charset=utf-8
 response.setContentType("text/html");
 response.setCharacterEncoding("utf-8");
 PrintWriter writer = response.getWriter();
 
 writer.println("<html>");
 writer.println("<body>");
 writer.println(" <div>์•ˆ๋…•?</div>");
 writer.println("</body>");
 writer.println("</html>")

 

@ ์‘๋‹ต์— ๋ฐ์ดํ„ฐ ๋„ฃ๊ธฐ - Json

Json๋„ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ํ…์ŠคํŠธ๋กœ ์ง์ ‘ ํŒŒ์‹ฑํ•  ์ˆ˜ ์žˆ์ง€๋งŒ, Object Mapper ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ(Jackson)์„ ์‚ฌ์šฉํ•˜๋ฉด ๊ฐ„ํŽธํ•˜๊ฒŒ ๊ฐ์ฒด๋ฅผ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ๋‹ค.

        response.setHeader("content-type", "application/json");
        response.setCharacterEncoding("utf-8"); // Json์€ UTF-8๋งŒ ์‚ฌ์šฉํ•œ๋‹ค. ์˜๋ฏธ์—†๋Š” ํŒŒ๋ผ๋ฉ”ํƒ€
        
        HelloData data = new HelloData(); // ๋ฐ์ดํ„ฐ ์ „๋‹ฌ ๊ฐ์ฒด(DTO)
        data.setUsername("kim");
        data.setAge(20);
        
        //{"username":"kim","age":20}
        // ObjectMapper๋กœ JSONํ˜•ํƒœ๋กœ ์ „ํ™˜
        String result = objectMapper.writeValueAsString(data);
        response.getWriter().write(result);

 

๋ธ”๋กœ๊ทธ์˜ ์ •๋ณด

JiwonDev

JiwonDev

ํ™œ๋™ํ•˜๊ธฐ