introduzione
Dovresti usare doGet()
quando vuoi intercettare le richieste HTTP GET . Da utilizzare doPost()
quando si desidera intercettare le richieste HTTP POST . È tutto. Non portare l'uno all'altro o viceversa (come nel malaugurato processRequest()
metodo di generazione automatica di Netbeans ). Questo non ha assolutamente senso.
OTTENERE
Di solito, le richieste HTTP GET sono idempotenti . Vale a dire che si ottiene esattamente lo stesso risultato ogni volta che si esegue la richiesta (lasciando l'autorizzazione / autenticazione e la natura time-sensitive della pagina - risultati di ricerca, ultime notizie, ecc. - al di fuori della considerazione). Possiamo parlare di una richiesta segnalibro. Facendo clic su un collegamento, facendo clic su un segnalibro, inserendo un URL non elaborato nella barra degli indirizzi del browser, eccetera, verrà attivata una richiesta HTTP GET. Se un servlet è in ascolto sull'URL in questione, doGet()
verrà chiamato il suo metodo. Di solito viene utilizzato per preelaborare una richiesta. Cioè fare alcune cose di lavoro prima di presentare l'output HTML da un JSP, come la raccolta di dati per la visualizzazione in una tabella.
@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>
Anche visualizzare / modificare i collegamenti ai dettagli come mostrato nell'ultima colonna sopra sono generalmente idempotenti.
@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>
INVIARE
Le richieste HTTP POST non sono idempotenti. Se l'utente finale ha inviato in anticipo un modulo POST su un URL, che non ha eseguito un reindirizzamento, l'URL non è necessariamente segnalibro. I dati del modulo inviato non si riflettono nell'URL. Copiare l'URL in una nuova finestra / scheda del browser potrebbe non produrre necessariamente lo stesso risultato dopo l'invio del modulo. Un tale URL non è quindi segnalibro. Se un servlet è in ascolto sull'URL in questione, doPost()
verrà chiamato. Di solito viene utilizzato per postelaborare una richiesta. Cioè raccogliere dati da un modulo HTML inviato e fare alcune cose di lavoro con esso (conversione, convalida, salvataggio in DB, eccetera). Infine, di solito il risultato viene presentato come HTML dalla pagina JSP inoltrata.
<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>
... che può essere utilizzato in combinazione con questo pezzo di Servlet:
@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);
}
}
}
Vedi, se User
si trova nel DB (cioè nome utente e password sono validi), allora User
sarà messo nell'ambito della sessione (cioè "loggato") e il servlet reindirizzerà a qualche pagina principale (questo esempio va a http://example.com/contextname/home
), altrimenti imposterà un messaggio di errore e inoltrerà la richiesta alla stessa pagina JSP in modo che il messaggio venga visualizzato da ${error}
.
Se necessario si può anche "nascondere" la in login.jsp
in /WEB-INF/login.jsp
modo che gli utenti possano accedervi solo dal servlet. Ciò mantiene pulito l'URL http://example.com/contextname/login
. Tutto quello che devi fare è aggiungere un doGet()
al servlet in questo modo:
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.getRequestDispatcher("/WEB-INF/login.jsp").forward(request, response);
}
(e aggiorna la stessa riga di doPost()
conseguenza)
Detto questo, non sono sicuro che stia solo giocando e sparando al buio, ma il codice che hai pubblicato non sembra buono (come usare compareTo()
invece di equals()
e scavare nei nomi dei parametri invece di usare getParameter()
e il id
e password
sembra essere dichiarate come variabili di istanza servlet - che NON è threadsafe ). Quindi consiglio vivamente di imparare un po 'di più sull'API Java SE di base utilizzando i tutorial Oracle (controllare il capitolo "Trails Covering the Basics") e su come utilizzare JSP / Servlet nel modo corretto utilizzando questi tutorial .
Guarda anche:
Aggiornamento : come per l'aggiornamento della tua domanda (che è piuttosto importante, non dovresti rimuovere parti della tua domanda originale, questo renderebbe le risposte inutili .. piuttosto aggiungi le informazioni in un nuovo blocco), si scopre che sei impostando inutilmente il tipo di codifica del form su multipart/form-data
. Questo invierà i parametri della richiesta in una composizione diversa da quella (predefinita) application/x-www-form-urlencoded
che invia i parametri della richiesta come stringa di query (ad esempio name1=value1&name2=value2&name3=value3
). Hai bisogno solo multipart/form-data
ogni volta che hai un file<input type="file">
elemento nel modulo per caricare file che possono essere dati non di caratteri (dati binari). Questo non è il tuo caso, quindi rimuovilo e funzionerà come previsto. Se hai bisogno di caricare file, dovrai impostare il tipo di codifica così e analizzare tu stesso il corpo della richiesta. Di solito usi Apache Commons FileUpload lì per, ma se sei già su una nuova API Servlet 3.0, puoi semplicemente usare le funzionalità integrate a partire da HttpServletRequest#getPart()
. Vedi anche questa risposta per un esempio concreto: come caricare file sul server usando JSP / Servlet?