doGet und doPost in Servlets

105

Ich habe eine HTML-Seite entwickelt, die Informationen an ein Servlet sendet. Im Servlet verwende ich die Methoden doGet()und 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");
}

Der HTML-Seitencode, der das Servlet aufruft, lautet:

<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> 

Wenn ich method = "get"im Servlet verwende, erhalte ich den Wert von ID und Passwort. Bei Verwendung method = "post"werden jedoch ID und Passwort auf gesetzt null. Warum bekomme ich in diesem Fall keine Werte?

Ich möchte auch wissen, wie die vom Servlet generierten oder validierten Daten verwendet werden. Wenn beispielsweise das oben gezeigte Servlet den Benutzer authentifiziert, möchte ich die Benutzer-ID auf meiner HTML-Seite drucken. Ich sollte in der Lage sein, die Zeichenfolge 'id' als Antwort zu senden und diese Informationen in meiner HTML-Seite zu verwenden. Ist es möglich?

Dedalo
quelle
Wie verwenden Sie die Post-Methode bei HTML?
Igor Artamonov
Und was brauchen Sie für eine so seltsame Schleife über Parameternamen?
Igor Artamonov
1
Haben Sie versucht, "enctype = multipart / form-data" zu entfernen? Ich vermute, das ist dein Problem.
Jack Leow
Das war's. Warum postet keine Arbeit, wenn diese vorhanden ist? Danke für Ihre Hilfe!
Dedalo

Antworten:

197

Einführung

Sie sollten verwenden, doGet()wenn Sie HTTP-GET-Anforderungen abfangen möchten . Sie sollten verwenden, doPost()wenn Sie HTTP-POST-Anforderungen abfangen möchten . Das ist alles. Portieren Sie das eine nicht zum anderen oder umgekehrt (wie bei der unglücklichen automatisch generierten processRequest()Methode von Netbeans ). Das macht keinen Sinn.

BEKOMMEN

Normalerweise sind HTTP-GET-Anforderungen idempotent . Das heißt, Sie erhalten bei jeder Ausführung der Anforderung genau das gleiche Ergebnis (wobei die Autorisierung / Authentifizierung und die zeitkritische Natur der Seite - Suchergebnisse, letzte Nachrichten usw. - nicht berücksichtigt werden). Wir können über eine mit Lesezeichen versehene Anfrage sprechen. Wenn Sie auf einen Link klicken, auf ein Lesezeichen klicken, eine unformatierte URL in die Adressleiste des Browsers eingeben usw. wird eine HTTP-GET-Anforderung ausgelöst. Wenn ein Servlet die betreffende URL abhört, wird seine doGet()Methode aufgerufen. Es wird normalerweise verwendet, um eine Anfrage vorzuverarbeiten . Das heißt, Sie erledigen einige geschäftliche Aufgaben, bevor Sie die HTML-Ausgabe einer JSP präsentieren, z. B. das Sammeln von Daten zur Anzeige in einer Tabelle.

@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>

Auch das Anzeigen / Bearbeiten von Detaillinks, wie in der letzten Spalte oben gezeigt, ist normalerweise idempotent.

@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

HTTP-POST-Anforderungen sind nicht idempotent. Wenn der Endbenutzer zuvor ein POST-Formular für eine URL gesendet hat, für die keine Umleitung durchgeführt wurde, ist die URL nicht unbedingt mit einem Lesezeichen versehen. Die übermittelten Formulardaten werden nicht in der URL wiedergegeben. Das Kopieren der URL in ein neues Browserfenster / eine neue Registerkarte führt möglicherweise nicht unbedingt zu genau dem gleichen Ergebnis wie nach dem Senden des Formulars. Eine solche URL ist dann nicht mit einem Lesezeichen versehen. Wenn ein Servlet die betreffende URL abhört, doPost()wird sie aufgerufen. Es wird normalerweise verwendet, um eine Anfrage nachzubearbeiten . Das heißt, Sie sammeln Daten aus einem übermittelten HTML-Formular und erledigen damit einige geschäftliche Aufgaben (Konvertierung, Validierung, Speichern in der Datenbank usw.). Schließlich wird das Ergebnis normalerweise als HTML von der weitergeleiteten JSP-Seite dargestellt.

