Запутался с разными методами создания куки в HttpClient

Существуют разные способы создания файлов cookie в HttpClient, я не понимаю, какой из них лучше. Мне нужно создавать, извлекать и изменять файлы cookie.

Например, я могу использовать следующий код, чтобы просмотреть список файлов cookie и изменить их, но как их создать?

Это правильный метод для их извлечения? Мне нужно, чтобы они были доступны во всех классах.

  • Кроме того, методы, которые я обнаружил, обычно требуют объектов httpresponse, httprequest для отправки файла cookie в браузер, но что если я не хочу их использовать?

Код

import org.apache.commons.httpclient.Cookie;
import org.apache.commons.httpclient.HttpState;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.methods.GetMethod;

public class GetCookiePrintAndSetValue {

  public static void main(String args[]) throws Exception {

    HttpClient client = new HttpClient();
    client.getParams().setParameter("http.useragent", "My Browser");

    GetMethod method = new GetMethod("http://localhost:8080/");
    try{
      client.executeMethod(method);
      Cookie[] cookies = client.getState().getCookies();
      for (int i = 0; i < cookies.length; i++) {
        Cookie cookie = cookies[i];
        System.err.println(
          "Cookie: " + cookie.getName() +
          ", Value: " + cookie.getValue() +
          ", IsPersistent?: " + cookie.isPersistent() +
          ", Expiry Date: " + cookie.getExpiryDate() +
          ", Comment: " + cookie.getComment());

        cookie.setValue("My own value");
      }
      client.executeMethod(method);
    } catch(Exception e) {
      System.err.println(e);
    } finally {
      method.releaseConnection();
    }
  }
}

И я пытался создать файл cookie, используя следующий код, но он не

import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.methods.GetMethod;

....

public String execute() {
try{

     System.err.println("Creating the cookie");
     HttpClient httpclient = new HttpClient();
     httpclient.getParams().setParameter("http.useragent", "My Browser");

     GetMethod method = new GetMethod("http://localhost:8080/");
     httpclient.executeMethod(method);
     org.apache.commons.httpclient.Cookie cookie = new 
                                                org.apache.commons.httpclient.Cookie();
     cookie.setPath("/");
     cookie.setName("Tim");
     cookie.setValue("Tim");
     cookie.setDomain("localhost");
     httpclient.getState().addCookie(cookie);
     httpclient.executeMethod(method);
     System.err.println("cookie");

  }catch(Exception e){
     e.printStackTrace();
  }

Вывод выглядит следующим образом, но файл cookie не создается.

SEVERE: Creating the cookie
SEVERE: cookie

Сценарий

1)User has access to a form to search for products (example.com/Search/Products)
2)User fills up the form and submit it to class Search
3)Form will be submitted to Search class 
4)Method Products of Search class returns and shows the description of product        
  (example.com/Search/Products)
5)User clicks on "more" button for more description about product 
6)Request will be sent to Product class (example.com/Product/Description?id=4)
7)User clicks on "add to cookie" button to add the product id to the cookie 

Product class is subclasse of another class. So it can not extend any more class.

person Community    schedule 22.07.2013    source источник
comment
Вам нужно создать CookieStore и установить его в контексте каждый раз, когда вы делаете запрос. Вот так. in-httpclient-4-1" title="как обрабатывать сеанс в httpclient 4 1"> stackoverflow.com/questions/6272575/   -  person Phani    schedule 24.07.2013


Ответы (2)


Во втором примере вы создаете новый файл cookie на стороне клиента (т. е. вы имитируете браузер и отправляете файл cookie на сервер).

Это означает, что вам необходимо предоставить всю соответствующую информацию, чтобы клиент мог решить, отправлять ли файл cookie на сервер или нет.

В коде вы правильно указали путь, имя и значение, но информация домен отсутствует.

org.apache.commons.httpclient.Cookie cookie 
  = new org.apache.commons.httpclient.Cookie();
