introduction
Vous devez utiliser doGet()
lorsque vous souhaitez intercepter des requêtes HTTP GET . Vous devez utiliser doPost()
lorsque vous souhaitez intercepter des requêtes HTTP POST . C'est tout. Ne portez pas l'un sur l'autre ou vice versa (comme dans la malheureuse processRequest()
méthode auto-générée de Netbeans ). Cela n'a aucun sens.
AVOIR
Habituellement, les requêtes HTTP GET sont idempotentes . C'est-à-dire que vous obtenez exactement le même résultat à chaque fois que vous exécutez la requête (en laissant l'autorisation / authentification et la nature sensible du temps de la page — résultats de la recherche, dernières nouvelles, etc. — hors de considération). Nous pouvons parler d'une demande pouvant être mise en signet. Cliquer sur un lien, cliquer sur un signet, saisir une URL brute dans la barre d'adresse du navigateur, etc. déclencheront tous une requête HTTP GET. Si un servlet écoute sur l'URL en question, sa doGet()
méthode sera appelée. Il est généralement utilisé pour prétraiter une demande. C'est-à-dire faire des affaires avant de présenter la sortie HTML d'une JSP, comme la collecte de données à 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);
}
}
<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 plus, afficher / modifier les liens détaillés 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>
PUBLIER
Les requêtes 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 ne peut pas nécessairement être mise en signet. Les données de formulaire soumises ne sont pas reflétées dans l'URL. Copypaster l'URL dans une nouvelle fenêtre / onglet de navigateur ne donnera pas nécessairement exactement le même résultat qu'après l'envoi du formulaire. Une telle URL ne peut alors pas être mise en signet. Si un servlet écoute sur l'URL en question, alors doPost()
il sera appelé. Il est généralement utilisé pour post - traiter une demande. C'est-à-dire collecter des données à partir d'un formulaire HTML soumis et faire des affaires avec lui (conversion, validation, sauvegarde dans DB, etc.). Enfin, le résultat est généralement présenté au format 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é dans DB (c'est-à-dire que le nom d'utilisateur et le mot de passe sont valides), alors le User
sera mis dans la portée de la session (c'est-à-dire "connecté") et le servlet sera redirigé vers une page principale (cet exemple va à http://example.com/contextname/home
), sinon il définira un message d'erreur et transmettra la demande à la même page JSP afin que le message soit affiché par ${error}
.
Vous pouvez si nécessaire également "masquer" l' login.jsp
entrée /WEB-INF/login.jsp
pour que les utilisateurs ne puissent y accéder que par le servlet. Cela maintient l'URL propre http://example.com/contextname/login
. Tout ce que vous avez à faire est d'ajouter un doGet()
au 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 en doPost()
conséquence)
Cela dit, je ne sais pas s'il s'agit simplement de jouer et de filmer dans le noir, mais le code que vous avez posté n'a pas l'air bien (comme utiliser à la compareTo()
place equals()
et creuser dans les noms de paramètres au lieu d'utiliser simplement getParameter()
et le id
et password
semble être déclarée comme des variables d'instance de servlet - ce qui n'est PAS threadsafe ). Je vous recommande donc fortement d'en apprendre un peu plus sur l'API Java SE de base en utilisant les tutoriels Oracle (consultez le chapitre "Trails Covering the Basics") et comment utiliser JSP / Servlets correctement en utilisant ces tutoriels .
Voir également:
Mise à jour : selon la mise à jour de votre question (ce qui est assez important, vous ne devriez pas supprimer des parties de votre question d'origine, cela rendrait les réponses sans valeur ... ajoutez plutôt les informations dans un nouveau bloc), il s'avère que vous êtes définir inutilement le type de codage du formulaire sur multipart/form-data
. Cela enverra les paramètres de demande dans une composition différente de celle (par défaut) application/x-www-form-urlencoded
qui envoie les paramètres de demande sous forme de chaîne de requête (par exemple name1=value1&name2=value2&name3=value3
). Vous n'avez besoin multipart/form-data
que lorsque vous avez un<input type="file">
élément 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, alors supprimez-le simplement et cela fonctionnera comme prévu. Si jamais vous avez besoin de télécharger des fichiers, vous devrez définir le type d'encodage et analyser vous-même le corps de la requête. Habituellement, vous utilisez Apache Commons FileUpload là pour, mais si vous utilisez déjà la nouvelle API Servlet 3.0, vous pouvez simplement utiliser les fonctionnalités intégrées en commençant par HttpServletRequest#getPart()
. Voir aussi cette réponse pour un exemple concret: Comment télécharger des fichiers sur le serveur en utilisant JSP / Servlet?