• 第2天:servlet常见的接口和方法


    1、常见接口:

    2、ServletRequset接口

    Servlet容器对于接受到的每一个Http请求,都会创建一个ServletRequest对象,并把这个对象传递给Servlet的Sevice( )方法。其中,ServletRequest对象内封装了关于这个请求的许多详细信息。

    常用的方法:

    public interface ServletRequest {
     
        Map<String, String[]> getParameterMap();//返回请求主体参数的key-value
     
        String getContentType();//返回主体的MIME类型
     
        String getParameter(String var1);//返回请求参数的值
     
    }

    3、ServletResponse接口

    javax.servlet.ServletResponse接口表示一个Servlet响应,在调用Servlet的Service( )方法前,Servlet容器会先创建一个ServletResponse对象,并把它作为第二个参数传给Service( )方法。ServletResponse隐藏了向浏览器发送响应的复杂过程。

    方法:

    public interface ServletResponse {
        String getCharacterEncoding();
    
        String getContentType();
    
        ServletOutputStream getOutputStream() throws IOException;
    
        PrintWriter getWriter() throws IOException;
    
        void setCharacterEncoding(String var1);
    
        void setContentLength(int var1);
    
        void setContentLengthLong(long var1);
    
        void setContentType(String var1);
    
        void setBufferSize(int var1);
    
        int getBufferSize();
    
        void flushBuffer() throws IOException;
    
        void resetBuffer();
    
        boolean isCommitted();
    
        void reset();
    
        void setLocale(Locale var1);
    
        Locale getLocale();
    }

    其中的getWriter()方法,它返回了一个可以向客户端发送文本的的Java.io.PrintWriter对象。默认情况下,PrintWriter对象使用ISO-8859-1编码(该编码在输入中文时会发生乱码)

        在向客户端发送响应时,大多数都是使用该对象向客户端发送HTML。

    还有一个方法也可以用来向浏览器发送数据,它就是getOutputStream,从名字就可以看出这是一个二进制流对象,因此这个方法是用来发送二进制数据的。

    在发送任何HTML之前,应该先调用setContentType()方法,设置响应的内容类型,并将“text/html”作为一个参数传入,这是在告诉浏览器响应的内容类型为HTML,需要以HTML的方法解释响应内容而不是普通的文本,或者也可以加上“charset=UTF-8”改变响应的编码方式以防止发生中文乱码现象。

    4、ServletConfig接口

    当Servlet容器初始化Servlet时,Servlet容器会给Servlet的init( )方式传入一个ServletConfig对象。

    public interface ServletConfig {
        String getServletName();//获取该servlet在web.xml中配置的name值
    
        ServletContext getServletContext();//获取应用上下文对象
    
        String getInitParameter(String var1);//获取该servlet的初始化参数
    
        Enumeration<String> getInitParameterNames();//获取该servlet的name集合
    }

    5、ServletContext对象

     ServletContext对象表示Servlet应用程序。每个Web应用程序都有且只有一个ServletContext象。在将一个应用程序同时部署到多个容器的分布式环境中,每台Java虚拟机上的Web应用都会有一个ServletContext对象。

     servletConfig.getServletContext(); 获得ServletContext对象

    ServletContext对象对象的作用?

    有了ServletContext对象,就可以共享从应用程序中的所有资料处访问到的信息,并且可以动态注册Web对象。前者将对象保存在ServletContext中的一个内部Map中。保存在ServletContext中的对象被称作属性。

    属性常见方法:

    Object getAttribute(String var1);//根据name获取属性值
     
    Enumeration<String> getAttributeNames();//获取属性的name集合
     
    void setAttribute(String var1, Object var2);//设置name属性的值
     
    void removeAttribute(String var1);//根据name值移除对应属性

    6、GenericServlet抽象类 

    编写Servlet一直是通过实现Servlet接口来编写的,但是,使用这种方法,则必须要实现Servlet接口中定义的所有的方法,即使有一些方法中没有任何东西也要去实现,并且还需要自己手动的维护ServletConfig这个对象的引用。因此,这样去实现Servlet是比较麻烦的。

    GenericServlet抽象类的出现很好的解决了这个问题。本着尽可能使代码简洁的原则,GenericServlet实现了Servlet和ServletConfig接口,下面是GenericServlet抽象类的具体代码:

    public abstract class GenericServlet implements Servlet, ServletConfig, Serializable {
        private static final long serialVersionUID = 1L;
        private transient ServletConfig config;
    
        public GenericServlet() {
        }
    
        public void destroy() {
        }
    
        public String getInitParameter(String name) {
            return this.getServletConfig().getInitParameter(name);
        }
    
        public Enumeration<String> getInitParameterNames() {
            return this.getServletConfig().getInitParameterNames();
        }
    
        public ServletConfig getServletConfig() {
            return this.config;
        }
    
        public ServletContext getServletContext() {
            return this.getServletConfig().getServletContext();
        }
    
        public String getServletInfo() {
            return "";
        }
    
        public void init(ServletConfig config) throws ServletException {
            this.config = config;
            this.init();
        }
    
        public void init() throws ServletException {
        }
    
        public void log(String msg) {
            this.getServletContext().log(this.getServletName() + ": " + msg);
        }
    
        public void log(String message, Throwable t) {
            this.getServletContext().log(this.getServletName() + ": " + message, t);
        }
    
        public abstract void service(ServletRequest var1, ServletResponse var2) throws ServletException, IOException;
    
        public String getServletName() {
            return this.config.getServletName();
        }
    }

    GenericServlet抽象类相比于直接实现Servlet接口的优点:

    1.为Servlet接口中的所有方法提供了默认的实现,则程序员需要什么就直接改什么,不再需要把所有的方法都自己实现了。

    2.提供方法,包围ServletConfig对象中的方法。

    3.将init( )方法中的ServletConfig参数赋给了一个内部的ServletConfig引用从而来保存ServletConfig对象,不需要程序员自己去维护ServletConfig了。

    多出的方法init()的作用:

    public void init() throws ServletException {
    }

    为什么已经有了一个init(ServletConfig config)方法,还要再提供一个init()空参的方法呢?

    抽象类是无法直接产生实例的,需要另一个类去继承这个抽象类,那么就会发生方法覆盖的问题,如果在类中覆盖了GenericServlet抽象类的init()方法,那么程序员就必须手动的去维护ServletConfig对象了,还得调用super.init(servletConfig)方法去调用父类GenericServlet的初始化方法来保存ServletConfig对象,这样会给程序员带来很大的麻烦。GenericServlet提供的第二个不带参数的init( )方法,就是为了解决上述问题的。

    这个不带参数的init()方法,是在ServletConfig对象被赋给ServletConfig引用后,由第一个带参数的init(ServletConfig servletconfig)方法调用的,那么这意味着,当程序员如果需要覆盖这个GenericServlet的初始化方法,则只需要覆盖那个不带参数的init( )方法就好了,此时,servletConfig对象仍然有GenericServlet保存着。

    GenericServlet中,从servlet接口带来的init(ServletConfig config)对它进行重写时,如果忘了调用super.init(config)时,就会出现空指针异常,为了解决这样的情况,GenericServlet中于是有了一个无参的init()方法

    如何没有空参init()方法的话,继承MygenericServlet 的类 要想在初始化的时候做些事,就必须
    调用super.init(servletConfig) ————麻烦;
    或者 复写掉父类的方法————导致父类的初始化操作无效;

    7、HttpServlet抽象类(常用)

    HttpServlet是由GenericServlet抽象类扩展而来的,HttpServlet抽象类的声明如下所示:

    public abstract class HttpServlet extends GenericServlet 

    使用HttpServlet抽象类时,还需要借助分别代表Servlet请求和Servlet响应的HttpServletRequest和HttpServletResponse对象

    public interface HttpServletRequest extends ServletRequest
    public interface HttpServletResponse extends ServletResponse

     HttpServlet抽象类覆盖了GenericServlet抽象类中的Service( )方法,并且在该方法中调用了自己独有的Service(HttpServletRequest request,HttpServletResponse方法。

        public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {//覆盖的SenericServlet类的service方法
            HttpServletRequest request;
            HttpServletResponse response;
            try {
                request = (HttpServletRequest)req;
                response = (HttpServletResponse)res;
            } catch (ClassCastException var6) {
                throw new ServletException(lStrings.getString("http.non_http"));
            }
    
            this.service(request, response);//自己重写的service方法
        }

     HttpServlet中的service方法把接收到的ServletRequsest类型的对象转换成了HttpServletRequest类型的对象,把ServletResponse类型的对象转换成了HttpServletResponse类型的对象

    自己重写的service方法代码:

    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            String method = req.getMethod();
            long lastModified;
            if (method.equals("GET")) {
                lastModified = this.getLastModified(req);
                if (lastModified == -1L) {
                    this.doGet(req, resp);
                } else {
                    long ifModifiedSince;
                    try {
                        ifModifiedSince = req.getDateHeader("If-Modified-Since");
                    } catch (IllegalArgumentException var9) {
                        ifModifiedSince = -1L;
                    }
    
                    if (ifModifiedSince < lastModified / 1000L * 1000L) {
                        this.maybeSetLastModified(resp, lastModified);
                        this.doGet(req, resp);
                    } else {
                        resp.setStatus(304);
                    }
                }
            } else if (method.equals("HEAD")) {
                lastModified = this.getLastModified(req);
                this.maybeSetLastModified(resp, lastModified);
                this.doHead(req, resp);
            } else if (method.equals("POST")) {
                this.doPost(req, resp);
            } else if (method.equals("PUT")) {
                this.doPut(req, resp);
            } else if (method.equals("DELETE")) {
                this.doDelete(req, resp);
            } else if (method.equals("OPTIONS")) {
                this.doOptions(req, resp);
            } else if (method.equals("TRACE")) {
                this.doTrace(req, resp);
            } else {
                String errMsg = lStrings.getString("http.method_not_implemented");
                Object[] errArgs = new Object[]{method};
                errMsg = MessageFormat.format(errMsg, errArgs);
                resp.sendError(501, errMsg);
            }
    
        }
    View Code

    我们会发现在service方法中还是没有任何的服务逻辑,但是却在解析HttpServletRequest中的方法参数,并调用以下方法之一:doGet,doPost,doHead,doPut,doTrace,doOptions和doDelete。这7种方法中,每一种方法都表示一个Http方法。doGet和doPost是最常用的。所以,如果我们需要实现具体的服务逻辑,不再需要覆盖service方法了,只需要覆盖doGet或者doPost就好了。

        总之,HttpServlet有两个特性是GenericServlet所不具备的:

        1.不用覆盖service方法,而是覆盖doGet或者doPost方法。在少数情况,还会覆盖其他的5个方法。

        2.使用的是HttpServletRequest和HttpServletResponse对象。

    8、HttpServletRequest接口

      HttpServletRequest表示Http环境中的Servlet请求。它扩展于javax.servlet.ServletRequest接口,并添加了几个方法。方法头:

    public interface HttpServletRequest extends ServletRequest

    常用方法:

        String getHeader(String var1);//返回指定http标题的值
    
        Cookie[] getCookies();//返回一个cookie对象的数组
    
        String getContextPath();//返回请求上下文的请求URL部分
    
        String getQueryString();//返回请求URL中的查询字符串
    
        HttpSession getSession();////返回与这个请求相关的会话对象
    
        String getMethod();//返回生成这个请求HTTP的方法名称

    9、HttpServletRequest内封装的请求

    9.1、通过request获得请求行

    假设查询字符串为:username=zhangsan&password=123

    获得客户端的请求方式:String getMethod()

    获得请求的资源:

    String getRequestURI()

    StringBuffer getRequestURL()

    String getContextPath() ---web应用的名称

    String getQueryString() ---- get提交url地址后的参数字符串

    9.2、通过request获得请求头

    long getDateHeader(String name)

    String getHeader(String name)

    Enumeration getHeaderNames()

    Enumeration getHeaders(String name)

    int getIntHeader(String name)

    referer头的作用:执行该此访问的的来源,做防盗链

    9.3、通过request获得请求体

    请求体中的内容是通过post提交的请求参数,格式是:

    username=zhangsan&password=123&hobby=football&hobby=basketball

    key ---------------------- value

    username                               [zhangsan]

    password                               [123]

    hobby                                          [football,basketball]                                       

    以上面参数为例,通过一下方法获得请求参数:

    String getParameter(String name)

    String[] getParameterValues(String name)

    Enumeration getParameterNames()

    Map<String,String[]> getParameterMap()

          注意:get请求方式的请求参数 上述的方法一样可以获得。

    9.4、Request乱码问题的解决方法

    在前面我们讲过,在service中使用的编码解码方式默认为:ISO-8859-1编码,但此编码并不支持中文,因此会出现乱码问题,所以我们需要手动修改编码方式为UTF-8编码,才能解决中文乱码问题,下面是发生乱码的具体细节:

    解决post提交方式的乱码:request.setCharacterEncoding("UTF-8");

     解决get提交的方式的乱码:

    parameter = newString(parameter.getbytes("iso8859-1"),"utf-8");

    10、HttpServletResponse接口

    在Service API中,定义了一个HttpServletResponse接口,它继承自ServletResponse接口,专门用来封装HTTP响应消息。    由于HTTP请求消息分为状态行,响应消息头,响应消息体三部分,因此,在HttpServletResponse接口中定义了向客户端发送响应状态码,响应消息头,响应消息体的方法。

    10.1、通过Response设置响应

    void addCookie(Cookie var1);//给这个响应添加一个cookie
    
    void addHeader(String var1, String var2);//给这个请求添加一个响应头
    
    void sendRedirect(String var1) throws IOException;//发送一条响应码,讲浏览器跳转到指定的位置
    
    void setStatus(int var1);//设置响应行的状态码

    addHeader(String name, String value)

    addIntHeader(String name, int value)

    addDateHeader(String name, long date)

    setHeader(String name, String value)

    setDateHeader(String name, long date)

    setIntHeader(String name, int value)

    其中,add表示添加,而set表示设置

    PrintWriter getWriter()

    获得字符流,通过字符流的write(String s)方法可以将字符串设置到response   缓冲区中,随后Tomcat会将response缓冲区中的内容组装成Http响应返回给浏览器端。

    ServletOutputStream getOutputStream()

    获得字节流,通过该字节流的write(byte[] bytes)可以向response缓冲区中写入字节,再由Tomcat服务器将字节内容组成Http响应返回给浏览器。

    注意:虽然response对象的getOutSream()和getWriter()方法都可以发送响应消息体,但是他们之间相互排斥,不可以同时使用,否则会发生异常。

    10.2、Response的乱码问题

    原因:response缓冲区的默认编码是iso8859-1,此码表中没有中文。所以需要更改response的编码方式:

    httpServletResponse.setCharacterEncoding("UTF-8");

     通过更改response的编码方式为UTF-8,仍然无法解决乱码问题,因为发送端服务端虽然改变了编码方式为UTF-8,但是接收端浏览器端仍然使用GB2312编码方式解码,还是无法还原正常的中文,因此还需要告知浏览器端使用UTF-8编码去解码。

    httpServletResponse.setHeader("Content-Type","text/html;charset=UTF-8");

    上面通过调用两个方式分别改变服务端对于Response的编码方式以及浏览器的解码方式为同样的UTF-8编码来解决编码方式不一样发生乱码的问题。

    response.setContentType("text/html;charset=UTF-8")这个方法包含了上面的两个方法的调用,因此在实际的开发中,只需要调用一个response.setContentType("text/html;charset=UTF-8")方法即可。

     

    10.3、Response的工作流程

    11、Servlet的工作流程

     12、编写第一个Servlet

    写一个简单的用户名,密码的登录界面的html文件:

      <form action="/servlet/form" method="post">
        <span>用户名</span><input type="text" name="username"><br>
        <span>密码</span><input type="password" name="password"><br>
        <input type="submit" name="submit">
      </form>

     写一个Servlet用来接收处理表单发送过来的请求,这个Servlet的名称就叫做HiHttpServlet:

    public class HiHttpServlet extends HttpServlet {
        @Override
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            //设置请求的编码格式为UTF-8编码,否则发生中文乱码现象
            request.setCharacterEncoding("UTF-8");
            System.out.println(request.getMethod());//获取请求的方式
            System.out.println(request.getRequestURL());//获取请求的链接
            System.out.println(request.getRequestURI());//获取请求的URI
            System.out.println(request.getContextPath());//获取web应用名称
            System.out.println(request.getParameterMap());//获取请求的参数map集合(get和post都可以)
            System.out.println(request.getQueryString());//获取get提交url地址后的参数字符串(get方式的能获取到)
            System.out.println("username:"+request.getParameter("username"));
            System.out.println("password:"+request.getParameter("password"));
    
            //设置响应的编码格式为UTF-8编码,否则发生中文乱码现象
            response.setContentType("text/html;charset=utf-8");
            response.getWriter().println("你好,HiHttpServlet");
        }
    }

    web.xml:

        <servlet>
            <servlet-name>hiHttpServlet</servlet-name>
            <servlet-class>com.servlet.javaweb.HiHttpServlet</servlet-class>
        </servlet>
    
        <servlet-mapping>
            <servlet-name>hiHttpServlet</servlet-name>
            <url-pattern>/form</url-pattern>
        </servlet-mapping>

    结果:

     

    功能点小结:

    1. Servlet 的 HelloWorld
    1). 创建一个 Servlet 接口的实现类. 
    public class HelloServlet implements Servlet
    
    2). 在 web.xml 文件中配置和映射这个 Servlet
    
        <!-- 配置和映射 Servlet -->
        <servlet>
            <!-- Servlet 注册的名字 -->
            <servlet-name>helloServlet</servlet-name>
            <!-- Servlet 的全类名 -->
            <servlet-class>com.atguigu.javaweb.HelloServlet</servlet-class>
        </servlet>
        
        <servlet-mapping>
            <!-- 需要和某一个 servlet 节点的 serlvet-name 子节点的文本节点一致 -->
            <servlet-name>helloServlet</servlet-name>
            <!-- 映射具体的访问路径: / 代表当前 WEB 应用的根目录. -->
            <url-pattern>/hello</url-pattern>
        </servlet-mapping>
    
    2. Servlet 容器: 运行 Servlet、JSP、Filter 等的软件环境. 
    1). 可以来创建 Servlet, 并调用 Servlet 的相关生命周期方法. 
    2). JSP, Filter, Listener, Tag ...
    
    3. Servlet 生命周期的方法: 以下方法都是由 Serlvet 容器负责调用. 
    1). 构造器: 只被调用一次. 只有第一次请求 Servlet 时, 创建 Servlet 的实例. 调用构造器. 
    这说明 Serlvet 的单实例的!
    2). init 方法: 只被调用一次. 在创建好实例后立即被调用. 用于初始化当前 Servlet. 
    3). service: 被多次调用. 每次请求都会调用 service 方法. 实际用于响应请求的. 
    4). destroy: 只被调用一次. 在当前 Servlet 所在的 WEB 应用被卸载前调用. 用于释放当前 Servlet 所占用的资源. 
    
    4. load-on-startup 参数:
    1).  配置在 servlet 节点中:
    
        <servlet>
            <!-- Servlet 注册的名字 -->
            <servlet-name>secondServlet</servlet-name>
            <!-- Servlet 的全类名 -->
            <servlet-class>com.atguigu.javaweb.SecondServlet</servlet-class>
            <!-- 可以指定 Servlet 被创建的时机 -->
            <load-on-startup>2</load-on-startup>
        </servlet>
        
    2). load-on-startup: 可以指定 Serlvet 被创建的时机. 若为负数, 则在第一次请求时被创建.若为 0 或正数, 则在当前 WEB 应用被
    Serlvet 容器加载时创建实例, 且数组越小越早被创建. 
    
    5. 关于 serlvet-mapping:
    
    1). 同一个Servlet可以被映射到多个URL上,即多个 <servlet-mapping> 元素的<servlet-name>子元素的设置值可以是同一个
    Servlet的注册名。 
    
    2). 在Servlet映射到的URL中也可以使用 * 通配符,但是只能有两种固定的格式:
    一种格式是“*.扩展名”,另一种格式是以正斜杠(/)开头并以“/*”结尾。
    
    <servlet-mapping>
        <servlet-name>secondServlet</servlet-name>
        <url-pattern>/*</url-pattern>
    </servlet-mapping>
    
    OR
    
    <servlet-mapping>
        <servlet-name>secondServlet</servlet-name>
        <url-pattern>*.do</url-pattern>
    </servlet-mapping>
    
    注意: 以下的既带 / 又带扩展名的不合法. 
    
    <servlet-mapping>
        <servlet-name>secondServlet</servlet-name>
        <url-pattern>/*.action</url-pattern>
    </servlet-mapping>
    
    6. ServletConfig: 封装了 Serlvet 的配置信息, 并且可以获取 ServletContext 对象
    
    1). 配置 Serlvet 的初始化参数
    
        <servlet>
            <servlet-name>helloServlet</servlet-name>
            <servlet-class>com.atguigu.javaweb.HelloServlet</servlet-class>
            
            <!-- 配置 Serlvet 的初始化参数。 且节点必须在 load-on-startup 节点的前面 -->
            <init-param>
                <!-- 参数名 -->
                <param-name>user</param-name>
                <!-- 参数值 -->
                <param-value>root</param-value>
            </init-param>
            
            <init-param>
                <param-name>password</param-name>
                <param-value>1230</param-value>
            </init-param>
            
            <load-on-startup>-1</load-on-startup>
            
        </servlet>
    
    2). 获取初始化参数: 
    
        > getInitParameter(String name): 获取指定参数名的初始化参数
        > getInitParameterNames(): 获取参数名组成的 Enumeration 对象. 
        
        String user = servletConfig.getInitParameter("user");
        System.out.println("user: " + user);
        
        Enumeration<String> names = servletConfig.getInitParameterNames();
        while(names.hasMoreElements()){
            String name = names.nextElement();
            String value = servletConfig.getInitParameter(name);
            System.out.println("^^" + name + ": " + value);
        }
    
    3). 获取 Serlvet 的配置名称(了解)
    
    7. ServletContext
    
    1). 可以由  SerlvetConfig 获取:
    
    ServletContext servletContext = servletConfig.getServletContext();
    
    
    2). 该对象代表当前 WEB 应用: 可以认为 SerlvetContext 是当前 WEB 应用的一个大管家. 可以从中获取到当前 WEB 应用的各个方面的信息.
    
    ①. 获取当前 WEB 应用的初始化参数
    
    设置初始化参数: 可以为所有的 Servlet 所获取, 而 Servlet 的初始化参数只用那个 Serlvet 可以获取. 
    
    <!-- 配置当前 WEB 应用的初始化参数 -->
    <context-param>
        <param-name>driver</param-name>
        <param-value>com.mysql.jdbc.Driver</param-value>
    </context-param>
    
    方法:
    
    getInitParameter
    getInitParameterNames    
    
    代码:
    
    ServletContext servletContext = servletConfig.getServletContext();
            
    String driver = servletContext.getInitParameter("driver");
    System.out.println("driver:" + driver);
    
    Enumeration<String> names2 = servletContext.getInitParameterNames();
    while(names2.hasMoreElements()){
        String name = names2.nextElement();
        System.out.println("-->" + name); 
    }
    
    ②. 获取当前 WEB 应用的某一个文件在服务器上的绝对路径, 而不是部署前的路径
    
    getRealPath(String path);
    
    代码:
    
    String realPath = servletContext.getRealPath("/note.txt");
    System.out.println(realPath);
    
    ③. 获取当前 WEB 应用的名称: 
    
    getContextPath()
    
    代码:
    
    String contextPath = servletContext.getContextPath();
    System.out.println(contextPath); 
    
    ④. 获取当前 WEB 应用的某一个文件对应的输入流. 
    
    getResourceAsStream(String path): path 的 / 为当前 WEB 应用的根目录. 
    
    代码:
    
    InputStream is2 = servletContext.getResourceAsStream("/WEB-INF/classes/jdbc.properties");
        
    ⑤. 和 attribute 相关的几个方法:     
    
    8. GET 请求和 POST 请求:
    
    1). 使用GET方式传递参数:
    
    ①. 在浏览器地址栏中输入某个URL地址或单击网页上的一个超链接时,浏览器发出的HTTP请求消息的请求方式为GET。 
    ②. 如果网页中的<form>表单元素的 method 属性被设置为了“GET”,浏览器提交这个FORM表单时生成的HTTP请求消息的请求方式也为GET。 
    ③. 使用GET请求方式给WEB服务器传递参数的格式:  
    
    http://www.atguigu.com/counter.jsp?name=lc&password=123
    
    ④. 使用GET方式传送的数据量一般限制在 1KB 以下。 
    
    2). 使用 POST 方式传递参数:
    
    ①. POST 请求方式主要用于向 WEB 服务器端程序提交 FORM 表单中的数据: form 表单的 method 置为 POST
    ②. POST 方式将各个表单字段元素及其数据作为 HTTP 消息的实体内容发送给 WEB 服务器,传送的数据量要比使用GET方式传送的数据量大得多。  
    
    POST /counter.jsp HTTP/1.1
    referer: http://localhost:8080/Register.html
    content-type: application/x-www-form-urlencoded
    host: localhost:8080
    content-length: 43
    
    name=zhangsan&password=123              --请求体中传递参数. 
    
    9. 如何在 Serlvet 中获取请求信息:
    
    1). Servlet 的 service() 方法用于应答请求: 因为每次请求都会调用 service() 方法
    
    public void service(ServletRequest request, ServletResponse response)
                throws ServletException, IOException
                
    ServletRequest: 封装了请求信息. 可以从中获取到任何的请求信息.
    ServletResponse: 封装了响应信息, 如果想给用户什么响应, 具体可以使用该接口的方法实现. 
    
    这两个接口的实现类都是服务器给予实现的, 并在服务器调用 service 方法时传入. 
    
    2). ServletRequest: 封装了请求信息. 可以从中获取到任何的请求信息.
    
    ①. 获取请求参数: 
    
        > String getParameter(String name): 根据请求参数的名字, 返回参数值. 
        若请求参数有多个值(例如 checkbox), 该方法只能获取到第一个提交的值. 
    
        > String[] getParameterValues(String name): 根据请求参数的名字, 返回请求参数对应的字符串数组. 
        
        > Enumeration getParameterNames(): 返回参数名对应的 Enumeration 对象, 
        类似于 ServletConfig(或 ServletContext) 的 getInitParameterNames() 方法. 
    
        > Map getParameterMap(): 返回请求参数的键值对: key: 参数名,  value: 参数值, String 数组类型. 
    
    ②. 获取请求的 URI:
    
        HttpServletRequest httpServletRequest = (HttpServletRequest) request;
            
        String requestURI = httpServletRequest.getRequestURI();
        System.out.println(requestURI); //  /day_29/loginServlet
    
    ③. 获取请求方式: 
    
        String method = httpServletRequest.getMethod();
        System.out.println(method); //GET
        
    ④. 若是一个 GET 请求, 获取请求参数对应的那个字符串, 即 ? 后的那个字符串. 
    
        String queryString = httpServletRequest.getQueryString();
        System.out.println(queryString); //user=atguigu&password=123456&interesting=game&interesting=party&interesting=shopping
    
    ⑤. 获取请求的 Serlvet 的映射路径 
      
       String servletPath = httpServletRequest.getServletPath();
       System.out.println(servletPath);  //  /loginServlet
       
    ⑥. 和 attribute 相关的几个方法:        
    
    3). HttpServletRequest: 是 SerlvetRequest 的子接口. 针对于 HTTP 请求所定义. 里边包含了大量获取 HTTP 请求相关的方法. 
     
    4). ServletResponse: 封装了响应信息, 如果想给用户什么响应, 具体可以使用该接口的方法实现. 
    
    ①. *getWriter(): 返回 PrintWriter 对象. 调用该对象的 print() 方法, 将把 print() 中的参数直接打印
    到客户的浏览器上. 
    
    ②. 设置响应的内容类型: response.setContentType("application/msword");
    
    ③. void sendRedirect(String location): 请求的重定向. (此方法为 HttpServletResponse 中定义.)

    参考博客:https://blog.csdn.net/qq_19782019/article/details/80292110

  • 相关阅读:
    扩展IList对象,实现深拷贝扩展方法
    Repeater 汇总某一列(序号,分页) 最简单方法
    Query siblings()
    C#中求两个日期相差的年月日时分秒
    SQL语句中的 "... like '%@strKeyword% ' "这样写查不出结果
    sql server 编辑前200行..编辑前N行配置..
    .Net读取Excle数据写入到数据库
    jquery设置元素的readonly和disabled
    页面有ScriptManager , UPdatepanel 有些错误不报错...的解决方法
    一次性删除数据库所有表和所有存储过程 SQL语句
  • 原文地址:https://www.cnblogs.com/lzghyh/p/13970209.html
Copyright © 2020-2023  润新知