cookie.setDomain("localhost");
cookie.setPath("/");
cookie.setName("Tim");
cookie.setValue("Tim");

Это работает, если вы пытаетесь отправить файл cookie на http-сервер.

Однако ваш второй пример основан на методе execute, и, поскольку вы намекаете на struts2 в своем теге, возможно, класс, содержащий его, должен быть struts2 Action.

В этом случае вы пытаетесь отправить новый файл cookie в браузер.

Первый подход состоит в том, чтобы получить HttpServletResponse как в:

Итак, ваш Action должен выглядеть так:

public class SetCookieAction 
    implements ServletResponseAware  // needed to access the 
                                     // HttpServletResponse
{

    HttpServletResponse servletResponse;

    public String execute() {
        // Create the cookie
        Cookie div = new Cookie("Tim", "Tim");
        div.setMaxAge(3600); // lasts one hour 
        servletResponse.addCookie(div);
        return "success";
    }


    public void setServletResponse(HttpServletResponse servletResponse) {
        this.servletResponse = servletResponse;
    }

}

Другой подход (без HttpServletResponse) можно получить с помощью CookieProviderInterceptor.

Включите его в struts.xml

<action ... >
  <interceptor-ref name="defaultStack"/>
  <interceptor-ref name="cookieProvider"/>
  ...
</action>

затем реализуйте CookieProvider как:

public class SetCookieAction 
    implements CookieProvider  // needed to provide the coookies
{

    Set<javax.servlet.http.Cookie> cookies=
            new HashSet<javax.servlet.http.Cookie>();

    public Set<javax.servlet.http.Cookie> getCookies() 
    {
            return cookies;
    }

    public String execute() {
        // Create the cookie
        javax.servlet.http.Cookie div = 
                new javax.servlet.http.Cookie("Tim", "Tim");
        div.setMaxAge(3600); // lasts one hour 
        cookies.put(cookie)
        return "success";
    }

}

(кредиты @RomanC за указание на это решение)

Если вам впоследствии понадобится прочитать его, у вас есть два варианта:

  • внедрите ServletRequestAware в свой Action и прочитайте куки из HttpServletRequest
  • введите CookieInterceptor и внедрите CookiesAware в свой Action, метод setCookieMap позволяет читать файлы cookie.

Здесь вы можете найти актуальную информацию:

