天天看點

C# 模拟浏覽器 發生 JSON 格式 Http請求,Java 服務端響應Json 格式的Http 請求

一、前言

1. 月初公司接到美的的一個單,需要我寫一個需要支援USB線上燒錄和支援聯網上傳日志的燒錄工具,客戶提供伺服器接口,

使用Http協定POST 請求方式進行資料交換,交換格式使用JSON.看到這個協定時,覺得應該挺簡單的,因為自己最近在學習Java Web 方面的知識,剛好可以自己編寫用戶端燒錄軟體,然後自己編寫Java 服務端進行測試。于是記錄一下自己對于這個項目的經驗總結。

二、知識

1. HTTP協定是Hyper Text Transfer Protocol(超文本傳輸協定)的縮寫,是用于從網際網路(WWW:World Wide Web )伺服器傳輸超文本到本地浏覽器的傳送協定。 

即:主要時使用者傳輸文本。

2. HTTP預設端口号為80,但是你也可以改為8080或者其他端口。

3. 浏覽器作為HTTP用戶端通過URL向HTTP服務端即WEB伺服器發送所有請求,服務端響應用戶端所有請求。

根據HTTP标準,HTTP請求可以使用多種請求方法。

HTTP1.0定義了三種請求方法: GET, POST 和 HEAD方法。

HTTP1.1新增了五種請求方法:OPTIONS, PUT, DELETE, TRACE 和 CONNECT 方法。

4. 

用戶端請求消息

用戶端發送一個HTTP請求到伺服器的請求消息包括以下格式:請求行(request line)、請求頭部(header)、空行和請求資料四個部分組成,下圖給出了請求封包的一般格式。

伺服器響應消息

HTTP響應也由四個部分組成,分别是:狀态行、消息報頭、空行和響應正文。

http定義了與伺服器互動的不同方法,最常用的方法有2種,分别是GET,POST

其中最重要的兩種方法:GET是向伺服器發索取資料的一種請求,而POST是向伺服器送出資料的一種請求。

抓包可以顯示,浏覽器輸入網址(URL)後,點選回車,第一次通路伺服器為GET請求,本地并未儲存任何cookies資訊,故http請求頭部中并未包含任何cookie資訊。

5. 使用C# 模拟浏覽器發送請求時,根據協定,則請求類型(Content-type)  為 JSON , 請求中送出資料為 JSON 格式字元串,

Java 伺服器響應的是,在HttpResponse 中,傳回資料的類型 SetContentType 不是 “text/html; Charset=utf-8” 而是 JSON.

三、代碼如下

1. C# 模拟浏覽器發送POST請求, 請求類型為JSON 

/// <summary>
    /// http請求
    /// </summary>
    class HttpWeb
    {
        public static string HttpSendPostRequest(string url, string param)
        {
            var result = string.Empty;
            //注意送出的編碼 這邊是需要改變的 這邊預設的是Default:系統目前編碼
            byte[] postData = Encoding.UTF8.GetBytes(param);

            // 設定送出的相關參數 
            HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;
            Encoding myEncoding = Encoding.UTF8;
            
            request.Method = "POST";
            request.KeepAlive = false;
            request.AllowAutoRedirect = true;
            request.ContentType = "application/json";            //請求類型JSON
            request.UserAgent = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727; .NET CLR  3.0.04506.648; .NET CLR 3.5.21022; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)";
            request.ContentLength = postData.Length;
            request.Timeout = 5000;

            // 送出請求資料 
            System.IO.Stream outputStream = request.GetRequestStream();
            outputStream.Write(postData, 0, postData.Length);
            outputStream.Close();

            HttpWebResponse response;
            Stream responseStream;
            StreamReader reader;
            string srcString;
           
            response = request.GetResponse() as HttpWebResponse;
            switch(response.StatusCode)
            {
                case HttpStatusCode.OK:
                    break;

                default:
                    response.Close();
                    throw new Exception("向伺服器發送請求失敗");
            }

            responseStream = response.GetResponseStream();
            reader = new System.IO.StreamReader(responseStream, Encoding.GetEncoding("UTF-8"));
            
            srcString = reader.ReadToEnd();
            result = srcString;   //傳回值指派
            
            reader.Close();
            response.Close();

            return result;
        }
    }
           

2. Java WEB 服務端代碼

public class RfidSerialNumberServlet extends HttpServlet
{
	private static final String TAG = RfidSerialNumberServlet.class.getSimpleName();
    /**
     * @see HttpServlet#HttpServlet()
     */
    public RfidSerialNumberServlet() {
        super();
        // TODO Auto-generated constructor stub
    }

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		
		String jsonData = null;
		
		try
		{
			jsonData = Utils.GetHttpServletRequestData(request);			//擷取Http請求資料
		} 
		catch (Exception e)
		{
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		//講Json 序列化
		RfidSerialNumber rfidSerialNumber = (RfidSerialNumber)JsonUtils.jsonToBean(jsonData, RfidSerialNumber.class);
				
		Log.d(TAG, "收到設定線體号和工單号請求 , url = " + request.getRequestURL() +  ", 資料 = " + jsonData);
		Log.d(TAG, "線體号 = " + rfidSerialNumber.getLineNo());
		Log.d(TAG, "工單号 = " + rfidSerialNumber.getWorksheetSn());
		
		RfidSerailNumberResult result = new RfidSerailNumberResult();
		
		result.setDesc("操作成功");
		result.setRetCode("0");
		
		RfidSerailNumberResult.Result rst = result.new Result();
		
		rst.setGuid("12345678");
		result.setResult(rst);
		
		response.setCharacterEncoding("UTF-8");
		response.setContentType("application/json; charset=utf-8");				//設定傳回資料類型為JSON
		response.getWriter().write(JsonUtils.doMainToJson(result));	
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		doGet(request, response);
	}

}
           

參考:菜鳥教程網 - http 學習 (一個挺好的網站)