{"id":689,"date":"2020-07-27T21:00:02","date_gmt":"2020-07-27T12:00:02","guid":{"rendered":"http:\/\/mobilelab.khu.ac.kr\/?p=689"},"modified":"2020-04-05T19:10:30","modified_gmt":"2020-04-05T10:10:30","slug":"be-dart-programmer-28","status":"publish","type":"post","link":"http:\/\/mobilelab.khu.ac.kr\/wordpress\/2020\/07\/27\/be-dart-programmer-28\/","title":{"rendered":"Dart Programmer \ub418\uae30 [28]"},"content":{"rendered":"\n<h4><strong>&lt; HTTP <\/strong>\uc11c\ubc84\uac1c\ubc1c<strong> &#8211; GET &amp; POST in HTTP Server &gt;<\/strong><\/h4>\n\n\n\n<p>\uc0c1\uc138\ud55c \uc124\uba85\uc744 \ud558\uae30\uc804\uc5d0 \uac04\ub2e8\ud55c \uc791\uc5c5\uc744 \ud574 \ubd05\ub2c8\ub2e4. \uba3c\uc800, \uc55e\uc11c\uc5d0\uc11c \uc791\uc131\ud55c darttutorial-27-02.dart\ub97c \ub2e4\uc2dc \ubd88\ub7ec \uc635\ub2c8\ub2e4. \uadf8\ub9ac\uace0 handleRequest() \ud568\uc218\uc548\uc758 case &#8216;GET&#8217;: \uad6c\ubb38\uc774 stdout.writeln(&#8220;${DateTime.now()}: GET ${<strong><em>req.uri.path<\/em><\/strong>}&#8221;);\ub97c stdout.writeln(&#8220;${DateTime.now()}: GET ${<strong><em>req.uri<\/em><\/strong>}&#8221;);\ub85c \ubcc0\uacbd\ud569\ub2c8\ub2e4. \uc989 URI\uc758 path \uc815\ubcf4\ub9cc \ubcf4\ub358 \uac83\uc744 URI \uc804\uccb4\ub97c \ucd9c\ub825\ud558\ub3c4\ub85d \ubc14\uafbc \uac81\ub2c8\ub2e4. \uadf8\ub9ac\uace0 \uc2e4\ud589\ud569\ub2c8\ub2e4. \ub2e4\uc74c\uc73c\ub85c\ub294 \uc6f9\ube0c\ub77c\uc6b0\uc800\ub97c \uc2e4\ud589\ud55c \ud6c4, \uc8fc\uc18c\ucc3d\uc5d0 http:\/\/localhost:4040\/?q=4 \ub77c\uace0 \ud0c0\uc774\ud551\ud558\uace4 \uc5d4\ud130\ub97c \ud0c0\uc774\ud551 \ud569\ub2c8\ub2e4. \uadf8\ub7ec\uba74 \uc11c\ubc84\ucabd \ud654\uba74\uc5d0 &#8220;2020-02-14 11:34:06.907564: GET <a>\/<\/a>?q=4&#8243;\uc640 \uac19\uc774 \ucd9c\ub825\uc774 \ub429\ub2c8\ub2e4. \uc774\ub7f0 \uc2dd\uc73c\ub85c q\ub77c\ub294 \ubcc0\uc218\uac00 4\ub77c\ub294 \uac12\uc744 \uac16\ub3c4\ub85d \ud558\ub77c\ub294 \uc815\ubcf4\ub97c HTTP Client\uc5d0\uc11c HTTP Server\ub85c \uc804\ub2ec\ud55c \uac83\uc785\ub2c8\ub2e4. Get \uba85\ub839\uc744 \ud1b5\ud574\uc11c Client\uac00 Server\ub85c \uc815\ubcf4\ub97c \ubcf4\ub0bc\uc218 \uc788\ub294 \uac83\uc744 \ud655\uc778\ud55c \uc148\uc785\ub2c8\ub2e4. \uc774\uc640 \uac19\uc740 \ubc29\uc2dd\uc5d0 \ub300\ud574\uc11c \uc624\ub298\uc758 \uae00\uc5d0\uc11c \uc880 \ub354 \uc54c\uc544\uac00 \ubcf4\ub3c4\ub85d \ud558\uaca0\uc2b5\ub2c8\ub2e4.<\/p>\n\n\n\n<h4>RESTful GET Request<\/h4>\n\n\n\n<p>REST\ub294 REpresentational State Transfer\uc758 \uc57d\uc5b4\ub85c\uc368, \uc6f9\uc11c\ube44\uc2a4\uc5d0\uc11c HTTP Client\uac00 HTTP Server\ub85c (\ub9c8\uce58 \ud568\uc218 \ud638\ucd9c\uc2dc, \uc785\ub825 \ud30c\ub77c\uba54\ud0c0\ub97c \uc804\ub2ec\ud558\ub4ef\uc774) \uae30\ub2a5 \ub3d9\uc791\uc5d0 \ud544\uc694\ud55c \ud30c\ub77c\uba54\ud0c0(\ub4e4)\uc744 \uc804\ub2ec\ud558\ub294 \ubc29\ubc95\uc785\ub2c8\ub2e4. \uc8fc\uace0 \ubc1b\ub294 \ubcc0\uc218\uc640 \uc774\uc758 \uac12\uc744, \uc601\uc5b4 \uc774\ub984 \uadf8\ub300\ub85c, \ud45c\ud604\ud574\uc8fc\ub294 \ubc29\uc2dd\uc774\uba70, \uc5b4\ub5a4 \ud45c\uc900\uc774 \uc874\uc7ac\ud558\ub294 \uac83\uc740 \uc544\ub2d9\ub2c8\ub2e4.<\/p>\n\n\n\n<p>darttutorial-27-02.dart \ud504\ub85c\uadf8\ub7a8\uc758 \uc55e\uc11c \uc218\uc815\ud55c \ubd80\ubd84\uc744 \ud55c\ubc88 \ub354 \uc218\uc815\ud574 \ubd05\ub2c8\ub2e4. \uc55e\uc11c \uc218\uc815\ud588\ub358 \uad6c\ubb38\uc744 stdout.writeln(&#8220;${DateTime.now()}: GET ${<strong><em>req.uri.queryParameters[&#8216;q&#8217;]<\/em><\/strong>}&#8221;);\uc73c\ub85c \ubcc0\uacbd\ud569\ub2c8\ub2e4. \uc758\ubbf8\ub294 URI \uc815\ubcf4\uac00 map \ud615\ud0dc\ub85c \uad00\ub9ac\ud558\ub294 parameter \uc815\ubcf4 \uc911 &#8216;q&#8217;\ub97c key \uac12\uc73c\ub85c \ud558\ub294 \uacbd\uc6b0\uc758 value\ub97c \ub3c4\ucd9c\ud55c\ub2e4\ub294 \uc758\ubbf8\uc785\ub2c8\ub2e4. \uc989, \uc0ac\uc6a9\uc790\uac00 \ubcf4\ub0b8 REST \ud0c0\uc785\uc758 \uac12\ub4e4\uc774 map \ud615\ud0dc\ub85c \uc800\uc7a5\uc774 \ub418\ub294\ub370, \uc774\uc911 &#8216;q&#8217;\uc5d0 \ud574\ub2f9\ud558\ub294 \uac12\ub9cc \ucd94\ucd9c\ud574\uc11c \ucd9c\ub825\ud55c\ub2e4\ub294 \uc758\ubbf8\uc785\ub2c8\ub2e4. \ub2e4\uc2dc \uc11c\ubc84\ub97c \uc218\ud589\ud558\uace0, Client\ub294 \uc55e\uc11c\uc640 \ub3d9\uc77c\ud558\uac8c http:\/\/localhost:4040\/?q=4\ub85c \ub3d9\uc791\ud574 \ubd05\ub2c8\ub2e4. \uadf8\ub7ec\uba74, \uc11c\ubc84\uc758 \ucd9c\ub825\uc73c\ub85c &#8220;GET 4&#8243;\uac00 \ucd9c\ub825\ub418\ub294 \uac83\uc744 \ubcfc \uc218 \uc788\uc2b5\ub2c8\ub2e4. \uc774\ub807\uac8c \uc11c\ubc84\uc5d0\uc11c\ub294 client\uac00 \ubcf4\ub0b8 \uc77c\uc885\uc758 \ubcc0\uc218\ub4e4\uc758 \uac12\uc744 \ucd94\ucd9c\ud568\uc73c\ub85c\uc11c, \ub3d9\uc801\uc73c\ub85c client\uac00 \uc694\uccad\ud55c \ub3d9\uc791\uacfc \ud30c\ub77c\uba54\ud0c0\uc5d0 \ub530\ub978 \ub3d9\uc801\uc774 \uac00\ub2a5\ud569\ub2c8\ub2e4. <\/p>\n\n\n\n<p>\ub9cc\uc57d HTTP Client\uac00 \ubcf5\uc218\uc758 \ubcc0\uc218 \uac12\uc744 \uc11c\ubc84\uc5d0 \uc804\ub2ec\ud558\uace0 \uc2f6\ub2e4\uba74 \uc5b4\ub5bb\uac8c \ud560\uae4c\uc694? \uc5b4\ub835\uc9c0 \uc54a\uc2b5\ub2c8\ub2e4. http:\/\/localhost:4040\/?q=4&amp;p=5.0&amp;r=&#8221;Dart&#8221; \ucc98\ub7fc \ud558\uba74, q\/p\/r \ubcc0\uc218\uc5d0 \uac01\uac01 4\/5.0\/&#8221;Dart&#8221;\ub97c \uac12\uc73c\ub85c \ud574\uc11c \uc11c\ubc84\uc5d0 \uc804\ub2ec\ud55c \uac83\uc785\ub2c8\ub2e4. \uc774\ub97c \uc81c\ub300\ub85c \ubcf4\uae30 \uc704\ud574\uc11c, \uc774\ubc88\uc5d0\ub294 \uc11c\ubc84\uc758 Get\uc744 \ucc98\ub9ac\ud558\ub294 \uc704\uc758 \ucf54\ub4dc\ub97c stdout.writeln(&#8220;${DateTime.now()}: GET ${<strong><em>req.uri.queryParameters<\/em><\/strong>}&#8221;);\uc73c\ub85c \ubcc0\uacbd\ud569\ub2c8\ub2e4. \uadf8\ub7ec\uba74, 2020-02-14 12:16:48.918590: GET {q: 4, p: 5.0, r: &#8220;Dart&#8221;} \ucc98\ub7fc Map \ud0c0\uc785\uc758 \uac12\uc774 \ucd9c\ub825 \ub429\ub2c8\ub2e4. \uc774\ub807\uac8c HTTP Client\uc640 \uc11c\ubc84\ub294 REST \ubc29\uc2dd\uc744 \uc0ac\uc6a9\ud574\uc11c \uac04\ub2e8\ud558\uac8c \ubcf5\uc218 \ud30c\ub77c\uba54\ud0c0\uc758 \uc815\ubcf4\ub97c \uc804\ub2ec\ud560 \uc218 \uc788\uace0, \uc774\ub97c \ud1b5\ud55c \ub3d9\uc801\uc778 \ub3d9\uc791\uc774 \uac00\ub2a5\ud569\ub2c8\ub2e4.<\/p>\n\n\n\n<h4>HTTP Classes<\/h4>\n\n\n\n<p>HTTP \uad00\ub828 Class\ub4e4\uc5d0 \ub300\ud574\uc11c \ubd80\uc5b8 \uc124\uba85\uc744 \ud560 \uc2dc\uc810 \uc785\ub2c8\ub2e4. \uba3c\uc800 HttpRequest\ub294 \uacc4\uc18d \ub4f1\uc7a5\ud558\uace0 \uc788\uc9c0\ub9cc, Client\uac00 \uc804\ub2ec\ud55c \uc694\uccad\uc5d0 \ub300\ud55c \uc815\ubcf4\ub97c \uc800\uc7a5\ud569\ub2c8\ub2e4. method Property\ub294 HTTP\uc758 \ud45c\uc900 \uba85\ub839\uc744 \uc758\ubbf8\ud558\uc5ec, GET\/PUT\/POST \ub4f1\uc758 \uc815\ubcf4\ub97c \uac16\uc2b5\ub2c8\ub2e4. uri Property\ub294 Uri \uac1d\uccb4\ub97c \uc800\uc7a5\ud558\ub294\ub370, scheme, host, port, querystring\uacfc \uac19\uc774 HTTP Request \uba54\uc2dc\uc9c0\uc548\uc5d0 \ud3ec\ud568\ub41c \uc815\ubcf4\ub4e4\uc744 \ud3ec\ud568\ud558\uace0 \uc788\uc2b5\ub2c8\ub2e4. response Property\ub294 HttpResponse \uac1d\uccb4\ub97c \uc800\uc7a5\ud558\uc5ec, HttpRequest\uc5d0 \ub300\ud55c \uc751\ub2f5 \uc815\ubcf4\ub97c \uc800\uc7a5\ud558\uace0 \uc788\uc2b5\ub2c8\ub2e4. \ub9c8\uc9c0\ub9c9\uc73c\ub85c headers Property\ub294 HttpHeaders \uac1d\uccb4\ub97c \uc800\uc7a5\ud558\uc5ec, HTTP Request\uc758 \ud5e4\ub354 \uc815\ubcf4\ub97c \ud3ec\ud568\ud558\ub294\ub370, ContentType, content length, date \ub4f1\uc758 \uc815\ubcf4\ub97c \uc800\uc7a5\ud558\uace0 \uc788\uc2b5\ub2c8\ub2e4. \uc774\ubbf8 \uc6b0\ub9ac\ub294 darttutorial-27-02.dart \uc5d0\uc11c req.method \ubb38\ubc95\uc744 \ud1b5\ud574\uc11c &#8220;GET&#8221;\uacfc \ub9e4\uce6d\uc774 \ub418\ub294\uc9c0\ub97c \ud655\uc778 \ud588\uc73c\uba70, \ub2e4\uc74c\uacfc \uac19\uc740 \ucf54\ub4dc\ub97c \ud1b5\ud574\uc11c, HTTP Request\uc5d0 \ub300\ud55c \uc751\ub2f5\uc758 \ucf54\ub4dc\uc640 Body \ub0b4\uc6a9\uc744 \ucc44\uc6b0\ub294 \uac83\uc744 \ubcf4\uc558\uc2b5\ub2c8\ub2e4. \uadf8\ub9ac\uace0 \uc774\ubc88 \uae00\uc758 req.uri.queryParameters \ubb38\ubc95\uc73c\ub85c HTTP Request\uc758 URI \ub0b4\uc758 Map \uc815\ubcf4\ub97c \uc811\uadfc\ud558\ub294 \uac83\ub3c4 \ud655\uc778 \ud588\uc2b5\ub2c8\ub2e4.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>res\n  ..statusCode = HttpStatus.methodNotAllowed\n  ..write('${DateTime.now()}: Unsupported request: ${req.method}.');<\/code><\/pre>\n\n\n\n<p>HTTP Request\uc5d0 \ub300\ud55c \uc751\ub2f5\uc73c\ub85c \ub9cc\ub4e4\uc5b4\uc9c0\ub294 HTTP Response \uc815\ubcf4\ub294 HttpResponse \uac1d\uccb4\ub85c \ub9cc\ub4e4\uc5b4 \uc9d1\ub2c8\ub2e4. \uac00\uc7a5 \uae30\ucd08\uc801\uc73c\ub85c \ud568\uc218\uc758 \ub9ac\ud134 \uac12\uc774 \uc788\ub4ef\uc774, HTTP Request\uc5d0 \ub300\ud55c \uc131\uacf5\/\uc2e4\ud328 \uc5ec\ubd80\ub97c \uc54c\ub9ac\ub294 \uc815\ubcf4\uac00 \uc788\uc73c\uba70, \uc774\ub294 HttpResponse\uc758 statusCode Property\uc5d0 \uc800\uc7a5\ud569\ub2c8\ub2e4. \uac00\uc7a5 \ub300\ud45c\uc801\uc778 \ub450 \uac12\uc740 \uc131\uacf5\uc801\uc73c\ub85c Request\uac00 \ucc98\ub9ac\ub418\uc5c8\uc74c\uc744 \uc758\ubbf8\ud558\ub294 HttpStatus.ok\uc774\uace0, \uc11c\ubc84\uac00 \ucc98\ub9ac\ud560 \uc218 \uc5c6\ub2e4\ub294 \uc758\ubbf8\uc778 (\uadf8\ub9ac\uace0 darttutorial-28-01.dart\uc5d0\uc11c \ub4f1\uc7a5\ud588\uc5c8\ub358) HttpStatus.methodNotAllowed \uc785\ub2c8\ub2e4. HttpResponse\uc548\uc5d0\ub294 \uadf8\uc678\uc5d0 \uc720\uc6a9\ud55c property\ub4e4\uc774 \uc788\uc2b5\ub2c8\ub2e4. contentLength Property\ub294 HTTP Response\uc758 \ud06c\uae30\ub97c \uc758\ubbf8\ud569\ub2c8\ub2e4. cookies Property\ub294 HTTP Response\ub97c \ubc1b\uc740 HTTP Client\uac00 \uc800\uc7a5\ud574\uc57c \ud558\ub294 Cookies\uc758 \ub9ac\uc2a4\ud2b8 \uc815\ubcf4\ub97c \ud3ec\ud568\ud569\ub2c8\ub2e4. encodingProperty\ub294 JSON\uc774\ub098 UTF-6\uacfc \uac19\uc740 \ubb38\uc790\uc5f4\uc744 \uc800\uc7a5\ud560 \ub54c \uc0ac\uc6a9\ud558\uba70, headers Property\ub294 response\uc758 \ud5e4\ub354\ub97c HttpHeaders \uac1d\uccb4\ub85c \uc800\uc7a5\ud569\ub2c8\ub2e4. <\/p>\n\n\n\n<h4>HTTP POST Request Support in HTTP Server<\/h4>\n\n\n\n<p>\uc55e\uc11c\uc5d0\uc11c URI\uc5d0 RESTful\uc758 \ud615\ud0dc\ub85c \ud568\uc218\ub97c \ud638\ucd9c\ud558\ub294 \uac83\ucc98\ub7fc, \ubcf5\uc218\uc758 \ud30c\ub77c\uba54\ud0c0\uc5d0 \ub300\ud55c \uac12\uc744 \uc804\ub2ec\ud558\ub294 \ubc29\ubc95\uc744 \ubcf4\uc558\uc2b5\ub2c8\ub2e4. \ub354 \ub9ce\uc740 \uc815\ubcf4\ub97c \uc804\ub2ec\ud558\uace0\uc790 \ud55c\ub2e4\uba74 HTTP POST Request\ub97c \uc0ac\uc6a9\ud560 \uc218 \uc788\uc2b5\ub2c8\ub2e4. \uc608\ub97c\ub4e4\uc5b4 HTTP Client\ub85c\ubd80\ud130 Map \ud0c0\uc785\uc758 \uc815\ubcf4\ub97c HTTP Server\uac00 \uc218\uc2e0\ud558\uc5ec, \uc774\ub4e4\uc744 \ud654\uc77c\uc5d0 \uc800\uc7a5\ud558\ub294 \uc608\uc81c\ub97c \uc0dd\uac01\ud560 \uc218 \uc788\uc2b5\ub2c8\ub2e4. <\/p>\n\n\n\n<p>\uc774\ub7f4\ub54c \uc5b8\uc5b4\uc640 \ub3c5\ub9bd\uc801\uc73c\ub85c \uc815\ubcf4\ub97c \uc800\uc7a5\ud558\ub294 \ub300\ud45c\uc801\uc778 \ud615\ud0dc\uac00 JSON(JavaScript Object Notation) \uc785\ub2c8\ub2e4. \ub2e8\uc5b4\ub294 \uc0dd\uc18c\ud558\uc9c0\ub9cc, Dart \uc5b8\uc5b4\uc758 Map\uacfc \uac70\uc758 \uac19\uc740 \ud615\ud0dc\ub77c\uace0 \ubcf4\uba74 \ub429\ub2c8\ub2e4. \uc544\ub798\ub294 \uc704\ud0a4\ud398\ub514\uc544\uc5d0\uc11c \ud55c \uc0ac\ub78c\uc758 \uc815\ubcf4\ub97c \uc800\uc7a5\ud558\ub294 JSON\uc758 \uc608\uc81c\uc785\ub2c8\ub2e4 [<a href=\"https:\/\/ko.wikipedia.org\/wiki\/JSON\">\ucd9c\ucc98<\/a>]. <\/p>\n\n\n\n<pre class=\"wp-block-code\"><code> {\n    \"\uc774\ub984\": \"\ud64d\uae38\ub3d9\",\n    \"\ub098\uc774\": 25,\n    \"\uc131\ubcc4\": \"\uc5ec\",\n    \"\uc8fc\uc18c\": \"\uc11c\uc6b8\ud2b9\ubcc4\uc2dc \uc591\ucc9c\uad6c \ubaa9\ub3d9\",\n    \"\ud2b9\uae30\": [\"\ub18d\uad6c\", \"\ub3c4\uc220\"],\n    \"\uac00\uc871\uad00\uacc4\": {\"#\": 2, \"\uc544\ubc84\uc9c0\": \"\ud64d\ud310\uc11c\", \"\uc5b4\uba38\ub2c8\": \"\ucd98\uc12c\"},\n    \"\ud68c\uc0ac\": \"\uacbd\uae30 \uc218\uc6d0\uc2dc \ud314\ub2ec\uad6c \uc6b0\ub9cc\ub3d9\"\n }<\/code><\/pre>\n\n\n\n<p>\uc704\uc640 \uac19\uc740 JSON \ud0c0\uc785\uc758 \ub370\uc774\ud0c0\ub97c HTTP \ud504\ub85c\ud1a0\ucf5c\ub85c \uc804\uc1a1\ud560 \ub54c, &#8216;application\/json&#8217; \ub77c\uace0 \uc9c0\uce6d\ud569\ub2c8\ub2e4. JSON \ud0c0\uc785\uc758 \ub370\uc774\ud0c0\ub97c HTTP Client\uc5d0\uc11c \ubc1b\uc544\uc11c \ud654\uc77c\uc5d0 \uc800\uc7a5\ud558\ub294 \uae30\ub2a5\uc744 darttutorial-27-02.dart \ud504\ub85c\uadf8\ub7a8\uc5d0 \ucd94\uac00\ud558\ub294 \ud568\uc218 handlePostRequest()\ub97c \ub2e4\uc74c\uacfc \uac19\uc774 \ub9cc\ub4e4 \uc218 \uc788\uc2b5\ub2c8\ub2e4.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/ Handler for HTTP POST Request.\nFuture handlePostRequest(HttpRequest req) async {\n  \/\/ #1 Retrieve an associated HttpResponse object in HttpRequst object.\n  HttpResponse res = req.response;\n\n  \/\/ #2 Do something : Example - Write file based on the reseived JSON.\n  if (req.headers.contentType?.mimeType == 'application\/json') {\n    try {\n      \/\/ #2.1 utf8.decoder.bind(req) : Retrieve multiple chunks within a same HTTP Request.\n      \/\/ #2.2 .join() : Puts the chunks together.  \n      String jsonContent = await utf8.decoder.bind(req).join();\n\n      \/\/ #2.3 Retrieve file name from HTTP POST Request\n      var jsonFileName = req.uri.pathSegments.last; \n\n      \/\/ #2.4 Save the received JSON content into a file in a current working directory\n      await File(jsonFileName).writeAsString(jsonContent, mode: FileMode.write);\n\n      \/\/ #2.5 Decode the received JSON content and concert into MAP format\n      var jsonData = jsonDecode(jsonContent) as Map;\n\n      \/\/ #2.6 Make a response for success case\n      req.response\n        ..statusCode = HttpStatus.ok\n        ..write('${DateTime.now()}: Wrote data for ${jsonData}.');\n    } catch (e) {\n      \/\/ #2.7 Make a response for failed case\n      res\n        ..statusCode = HttpStatus.internalServerError\n        ..write('${DateTime.now()}: Exception during file I\/O: $e.');\n    }\n  } else {\n    \/\/ 2.8 Make a response for not supported POST Request (not a JSON format)\n    res\n    ..statusCode = HttpStatus.methodNotAllowed\n    ..write('${DateTime.now()}: Unsupported POST type: ${req.headers.contentType?.mimeType}.');\n  }\n\n  \/\/ #3 Close the response and send it to the client.\n  await res.close();\n}<\/code><\/pre>\n\n\n\n<p>handlePostRequest() \ud568\uc218\uc5d0 \ub300\ud574\uc11c \uc790\uc138\ud788 \uc54c\uc544 \ubd05\ub2c8\ub2e4. \uc785\ub825 \ud30c\ub77c\uba54\ud0c0\ub294 \ub2e4\ub978 HTTP Request\uc640 \ub9c8\ucc2c\uac00\uc9c0\ub85c HTTP Client\ub85c\ubd80\ud130 \ubc1b\uc740 \uba54\uc138\uc9c0\uac00 \ud3ec\ud568\ub41c HttpRequest \uac1d\uccb4\ub97c \ubc1b\uc2b5\ub2c8\ub2e4. \uadf8\ub9ac\uace0 \ube44\ub3d9\uae30 \ubaa8\ub4dc \ub3d9\uc791\uc744 \uc704\ud55c \uae30\ub2a5\uc774 \ud3ec\ud568\ub418\uc5c8\uae30\uc5d0, async\uc640 Future\uc758 \ubb38\ubc95\uc744 \uc0ac\uc6a9\ud558\uace0 \uc788\uc2b5\ub2c8\ub2e4. #1\uacfc #3\uc740 GET\uc744 \ucc98\ub9ac\ud558\ub294 \ud568\uc218\uc640 \ub3d9\uc77c \ud569\ub2c8\ub2e4. #2\uc758 \uad6c\ubb38\uc744 \ubcf4\uba74, req.headers.contentType?.mimeType == &#8216;application\/json&#8217; \uad6c\ubb38\uc744 \ud1b5\ud574\uc11c, \ub2f9\uc7a5\uc740 JSON \ub370\uc774\ud0c0 \ud0c0\uc785\ub9cc \ucc98\ub9ac\ud558\uaca0\ub2e4\uace0 \uc120\uc5b8 \ud588\uc2b5\ub2c8\ub2e4. \ub530\ub77c\uc11c, \ub2e4\ub978 \ud0c0\uc785\uc73c\ub85c POST\uac00 \uc218\uc2e0\ub418\uba74, #2.8\uc5d0 \uc758\ud574\uc11c &#8220;\uc9c0\uc6d0\ud558\uc9c0 \uc54a\ub294 \ud0c0\uc785&#8221;\uc774\ub77c\ub294 \uba54\uc138\uc9c0\ub97c \ud68c\uc2e0\ud558\uac8c \ub429\ub2c8\ub2e4. JSON \ud0c0\uc785\uc774\ub77c\uba74, \ud6c4\uc18d\uc791\uc5c5\uc744 \ud558\uac8c \ub429\ub2c8\ub2e4. #2.1\uc73c\ub85c \uc774 \uc791\uc5c5\uc744 \uc2dc\uc791\ud558\ub294\ub370, HTTP POST Request\uc5d0 \ud3ec\ud568\ub41c \uc815\ubcf4\ub4e4\uc744 UTF-8 \ud615\ud0dc\ub85c \ubcc0\ud658\ud558\uace0, (\ud1b5\uc2e0\uc0c1\uc5d0\uc11c \uac19\uc740 HTTP POST Request \uba54\uc2dc\uc9c0\uac00 \uc5ec\ub7ec\uac1c\uc758 \ud1b5\uc2e0 \uba54\uc2dc\uc9c0\ub85c \ub098\ub258\uc5b4\uc838\uc11c \uc218\uc2e0\ub420 \uc218 \uc788\uc73c\ub2c8) \uac19\uc740 HTTP Request\uc5d0 \uc18d\ud55c \uba54\uc2dc\uc9c0\ub97c \ud558\ub098\ub85c \ubb36\uc5b4 \uc8fc\ub294 \uc791\uc5c5\uc744 #2.2\uc5d0\uc11c join()\uc73c\ub85c \uc218\ud589\ud569\ub2c8\ub2e4. \uc774\ub807\uac8c \ud574\uc11c jsonContent\uc740 HTTP Client\uac00 \uc804\ub2ec\ud55c HTTP POST Request\uc758 \ubaa8\ub4e0 \uc815\ubcf4\ub97c \ud558\ub098\uc758 \ubb38\uc790\uc5f4\uc5d0 \ub2f4\uc2b5\ub2c8\ub2e4.<\/p>\n\n\n\n<p>\ub2e4\uc74c\uc73c\ub85c POST\ub97c \ud1b5\ud574\uc11c \uc804\ub2ec\ub41c Map \ud615\uc2dd\uc758 \ub370\uc774\ud0c0\ub97c \uc800\uc7a5\ud560 \ud654\uc77c\uc774\ub984\uc744 HTTP Client\uac00 \uc804\uc1a1\ud588\uc73c\uba70, \uc774\ub97c \ubc1b\uc544\uc57c \ud569\ub2c8\ub2e4. \uc774\ub97c \uc704\ud574\uc11c \uc775\uc219\ud55c req.uri Property\uac00 \ub2e4\uc2dc \ub4f1\uc7a5\ud588\uace0, \uc774\ubc88\uc5d0\ub294 URI\uc5d0\uc11c \ub9c8\uc9c0\ub9c9\uc5d0 \ud3ec\ud568\ub418\uc5b4 \uc788\uc744 \ud654\uc77c\uc774\ub984\ub9cc \ucd94\ucd9c\ud558\ub294 \uc791\uc5c5\uc744 #2.3\uc5d0\uc11c pathSegments.last Property\ub97c \ud1b5\ud574\uc11c \ud655\ubcf4\ud569\ub2c8\ub2e4.<\/p>\n\n\n\n<p>#2.4\uc5d0\uc11c \ub4dc\ub514\uc5b4 \ud654\uc77c\uc5d0 \uc800\uc7a5\ud558\ub294 \uc791\uc5c5\uc744 (\ub2e8\uc21c\ud558\uac8c \ud55c\uc904\uc774\uc9c0\ub9cc) \uc131\uacf5\uc801\uc73c\ub85c \uc218\ud589\ud569\ub2c8\ub2e4. \uc800\uc7a5\ud560 \ud654\uc77c \uc774\ub984\uc744 File \ud074\ub798\uc2a4\uc758 Constructor\uc5d0 \uc804\ub2ec\ud558\uc5ec, File \uac1d\uccb4\ub97c \ub9cc\ub4e4\uba74\uc11c, JSON \ud615\ud0dc\ub85c \ubc1b\uc740 \uc815\ubcf4\ub97c File \uac1d\uccb4\uc5d0 \uc800\uc7a5\ud558\ub3c4\ub85d writeAsString()\ub97c \uc2e4\ud589\ud569\ub2c8\ub2e4. \uc774\ub807\uac8c \ud574\uc11c JSON \ud0c0\uc785\uc73c\ub85c \uc804\ub2ec \ubc1b\uc740 \uc815\ubcf4\ub294 \uc11c\ubc84\uc5d0 \ud654\uc77c \ud615\ud0dc\ub85c \uc800\uc7a5\ub429\ub2c8\ub2e4.<\/p>\n\n\n\n<p>#2.5\ub294 \ud639\uc2dc\ub77c\ub3c4 \uc788\uc744 \uc11c\ubc84\uc5d0\uc11c\uc758 \ub370\uc774\ud0c0 \ucc98\ub9ac\ub97c \uc704\ud558\uc5ec, JSON \ud615\ud0dc\uc758 \ub370\uc774\ud0c0\ub97c \uc544\uc608 Dart \uc5b8\uc5b4\uc758 Map \ud615\ud0dc\ub85c \ubc14\uafbc\ud6c4 jsonData \ubcc0\uc218\uc5d0 \uc800\uc7a5\ud569\ub2c8\ub2e4. \uc774\ud6c4 #2.6\uc5d0\uc11c \uc131\uacf5\uc801\uc778 \uc751\ub2f5\uc774\ub77c\ub294 \ucf54\ub4dc\uc640 \ud568\uaed8 \uc800\uc7a5\ud55c \ub0b4\uc6a9\uc744 \ub2e4\uc2dc HTTP Client\uc5d0\uac8c HTTP Response \uba54\uc2dc\uc9c0\ub85c \uc804\ub2ec\ud558\uac8c \ub429\ub2c8\ub2e4.<\/p>\n\n\n\n<p>POST Request\ub97c \ub2e4\ub8e8\ub294 \ud568\uc218\ub97c \ucd94\uac00\ud588\uc73c\ub2c8, \uc55e\uc11c \ub9cc\ub4e4\uc5c8\ub358 handleRequest()\uc5d0\uc11c handlePostRequest()\ub97c \ud638\ucd9c\ud560 \uc218 \uc788\ub3c4\ub85d \ucd94\uac00\ud574\uc57c \ud569\ub2c8\ub2e4. \uc544\ub798\ub294 case &#8220;POST&#8221;:\ub97c \ud1b5\ud574\uc11c HTTP POST Request\uac00 \uc218\uc2e0\ub418\uba74, handlePostRequest()\ub97c \uc218\ud589\ud558\ub3c4\ub85d \uc218\uc815\ud55c \ud568\uc218 \uc785\ub2c8\ub2e4.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/ Handler for HTTP Request.\nFuture handleRequest(HttpRequest req) async {\n    \/\/ #1 Do something based on HTTP request types.\n    switch (req.method) {\n      \/\/ #1.1 GET Request.\n      case 'GET':\n        \/\/ Print log message and activate HTTP Get Request handler.\n        stdout.writeln(\"${DateTime.now()}: GET ${req.uri}\");\n        await handleGetRequest(req);\n        break;\n      \/\/ #1.2 GET Request.\n      case 'POST':\n        \/\/ Print log message and activate HTTP Post Request handler.\n        stdout.writeln(\"${DateTime.now()}: POST ${req.uri}\");\n        await handlePostRequest(req);\n        break;\n      \/\/ #1.3 Other Requests.\n      default:\n        stdout.writeln(\"${DateTime.now()}: ${req.method} not allowed\");\n        await handleNotAllowedRequest(req);\n    }\n}<\/code><\/pre>\n\n\n\n<p>\uc790 \uc774\uc81c \uae30\uc874\uc758 darttutorial-27-02.dart\uc5d0 \uc704\uc5d0\uc11c \uc218\uc815\ud55c \ud568\uc218\ub4e4\uc744 \ubaa8\ub450 \ud3ec\ud568\ud558\ub3c4\ub85d \ubcc0\uacbd\ud55c darttutorial-28-01.dart \ud504\ub85c\uadf8\ub7a8\uc744 \ub9cc\ub4e4\uc5c8\uc2b5\ub2c8\ub2e4. \uc544\ub798\uc758 \uc18c\uc2a4 \ud504\ub85c\uadf8\ub7a8\uc740 POST Reqeust\ub97c \uc218\uc815\uacfc \ud568\uaed8, \ub2e4\ub978 \ubd80\ubd84\uc5d0 \ub300\ud574\uc11c \uc77c\ubd80 \uac1c\uc120\ud55c \ud615\ud0dc\uc785\ub2c8\ub2e4. \uc774\ub807\uac8c \ud574\uc11c, \uc6b0\ub9ac\uc758 HTTP Server\ub294 GET\uacfc POST\ub97c \ucc98\ub9ac\ud558\ub3c4\ub85d \ud5a5\uc0c1 \ub418\uc5c8\uc2b5\ub2c8\ub2e4.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/ darttutorial-28-01.dart\n\nimport \"dart:io\";\nimport 'dart:async';\nimport 'dart:convert';\n\n\/\/ Handler for HTTP GET Request.\nFuture handleGetRequest(HttpRequest req) async {\n  \/\/ #1 Retrieve an associated HttpResponse object in HttpRequst object.\n  HttpResponse res = req.response;\n\n  \/\/ #2 Do something : Example - Write text body in the response.\n  res\n  ..statusCode = HttpStatus.ok\n  ..write('${DateTime.now()}: Hello World!');\n\n  \/\/ #3 Close the response and send it to the client.\n  await res.close();\n}\n\n\/\/ Handler for HTTP POST Request.\nFuture handlePostRequest(HttpRequest req) async {\n  \/\/ #1 Retrieve an associated HttpResponse object in HttpRequst object.\n  HttpResponse res = req.response;\n\n  \/\/ #2 Do something : Example - Write file based on the reseived JSON.\n  if (req.headers.contentType?.mimeType == 'application\/json') {\n    try {\n      \/\/ #2.1 utf8.decoder.bind(req) : Retrieve multiple chunks within a same HTTP Request.\n      \/\/ #2.2 .join() : Puts the chunks together.  \n      String jsonContent = await utf8.decoder.bind(req).join();\n\n      \/\/ #2.3 Retrieve file name from HTTP POST Request\n      var jsonFileName = req.uri.pathSegments.last; \n\n      \/\/ #2.4 Save the received JSON content into a file in a current working directory\n      await File(jsonFileName).writeAsString(jsonContent, mode: FileMode.write);\n\n      \/\/ #2.5 Decode the received JSON content and concert into MAP format\n      var jsonData = jsonDecode(jsonContent) as Map;\n\n      \/\/ #2.6 Make a response for success case\n      req.response\n        ..statusCode = HttpStatus.ok\n        ..write('${DateTime.now()}: Wrote data for ${jsonData}.');\n    } catch (e) {\n      \/\/ #2.7 Make a response for failed case\n      res\n        ..statusCode = HttpStatus.internalServerError\n        ..write('${DateTime.now()}: Exception during file I\/O: $e.');\n    }\n  } else {\n    \/\/ 2.8 Make a response for not supported POST Request (not a JSON format)\n    res\n    ..statusCode = HttpStatus.methodNotAllowed\n    ..write('${DateTime.now()}: Unsupported POST type: ${req.headers.contentType?.mimeType}.');\n  }\n\n  \/\/ #3 Close the response and send it to the client.\n  await res.close();\n}\n\n\/\/ Handler for not allowed HTTP Request.\nFuture handleNotAllowedRequest(HttpRequest req) async {\n  \/\/ #1 Retrieve an associated HttpResponse object in HttpRequst object.\n  HttpResponse res = req.response;\n\n  \/\/ #2 Do something : Example - Write text body in the response.\n  res\n  ..statusCode = HttpStatus.methodNotAllowed\n  ..write('${DateTime.now()}: Unsupported request: ${req.method}.');\n\n  \/\/ #3 Close the response and send it to the client.\n  await res.close();\n}\n\n\/\/ Handler for HTTP Request.\nFuture handleRequest(HttpRequest req) async {\n    \/\/ #1 Do something based on HTTP request types.\n    switch (req.method) {\n      \/\/ #1.1 GET Request.\n      case 'GET':\n        \/\/ Print log message and activate HTTP Get Request handler.\n        stdout.writeln(\"${DateTime.now()}: GET ${req.uri.queryParameters}\");\n        await handleGetRequest(req);\n        break;\n      \/\/ #1.2 GET Request.\n      case 'POST':\n        \/\/ Print log message and activate HTTP Post Request handler.\n        stdout.writeln(\"${DateTime.now()}: POST ${req.uri}\");\n        await handlePostRequest(req);\n        break;\n      \/\/ #1.3 Other Requests.\n      default:\n        stdout.writeln(\"${DateTime.now()}: ${req.method} not allowed\");\n        await handleNotAllowedRequest(req);\n    }\n}\n\nFuture main() async {\n  \/\/ #1 Specify HTTP Server address (localhost) and port.\n  final HOST = InternetAddress.loopbackIPv4; \/\/ or \"0.0.0.0\" to allow access from other machines\n  final PORT = 4049;\n\n  \/\/ #2 Starts listening for HTTP requests on the address and port.\n  var httpServer = await HttpServer.bind(HOST, PORT);\n  stdout.writeln(\"${DateTime.now()}: HTTP Server running at ${HOST.address}:$PORT\");\n\n  \/\/ #3 Listening for HTTP requests and handle requests.\n  await for (HttpRequest httpRequest in httpServer) {\n    try {\n      \/\/ #3.1 Activate a HTTP Request handler\n      handleRequest(httpRequest);\n    } catch(e) {\n      \/\/ #3.2 Print message at exception handling case\n      stdout.writeln('${DateTime.now()}: Exception in handleRequest: $e');\n    }\n  }\n}<\/code><\/pre>\n\n\n\n<h4>Secure Connection using HTTPS<\/h4>\n\n\n\n<p>HttpServer \ud074\ub798\uc2a4\ub294 \uc554\ud638\ud654\ub41c \ubcf4\uc548 \ud1b5\uc2e0\uc744 \uc9c0\uc6d0\ud558\ub294 HTTPS (Hyper Text Transfer Protocol with Secure Sockets Layer) \ud1b5\uc2e0\uc744 \uc9c0\uc6d0\ud569\ub2c8\ub2e4. \uc774\ub97c \uc704\ud574\uc11c bindSecure() \uba54\uc18c\ub4dc\ub97c \uc9c0\uc6d0\ud569\ub2c8\ub2e4.  \uc544\ub798\uc758 \uc608\uc81c\ub97c \ubcf4\uba74 \uae30\uc874 bind() \uba54\uc18c\ub4dc\uc640\uc758 \ucc28\uc774\uc810\uc73c\ub85c serverConect\uc5d0 \ubcf4\uc548 \uc815\ubcf4\uac00 \ud3ec\ud568\ub418\uc5b4\uc57c \ud55c\ub2e4\ub294 \uc810 \uc785\ub2c8\ub2e4.  <br>Certificate Authority (CA)\ub77c\uace0 \ubd88\ub9ac\uc6b0\ub294 \uc815\ubcf4\ub85c\uc11c, \uc774\ub294 \uc11c\ubc84\ub97c \uc6b4\uc601\ud558\ub294 \uac1c\ubc1c\uc790\uac00 \uc9c1\uc811 \ubcf4\uc548 \uc815\ubcf4\ub97c \ud68d\ub4dd\ud574\uc57c \ud569\ub2c8\ub2e4. \uc774\uc5d0 \ub300\ud55c \uc790\uc138\ud55c \uc0ac\ud56d\uc740 What is SSL and What are certificates [<a href=\"https:\/\/www.tldp.org\/HOWTO\/SSL-Certificates-HOWTO\/x64.html\">\ucc38\uc870<\/a>]\ub97c \ucc38\uc870\ud558\uae30 \ubc14\ub78d\ub2c8\ub2e4.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>var server = await HttpServer.bindSecure(\n    'localhost',\n    4047,\n    serverContext,\n  );<\/code><\/pre>\n\n\n\n<p>Dart \uacf5\uc2dd \uc0ac\uc774\ud2b8\uc5d0\uc11c HTTPS\ub97c \uc9c0\uc6d0\ud558\ub294 \uc608\uc81c \ud504\ub85c\uadf8\ub7a8\uc774 \ub2e4\uc74c\uacfc \uac19\uc774 \ub4f1\ub85d\ub418\uc5b4 \uc788\uc2b5\ub2c8\ub2e4. \ubcf4\uc548\uacfc \uad00\ub828\ud55c \uc815\ubcf4\ub97c \ub2f4\uc740 pem \ud654\uc77c\uc744 \uac1c\ubc1c\uc790\uac00 \uc0dd\uc131\ud55c \ud6c4, \uc774\ub97c \ud1a0\ub300\ub85c bindSecure()\ub97c \uc2e4\ud589\ud558\ub294 \uc608\uc81c\uc774\ub2c8 \ucc38\uc870\ud558\uae30 \ubc14\ub78d\ub2c8\ub2e4. <\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/ Source: https:\/\/dart.dev\/tutorials\/server\/httpserver#using-https\n\nimport 'dart:io';\n\nString certificateChain = 'server_chain.pem';\nString serverKey = 'server_key.pem';\n\nFuture main() async {\n  var serverContext = SecurityContext(); \/*1*\/\n  serverContext.useCertificateChain(certificateChain); \/*2*\/\n  serverContext.usePrivateKey(serverKey, password: 'dartdart'); \/*3*\/\n\n  var server = await HttpServer.bindSecure(\n    'localhost',\n    4047,\n    serverContext, \/*4*\/\n  );\n  print('Listening on localhost:${server.port}');\n  await for (HttpRequest request in server) {\n    request.response.write('Hello, world!');\n    await request.response.close();\n  }\n}<\/code><\/pre>\n\n\n\n<h4>\ub9c8\ubb34\ub9ac<\/h4>\n\n\n\n<p>\ubb54\uac00 \uc774\uc0c1\ud569\ub2c8\ub2e4. POST Request\ub85c JSON \ud615\ud0dc\uc758 \uc790\ub8cc\ub97c \ubc1b\uc544\uc11c, \ud654\uc77c\ub85c \uc800\uc7a5\ub3c4 \ud558\uace0 Dart \uc5b8\uc5b4\uc758 Map \uc790\ub8cc \ud615\ud0dc\ub85c \ubcc0\uacbd\ub3c4 \ud574\uc8fc\ub294 \uc11c\ubc84 \ud504\ub85c\uadf8\ub7a8\uc744 \uac1c\ubc1c\ud588\uc9c0\ub9cc, \uc774\uc5d0 \ub300\ud55c \uc2e4\ud589 \ub3d9\uc791\uc740 \ubcf4\uc774\uc9c0 \uc54a\uc558\uc2b5\ub2c8\ub2e4. \uc774 \ud504\ub85c\uadf8\ub7a8\uc744 \uc218\ud589\ud558\ub824\uba74 HTTP Client\uac00 HTTP POST Request \uba54\uc138\uc9c0\ub97c HTTP Server\uc5d0\uac8c \uc804\ub2ec \ud560 \uc218 \uc788\uc5b4\uc57c \ud569\ub2c8\ub2e4. \ub2e4\uc74c \uae00\uc5d0\uc11c darttutorial-28-01.dart \ud504\ub85c\uadf8\ub7a8\uacfc \ub300\ud654\ub97c \ub098\ub20c HTTP POST Client \ud504\ub85c\uadf8\ub7a8\uc744 \ub9cc\ub4e4\uc5b4 \ubcf4\ub3c4\ub85d \ud558\uaca0\uc2b5\ub2c8\ub2e4.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"alignright is-resized\"><img decoding=\"async\" loading=\"lazy\" src=\"http:\/\/mobilelab.khu.ac.kr\/wordpress\/wp-content\/uploads\/2020\/01\/b05-1.jpg\" alt=\"\" class=\"wp-image-267\" width=\"135\" height=\"48\"\/><\/figure><\/div>\n\n\n\n<p><strong>Creative Commons License<\/strong> (<strong>CC BY-NC-ND<\/strong>)<\/p>\n","protected":false},"excerpt":{"rendered":"<p>&lt; HTTP \uc11c\ubc84\uac1c\ubc1c &#8211; GET &amp; POST in HTTP Server &gt; \uc0c1\uc138\ud55c \uc124\uba85\uc744 \ud558\uae30\uc804\uc5d0 \uac04\ub2e8\ud55c \uc791\uc5c5\uc744 \ud574 \ubd05\ub2c8\ub2e4. \uba3c\uc800, \uc55e\uc11c\uc5d0\uc11c \uc791\uc131\ud55c darttutorial-27-02.dart\ub97c \ub2e4\uc2dc \ubd88\ub7ec \uc635\ub2c8\ub2e4. \uadf8\ub9ac\uace0 handleRequest() \ud568\uc218\uc548\uc758 case &#8216;GET&#8217;: &#8230;<\/p>\n","protected":false},"author":1,"featured_media":980,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"om_disable_all_campaigns":false,"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0},"categories":[3],"tags":[14],"aioseo_notices":[],"_links":{"self":[{"href":"http:\/\/mobilelab.khu.ac.kr\/wordpress\/wp-json\/wp\/v2\/posts\/689"}],"collection":[{"href":"http:\/\/mobilelab.khu.ac.kr\/wordpress\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/mobilelab.khu.ac.kr\/wordpress\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/mobilelab.khu.ac.kr\/wordpress\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/mobilelab.khu.ac.kr\/wordpress\/wp-json\/wp\/v2\/comments?post=689"}],"version-history":[{"count":8,"href":"http:\/\/mobilelab.khu.ac.kr\/wordpress\/wp-json\/wp\/v2\/posts\/689\/revisions"}],"predecessor-version":[{"id":723,"href":"http:\/\/mobilelab.khu.ac.kr\/wordpress\/wp-json\/wp\/v2\/posts\/689\/revisions\/723"}],"wp:featuredmedia":[{"embeddable":true,"href":"http:\/\/mobilelab.khu.ac.kr\/wordpress\/wp-json\/wp\/v2\/media\/980"}],"wp:attachment":[{"href":"http:\/\/mobilelab.khu.ac.kr\/wordpress\/wp-json\/wp\/v2\/media?parent=689"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/mobilelab.khu.ac.kr\/wordpress\/wp-json\/wp\/v2\/categories?post=689"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/mobilelab.khu.ac.kr\/wordpress\/wp-json\/wp\/v2\/tags?post=689"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}