doGet i doPost w Serwletach

Opracowałem stronę HTML, która wysyła informacje do serwletu. W Servlecie stosuję metody doGet() i doPost():

public void doGet(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException  {

     String id = req.getParameter("realname");
     String password = req.getParameter("mypassword");
}

public void doPost(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException {

    String id = req.getParameter("realname");
    String password = req.getParameter("mypassword");
}

W kodzie strony html wywołującym Servlet jest:

<form action="identification" method="post" enctype="multipart/form-data">
    User Name: <input type="text" name="realname">
    Password: <input type="password" name="mypassword">
    <input type="submit" value="Identification">
</form> 

Kiedy używam method = "get" w Servlecie, dostaję wartość id i hasła, jednak gdy używam method = "post", id i hasło są ustawione na null. Dlaczego nie dostanę wartości w tym przypadku?

Kolejną rzeczą, którą chciałbym wiedzieć, jest to, jak korzystać z danych generowanych lub sprawdzanych przez Servlet. Na na przykład, jeśli serwlet pokazany powyżej uwierzytelnia użytkownika, chciałbym wydrukować identyfikator użytkownika na mojej stronie HTML. Powinienem być w stanie wysłać łańcuch " id " jako odpowiedź i użyć tych informacji w mojej stronie HTML. Czy to możliwe?

Author: drognisep, 2010-02-28

5 answers

Wprowadzenie

Powinieneś użyć doGet() gdy chcesz przechwycić na HTTP GET requests. Należy użyć doPost() gdy chcesz przechwycić na żądania HTTP POST . To wszystko. Nie należy przenosić jednego na drugi ani odwrotnie (np. w nieszczęsnej, automatycznie wygenerowanej metodzie processRequest() Netbeans). To nie ma sensu.

GET

Zazwyczaj żądania HTTP GET to idempotent. Czyli otrzymujesz dokładnie taki sam wynik za każdym razem, gdy wykonujesz żądanie (pozostawiając autoryzację/uwierzytelnienie i wrażliwy na czas charakter Strony -wyniki wyszukiwania, Ostatnie wiadomości itp. - Poza rozważeniem). Możemy porozmawiać o zamówieniu. Klikając link, klikając zakładkę, wpisując surowy adres URL w pasku adresu przeglądarki, etcetera wszystko odpali żądanie HTTP GET. Jeśli Servlet nasłuchuje danego adresu URL, to zostanie wywołana jego metoda doGet(). Zwykle jest używany do preprocesu żądania. Tj. robienie kilku sprawy biznesowe przed przedstawieniem wyjścia HTML z JSP, takie jak zbieranie danych do wyświetlenia w tabeli.

@WebServlet("/products")
public class ProductsServlet extends HttpServlet {

    @EJB
    private ProductService productService;

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        List<Product> products = productService.list();
        request.setAttribute("products", products); // Will be available as ${products} in JSP
        request.getRequestDispatcher("/WEB-INF/products.jsp").forward(request, response);
    }

}
<table>
    <c:forEach items="${products}" var="product">
        <tr>
            <td>${product.name}</td>
            <td><a href="product?id=${product.id}">detail</a></td>
        </tr>
    </c:forEach>
</table>

Również linki do wyświetlania / edycji szczegółów, jak pokazano w ostatniej kolumnie powyżej, są zwykle idempotentne.

@WebServlet("/product")
public class ProductServlet extends HttpServlet {

    @EJB
    private ProductService productService;

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        Product product = productService.find(request.getParameter("id"));
        request.setAttribute("product", product); // Will be available as ${product} in JSP
        request.getRequestDispatcher("/WEB-INF/product.jsp").forward(request, response);
    }

}
<dl>
    <dt>ID</dt>
    <dd>${product.id}</dd>
    <dt>Name</dt>
    <dd>${product.name}</dd>
    <dt>Description</dt>
    <dd>${product.description}</dd>
    <dt>Price</dt>
    <dd>${product.price}</dd>
    <dt>Image</dt>
    <dd><img src="productImage?id=${product.id}" /></dd>
</dl>

POST

Żądania HTTP POST nie są idempotentne. Jeśli użytkownik końcowy przesłał wcześniej formularz posta na adresie URL, który nie wykonał przekierowania, adres URL nie musi być księgowany. Przesłane dane formularza nie są odzwierciedlane w adresie URL. Skopiowanie adresu URL do nowego okna/karty przeglądarki może niekoniecznie dać dokładnie taki sam wynik, jak po przesłaniu formularza. Taki adres URL nie jest wtedy bookmarkable. Jeśli Servlet nasłuchuje pod danym adresem URL, to zostanie wywołana jego doPost(). Zwykle jest używany do postprocesu żądania. Czyli zbieranie danych z przesłanego formularza HTML i robienie z nim pewnych rzeczy biznesowych (konwersja, Walidacja, zapisywanie w DB itp.). Ostatecznie zazwyczaj wynik jest prezentowany jako HTML z przekierowanie strony JSP.

<form action="login" method="post">
    <input type="text" name="username">
    <input type="password" name="password">
    <input type="submit" value="login">
    <span class="error">${error}</span>
</form>

...co może być używane w połączeniu z tym kawałkiem Servleta:

@WebServlet("/login")
public class LoginServlet extends HttpServlet {

    @EJB
    private UserService userService;

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        User user = userService.find(username, password);

        if (user != null) {
            request.getSession().setAttribute("user", user);
            response.sendRedirect("home");
        }
        else {
            request.setAttribute("error", "Unknown user, please try again");
            request.getRequestDispatcher("/login.jsp").forward(request, response);
        }
    }

}

Widzisz, Jeśli User znajduje się w DB (tzn. nazwa użytkownika i hasło są ważne), to User zostanie umieszczony w obszarze sesji (tzn. "zalogowany") i servlet przekieruje na jakąś stronę główną( ten przykład idzie do http://example.com/contextname/home), w przeciwnym razie ustawi komunikat o błędzie i przekaże żądanie z powrotem do tej samej strony JSP tak, że wiadomość zostanie wyświetlona przez ${error}.

Możesz, jeśli konieczne jest również "ukrycie" login.jsp w /WEB-INF/login.jsp, aby użytkownicy mogli uzyskać do niego dostęp tylko przez servlet. Dzięki temu adres URL jest czysty http://example.com/contextname/login. Wszystko, co musisz zrobić, to dodać doGet() do servletu w następujący sposób:

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    request.getRequestDispatcher("/WEB-INF/login.jsp").forward(request, response);
}

(i odpowiednio zaktualizować ten sam wiersz w doPost())

To powiedziawszy, nie jestem pewien, czy to tylko zabawa i strzelanie w ciemności, ale kod, który napisałeś, nie wygląda dobrze (na przykład używanie compareTo() zamiast equals() i kopanie w nazwach parametrów zamiast samo użycie getParameter() oraz id i passwordwydaje się być zadeklarowane jako zmienne instancji servleta - co nie jest threadsafe). Dlatego zdecydowanie polecam dowiedzieć się trochę więcej o podstawowym API Java SE przy użyciu samouczków Oracle (sprawdź rozdział "szlaki obejmujące podstawy") i jak używać JSP/Servletów we właściwy sposób używając tych samouczków.

Zobacz też:


Update: zgodnie z aktualizacją twojego pytania (co jest dość poważne, nie powinieneś usuwać części oryginalnego pytania, co uczyniłoby odpowiedzi bezwartościowymi .. raczej dodaj informacje w nowym block), okazuje się, że niepotrzebnie ustawiasz typ kodowania formularza na multipart/form-data. Spowoduje to wysłanie parametrów żądania w innym składzie niż (domyślnie) application/x-www-form-urlencoded, który wysyła parametry żądania jako ciąg zapytania (np. name1=value1&name2=value2&name3=value3). Do przesyłania plików, które mogą być danymi nie-znakowymi (dane binarne), potrzebujesz tylko multipart/form-data, gdy masz element <input type="file"> w formularzu. Tak nie jest w Twoim przypadku, więc po prostu usuń go, a będzie działał zgodnie z oczekiwaniami. Jeśli kiedykolwiek będziesz potrzebować PRZEŚLIJ PLIKI, następnie będziesz musiał ustawić typ kodowania tak i samodzielnie przetworzyć treść żądania. Zazwyczaj używasz Apache Commons FileUpload , ale jeśli jesteś już na nowym API Servlet 3.0, możesz po prostu użyć wbudowanych udogodnień zaczynających się od HttpServletRequest#getPart(). Zobacz także tę odpowiedź na konkretny przykład: jak przesłać pliki na serwer za pomocą JSP / Servlet?

 181
Author: BalusC,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:18:14

