doGet y doPost en Servlets

12 minutos de lectura

doGet y doPost en Servlets
dédalo

Desarrollé una página HTML que envía información a un Servlet. En el Servlet, estoy usando los métodos doGet() y 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");
}

En el código de la página html que llama al 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> 

cuando uso method = "get" en el Servlet, obtengo el valor de id y contraseña, sin embargo, cuando uso method = "post"id y contraseña se establecen en null. ¿Por qué no obtengo los valores en este caso?

Otra cosa que me gustaría saber es cómo usar los datos generados o validados por el Servlet. Por ejemplo, si el Servlet que se muestra arriba autentica al usuario, me gustaría imprimir la identificación del usuario en mi página HTML. Debería poder enviar la cadena ‘id’ como respuesta y usar esta información en mi página HTML. ¿Es posible?

  • ¿Cómo estás usando el método de publicación en html?

    – Ígor Artamonov

    28 de febrero de 2010 a las 1:08

  • Y también, ¿para qué necesitas un bucle tan extraño sobre los nombres de los parámetros?

    – Ígor Artamonov

    28 de febrero de 2010 a las 1:08

  • ¿Has intentado eliminar `enctype=multipart/form-data`? Sospecho que ese es tu problema.

    – Jack Leow

    28 de febrero de 2010 a las 14:14

  • Eso fue todo. ¿Por qué no se publica trabajo cuando esto está presente? ¡Gracias por tu ayuda!

    – dédalo

    28 de febrero de 2010 a las 15:08

doGet y doPost en Servlets
BalusC

Introducción

Deberías usar doGet() cuando quieras interceptar Solicitudes HTTP GET. Deberías usar doPost() cuando quieras interceptar Solicitudes HTTP POST. Eso es todo. No transfiera el uno al otro o viceversa (como en el desafortunado autogenerado de Netbeans). processRequest() método). Esto no tiene ningún sentido.

OBTENER

Por lo general, las solicitudes HTTP GET son idempotente. Es decir, obtiene exactamente el mismo resultado cada vez que ejecuta la solicitud (dejando la autorización/autenticación y la naturaleza sensible al tiempo de la página (resultados de búsqueda, últimas noticias, etc.) fuera de consideración). Podemos hablar de una solicitud de marcadores. Al hacer clic en un enlace, hacer clic en un marcador, ingresar la URL sin formato en la barra de direcciones del navegador, etcétera, se activará una solicitud HTTP GET. Si un Servlet está escuchando en la URL en cuestión, entonces su doGet() se llamará al método. por lo general se usa para preprocesar una solicitud. Es decir, hacer algunas cosas comerciales antes de presentar la salida HTML de un JSP, como recopilar datos para mostrarlos en una tabla.

@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);
    }

}

Tenga en cuenta que el archivo JSP se coloca explícitamente en /WEB-INF carpeta para evitar que los usuarios finales puedan acceder a ella directamente sin invocar el servlet de preprocesamiento (y así terminar confundidos al ver una tabla vacía).

<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>

Además, los enlaces de detalles para ver/editar, como se muestra en la última columna de arriba, suelen ser idempotentes.

@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>

CORREO

Las solicitudes HTTP POST no son idempotentes. Si el usuario final ha enviado un formulario POST en una URL de antemano, que no ha realizado una redirección, entonces la URL no se puede marcar necesariamente. Los datos del formulario enviado no se reflejan en la URL. Es posible que copiar y pegar la URL en una nueva ventana/pestaña del navegador no produzca exactamente el mismo resultado que después de enviar el formulario. Tal URL entonces no se puede marcar. Si un Servlet está escuchando en la URL en cuestión, entonces su doPost() sera llamado. por lo general se usa para proceso después de una solicitud. Es decir, recopilar datos de un formulario HTML enviado y hacer algunas cosas comerciales con él (conversión, validación, guardado en DB, etcétera). Finalmente, por lo general, el resultado se presenta como HTML desde la página JSP reenviada.

<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>

… que se puede usar en combinación con esta pieza 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);
        }
    }

}

Ya ves, si el User se encuentra en DB (es decir, el nombre de usuario y la contraseña son válidos), entonces el User se pondrá en el ámbito de la sesión (es decir, “iniciar sesión”) y el servlet se redirigirá a alguna página principal (este ejemplo va a http://example.com/contextname/home), de lo contrario, establecerá un mensaje de error y reenviará la solicitud a la misma página JSP para que el mensaje se muestre ${error}.

Si es necesario, también puede “ocultar” el login.jsp en /WEB-INF/login.jsp para que los usuarios solo puedan acceder a él mediante el servlet. Esto mantiene la URL limpia http://example.com/contextname/login. Todo lo que necesita hacer es agregar un doGet() al servlet así:

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    request.getRequestDispatcher("/WEB-INF/login.jsp").forward(request, response);
}

(y actualizar la misma línea en doPost() respectivamente)

Dicho esto, no estoy seguro de si solo está jugando y disparando en la oscuridad, pero el código que publicaste no se ve bien (como usar compareTo() en lugar de equals() y cavar en los nombres de los parámetros en lugar de simplemente usar getParameter() y el id y password parece estar declarado como variables de instancia de servlet, que NO es seguro para subprocesos). Por lo tanto, recomiendo enfáticamente aprender un poco más sobre la API básica de Java SE usando el Tutoriales de Oracle (consulte el capítulo “Senderos que cubren los conceptos básicos”) y cómo usar JSP/Servlets de la manera correcta usando esos tutoriales.