person Carlo Pellegrini    schedule 22.07.2013
comment
Я добавил setDomain и изменил его на localhost, localhost:8080 и localhost:8080, но ни один из них не работал. - person Tim Norman; 23.07.2013
comment
Для предоставленного вами кода ответ должен работать (я разместил тест на Github). Мне интересно, как вы проверяете правильность отправки файла cookie (может быть, тег Struts2 относится к серверному приложению?). Является ли вопрос как я могу отправить файл cookie клиенту с помощью Struts2 или как я могу отправить собственный файл cookie на сервер с помощью commons-httpclient? - person Carlo Pellegrini; 24.07.2013
comment
Я не уверен в этих именах, но я полагаю, что httpclient, поскольку мне нужно создавать, изменять и удалять файлы cookie без объекта запроса и ответа. Вопрос обновлен - person Tim Norman; 25.07.2013
comment
Я также пытался использовать другой код, но он не распознает его в server.setHandler(this); хотя я использовал org.mortbay.jetty.Server и не уверен, что это вызывает проблему. - person Tim Norman; 25.07.2013
comment
Извините, но я все еще озадачен. Возможно, если бы вы объяснили общий сценарий, мы могли бы быть более полезными. Вы пытаетесь подключиться к существующему серверу из автономного приложения? - person Carlo Pellegrini; 25.07.2013
comment
@CarloPellegrini OP говорит, что нельзя использовать запрос и ответ. - person Roman C; 25.07.2013
comment
@RomanC Я знаю, но другого пути просто нет (в среде Servlet или Struts2) - person Carlo Pellegrini; 25.07.2013
comment
@CarloPellegrini Тогда вы должны объяснить это в ответе, а не в комментариях. - person Roman C; 25.07.2013
comment
@RomanC Я думал, что уже сделал это. В любом случае я отредактировал ответ, чтобы подчеркнуть информацию. - person Carlo Pellegrini; 25.07.2013
comment
@CarloPellegrini Но вы ошибаетесь, а как насчет перехватчика cookie-провайдера? - person Roman C; 25.07.2013
comment
давайте продолжим обсуждение в чате - person Carlo Pellegrini; 25.07.2013
comment
Я уже добавил определения перехватчиков в свой файл struts.xml, но когда я реализую интерфейс CooKieProvider, он показывает, что его не существует. - person Tim Norman; 26.07.2013
comment
@RomanC каковы плюсы и минусы каждого подхода? У меня есть класс действий, которому нужно вызвать метод другого класса, и этот метод будет получать доступ к файлу cookie, поэтому меня не интересуют объекты ответа на запрос, поскольку второй метод расширяет другой класс, поэтому он не может расширить класс ActionSuper - person Tim Norman; 26.07.2013
comment
@TimNorman Вы должны уточнить № 7 в своем сценарии, неясно, чего вы пытаетесь достичь. - person Roman C; 26.07.2013
comment
@TimNorman Вы сможете найти org.apache.struts2.interceptor.CookieProvider (он совершенно новый, доступен в struts с версии 2.3.15) - person Carlo Pellegrini; 26.07.2013
comment
@TimNorman В № 7 вы можете создать файл cookie двумя способами: * на стороне клиента: через JavaScript, см. document.cookie * на стороне сервера: кнопка приведет к действию, подобному тому, что указано в ответе. Какой сценарий вы используете? - person Carlo Pellegrini; 26.07.2013

Во-первых, вы, вероятно, не хотите использовать HttpClient, который является клиентом (например, эмулирует браузер), а не сервером (который может создавать файлы cookie, которые будут храниться в браузере пользователя).

Тем не менее, я сначала объясню, что происходит в вашем первом примере кода:

  • Вы отправляете GET-запрос на сервер
  • Сервер отправляет вам несколько файлов cookie вместе с ответом (контентом)
  • Вы изменяете файлы cookie в своем экземпляре HttpClient.
  • Вы отправляете эти файлы cookie обратно на сервер
  • То, что сервер делает с вашими измененными файлами cookie, полностью зависит от того, на что запрограммирован этот сервер.
  • При следующем запросе сервер может отправить вам эти измененные файлы cookie или нет, что, как я уже сказал, зависит от того, на что он запрограммирован.

Что касается вашего второго примера:

  • Вы создаете файл cookie
  • Вы устанавливаете некоторую информацию в файле cookie
  • Вы отправляете файл cookie на сервер (внутри вашего запроса GET)
  • Теперь сервер делает с вашим файлом cookie то, на что он запрограммирован. Возможно, сервер игнорирует ваш файл cookie (например, не отправляет его вам).

С другой стороны то, что вы, возможно, захотите сделать, это написать веб-приложение (например, на стороне сервера), которое создает файл cookie и изменяет его в зависимости от ввода клиента (т. браузер).

Для этого вы можете использовать Servlet API. Что-то в духе:

javax.servlet.http.Cookie cookie = new 
    javax.servlet.http.Cookie("your cookie's name", "your cookie's value");
//response has type javax.servlet.http.HttpServletResponse
response.addCookie(cookie);

Создание веб-приложения выходит за рамки простого ответа на stackoverflow, но в Интернете есть много хороших руководств.

Нельзя создать веб-приложение, если пользователь должен использовать браузер для просмотра ваших продуктов. Просто есть разные способы создания одного, разных фреймворков. API сервлета (например, HttpServletResponse и HttpServletResponse) является самым простым.

Я бы сказал, что он (API сервлета) также является самым простым, который вы можете найти для решения именно этой проблемы с java, хотя начать его не совсем просто с веб-приложениями вообще.

person Community    schedule 29.07.2013