在doGet方法中调用doPost方法是正确的吗?

时间:2014-12-15 15:33:45

标签: java servlets

我的问题来自this code

简而言之,它确实:

@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException 
{    
    response.setContentType("text/html;charset=UTF-8");
    PrintWriter out = response.getWriter();
    try
    {
        out.println("<html>");
        out.println("<head>");
        out.println("<title>Hi World</title>");
        out.println("</head>");
        out.println("<body>");
        out.println("<h1> Hello World </h1>");
        doPost(request,response); // <<--- ???
        out.println("</body>");
        out.println("</html>");    
    } 
    finally 
    {
        out.close();
    }
}

我知道这只是一个示例代码。但是在这种情况下,我是一个新手并且把这个“doPost放在一个doGet的东西,因为我在SO上阅读它,我认为它没问题”:这样做有什么问题?这是无效的(由于没有充分的理由,两次击中服务器)?在服务器上触发不必要的请求?太多不必要的代码(对于doPost和doGet方法)?是utterly nonsense吗? 或者,也许有些情况下这样做是合理的吗?

3 个答案:

答案 0 :(得分:1)

您必须先了解doPostdoGet 只是方法

  

它是无效的(由于没有充分的理由,两次击中服务器)

您没有点击服务器。你正在调用一个方法。它与编写单独的方法foo(..)并调用它相同。

doPostdoGet(以及其他)是Servlet API的一部分,它通过为您提供处理特定请求类型的入口点来尝试简化您的生活。

如果两个处理程序完全相同,请不要重复相同的代码。把它放在一个方法中并从另一个方法调用它。或者更好的是,将逻辑提取到一个完全不同的方法并从两者中调用它。


Servlet容器(YMMV)的流程:

  1. 服务器接受套接字连接。
  2. 服务器调度线程以处理请求
  3. 线程解析请求标头和正文,并准备ServletRequestServletResponse个对象。
  4. 线程确定Servlet / Filter路由。 (这是确定Servlet合适的地方。)
  5. 线程调用HttpServlet#service(..)
  6. 该调用委托给您子类型中的相应doXYZ方法。
  7. 堆栈在调用完成后重新开始,线程会清理请求并提交响应。

答案 1 :(得分:0)

客户端(浏览器)不会注意您在服务器代码中调用的方法。

在这种情况下,您可以重复doPost()中的代码,以避免doGet()中的重复,这很好。

问题是doPost()附带了一些字符串。在这种情况下,它会更改响应标头。这并不总是有效:如果服务器代码已开始发送响应,则会自动忽略更改为标题字段。因此,如果存在输出缓冲区并且缓冲区足够大,代码将起作用。一个小小的改变可能会使代码突然出现意外且难以理解的方式。

更好的解决方案是将代码拆分为由doGet()doPost()调用的辅助方法。

事实上,在我的旧代码中,我在Servlet API和我的代码之间有一个抽象层。我的代码将获得标题字段的映射以及输出的Writer。这样,测试代码就很简单了(比如在第一个字符写入put()后调用Writer时使用会抛出异常的地图切换地图。)

答案 2 :(得分:0)

为了说明其他人已经写过的内容,处理此问题的最简单方法是:

doGet(...) {
   processRequest(...);
}

doPost(...) {
    processRequest(...);
}

processRequest(...) {
    ...
}