当前位置: 首页 > 面试题库 >

Servlet中的doGet和doPost

阎安邦
2023-03-14
问题内容

我已经开发了一个将信息发送到Servlet的HTML页面。在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> 

method = “get”在Servlet中使用时,我会获得id和password的值,但是在使用时method = “post”,id和password会设置为null。为什么在这种情况下我无法获取值?

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


问题答案:

介绍

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

GET

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

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

同样,如上最后一列所示,查看/编辑详细信息链接通常也是幂等的。

@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,则将doPost()调用它。通常用于对请求进行后处理。即从提交的HTML表单中收集数据并进行一些处理(转换,验证,保存到DB等)。最后,通常结果从转发的JSP页面以HTML形式呈现。

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

}

你会看到,如果User在数据库中找到(即用户名和密码有效),则会User将其放入会话范围(即“登录”),并且servlet将重定向到某个主页(此示例转到http://example.com/contextname/home),否则它将设置一条错误消息,并将请求转发回同一JSP页面,以使该消息显示为${error}。

如果需要,你也可以“隐藏”其中login.jsp,/WEB-INF/login.jsp以便用户只能通过servlet访问它。这样可以保持URL干净http://example.com/contextname/login。你需要做的就是doGet()像这样向servlet 添加一个:

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

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



 类似资料:
  • 我使用的是Apache Tomcat7.0 Servlet容器。我一直在研究JavaServer Faces中的请求处理。我可以在web.xml中看到以下配置块:

  • 如何解决这个问题?

  • 问题内容: 我正在尝试将String发送到服务器(在tomcat上运行),并让它返回String。客户端发送字符串,服务器接收它,但是当客户端取回它时,字符串为null。 doGet()应该将String in =从客户端输入。但是doPost()在= null中发送String。 为什么?我假设doGet()在doPost()之前运行,因为它是由客户端首先调用的。 服务器: 客户: 问题答案:

  • 编辑:这不是这个问题的重复,因为我正在尝试在同一个servlet的和之间发送数据。另一个问题询问如何在不同的servlet之间发送数据,但我已经通过将信息附加到URL来做到这一点(参见下面的第一个代码片段),这在同一个servlet中是做不到的。另外,链接的问题来自2011年,使用Tomcat 5.5,而我使用8.5。 我正在开发一个带有两个servlet和一个过滤器的小型Java 8/Tomca

  • 问题内容: 显然,该方法的返回类型为void,因此,它不返回任何内容。从这个意义上讲,我使用“返回”一词来表示将响应发送回请求它的客户端。 我正在尝试实现一个长轮询的Servlet。最好在我有想要发回的东西之前不发送响应,这将是有益的。因此,在doGet方法中,将连接的用户的ID和AsyncContext添加到映射中: 然后,当我有东西要发回时,我可以检索适当的上下文并写入其响应输出流: 但是,客

  • 我遇到了一个奇怪的问题。对于单个HTTP请求,我的servlet的doGet方法被多次调用。每隔10-12秒重新运行一次,直到初始过程完成。 下面是我的servlet代码 下面是web.xml中的映射 我使用的是SEAM和JSF,但这是一个独立的servlet。日志中也没有例外。我还验证了INIT方法只被调用一次。重复的是服务方法。所有重新运行的标识哈希代码都是相同的(System.Identit