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

Java 在doGet方法中调用doPost方法正确吗?,java,servlets,Java,Servlets,我的问题来自 简言之,它确实: @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=UTF-8"); PrintWriter out = response.getWriter();

我的问题来自

简言之,它确实:

@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();
    }
}
@覆盖
受保护的void doGet(HttpServletRequest请求、HttpServletResponse响应)
抛出ServletException、IOException
{    
setContentType(“text/html;charset=UTF-8”);
PrintWriter out=response.getWriter();
尝试
{
out.println(“”);
out.println(“”);
out.println(“Hi World”);
out.println(“”);
out.println(“”);
out.println(“你好世界”);
doPost(请求、响应);//客户端(浏览器)不会注意到您在服务器代码中调用了哪些方法

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

问题在于
doPost()
附带了一些字符串。在这种情况下,它会更改响应头。这并不总是起作用:如果服务器代码已开始发送响应,则更改为头字段将被静默忽略。因此,如果有输出缓冲区且缓冲区足够大,则代码将起作用。一个小的更改可能会使代码在unep中中断不易理解和理解的方式

更好的解决方案是将代码拆分为助手方法,这些方法由
doGet()
doPost()
调用


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

您必须首先了解
doPost
doGet
只是方法

它是否无效(无正当理由两次点击服务器)

您没有点击服务器。您正在调用一个方法。这与编写一个单独的方法
foo(…)
并调用它是一样的

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

如果两个处理程序执行完全相同的操作,不要重复相同的代码。将其放在一个方法中,然后从另一个方法中调用。或者更好的是,将逻辑提取到一个完全不同的方法中,然后从这两个方法中调用


Servlet容器(YMMV)的流:

  • 服务器接受套接字连接
  • 服务器分派线程来处理请求
  • 线程解析请求头和请求体,并准备
    ServletRequest
    ServletResponse
    对象
  • 线程决定Servlet/过滤器路由。(这将决定您的
    Servlet
    是否合适。)
  • 线程调用HttpServlet服务(..)
  • 该调用将委托给子类型中相应的
    doXYZ
    方法
  • 调用完成时堆栈倒回,线程清理请求并提交响应

  • 为了说明其他人已经写了什么,最简单的处理方法是:

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

    如果你的webapp对get和post的处理方式基本相同,那么你可以选择复制代码(浪费、容易出错)、用另一种方法调用代码(简单方法),或者创建一个同时处理这两种代码的助手方法(长期方法)。如果出于某种原因,您需要两者都做完全相同的事情,那么调用另一个,除了调用另一个之外什么也不做是有意义的。但是做上面正在做的事情是可怕的。不仅仅是他们在调用另一个之前和之后都在做其他事情,而是在servlet中打印HTML这样做是很糟糕的。