web-dev-qa-db-fra.com

doGet et doPost dans 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> 

Lorsque j'utilise method = "get" dans le Servlet, j'obtiens la valeur id et mot de passe. Toutefois, lorsque vous utilisez method = "post", id et mot de passe sont définis sur null. Pourquoi je ne reçois pas les valeurs dans ce cas?

Une autre chose que j'aimerais savoir, c'est comment utiliser les données générées ou validées par le Servlet. Par exemple, si le servlet illustré ci-dessus authentifie l'utilisateur, j'aimerais imprimer l'ID utilisateur dans ma page HTML. Je devrais pouvoir envoyer la chaîne 'id' en réponse et utiliser cette information dans ma page HTML. C'est possible?

104
dedalo

Introduction

Vous devez utiliser doGet() lorsque vous souhaitez intercepter sur demandes HTTP GET . Vous devez utiliser doPost() lorsque vous souhaitez intercepter sur requêtes HTTP POST . C'est tout. Ne portez pas l'un sur l'autre ou inversement (comme dans la méthode malheureuse auto-générée processRequest() de Netbeans). Cela n’a aucun 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 demande (autorisation laissée/authentification et nature de la page tenant compte du facteur temps - résultats de la recherche, dernières nouvelles, etc. - en dehors de toute considération). Nous pouvons parler d'une demande avec un signet. En cliquant sur un lien, en cliquant sur un signet, en entrant l'URL brute dans la barre d'adresse du navigateur, etc., une requête HTTP GET est envoyée. Si un servlet écoute sur l'URL en question, sa méthode doGet() sera appelée. Il est généralement utilisé pour prétraiter une requête. C'est à dire. effectuer des tâches professionnelles avant de présenter la sortie HTML d'une JSP, telle que 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, les liens de détail affichés/montrés 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 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, l'URL ne peut pas nécessairement être mise en favori. Les données de formulaire soumises ne sont pas reflétées dans l'URL. Copier l'URL dans une nouvelle fenêtre/un nouvel onglet de navigateur peut ne pas donner exactement 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, sa doPost() sera appelée. Il est généralement utilisé pour post-traiter une requête. C'est à dire. la collecte de données à partir d’un formulaire HTML soumis et l’exécution de tâches commerciales (conversion, validation, enregistrement dans une base de données, etc.). Enfin, le résultat est généralement présenté sous forme 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’est-à-dire que le nom d’utilisateur et le mot de passe sont valides), le User sera placé dans le champ de la session (c’est-à-dire "connecté") et le servlet sera redirigé vers page principale (cet exemple passe à _http://example.com/contextname/home_), sinon un message d'erreur sera créé et la demande sera renvoyée à la même page JSP afin que le message soit affiché par _${error}_.

Si nécessaire, vous pouvez également "masquer" le _login.jsp_ dans _/WEB-INF/login.jsp_ afin que les utilisateurs ne puissent y accéder que par le servlet. Ceci garde l'URL propre _http://example.com/contextname/login_. Tout ce que vous avez à faire est d’ajouter une 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 mettez à jour la même ligne dans doPost() en conséquence)

Cela dit, je ne suis pas sûr qu’il s’agisse simplement de jouer dans le noir, mais le code que vous avez publié n’a pas l’air bon (utiliser compareTo() à la place de equals() et creuser dans les noms de paramètres au lieu d’utiliser simplement getParameter() et le id et password semble être déclaré en tant que variables d'instance de servlet - ce qui n'est PAS threadsafe ). Je recommande donc vivement d’en apprendre un peu plus sur les API de base Java SE à l’aide de tutoriels Oracle (consultez le chapitre "Pistes couvrant les bases") et sur l’utilisation de JSP/Servlets. de la bonne façon en utilisant ces tutoriels .

Voir également:


