• 7. HttpServlet类


    继承HttpServlet类

    在实际应用中常用的http提交方式有get和post(除此之外还有put、delete),在之前所编写的servlet中是无法直接处理这两种提交方式的,为了方便开发,JavaEE规范的API提供了javax.servlet.http.HttpServlet类,在实际开发中也经常使用继承HttpServlet类的方式创建一个servlet

    package httpservlet;
    
    import java.io.IOException;
    
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    /*记得继承HttpServlet类*/
    public class httpservlet extends HttpServlet {
    
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            System.out.println("我收到了 Get请求");
        }
    
        @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            System.out.println("我收到了 Post请求");
        }
        
    
    }

    上面是通过继承HttpServlet,在httpservlet类中并没有重写service方法主要重写了doGet和doPost方法来分别处理http请求中的get和post,除此之外,在HttpServlet类中还有doPut、doDelete等其他用于处理http请求的方法。

    我们可以配置一下配置文件xml 然后访问 当是get访问的话 那么会调用doget 方法 当时post 那么就会调用post (但是默认情况下是get 具体要用html的form表单来实现):

    然后我们配置好 那个 xml:

      
      <servlet>
      <servlet-name>httpservlet</servlet-name>
      <servlet-class>httpservlet.httpservlet</servlet-class>
      </servlet>
      
      <servlet-mapping>
      <servlet-name>httpservlet</servlet-name>
      <url-pattern>/httpservlet</url-pattern>
      </servlet-mapping>
      

    再然后我们应该再index的html写个表单 就写登录吧:

    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <title>Insert title here</title>
    </head>
    <body>
    <!-- action    URL    规定当提交表单时向何处发送表单数据。 -->
    <!-- method    get、post    规定用于发送 form-data 的 HTTP 方法。 -->
    
    <form action="httpservlet" method="post">
        账号:<input type="text"  placeholder ="请输入账户" >
        <br>
        密码:<input type="password" placeholder="请输入密码">
        <br>
        <input type = "submit" value = "登录">
    
    </form>
    </body>
    </html>

    你也可以尝试不写这个页面直接访问 他的 httpservlet 会发现 他打印的是 我收到了 Get请求 因为呢 他默认是 Get请求。

    ------------------------------------------------------------小技巧:

    快速创建Servlet

    在IDEA中直接创建Servlet,会自动生成相关的web.xml配置信息。

    在eclipse中右键—>new—>servlet可以快速创建一个Servlet,该Servlet会默认继承HttpServlet类并重写doGet和doPost方法,并且在创建的过程中可以帮我们生成web.xml相关servlet标签配置,这样就不用手动编写了。

    ------------------------------------------------------------模板方法设计模式:

    模板方法设计模式

    什么是模板方法设计模式
    定义一个抽象类,将部分逻辑以具体方法以及具体构造函数的形式实现,然后声明一些抽象方法来迫使子类实现剩余的逻辑。不同的子类可以以不同的方式实现这些抽象方法,从而对剩余的逻辑有不同的实现。这就是模板方法模式的用意。
    比如考试的时候,学生是共用同一套试卷,只是学生各自的答案是不同的;因此,试题题目是模板方法是不变的(接口)而试题答案对于每个学生是可变的(重写)

    比如你交白卷 那我就报错! 啊哈哈笑死!


    HttpServlet源码分析 [通过service方法 分发 调用 doGet、doPost、doDelete....等等等方法...]

    通过HttpServlet源码可以看到,这是一个抽象类,该类继承了GenericServlet并重写了其父类中的Service方法

    public abstract class HttpServlet extends GenericServlet 

    HttpServlet类中重写的service方法:(两个:)

    @Override
        public void service(ServletRequest req, ServletResponse res)
            throws ServletException, IOException {
    
            HttpServletRequest  request;
            HttpServletResponse response;
    
            try {
                request = (HttpServletRequest) req;
                response = (HttpServletResponse) res;
            } catch (ClassCastException e) {
                throw new ServletException("non-HTTP request or response");
            }
            service(request, response);
        }
    }

    在重写的service方法中,将ServletRequest和ServletResponse强转成了HttpServletRequest和HttpServletResponse,并且调用另外一个service方法将强转后的HttpServletRequest和HttpServletResponse对象作为参数传递了过去,再看下这个service方法的源码:

     protected void service(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
    
            String method = req.getMethod();
    
            if (method.equals(METHOD_GET)) {
                long lastModified = getLastModified(req);
                if (lastModified == -1) {
                    // servlet doesn't support if-modified-since, no reason
                    // to go through further expensive logic
                    doGet(req, resp);
                } else {
                    long ifModifiedSince;
                    try {
                        ifModifiedSince = req.getDateHeader(HEADER_IFMODSINCE);
                    } catch (IllegalArgumentException iae) {
                        // Invalid date header - proceed as if none was set
                        ifModifiedSince = -1;
                    }
                    if (ifModifiedSince < (lastModified / 1000 * 1000)) {
                        // If the servlet mod time is later, call doGet()
                        // Round down to the nearest second for a proper compare
                        // A ifModifiedSince of -1 will always be less
                        maybeSetLastModified(resp, lastModified);
                        doGet(req, resp);
                    } else {
                        resp.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
                    }
                }
    
            } else if (method.equals(METHOD_HEAD)) {
                long lastModified = getLastModified(req);
                maybeSetLastModified(resp, lastModified);
                doHead(req, resp);
    
            } else if (method.equals(METHOD_POST)) {
                doPost(req, resp);
    
            } else if (method.equals(METHOD_PUT)) {
                doPut(req, resp);
    
            } else if (method.equals(METHOD_DELETE)) {
                doDelete(req, resp);
    
            } else if (method.equals(METHOD_OPTIONS)) {
                doOptions(req,resp);
    
            } else if (method.equals(METHOD_TRACE)) {
                doTrace(req,resp);
    
            } else {
                //
                // Note that this means NO servlet supports whatever
                // method was requested, anywhere on this server.
                //
    
                String errMsg = lStrings.getString("http.method_not_implemented");
                Object[] errArgs = new Object[1];
                errArgs[0] = method;
                errMsg = MessageFormat.format(errMsg, errArgs);
    
                resp.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED, errMsg);
            }
        }

    通过该源码可以看到,他从HttpServletRequest对象中的getMethod方法里面获取到http的请求方式然后将不同的请求方式交给了不同的方法来处理,这其中包含了doGet、doPost、doPut、doDelete等方法,在这些方法里面并没有写什么特殊的业务处理的代码这样做的目的就是让子类去重写这些方法所以说HttpServlet类中使用了模板方法设计模式。需要注意的是HttpServlet的子类不需要重写service方法,倘若重写了该方法后可能会导致所编写的Servlet无法正常工作。

    所以呢!!!如果你继承了httpservlet类 和 用了get 或 post方法那么就会报错 因为 他们的doget 或 dopost 是这样写的:(这相当于你交白卷啊! 想访问(要成绩) 但你 不写试卷)

    doget:

      protected void doGet(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException
        {
            String protocol = req.getProtocol();
            String msg = lStrings.getString("http.method_get_not_supported");
            if (protocol.endsWith("1.1")) {
                resp.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, msg);
            } else {
                resp.sendError(HttpServletResponse.SC_BAD_REQUEST, msg);
            }
        }

    dopost:

     protected void doPost(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
    
            String protocol = req.getProtocol();
            String msg = lStrings.getString("http.method_post_not_supported");
            if (protocol.endsWith("1.1")) {
                resp.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, msg);
            } else {
                resp.sendError(HttpServletResponse.SC_BAD_REQUEST, msg);
            }
        }

    自己认真看下 且 测试下即可!

    本文来自博客园,作者:咸瑜,转载请注明原文链接:https://www.cnblogs.com/bi-hu/p/14806757.html

  • 相关阅读:
    设计模式学习——前言和目录
    模板颜色搭配
    win7、xp下Meclipse SVN用户名修改
    JS编码解码
    用Javascript进行HTML转义(分享)
    打印异常信息
    lucene 抛出的异常(分享)
    SQL语句优化(分享)
    Java集群之session共享解决方案
    VUE中返回上一页
  • 原文地址:https://www.cnblogs.com/bi-hu/p/14806757.html
Copyright © 2020-2023  润新知