appkonthaiแอพคนไทย
Language
  • EN
  • TH
Font
  • M
  • L
  • XL
Theme
  • Light
  • Dark

HTTP Response

15 March 2018

15 มีนาคม 2561

HTTP Response

Concept

แนวคิด

การประมวลผลและตอบกลับ HTTP Request ที่ Client-side ส่งมา

The processing and response to the HTTP Request that sends from client-side.

Keywords

คีย์เวิร์ด

Requestข้อมูลที่ส่งมาจาก Client-side
Responseข้อมูลที่ Server-side ส่งกลับไป
HTTP Statusสถานะของ Response
HTTP Methodวิธีการรับส่งข้อมูล ตัวอย่างเช่น GET, POST
Serializationการแปลงข้อมูลให้อยู่ในรูปแบบที่สามารถรับส่งกันได้
Deserializationการแปลงข้อมูลที่ถูก Serialize แล้วกลับมาเป็นข้อมูลต้นฉบับ
RequestThe data sending from client-side.
ResponseThe send back data from server-side.
HTTP StatusThe status of the response.
HTTP MethodThe data sending method such as GET, POST.
SerializationThe data conversion to get the data that ready to send over the network.
DeserializationThe data conversion to get the original data.

บทความนี้เป็นบทความต่อเนื่องมาจากบทความก่อนหน้า คือ HTTP Request ซึ่งเป็นกระบวนการฝั่ง Client-side ในการทำ HTTP Request.

สำหรับบทความนี้จะเป็นกระบวนการฝั่ง Server-side เมื่อได้รับ Request จนกระทั่งส่ง Response กลับไป.

HTTP Response มีขั้นตอนการทำงานดังนี้

Server-side ได้รับ Request ที่ส่งเข้ามา

Server-side ตรวจสอบว่า Request นั้นส่งด้วย HTTP Method ใด เพื่อเลือกการประมวลผลที่เหมาะสม

Server-side เข้าถึงข้อมูลส่งมา ตามเงื่อนไขของ HTTP Method คือ

  • GET ดึงข้อมูลจาก Query String ใน URL โดยข้อมูลเหล่านี้จะต้องผ่านการทำ URL Decode เสียก่อนเพื่อแปลงกลับเป็นข้อมูลต้นฉบับ (เช่น การใช้ฟังชั่น decodeURIComponent บน JavaScript) แต่โดยทั่วไปตัว Web Server จะ Decode มาให้แล้ว
  • POST ดึงข้อมูลจาก Request Body โดยข้อมูลเหล่านี้จะต้องผ่านการ Deserialize เสียก่อนเพื่อแปลงกลับเป็นข้อมูลต้นฉบับ (เช่น การใช้ฟังชั่น JSON.parse บน JavaScript)

Server-side ประมวลผลจากข้อมูลที่ส่งมา

Server-side สร้าง Response และกำหนดค่า HTTP Status (ถ้าสำเร็จจะกำหนดเป็นค่า 200)

Server-side กำหนดข้อมูลที่ต้องการส่งกลับไป โดยข้อมูลเหล่านี้ถ้าไม่อยู่ในรูปแบบที่สามารถรับส่งได้ (ข้อมูลประเภท String) จะต้องผ่านการ Serialize เสียก่อน

Server-side กำหนดข้อมูลอื่นๆ เพิ่มเติมผ่านทาง HTTP Header ถ้าต้องการ เช่น Content-Type

Server-side ส่ง Response กลับไปให้ Client-side

HTTP Request

*เพื่อให้โค้ดตัวอย่างง่ายและกระชับ ผมจะใช้ HTTP ไลบรารี่พื้นฐานของแต่ละแพลตฟอร์มเท่านั้น

*โค้ดตัวอย่างนี้อ้างถึงโค้ดตัวอย่างในบทความก่อนหน้า คือ HTTP Request ซึ่งฝั่ง Client-side จะส่ง parameter ชื่อ client และ date ขึ้นมา

This is continued article from previous article HTTP Request which is the HTTP Request process on client-side.

This article will describe the server-side process when receiving the request until send back the response.

The HTTP Response has following steps.

Server-side check the HTTP Method of the request to determine how to process the request.

Server-side get the sending data according to HTTP Method.

  • GET get the data from Query String in the URL which this data must do URL decoding for convert it to the original data before use it (such as use decodeURIComponent function in JavaScript) but in general the URL decoding process already done by Web Server.
  • POST get the data from Request Body which this data must deserialize to convert it to the original data before use it (such as use JSON.parse function in JavaScript).

Server-side process the request.

Server-side create the response and define the HTTP Status (200 for success).

Server-side define the response data which this data need to serialize first if it's not ready to transfer.

Server-side define other data through HTTP Header, if needed, such as Content-Type.

Server-side send back the response to the client-side.

HTTP Request

*To keep the example code simple, I will use only native HTTP library on each platform.

*This example code refer to previous example code in HTTP Request which client-side will have "client" and "date" parameter in the request.

  • ASP.NET
  • ASP.NET Core
  • Java EE
  • Node.js
  • PHP

//Generic Handler

