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 User
in der Datenbank gefunden wird (dh Benutzername und Passwort sind gültig), User
wird 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.jsp
in /WEB-INF/login.jsp
so 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 id
und password
scheint 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-urlencoded
gesendet, die die Anforderungsparameter als Abfragezeichenfolge sendet (z name1=value1&name2=value2&name3=value3
. B. ). Sie brauchen nur, multipart/form-data
wenn 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?