Mise à jour : conformément à la mise à jour de votre question (ce qui est assez important, vous ne devriez pas supprimer une partie de votre question initiale, cela rendrait les réponses inutiles. plutôt add les informations dans un nouveau bloc), il s’avère que vous définissez 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 (valeur 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 que de _multipart/form-data_ chaque fois que vous avez un élément _<input type="file">_ dans le formulaire pour télécharger des fichiers qui peuvent être des données non caractères (données binaires). Ce n'est pas le cas dans votre cas, alors supprimez-le et tout fonctionnera comme prévu. Si vous avez besoin de télécharger des fichiers, vous devrez alors définir le type d'encodage et analyser vous-même le corps de la demande. Habituellement, vous utilisez le Apache Commons FileUpload , mais si vous utilisez déjà une nouvelle API Servlet 3.0, vous pouvez simplement utiliser les fonctions intégrées commençant par HttpServletRequest#getPart() . Voir également cette réponse pour un exemple concret: Comment télécharger des fichiers sur un serveur à l'aide de JSP/Servlet?

188
BalusC

GET et POST> sont utilisés par le navigateur pour demander une seule ressource au serveur. Chaque ressource nécessite une requête GET ou POST distincte.

  1. La méthode GET est généralement utilisée (et est la méthode par défaut) par les navigateurs pour extraire des informations des serveurs. Lorsque vous utilisez la méthode GET, la 3ème section du paquet de requête, qui est le corps de la requête, reste vide.

La méthode GET est utilisée de l'une des deux manières suivantes: lorsqu'aucune méthode n'est spécifiée, c'est-à-dire lorsque vous ou le navigateur demandez une ressource simple telle qu'une page HTML, une image, etc. Lorsqu'un formulaire est soumis et que vous choisissez la méthode = GET sur la balise HTML. Si la méthode GET est utilisée avec un formulaire HTML, 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 formulaire html et la valeur entrée dans ce champ), séparées par un "&" Exemple: GET /sultans/shop//form1.jsp?name= Sam% 20Sultan & iceCream = Vanilla HTTP/1.0 entête facultatif en-tête << ligne vide >>>

Les données de 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.).

  1. La méthode POST est utilisée lorsque vous créez un formulaire HTML et que request, méthode = POST, fait partie de la balise. La méthode POST permet au client d'envoyer des données de formulaire au serveur dans la section corps de la demande (comme indiqué précédemment). Les données sont codées et sont formatées de la même manière que la méthode GET, sauf que les données sont envoyées au programme via l'entrée standard.

Exemple: POST /sultans/shop//form1.jsp HTTP/1.0 en-tête optionnel en-tête << ligne vide >>> name = Sam% 20Sultan & iceCream = Vanilla

Lors de l'utilisation de la méthode post, la variable d'environnement QUERY_STRING 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 que la page URL ait été marqué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. (Utiliser pour les données sensibles) Peut envoyer plus de 4K de données au serveur.

Inconvénients de la méthode POST: impossible de créer un signet avec ses données

2
S. Mayol

Se pourrait-il que vous transmettiez les données via get, pas post?

<form method="get" ..>
..
</form>
0
Tom

L'implémentation de la méthode HttpServlet.service () du conteneur de servlet sera automatiquement transmise à doGet () ou à doPost () si nécessaire. Vous ne devriez donc pas avoir à remplacer la méthode de service.

0
Jay Jackson

Si vous utilisez <form action="identification" > pour votre formulaire html, les données sont transmises à l'aide de "Get" par défaut. Vous pouvez donc intercepter cette opération à l'aide de la fonction doGet dans votre code de servlet Java. De cette façon, les données seront transmises sous l'en-tête HTML et seront donc visibles dans l'URL lors de la soumission. D'autre part, si vous souhaitez transmettre des données dans le corps HTML, utilisez USE Post: <form action="identification" method="post"> et récupérez ces données dans la fonction doPost. En d’autres termes, les données seront transmises sous le corps html et non l’en-tête html, et vous ne verrez pas les données dans l’URL après la soumission du formulaire.

Exemples de mon HTML:

<body>  
<form action="StartProcessUrl" method="post">
.....
.....

Exemples de mon code de servlet Java:

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");

.........
.........
0
Uzair Zaman Sheikh