3

Java でサイトにログインするのにかなり問題があります。デフォルトの URLconnection POST リクエストを使用していますが、Cookie を適切に処理する方法がわかりません。このガイドを試してみました: http://www.hccp.org/java-net-cookie-how-to.htmlしかし、うまくいきませんでした。私は基本的に何日も努力してきましたが、誰かが私を助けたいと思ったら本当に助けが必要です.

おそらく、これは面倒なので、このようなもの用のカスタム ライブラリを使用する必要があると言われるでしょう。ダウンロードしてみましたが、セットアップして動作させる方法がわかりませんでした。私は何時間もの間、さまざまなことを試してきましたが、うまくいきません。私はむしろ標準の URL 接続でこれを行いたいのですが、誰かがこれに適した別のライブラリを動作させるのを手伝ってくれるなら、それも素晴らしいでしょう.

誰かが私が研究できる作業ソースを投稿できれば、本当に感謝しています。必要なのは、ログイン データをサイトに POST する -> サイトから Cookie を取得して保存する -> 次の URL 接続要求で Cookie を使用して、サイトのログイン バージョンを取得することです。

誰でもこれで私を助けることができますか?非常に高く評価されます。それは本当に多くのことを意味します。ライブで実際に私を手伝ってくれる人がいたら、インスタントメッセンジャーのアドレスを残してください. ありがとうございました。

package org.hccp.net;


import java.net.*;
import java.io.*;
import java.util.*;
import java.text.*;

    /**
     * CookieManager is a simple utilty for handling cookies when working
     * with java.net.URL and java.net.URLConnection
     * objects.
     * 
     * 
     *     Cookiemanager cm = new CookieManager();
     *     URL url = new URL("http://www.hccp.org/test/cookieTest.jsp");
     *     
     *      . . . 
     *
     *     // getting cookies:
     *     URLConnection conn = url.openConnection();
     *     conn.connect();
     *
     *     // setting cookies
     *     cm.storeCookies(conn);
     *     cm.setCookies(url.openConnection());
     * 
     *     @author Ian Brown
     *      
     **/

public class CookieManager {
        
    private Map store;

    private static final String SET_COOKIE = "Set-Cookie";
    private static final String COOKIE_VALUE_DELIMITER = ";";
    private static final String PATH = "path";
    private static final String EXPIRES = "expires";
    private static final String DATE_FORMAT = "EEE, dd-MMM-yyyy hh:mm:ss z";
    private static final String SET_COOKIE_SEPARATOR="; ";
    private static final String COOKIE = "Cookie";

    private static final char NAME_VALUE_SEPARATOR = '=';
    private static final char DOT = '.';
    
    private DateFormat dateFormat;

    public CookieManager() {

    store = new HashMap();
    dateFormat = new SimpleDateFormat(DATE_FORMAT);
    }
    

    /**
     * Retrieves and stores cookies returned by the host on the other side
     * of the the open java.net.URLConnection.
     *
     * The connection MUST have been opened using the connect()
     * method or a IOException will be thrown.
     *
     * @param conn a java.net.URLConnection - must be open, or IOException will be thrown
     * @throws java.io.IOException Thrown if conn is not open.
     */
    public void storeCookies(URLConnection conn) throws IOException {
    
    // let's determine the domain from where these cookies are being sent
    String domain = getDomainFromHost(conn.getURL().getHost());
    
    
    Map domainStore; // this is where we will store cookies for this domain
    
    // now let's check the store to see if we have an entry for this domain
    if (store.containsKey(domain)) {
        // we do, so lets retrieve it from the store
        domainStore = (Map)store.get(domain);
    } else {
        // we don't, so let's create it and put it in the store
        domainStore = new HashMap();
        store.put(domain, domainStore);    
    }
    
    
    
    
    // OK, now we are ready to get the cookies out of the URLConnection
    
    String headerName=null;
    for (int i=1; (headerName = conn.getHeaderFieldKey(i)) != null; i++) {
        if (headerName.equalsIgnoreCase(SET_COOKIE)) {
        Map cookie = new HashMap();
        StringTokenizer st = new StringTokenizer(conn.getHeaderField(i), COOKIE_VALUE_DELIMITER);
        
        // the specification dictates that the first name/value pair
        // in the string is the cookie name and value, so let's handle
        // them as a special case: 
        
        if (st.hasMoreTokens()) {
            String token  = st.nextToken();
            String name = token.substring(0, token.indexOf(NAME_VALUE_SEPARATOR));
            String value = token.substring(token.indexOf(NAME_VALUE_SEPARATOR) + 1, token.length());
            domainStore.put(name, cookie);
            cookie.put(name, value);
        }
    
        while (st.hasMoreTokens()) {
            String token  = st.nextToken();
            cookie.put(token.substring(0, token.indexOf(NAME_VALUE_SEPARATOR)).toLowerCase(),
             token.substring(token.indexOf(NAME_VALUE_SEPARATOR) + 1, token.length()));
        }
        }
    }
    }
 

