Introduction
Vous devez utiliser doGet()
lorsque vous voulez intercepter sur Demandes HTTP GET . Vous devez utiliser doPost()
lorsque vous voulez intercepter sur Demandes HTTP POST . C'est tout. Ne portez pas l'un vers l'autre ou vice versa (comme dans le malheureux système de génération automatique de Netbeans). processRequest()
méthode). Cela n'a aucun sens.
GET
Habituellement, les requêtes HTTP GET sont idempotent . C'est-à-dire que vous obtenez exactement le même résultat à chaque fois que vous exécutez la requête (sans tenir compte de l'autorisation/authentification et de la nature temporelle de la page - résultats de recherche, dernières nouvelles, etc.) Nous pouvons parler d'une demande de signet. Cliquer sur un lien, cliquer sur un signet, saisir une URL brute dans la barre d'adresse du navigateur, etc. déclenchera une requête HTTP GET. Si une servlet est à l'écoute de l'URL en question, alors sa fonction doGet()
sera appelée. Il est généralement utilisé pour prétraiter une demande. C'est-à-dire qu'il s'agit d'effectuer des opérations commerciales avant de présenter la sortie HTML d'une JSP, comme la collecte de données pour les afficher dans un tableau.
@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);
}
}
Notez que le fichier JSP est explicitement placé dans le répertoire /WEB-INF
afin d'empêcher les utilisateurs finaux d'y accéder directement sans invoquer le servlet de prétraitement (et donc de se tromper en voyant une table vide).
<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>
De même, les liens de visualisation/modification des détails, comme indiqué dans la dernière colonne ci-dessus, sont généralement idempotents.
@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
Les demandes HTTP POST ne sont pas idempotentes. Si l'utilisateur final a préalablement soumis un formulaire POST sur une URL, qui n'a pas effectué de redirection, alors l'URL n'est pas nécessairement enregistrable. Les données du formulaire soumis ne sont pas reflétées dans l'URL. Copier l'URL dans une nouvelle fenêtre ou un nouvel onglet du navigateur ne donne pas nécessairement le même résultat qu'après l'envoi du formulaire. Une telle URL ne peut donc pas être marquée d'un signet. Si une servlet est à l'écoute de l'URL en question, alors sa fonction doPost()
sera appelé. Il est généralement utilisé pour post-traitement une demande. C'est-à-dire collecter des données à partir d'un formulaire HTML soumis et faire des opérations commerciales avec elles (conversion, validation, sauvegarde dans la base de données, etc.) Enfin, le résultat est généralement présenté en HTML à partir de la page JSP transférée.
<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>
...qui peut être utilisé en combinaison avec ce morceau de 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);
}
}
}
Vous voyez, si le User
est trouvée dans la base de données (c'est-à-dire que le nom d'utilisateur et le mot de passe sont valides), alors la fonction User
sera placé dans la portée de la session (c.-à-d. "connecté") et la servlet redirigera vers une page principale (cet exemple va à http://example.com/contextname/home
), sinon il affichera un message d'erreur et renverra la requête à la même page JSP pour que le message soit affiché par ${error}
.
Si nécessaire, vous pouvez également "cacher" le login.jsp
en /WEB-INF/login.jsp
afin que les utilisateurs ne puissent y accéder que par la servlet. Cela permet de garder l'URL propre http://example.com/contextname/login
. Il suffit d'ajouter un doGet()
à la servlet comme ceci :
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.getRequestDispatcher("/WEB-INF/login.jsp").forward(request, response);
}
(et mettre à jour la même ligne dans doPost()
en conséquence)
Cela dit, je ne suis pas sûr qu'il s'agisse d'un simple jeu ou d'un tir dans le noir, mais le code que vous avez posté n'a pas l'air bon (comme l'utilisation de compareTo()
au lieu de equals()
et de creuser dans les noms de paramètres au lieu d'utiliser simplement getParameter()
y el id
y password
semblent être déclarés comme des variables d'instance de servlet - ce qui n'est PAS sans fil ). Je vous recommande donc vivement d'en apprendre un peu plus sur l'API de base de Java SE en utilisant l'application Didacticiels Oracle (consultez le chapitre "Pistes couvrant les bases") et comment utiliser JSP/Servlets de la bonne manière en utilisant ces tutoriels .
Voir aussi :
Mise à jour : selon la mise à jour de votre question (qui est assez importante, vous ne devriez pas supprimer des parties de votre question originale, cela rendrait les réponses sans valeur plutôt. ajouter l'information dans un nouveau bloc) , il s'avère que vous définissez inutilement le type d'encodage du formulaire à multipart/form-data
. Ceci enverra les paramètres de la requête dans une composition différente de celle de l'option (par défaut) application/x-www-form-urlencoded
qui envoie les paramètres de la requête sous la forme d'une chaîne de caractères de requête (par ex. name1=value1&name2=value2&name3=value3
). Il vous suffit de multipart/form-data
chaque fois que vous avez un <input type="file">
dans le formulaire pour télécharger des fichiers qui peuvent être des données sans caractère (données binaires). Ce n'est pas le cas dans votre cas, il suffit donc de le supprimer et tout fonctionnera comme prévu. Si vous avez besoin de télécharger des fichiers, vous devrez définir le type d'encodage et analyser le corps de la requête vous-même. Habituellement, vous utilisez la fonction Apache Commons FileUpload mais si vous utilisez déjà la nouvelle API Servlet 3.0, vous pouvez vous contenter d'utiliser les fonctions intégrées à partir de l'option HttpServletRequest#getPart()
. Voir aussi cette réponse pour un exemple concret : Comment télécharger des fichiers vers le serveur en utilisant JSP/Servlet ?
0 votes
Comment utilisez-vous la méthode post en HTML ?
0 votes
Et aussi, pourquoi avez-vous besoin d'une boucle aussi étrange sur les noms de paramètres?
1 votes
Avez-vous essayé de supprimer `enctype=multipart/form-data`? Je soupçonne que c'est votre problème.
0 votes
C'était ça. Pourquoi le message ne fonctionne-t-il pas lorsque c'est présent? Merci pour votre aide!