<%@ WebHandler Language="C#" Class="HttpResponse" %>

using System.Collections.Generic;
using System.IO;
using System.Web;
using System.Web.Script.Serialization;

public class HttpResponse : IHttpHandler {

	public class Response
	{
		public string method;
		public string client;
		public string date;
	}

	public void ProcessRequest(HttpContext context) {
		var res = new Response();
		res.method = context.Request.HttpMethod;
		if (res.method == "GET")
		{
			res.client = context.Request.QueryString["client"];
			res.date = context.Request.QueryString["date"];
		}
		else if (res.method == "POST")
		{
			var body = new StreamReader(context.Request.InputStream).ReadToEnd();
			var dict = new JavaScriptSerializer().Deserialize<Dictionary<string, string>>(body);
			res.client = dict["client"];
			res.date = dict["date"];
		}
		var json = new JavaScriptSerializer().Serialize(res);
		context.Response.Write(json);
	}

	public bool IsReusable {
		get {
			return false;
		}
	}
}

//HTTP.sys

using System.Collections.Generic;
using System.IO;

using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;

using Newtonsoft.Json;

public class Response
{
	public string method;
	public string client;
	public string date;
}

public class Program
{
	public static void Main(string[] args)
	{
		WebHost.CreateDefaultBuilder(args)
			.UseStartup<Startup>()
			.UseHttpSys(options =>
			{
				options.UrlPrefixes.Add("http://localhost:8080");
			})
			.Build().Run();
	}
}

public class Startup
{
	public void ConfigureServices(IServiceCollection services)
	{
	}

	public void Configure(IApplicationBuilder app)
	{
		app.Run(async (context) =>
		{
			var res = new Response();
			res.method = context.Request.Method;
			if (res.method == "GET")
			{
				res.client = context.Request.Query["client"];
				res.date = context.Request.Query["date"];
			}
			else if (res.method == "POST")
			{
				var body = new StreamReader(context.Request.Body).ReadToEnd();
				var dict = JsonConvert.DeserializeObject<Dictionary<string, string>>(body);
				res.client = dict["client"];
				res.date = dict["date"];
			}
			var json = JsonConvert.SerializeObject(res);
			await context.Response.WriteAsync(json);
		});
	}
}

//Servlet

import java.io.*;
import java.util.HashMap;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.*;

@WebServlet("/HttpResponse")
public class HttpResponse extends HttpServlet {
	
	private static final long serialVersionUID = 1L;
	
	public class Response {
		public String method;
		public String client;
		public String date;
	}

    public HttpResponse() {
    	
    }

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		process(request, response);
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		process(request, response);
	}
	
	public void process(HttpServletRequest request, HttpServletResponse response) throws IOException {
		Response res = new Response();
		res.method = request.getMethod();
		if (res.method == "GET") {
			res.client = request.getParameter("client");
			res.date = request.getParameter("date");
		}
		else if (res.method == "POST") {
			String body = streamToString(request.getInputStream());
			HashMap<String, String> dict = new HashMap<String, String>();
			dict = new com.google.gson.Gson().fromJson(body, dict.getClass());
			res.client = dict.get("client");
			res.date = dict.get("date");
		}
		String json = new com.google.gson.Gson().toJson(res);
		response.getWriter().write(json);
	}
	
	public String streamToString(InputStream input)
	{
		try {
			InputStream stream = new BufferedInputStream(input);
			StringBuilder builder = new StringBuilder();
			String line;
			BufferedReader reader = new BufferedReader(new InputStreamReader(stream));	
			while ((line = reader.readLine()) != null) {
				builder.append(line);
			}
			return builder.toString();
		}
		catch (Exception e) {
			return null;
		}
	}
}

//HTTP Module

var http = require('http');
var url = require('url');

http.createServer(function(request, response) {
	var res = {};
	res.method = request.method;
	if (res.method == 'GET') {
		var query = url.parse(request.url, true).query;
		res.client = query.client;
		res.date = query.date;
		response.write(JSON.stringify(res));
		response.end();
	}
	else if (res.method == 'POST') {
		var body = '';
		request.on('data', function (data) {
			body += data;
		});
		request.on('end', function (data) {
			var dict = JSON.parse(body);
			res.client = dict.client;
			res.date = dict.date;
			response.write(JSON.stringify(res));
			response.end();
		});
	}
}).listen(8080);

<?php
	class Response {
		public $method;
		public $client;
		public $date;
	}
	$res = new Response();
	$res->method = $_SERVER["REQUEST_METHOD"];
	if ($res->method == "GET")
	{
		$res->client = $_GET["client"];
		$res->date = $_GET["date"];
	}
	else if ($res->method == "POST")
	{
		$body = file_get_contents('php://input');
		$dict = json_decode($body);
		$res->client = $dict->{"client"};
		$res->date = $dict->{"date"};
	}
	$json = json_encode($res);
	echo $json;
?>
ประสมศักดิ์ ขุนหมื่น Prasomsak Khunmuen

แค่โปรแกรมเมอร์คนไทย ที่รักการเขียนโปรแกรม

I'm just a Thai Programmer who loves programming.