    /**
     * Prior to opening a URLConnection, calling this method will set all
     * unexpired cookies that match the path or subpaths for thi underlying URL
     *
     * The connection MUST NOT have been opened 
     * method or an IOException will be thrown.
     *
     * @param conn a java.net.URLConnection - must NOT be open, or IOException will be thrown
     * @throws java.io.IOException Thrown if conn has already been opened.
     */
    public void setCookies(URLConnection conn) throws IOException {
    
    // let's determine the domain and path to retrieve the appropriate cookies
    URL url = conn.getURL();
    String domain = getDomainFromHost(url.getHost());
    String path = url.getPath();
    
    Map domainStore = (Map)store.get(domain);
    if (domainStore == null) return;
    StringBuffer cookieStringBuffer = new StringBuffer();
    
    Iterator cookieNames = domainStore.keySet().iterator();
    while(cookieNames.hasNext()) {
        String cookieName = (String)cookieNames.next();
        Map cookie = (Map)domainStore.get(cookieName);
        // check cookie to ensure path matches  and cookie is not expired
        // if all is cool, add cookie to header string 
        if (comparePaths((String)cookie.get(PATH), path) && isNotExpired((String)cookie.get(EXPIRES))) {
        cookieStringBuffer.append(cookieName);
        cookieStringBuffer.append("=");
        cookieStringBuffer.append((String)cookie.get(cookieName));
        if (cookieNames.hasNext()) cookieStringBuffer.append(SET_COOKIE_SEPARATOR);
        }
    }
    try {
        conn.setRequestProperty(COOKIE, cookieStringBuffer.toString());
    } catch (java.lang.IllegalStateException ise) {
        IOException ioe = new IOException("Illegal State! Cookies cannot be set on a URLConnection that is already connected. " 
        + "Only call setCookies(java.net.URLConnection) AFTER calling java.net.URLConnection.connect().");
        throw ioe;
    }
    }

    private String getDomainFromHost(String host) {
    if (host.indexOf(DOT) != host.lastIndexOf(DOT)) {
        return host.substring(host.indexOf(DOT) + 1);
    } else {
        return host;
    }
    }

    private boolean isNotExpired(String cookieExpires) {
    if (cookieExpires == null) return true;
    Date now = new Date();
    try {
        return (now.compareTo(dateFormat.parse(cookieExpires))) <= 0;
    } catch (java.text.ParseException pe) {
        pe.printStackTrace();
        return false;
    }
    }

    private boolean comparePaths(String cookiePath, String targetPath) {
    if (cookiePath == null) {
        return true;
    } else if (cookiePath.equals("/")) {
        return true;
    } else if (targetPath.regionMatches(0, cookiePath, 0, cookiePath.length())) {
        return true;
    } else {
        return false;
    }
    
    }
    
    /**
     * Returns a string representation of stored cookies organized by domain.
     */

    public String toString() {
    return store.toString();
    }
    
    public static void main(String[] args) { 
    CookieManager cm = new CookieManager();
    try {
        URL url = new URL("http://www.hccp.org/test/cookieTest.jsp");
        URLConnection conn = url.openConnection();
        conn.connect();
        cm.storeCookies(conn);
        System.out.println(cm);
        cm.setCookies(url.openConnection());
    } catch (IOException ioe) {
        ioe.printStackTrace();
    }
    }
}
    
4

1 に答える 1

6

このコードは私のために働きます:

ログインフォームの取得(私の場合、ログインページを取得するとCookieが実際に設定されます)

    URL url = new URL(formPage);
    URLConnection conn = url.openConnection();

    String cookieHeader = conn.getHeaderFields().get("Set-Cookie").get(0);
    Matcher m = JSESSION_PATTERN.matcher(cookieHeader);
    m.find();
    jSessionId = m.group(1);

また、csrf値も取得する必要がありますが、ここでは省略します。

次に、次のようにしてログインします。

    URL url = new URL(formPage);

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

    conn.setRequestProperty("Cookie", "JSESSIONID=" + encode(jSessionId, "UTF-8")); 

    conn.setRequestMethod("POST");
    conn.setDoOutput(true);
    conn.setDoInput(true);

    DataOutputStream out = new DataOutputStream(conn.getOutputStream());
    out.writeBytes(String.format("_csrf_token=%s&xyz=%s&zyx=%s",
            encode(csrfToken, "UTF-8"),
            encode(USER, "UTF-8"),
            encode(PASS, "UTF-8")));

    out.close();

    // I have absolutely no idea why this is needed.
    conn.getInputStream().close();


    String cookieHeader = conn.getHeaderFields().get("Set-Cookie").get(0);
    Matcher m = JSESSION_PATTERN.matcher(cookieHeader);
    m.find();
    jSessionId = m.group(1);

その後、を使用してページを取得して処理できます

    URL url = new URL(thePage);
    URLConnection conn = url.openConnection();

    conn.setRequestProperty("Cookie", "JSESSIONID=" + encode(jSessionId, "UTF-8")); 

    BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
    String str;
    while ((str = in.readLine()) != null) {
        // process str...

お役に立てば幸いです。

于 2010-06-17T11:03:30.617 に答える