doGet et doPost en Servlets
j'ai développé une page HTML qui envoie des informations à un Servlet. Dans le Servlet, j'utilise les méthodes doGet()
et 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");
}
dans le code de page html qui appelle le Servlet est:
<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>
quand j'utilise method = "get"
dans le Servlet, j'obtiens la valeur de id et password, cependant quand j'utilise method = "post"
, id et password sont définis à null
. Pourquoi je n'ai pas les valeurs dans ce cas?
une autre chose que j'aimerais savoir est comment utiliser les données générées ou validées par le Servlet. Par exemple, si le Servlet ci-dessus authentifie l'utilisateur, j'aimerais imprimer le nom d'utilisateur dans ma page HTML. Je devrais être en mesure d'envoyer la chaîne 'id' comme réponse et utiliser cette information dans ma page HTML. Est-il possible?
5 réponses
Introduction
vous devez utiliser doGet()
lorsque vous voulez intercepter sur les requêtes HTTP GET . Vous devez utiliser doPost()
lorsque vous voulez intercepter sur les requêtes HTTP POST . C'est tout. Ne pas porter l'un à l'autre ou vice versa (comme dans la malheureuse méthode processRequest()
de Netbeans). Cela ne fait pas de proférer des sens.
GET
habituellement, les requêtes HTTP GET sont idempotent . C'est-à-dire: 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 temporelle de la page-Résultats de recherche, dernières nouvelles, etc-considérations externes). Nous pouvons parler d'une demande bookmarkable. En cliquant sur un lien, En cliquant sur un signet, en entrant L'URL brute dans la barre d'adresse du navigateur, etcetera lancera une requête HTTP GET. Si un Servlet écoute L'URL en question, puis sa méthode doGet()
sera appelée. Il est généralement utilisé pour préprocessus une requête. C'est-à-dire: faire des affaires avant de présenter la sortie HTML d'un JSP, comme rassembler des 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);
}
}
<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>
aussi voir/Modifier les liens de détails comme montré dans la dernière colonne ci-dessus sont généralement 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
les requêtes HTTP POST ne sont pas idempotent. Si l'utilisateur final a soumis un formulaire de POST sur une URL à l'avance, qui n'a pas effectué une redirection, alors L'URL n'est pas nécessairement bookmarkable. Les données du formulaire soumis ne sont pas reflétées dans L'URL. Le copyptage de l'URL dans une nouvelle fenêtre/Onglet de navigateur ne donne pas nécessairement le même résultat qu'après la soumission du formulaire. Une telle URL n'est alors pas bookmarkable. Si un Servlet écoute sur L'URL en question, alors son doPost()
s'appellera. Il est généralement utilisé pour postprocess une requête. C'est-à-dire: collecter des données à partir d'un formulaire HTML soumis et faire des affaires avec (conversion, validation, sauvegarde dans DB, etcetera). Enfin généralement le résultat est présenté en HTML à partir de la page JSP transmise.
<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 la base de données (c.-à-d. que le nom d'utilisateur et le mot de passe sont valides), alors le User
sera mis dans la portée de session (c.-à-d. "connecté") et le servlet redirigera vers une page principale (cet exemple va à http://example.com/contextname/home
), sinon il définira un message d'erreur et transmettra la demande de nouveau à la même page JSP de sorte que le message soit affiché par ${error}
.
vous pouvez si nécessaire aussi "cacher" le login.jsp
dans /WEB-INF/login.jsp
de sorte que les utilisateurs ne peuvent y accéder par le servlet. Cela maintient L'URL propre http://example.com/contextname/login
. Tout ce que vous devez faire est d'ajouter un doGet()
pour 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 si c'est juste jouer et tirer dans le noir, mais le code que vous avez posté n'a pas l'air bien (comme utiliser compareTo()
au lieu de equals()
et creuser dans les noms de paramètres au lieu d'utiliser simplement getParameter()
et id
et password
semble être déclaré comme des variables d'instance de servlet - qui N'est pas threadsafe ). Je 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 de la bonne manière en utilisant ces tutoriels .
voir aussi:
- nos servlets wiki page
- Java EE développement web, où dois-je commencer et quelles compétences ai-je besoin?
- Servlet renvoie "d'État HTTP 404 La ressource demandée (/servlet) n'est pas disponible"
- afficher les résultats JDBC en HTML dans la page JSP en utilisant MVC et le motif DAO
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 mettez inutilement le type d'encodage du formulaire à multipart/form-data
. Ceci enverra les paramètres de la requête dans un autre composition que le application/x-www-form-urlencoded
(par défaut) qui envoie les paramètres de la requête sous forme de chaîne de requête (par exemple name1=value1&name2=value2&name3=value3
). Vous n'avez besoin de multipart/form-data
que lorsque vous avez un élément <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 retirer et il va fonctionner comme prévu. Si vous avez besoin de télécharger des fichiers, alors vous devrez définir le type d'encodage so et analyser le corps de la requête vous-même. Habituellement, vous utilisez le Apache Commons FileUpload là pour, mais si vous êtes déjà sur la nouvelle API Servlet 3.0, alors vous pouvez juste utiliser les facilités de construction à partir de HttpServletRequest#getPart()
. Voir Aussi cette réponse pour un exemple concret: comment télécharger des fichiers vers le serveur en utilisant JSP / Servlet?
GET et POST sont tous deux utilisés par le navigateur pour demander une seule ressource à partir du serveur. Chaque ressource nécessite une requête GET ou POST séparée.
- la méthode GET est le plus souvent (et est la méthode par défaut) utilisée par les navigateurs pour récupérer des informations à partir de serveurs. En utilisant la méthode GET, la 3ème section du paquet request, qui est le corps de la requête, reste vide.
la méthode GET est utilisée dans l'un des deux cas suivants: façon: Lorsque aucune méthode n'est spécifié, c'est quand vous ou le navigateur demande une simple ressource, telle qu'une page HTML, une image, etc. Quand un formulaire est soumis, et vous choisissez method=GET sur la balise HTML. Si la méthode GET est utilisée avec un formulaire HTML, alors les données collectées via le formulaire sont envoyées au serveur en ajoutant un "?"à la fin de L'URL, puis en ajoutant toutes les paires nom=valeur (Nom du champ de la forme html et valeur entrée dans ce champ) séparées par un "&" Exemple: OBTENIR / sultans/shop/ / form1.jsp?nom=Sam%20Sultan&iceCream=vanille HTTP/1.0 facultatif headeroptional d'en-tête<< empty line >>>
les données de la forme nom=valeur seront stockées dans une variable d'environnement appelée QUERY_STRING. Cette variable sera envoyée à un programme de traitement (tel que JSP, Java servlet, PHP etc.)
- la méthode POST est utilisée lorsque vous créez un formulaire HTML, et la méthode request=POST comme partie de la balise. La méthode POST permet le client envoie les données du formulaire au serveur dans la section du corps de la requête (comme expliqué plus haut). Les données sont codées et formatées de la même manière que la méthode GET, sauf que les données sont envoyées au programme par l'intermédiaire de l'entrée standard.
exemple: POST / sultans/shop/ / form1.jsp HTTP/1.0 facultatif headeroptional d'en-tête<< empty line >>> nom=Sam%20Sultan&iceCream=vanille
lors de l'utilisation de la méthode post, le QUERY_STRING la variable d'environnement sera vide. Avantages / inconvénients de GET vs. POST
avantages de la méthode GET: Légèrement plus rapide Les paramètres peuvent être entrés via un formulaire ou en les ajoutant après L'URL Page peut être signetée avec ses paramètres
inconvénients de la méthode GET: Ne peut envoyer que 4K de données. (Vous ne devez pas l'utiliser lorsque vous utilisez un champ textarea) Les paramètres sont visibles à la fin de L'URL
avantages de la méthode POST: Les paramètres ne sont pas visibles à la fin de L'URL. (Utilisation pour les données sensibles) Peut envoyer plus de 4K de données au serveur
inconvénients de la méthode de la poste: Ne peuvent être mis en signet avec ses données
Le conteneur de servlet de mise en œuvre de HttpServlet.la méthode service() sera automatiquement redirigée vers doGet() ou doPost () si nécessaire, donc vous ne devriez pas avoir besoin de surcharger la méthode service.
se pourrait-il que vous transmettiez les données par get, pas par la poste?
<form method="get" ..>
..
</form>
si vous faites <form action="identification" >
pour votre forme html, les données seront passées en utilisant 'Get' par défaut et donc vous pouvez attraper ceci en utilisant la fonction doGet dans votre code servlet java. De cette façon, les données seront passées sous L'en-tête HTML et seront donc visibles dans L'URL lorsqu'elles seront soumises.
D'autre part, si vous voulez passer des données dans le corps HTML, puis Utiliser Post: <form action="identification" method="post">
et attraper ces données dans la fonction doPost. C'était, les données seront passées sous le corps html et non l'en-tête html, et vous ne pas voir les données dans L'URL après avoir soumis le formulaire.
exemples de mon html:
<body>
<form action="StartProcessUrl" method="post">
.....
.....
exemples de mon code Java servlet:
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");
.........
.........