doGet and doPost in Servlets介绍

2022-08-31 09:47:49

我开发了一个HTML页面,可以将信息发送到Servlet。在Servlet中,我使用以下方法和:doGet()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");
}

在调用 Servlet 的 html 页面代码中,是:

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

当我在Servlet中使用时,我得到id和密码的值,但是当使用时,id和密码设置为。在这种情况下,为什么我无法获得这些值?method = "get"method = "post"null

我想知道的另一件事是如何使用Servlet生成或验证的数据。例如,如果上面显示的Servlet对用户进行身份验证,我想在我的HTML页面中打印用户ID。我应该能够发送字符串“id”作为响应,并在我的HTML页面中使用此信息。可能吗?


答案 1

介绍

当你想要拦截HTTP GET请求时,你应该使用doGet()。当你想要拦截HTTP POST请求时,你应该使用doPost()。就这样。不要将一个移植到另一个,反之亦然(例如在 Netbeans 不幸的自动生成方法中)。这是完全没有道理的。processRequest()

获取

通常,HTTP GET 请求是幂等的。也就是说,每次执行请求时都会得到完全相同的结果(将授权/身份验证和页面的时间敏感性 ( 搜索结果,最新消息等 - 留在考虑范围之外)。我们可以讨论一个可添加书签的请求。单击链接,单击书签,在浏览器地址栏中输入原始URL等都将触发HTTP GET请求。如果 Servlet 正在侦听有问题的 URL,则将调用其方法。它通常用于预处理请求。即,在呈现来自 JSP 的 HTML 输出之前做一些业务工作,例如收集数据以在表中显示。doGet()

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

}

请注意,JSP 文件被显式放置在文件夹中,以防止最终用户能够在不调用预处理 servlet 的情况下直接访问它(因此最终因看到空表而感到困惑)。/WEB-INF

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

此外,如上一列所示,查看/编辑详细信息链接通常是幂等的。

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

发布

HTTP POST 请求不是幂等的。如果最终用户事先在 URL 上提交了 POST 表单,而该表单尚未执行重定向,则该 URL 不一定是可添加书签的。提交的表单数据不会反映在 URL 中。将 URL 复制粘贴到新的浏览器窗口/选项卡中不一定会产生与表单提交后完全相同的结果。这样一个 URL 是不可添加书签的。如果 Servlet 正在侦听有问题的 URL,则将调用它。它通常用于对请求进行后处理。即,从提交的HTML表单中收集数据并对其进行一些业务处理(转换,验证,保存在数据库中等)。最后,通常结果从转发的JSP页面显示为HTML。doPost()

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

...这可以与这块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);
        }
    }

}

你看,如果在 DB 中找到 (即用户名和密码是有效的),那么 将放在会话范围内(即“已登录”),并且 servlet 将重定向到某个主页(此示例转到 ),否则它将设置一条错误消息并将请求转发回相同的 JSP 页面,以便消息由 显示。UserUserhttp://example.com/contextname/home${error}

如有必要,您还可以“隐藏”in,以便用户只能通过 servlet 访问它。这将使 URL 保持干净。您需要做的就是像这样向 servlet 添加一个:login.jsp/WEB-INF/login.jsphttp://example.com/contextname/logindoGet()

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

(并相应地更新 doPost() 中的同一行)

也就是说,我不确定它是否只是在黑暗中玩耍和射击,但是您发布的代码看起来并不好(例如使用而不是挖掘参数名称,而不仅仅是使用和和似乎被声明为servlet实例变量 - 这不是线程安全的)。因此,我强烈建议使用Oracle教程(查看“覆盖基础知识的Trails”一章)学习更多关于基本Java SE API的知识,以及如何使用这些教程以正确的方式使用JSP / Servlets。compareTo()equals()getParameter()idpassword

另请参阅:


更新:根据您问题的更新(这是非常主要的,您不应该删除原始问题的一部分,这将使答案毫无价值......而是将信息添加到新块中),事实证明您不必要地将表单的编码类型设置为多部分/表单数据。这将以与(默认)不同的组合发送请求参数,后者将请求参数作为查询字符串(例如)发送。只有当表单中有一个元素时,您才需要上传可能是非字符数据(二进制数据)的文件。在您的案例中,情况并非如此,因此只需将其删除,它就会按预期工作。如果您需要上传文件,则必须设置编码类型并自行解析请求正文。通常你在那里使用Apache Commons FileUpload,但是如果你已经在使用全新的Servlet 3.0 API,那么你可以使用从HttpServletRequest#getPart()开始的内置工具。另请参阅此答案以获取具体示例:如何使用 JSP/Servlet 将文件上载到服务器?application/x-www-form-urlencodedname1=value1&name2=value2&name3=value3multipart/form-data<input type="file">


答案 2

浏览器使用 GET 和 POST 从服务器请求单个资源。每个资源都需要单独的 GET 或 POST 请求。

  1. GET 方法最常(并且是默认方法)由浏览器用于从服务器检索信息。使用 GET 方法时,请求数据包的第 3 部分(即请求正文)保持为空。

GET 方法以以下两种方式之一使用:未指定方法时,即您或浏览器请求简单资源(如 HTML 页面、图像等)时。提交表单时,在 HTML 标记上选择 method=GET。如果 GET 方法与 HTML 表单一起使用,则通过表单收集的数据将发送到服务器,方法是在 URL 末尾附加一个 “?”,然后添加所有 name=value 对(html 表单字段的名称和在该字段中输入的值),以“&” 分隔示例:GET /sultans/shop//form1.jsp?name=Sam%20Sultan&iceCream=vanilla HTTP/1.0 可选标头选项标头<<空行>>>

name=value 表单数据将存储在名为 QUERY_STRING 的环境中变量中。此变量将被发送到处理程序(如 JSP、Java servlet、PHP 等)。

  1. POST 方法在创建 HTML 表单时使用,并且请求方法 = POST 作为标记的一部分。POST 方法允许客户端在请求的请求正文部分中将表单数据发送到服务器(如前所述)。数据的编码和格式与 GET 方法类似,只是数据通过标准输入发送到程序。

示例:POST /sultans/shop//form1.jsp HTTP/1.0 可选标头选项标头<<空行>>> name=Sam%20Sultan&iceCream=vanilla

使用 post 方法时,QUERY_STRING环境变量将为空。GET 与 POST 的优缺点

GET方法的优点:稍微快一些 参数可以通过表单输入,也可以在URL页面之后附加参数,可以使用其参数添加书签

GET方法的缺点:只能发送4K数据。(使用文本区域字段时不应使用它)参数在 URL 的末尾可见

POST 方法的优点:参数在 URL 的末尾不可见。(用于敏感数据)可以向服务器发送更多 4K 数据

POST方法的缺点:无法使用其数据添加书签


推荐