Ver también:

  • Nuestra página wiki de servlets
  • Desarrollo web Java EE, ¿por dónde empiezo y qué habilidades necesito?
  • El servlet devuelve “Estado HTTP 404 El recurso solicitado (/servlet) no está disponible”
  • Mostrar JDBC ResultSet en HTML en la página JSP usando el patrón MVC y DAO

Actualizar: según la actualización de su pregunta (que es bastante importante, no debe eliminar partes de su pregunta original, esto haría que las respuestas no tuvieran valor … más bien agregar la información en un nuevo bloque), resulta que está configurando innecesariamente el tipo de codificación del formulario en multipart/form-data. Esto enviará los parámetros de solicitud en una composición diferente a la (predeterminada) application/x-www-form-urlencoded que envía los parámetros de la solicitud como una cadena de consulta (p. ej. name1=value1&name2=value2&name3=value3). Solo necesitas multipart/form-data cada vez que tienes un <input type="file"> elemento en el formulario para cargar archivos que pueden ser datos que no sean de caracteres (datos binarios). Este no es el caso en su caso, así que simplemente elimínelo y funcionará como se esperaba. Si alguna vez necesita cargar archivos, deberá configurar el tipo de codificación y analizar el cuerpo de la solicitud usted mismo. Usualmente usas el Carga de archivos de Apache Commons allí para, pero si ya está en la nueva API Servlet 3.0, entonces puede usar las instalaciones integradas comenzando con HttpServletRequest#getPart(). Consulte también esta respuesta para ver un ejemplo concreto: ¿Cómo cargar archivos en el servidor usando JSP/Servlet?

Tanto GET como POST son utilizados por el navegador para solicitar un solo recurso del servidor. Cada recurso requiere una solicitud GET o POST separada.

  1. El método GET es el más utilizado (y es el método predeterminado) por los navegadores para recuperar información de los servidores. Cuando se utiliza el método GET, la tercera sección del paquete de solicitud, que es el cuerpo de la solicitud, permanece vacía.

El método GET se usa de una de dos maneras: cuando no se especifica ningún método, es decir, cuando usted o el navegador solicitan un recurso simple, como una página HTML, una imagen, etc. Cuando se envía un formulario y usted elige el método =OBTENER en la etiqueta HTML. Si el método GET se usa con un formulario HTML, los datos recopilados a través del formulario se envían al servidor agregando un “?” al final de la URL, y luego agregar todos los pares nombre=valor (nombre del campo de formulario html y valor ingresado en ese campo) separados por un “&” Ejemplo: GET /sultans/shop//form1.jsp?name= Sam%20Sultan&iceCream=vainilla HTTP/1.0 encabezado opcional encabezado opcional << línea vacía >>>

Los datos del formulario nombre=valor se almacenarán en una variable de entorno llamada QUERY_STRING. Esta variable se enviará a un programa de procesamiento (como JSP, servlet de Java, PHP, etc.)

  1. El método POST se utiliza cuando crea un formulario HTML y solicita method=POST como parte de la etiqueta. El método POST permite al cliente enviar datos de formulario al servidor en la sección del cuerpo de la solicitud (como se explicó anteriormente). Los datos están codificados y tienen un formato similar al método GET, excepto que los datos se envían al programa a través de la entrada estándar.

Ejemplo: POST /sultans/shop//form1.jsp HTTP/1.0 encabezado opcional encabezado opcional<< línea vacía >>> nombre=Sam%20Sultan&iceCream=vainilla

Al usar el método de publicación, la variable de entorno QUERY_STRING estará vacía. Ventajas/desventajas de GET frente a POST

Ventajas del método GET: Ligeramente más rápido Los parámetros se pueden ingresar a través de un formulario o al agregarlos después de que la página URL se puede marcar con sus parámetros

Desventajas del método GET: solo puede enviar 4K de datos. (No debe usarlo cuando use un campo de área de texto) Los parámetros son visibles al final de la URL

Ventajas del método POST: Los parámetros no son visibles al final de la URL. (Úselo para datos confidenciales) Puede enviar más de 4K de datos al servidor

Desventajas del método POST: no se puede marcar con sus datos

1646965032 768 doGet y doPost en Servlets
jay jackson

La implementación del contenedor de servlet de HttpServlet.service() el método reenviará automáticamente a doGet() o doPost() según sea necesario, por lo que no debería necesitar anular el método de servicio.

1646965032 899 doGet y doPost en Servlets
Tomás

¿Podría ser que esté pasando los datos a través de obtener, no de publicar?

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

Si lo haces <form action="identification" > para su formulario html, los datos se pasarán usando ‘Obtener’ de forma predeterminada y, por lo tanto, puede detectar esto usando la función doGet en su código de servlet de Java. De esta manera, los datos se pasarán bajo el encabezado HTML y, por lo tanto, serán visibles en la URL cuando se envíen. Por otro lado, si desea pasar datos en el cuerpo HTML, entonces USE Post: <form action="identification" method="post"> y captura estos datos en la función doPost. Esto fue, los datos se pasarán debajo del cuerpo html y no del encabezado html, y no verá los datos en la URL después de enviar el formulario.

Ejemplos de mi html:

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

Ejemplos de mi código 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");

.........
.........

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad