apache HttpClient 學習系列--2 之HttpContext

首先是一個Servlet用於本次試驗。html

package com.lu.controller;

import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

@SuppressWarnings("serial")
public class RirectServlet extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        this.doPost(request, response);
    }

    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        request.setCharacterEncoding("UTF-8");
        response.setContentType("text/html;charset=utf-8");

        OutputStream out = response.getOutputStream();
        PrintWriter pw = new PrintWriter(out);

        // 記錄返回的內容
        String returnContent = null;

        HttpSession session = request.getSession();
        String user = (String) session.getAttribute("username");

        // 若是不爲空,說明已登陸
        if (user != null) {
            returnContent = "you have been logined, " + user;
        } else {
            // 爲空說明未登陸,設置username到session中
            String username = request.getParameter("username");
            session.setAttribute("username", username);
            returnContent = "login success";
        }

        try {
            pw.println(returnContent);
        } finally {
            pw.close();
            out.close();
        }
    }

}

在本機中訪問URI爲:http://localhost:8080/spiderweb/RirectServletjava

下面看請求web

package com.lu.test;

import java.util.ArrayList;
import java.util.List;

import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.protocol.HttpClientContext;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.protocol.BasicHttpContext;
import org.apache.http.protocol.HttpContext;
import org.apache.http.util.EntityUtils;

public class HttpClientTest {

    private static HttpContext localContext = new BasicHttpContext();
    private static HttpClientContext context = HttpClientContext
            .adapt(localContext);

    public static void main(String[] args) throws Exception {
        CloseableHttpClient httpClient = HttpClients.createDefault();

        try {
            // 模擬表單
            List<NameValuePair> params = new ArrayList<NameValuePair>();
            params.add(new BasicNameValuePair("username", "**"));
            UrlEncodedFormEntity entity = new UrlEncodedFormEntity(params,
                    "UTF-8");
            HttpPost httpPost = new HttpPost(
                    "http://localhost:8080/spiderweb/RirectServlet");
            httpPost.setEntity(entity);

            // 將HttpClientContext傳入execute()中
            CloseableHttpResponse response = httpClient.execute(httpPost,
                    context);

            try {
                HttpEntity responseEntity = response.getEntity();
                System.out.println(EntityUtils.toString(responseEntity));

            } finally {
                response.close();
            }
        } finally {
            httpClient.close();
        }

        CloseableHttpClient httpClient2 = HttpClients.createDefault();

        try {
            HttpGet httpGet = new HttpGet(
                    "http://localhost:8080/spiderweb/RirectServlet");

            // 設置相同的HttpClientContext
            CloseableHttpResponse response = httpClient2.execute(httpGet,
                    context);
            try {
                HttpEntity entity = response.getEntity();
                System.out.println(EntityUtils.toString(entity));
            } finally {
                response.close();
            }
        } finally {
            httpClient2.close();
        }

    }
}

輸出結果爲:apache

login success
you have been logined, **瀏覽器


可能你們認爲這個結果很正常。第一次登錄了,第二次確定會輸出you have been logined, **。可是你們別忘了,如今不是在瀏覽器環境下,瀏覽器會幫你提取服務器傳回的sessionId並在你下次請求的時候傳給服務器,那麼兩次請求用的就是同一個session對象,那麼天然的就會有上面的輸出。服務器

可是如今是在本身寫代碼訪問。咱們沒有獲取sessionId,也沒有向服務器傳送sessionId,那麼兩次請求服務器就會爲你建立兩個sessionId不一樣的session對象。cookie

那爲何輸出結果倒是跟瀏覽器獲得的結果同樣呢?確定是什麼東西爲咱們自動完成了獲取sessionId傳送sessionId的功能。毫無疑問,就是context。 BasicHttpContext裏有個Map<Object,Object>的對象用來記錄一次請求響應的信息,當響應信息返回時,就會被set到context裏,固然響應的cookie信息也就被存儲在context裏,包括傳回的sessionId。session

當第二次請求的時候傳入相同的context,那麼請求的過程當中會將context裏的sessionId提取出來傳給服務器,sessionId同樣,天然而然的就是同一個session對象。
那麼你們明白context的做用了嗎?
按照官方教程的說法來講ide

表明一個邏輯相關的會話的多個請求序列應該具備相同的HttpContext實例以確保請求之間的信息狀態的自動傳播this



因爲初學,不對的地方還望你們指出。

相關文章
相關標籤/搜索