اتصال إلى URL من داخل التطبيق صغير باستخدام HttpClient وإصلاحه مقابل استخدام URLConnection جدك وأباتشي

StackOverflow https://stackoverflow.com/questions/1216165

سؤال

في التعليمة البرمجية التالية، والتحقق من أن الاتصال إلى URL من داخل التطبيق صغير يحفظ جلسة المتصفح إذا تم استخدام طبقة URLConnection JDK ل. ولكن هذا ليس هو الحال إذا تم استخدام مكتبة HttpClient وإصلاحه أباتشي. لا أحد يعرف لماذا؟ بدلا من ذلك، هل هناك طريقة بالنسبة لي لضبط سبيل المثال الاتصال لاستخدامها من قبل مثيل HttpClient وإصلاحه؟

import java.applet.Applet;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URISyntaxException;
import java.net.URL;

import javax.net.ssl.SSLException;

import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.BasicResponseHandler;
import org.apache.http.impl.client.DefaultHttpClient;

public class HttpClientTesterApplet extends Applet {
    private static final long serialVersionUID = -1599714556710568947L;

    public void testHttpClient() throws ClientProtocolException, IOException,
            URISyntaxException {
        URL url = new URL(String.format("%s://localhost:%s/%s/testHttpClient",
                getParameter("protocol"), getParameter("port"),
                getParameter("context")));

        HttpClient client = new DefaultHttpClient();

        HttpPost post = new HttpPost(url.toURI());

        System.out.println("Executing request " + post.getURI());

        try {
            System.out
                    .println(client.execute(post, new BasicResponseHandler()));
        } catch (SSLException e) {
            System.out.println(e.getMessage());
        }

        System.out.println("Executed request " + post.getURI());

        System.out.println("Opening connection " + url);

        HttpURLConnection urlConnection = (HttpURLConnection) url
                .openConnection();

        System.out.println("Opened connection " + url);

        urlConnection.setRequestMethod("POST");

        System.out.println("Connecting");

        urlConnection.connect();

        System.out.println("Connected");

        InputStream inputStream = urlConnection.getInputStream();

        try {
            while (inputStream.read() != -1) {
                System.out.println("Reading");
            }
        } finally {
            inputStream.close();
        }
    }
}
هل كانت مفيدة؟

المحلول

وهذه هي مشكلة مشتركة مع المكتبات تنفذ اتصال URL الخاصة بها عن طريق المقبس. على ما يبدو، وتنفيذ JRE الطبقة URLConnection يمكن الحصول على المعلومات المتصفح مباشرة. كان علينا أن نوظف هذه التقنية كما ذكر oscargm أعلاه، أي على appserver كتابة طلب الكوكيز لتكون المعلمات إلى برنامج صغير والحصول على وثيقة ملفات تعريف الارتباط بالمتصفح باستخدام جافا سكريبت (هذا هو لحالة SSO حيث بمجموعة ملفات تعريف الارتباط قد لا تكون هي نفسها بسبب وكيل وسيط - خوادم بروكسي). لاحظ أنه إذا كان ملفات تعريف الارتباط HttpOnly - ستفشل شفرة جافا سكريبت

نصائح أخرى

ويجب أن ترسل ملفات تعريف الارتباط jsessionid أو إعادة كتابة URL الخاص بك لاستخدام jsessionid.

وهذه هي الطريقة خادم يعرف جلسة العمل الخاصة بك.

إذا توليد العلامة applet في صفحة JSP حيوي يمكنك تمرير jsessionidvalue إلى التطبيق الصغير كمعلمة ثم استخدامه.

post.setHeader("Cookie", "jsessionid=" + jsessionidValue );

وأعتقد أنك تستخدم نسخة قديمة من HttpClient وإصلاحه. تحقق من HttpClient وإصلاحه في موقع .

في المعهد الحالي، يمكنك استخدام HttpState في طريقة تنفيذ، بحيث التعليمات البرمجية الخاصة بك يمكن أن تبدو مثل هذا:

HttpClient client = new HttpClient();
HttpMethod method = new PostMethod(url.toURI());
HttpState state = new HttpState();

client.executeMethod(HttpConfiguration.ANY_HOST_CONFIGURATION, method, state);

في تنفيذ المقبل، لتمرير نفس الكائن "الدولة"، وستحصل على وثائق التفويض والكوكيز الحفاظ عليها.

والأسباب المحتملة، هو أنك لم تكن قد فعلت قطع) عند استخدام URLConnection، ومع ذلك، فإن مكتبة اباتشي وإغلاق الاتصال عند الانتهاء (أنت معها.

وثي مسألة مهمة.

والطبقة java.net.URLConnection القياسية يدمج بسهولة مع البرنامج المساعد جافا ومتصفح الإنترنت، ويمكن أن ترث الدورة، الرموز المصادقة HTTP، وصلات وكيل، وما إلى ذلك.

جعلت

والرجال في العموم أباتشي خطأ فادحا عندما قرروا تنفيذ HttpClient وإصلاحه من المقبس (أي من الصفر) بدلا من مجرد وضع على رأس java.net.URL القياسية * الطبقات. HttpClient وإصلاحه لا يرث من java.net.URLConnection لذلك لا يمكن أن ترث ميزات المؤسسة المتطورة.

وربما مشاريع مفتوحة المصدر ليست ذكية بما يعتقدون.

وأنا يمكن أن تجعل من العمل دون المرور الكوكيز كوسائط من صفحة ويب مع هذا الرمز:

private String retrieveCookies(URL url) throws IOException, URISyntaxException 
{ 
     String cookieValue = null;

     CookieHandler handler = CookieHandler.getDefault();
     if (handler != null)    {
          Map<String, List<String>> headers = handler.get(url.toURI(), new HashMap<String, List<String>>());

          List<String> cookiesList = headers.get("Cookie");
          if (cookiesList != null)
          {
              for (String v : cookiesList) {
                  if (cookieValue == null) 
                      cookieValue = v; 
                  else
                      cookieValue = cookieValue + ";" + v; 
              }
          }
     } 
     return cookieValue; 
}

...

httppost.addHeader("Cookie", retrieveCookies(new URL(uploadUrl)));

وCookieHandler الطبقة JDK يمكن لحسن الحظ الحصول على الكوكيز من متجر "النظام". في هذه الحالة انها مخزن المتصفح، accesed عن طريق البرنامج المساعد جافا.

ونوع من "العمل اليدوي"، لكنه يعمل.

ملحوظة: لقد وجدت رمز هنا

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top