Zarówno GET, jak i POST są używane przez przeglądarkę do żądania pojedynczego zasobu z serwera. Każdy zasób wymaga osobnego żądania GET lub POST.

  1. metoda GET jest najczęściej (i jest metodą domyślną) używana przez przeglądarki do pobierania informacji z serwerów. Podczas używania metody GET trzecia sekcja pakietu żądania, która jest ciałem żądania, pozostaje pusta.

Metoda GET jest używana na jeden z dwóch sposobów: Gdy żadna metoda nie jest określona, to wtedy lub przeglądarka żąda prostego zasobu, takiego jak strona HTML, obraz itp. Po przesłaniu formularza i wybraniu method = GET na znaczniku HTML. Jeśli metoda GET jest używana z formularzem HTML, to dane zebrane za pośrednictwem formularza są wysyłane do serwera przez dodanie"?"na końcu adresu URL, a następnie dodanie wszystkich par name=value (Nazwa pola formularza html i wartość wpisana w tym polu) oddzielonych "&" Przykład: GET / sultans / shop / / form1.jsp?name=Sam%20sultan&iceCream=vanilla HTTP / 1.0 opcjonalny nagłówek opcjonalny nagłówek > >

Nazwa = Wartość danych formularza będą przechowywane w zmiennej środowiskowej o nazwie QUERY_STRING. Ta zmienna zostanie wysłana do programu przetwarzającego (takiego jak JSP, Java servlet, PHP itd.)

  1. metoda POST jest używana podczas tworzenia formularza HTML i request method = POST jako część tagu. Metoda POST umożliwia klientowi wysłanie danych formularza do serwera w sekcji request body żądania (zgodnie z omówieniem wcześniej). Dane są zakodowane i formatowane podobnie jak metoda GET, z tą różnicą, że dane są wysyłane do programu poprzez standardowe wejście.

Przykład: POST / sultans / sklep / / form1.jsp HTTP / 1.0 opcjonalny nagłówek opcjonalny nagłówek > > name = Sam%20sultan&iceCream=vanilla

Podczas używania metody post, zmienna środowiskowa QUERY_STRING będzie pusta. Zalety / wady GET vs. POST

Zalety metody GET: Nieco szybciej Parametry można wprowadzić za pomocą formularza lub dodając je po adresie URL Strona może być oznakowana za pomocą jej parametrów

Wady metody GET: Może wysyłać tylko dane o wartości 4K. (Nie należy go używać podczas korzystania z pola textarea) Parametry są widoczne na końcu adresu URL

Zalety metody POST: Parametry NIE są widoczne na końcu adresu URL. (Wykorzystanie danych wrażliwych) Może wysłać więcej danych o wartości 4K na serwer

Wady postu metoda: Can nie może być zakładką z jego danymi

 2
Author: S. Mayol,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-06-17 21:44:32

Implementacja kontenera Serwleta Httpservleta.metoda service () będzie automatycznie przekazywana do metody doGet() lub doPost () w razie potrzeby, więc nie trzeba nadpisywać metody service.

 0
Author: Jay Jackson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-02-28 01:42:36

Czy to możliwe, że przekazujesz dane przez get, a nie post?

<form method="get" ..>
..
</form>
 0
Author: Tom,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-02-28 01:52:17

Jeśli wykonasz <form action="identification" > dla formularza html, dane będą przekazywane domyślnie za pomocą 'Get' i dlatego możesz to przechwycić za pomocą funkcji doGet w kodzie java servlet. W ten sposób dane będą przekazywane pod nagłówkiem HTML, a tym samym będą widoczne w adresie URL po przesłaniu. Z drugiej strony, jeśli chcesz przekazać dane w ciele HTML, użyj Post: <form action="identification" method="post"> i wyłapaj te dane w funkcji doPost. To było, dane będą przekazywane pod ciałem html, a nie nagłówkiem html, i nie zobaczysz danych w URL po przesłaniu formularza.

Przykłady z mojego html:

<body>  
<form action="StartProcessUrl" method="post">
.....
.....

Przykłady z mojego kodu java servlet:

protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // TODO Auto-generated method stub
        PrintWriter out = response.getWriter();
         String surname = request.getParameter("txtSurname");
         String firstname = request.getParameter("txtForename");
         String rqNo = request.getParameter("txtRQ6");
         String nhsNo = request.getParameter("txtNHSNo");

         String attachment1 = request.getParameter("base64textarea1");
         String attachment2 = request.getParameter("base64textarea2");

.........
.........
 0
Author: Uzair Zaman Sheikh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-06-11 01:41:07