<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>

... die in Kombination mit diesem Servlet verwendet werden können:

@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);
        }
    }

}

Sie sehen, wenn das Userin der Datenbank gefunden wird (dh Benutzername und Passwort sind gültig), Userwird das in den Sitzungsbereich gestellt (dh "angemeldet") und das Servlet wird auf eine Hauptseite umgeleitet (dieses Beispiel geht zu http://example.com/contextname/home), andernfalls Es wird eine Fehlermeldung gesetzt und die Anforderung an dieselbe JSP-Seite zurückgeleitet, damit die Nachricht von angezeigt wird ${error}.

Sie können bei Bedarf auch „verstecken“ die login.jspin /WEB-INF/login.jspso dass die Benutzer nur durch das Servlet zugreifen können. Dies hält die URL sauber http://example.com/contextname/login. Alles, was Sie tun müssen, ist doGet(), dem Servlet Folgendes hinzuzufügen :

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

(und aktualisieren Sie die gleiche Zeile doPost()entsprechend)

Das heißt, ich bin nicht sicher , ob es nur spielt herum und der Aufnahme im Dunkeln, aber der Code, den Sie nicht gepostet nicht gut aussehen (wie die Verwendung compareTo()anstelle von equals()und in den parameternames Graben statt nur mit getParameter()und idund passwordscheint als Servlet-Instanzvariablen deklariert werden (was NICHT threadsicher ist ). Ich würde daher dringend empfehlen, mithilfe der Oracle-Tutorials (siehe Kapitel "Trails Covering the Basics") und der richtigen Verwendung von JSP / Servlets mithilfe dieser Tutorials etwas mehr über die grundlegende Java SE-API zu erfahren .

Siehe auch:


Update : nach dem Update Ihrer Frage (was ziemlich großen, sollten Sie nicht Teile Ihrer ursprünglichen Frage entfernen, dies würde die Antworten wertlos .. vielmehr fügen die Informationen in einem neuen Block), es stellt sich heraus , dass Sie Setzen Sie den Codierungstyp des Formulars unnötigerweise auf multipart/form-data. Dadurch werden die Anforderungsparameter in einer anderen Zusammensetzung als die (Standard) application/x-www-form-urlencodedgesendet, die die Anforderungsparameter als Abfragezeichenfolge sendet (z name1=value1&name2=value2&name3=value3. B. ). Sie brauchen nur, multipart/form-datawenn Sie eine haben<input type="file">Element im Formular zum Hochladen von Dateien, bei denen es sich möglicherweise um Nicht-Zeichendaten (Binärdaten) handelt. Dies ist in Ihrem Fall nicht der Fall. Entfernen Sie es einfach und es funktioniert wie erwartet. Wenn Sie jemals Dateien hochladen müssen, müssen Sie den Codierungstyp so einstellen und den Anforderungshauptteil selbst analysieren. Normalerweise verwenden Sie dort den Apache Commons FileUpload für, aber wenn Sie bereits eine neue Servlet 3.0-API verwenden, können Sie einfach integrierte Funktionen verwenden, beginnend mit HttpServletRequest#getPart(). Ein konkretes Beispiel finden Sie auch in dieser Antwort: Wie lade ich Dateien mit JSP / Servlet auf den Server hoch?

BalusC
quelle
2

Sowohl GET als auch POST werden vom Browser verwendet, um eine einzelne Ressource vom Server anzufordern. Jede Ressource erfordert eine separate GET- oder POST-Anforderung.

  1. Die GET-Methode wird am häufigsten (und ist die Standardmethode) von Browsern verwendet, um Informationen von Servern abzurufen. Bei Verwendung der GET-Methode bleibt der dritte Abschnitt des Anforderungspakets, bei dem es sich um den Anforderungshauptteil handelt, leer.

Die GET-Methode wird auf zwei Arten verwendet: Wenn keine Methode angegeben ist, fordern Sie oder der Browser eine einfache Ressource wie eine HTML-Seite, ein Bild usw. an. Wenn ein Formular gesendet wird und Sie die Methode auswählen = GET auf dem HTML-Tag. Wenn die GET-Methode mit einem HTML-Formular verwendet wird, werden die über das Formular gesammelten Daten durch Anhängen eines "?" An den Server gesendet. bis zum Ende der URL und dann Hinzufügen aller Name = Wert-Paare (Name des HTML-Formularfelds und in dieses Feld eingegebener Wert) getrennt durch ein "&" Beispiel: GET /sultans/shop//form1.jsp?name= Sam% 20Sultan & iceCream = Vanille HTTP / 1.0 optionaler Headeroptionaler Header << leere Zeile >>>

Die Formulardaten name = value werden in einer Umgebungsvariablen namens QUERY_STRING gespeichert. Diese Variable wird an ein Verarbeitungsprogramm (wie JSP, Java-Servlet, PHP usw.) gesendet.

  1. Die POST-Methode wird verwendet, wenn Sie ein HTML-Formular erstellen und die Methode = POST als Teil des Tags anfordern. Mit der POST-Methode kann der Client Formulardaten an den Server im Abschnitt "Anfragetext" der Anforderung senden (wie bereits erläutert). Die Daten werden codiert und ähnlich wie bei der GET-Methode formatiert, außer dass die Daten über die Standardeingabe an das Programm gesendet werden.

Beispiel: POST /sultans/shop//form1.jsp HTTP / 1.0 optionaler Headeroptionaler Header << leere Zeile >>> name = Sam% 20Sultan & iceCream = vanilla

Bei Verwendung der post-Methode ist die Umgebungsvariable QUERY_STRING leer. Vor- und Nachteile von GET gegenüber POST

Vorteile der GET-Methode: Etwas schnellere Parameter können über ein Formular oder durch Anhängen eingegeben werden, nachdem die URL-Seite mit ihren Parametern als Lesezeichen versehen werden kann

Nachteile der GET-Methode: Es können nur Daten im Wert von 4 KB gesendet werden. (Sie sollten es nicht verwenden, wenn Sie ein Textfeld verwenden.) Parameter sind am Ende der URL sichtbar

Vorteile der POST-Methode: Parameter sind am Ende der URL nicht sichtbar. (Verwendung für vertrauliche Daten) Kann Daten im Wert von mehr als 4 KB an den Server senden

Nachteile der POST-Methode: Kann nicht mit ihren Daten vorgemerkt werden

S. Mayol
quelle
0

Die Implementierung der HttpServlet.service () -Methode durch den Servlet-Container wird bei Bedarf automatisch an doGet () oder doPost () weitergeleitet, sodass Sie die Servicemethode nicht überschreiben müssen.

Jay Jackson
quelle
0

Könnte es sein, dass Sie die Daten durch get weiterleiten, nicht posten?

<form method="get" ..>
..
</form>
Tom
quelle
0

Wenn Sie dies <form action="identification" >für Ihr HTML-Formular tun , werden die Daten standardmäßig mit 'Get' übergeben. Daher können Sie dies mit der Funktion doGet in Ihrem Java-Servlet-Code abrufen. Auf diese Weise werden Daten unter dem HTML-Header übergeben und sind daher bei der Übermittlung in der URL sichtbar. Wenn Sie dagegen Daten im HTML- <form action="identification" method="post">Text übergeben möchten, verwenden Sie Post: und fangen Sie diese Daten in der Funktion doPost ab. Dies war, Daten werden unter dem HTML-Text und nicht unter dem HTML-Header übergeben, und Sie werden die Daten nach dem Absenden des Formulars nicht in der URL sehen.

Beispiele aus meinem HTML:

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

Beispiele aus meinem Java-Servlet-Code:

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");

.........
.........
Uzair Zaman Sheikh
quelle