HttpGET请求 与 HttpPOST请求的区别:

GET请求:
    -    请求的参数 ,以键值对的形式    存储在网址中 ,在网址中, 编写在?后, 由1个或多个键值对组成, 键与值之间使用等号连接, 多个键值对之间使用&分割.
    -    只能传输字符串类型的参数.
    -    网址的最大长度为4kb 通常支持的文字 2048 个文字
    -    数据传输不安全

    tomcat8+版本    :    GET请求不会乱码

POST请求:
    -    请求的数据, 以键值对的形式存储在请求体中, 
    -    请求体是一个单独的数据包 , 较GET请求而言, 安全.
    -    可以传输任意类型的数据
    -    数据的大小 ,理论上是无上限的.

    tomcat8+版本    :    Post请求默认编码为 ISO-8859-1 (不支持中文)

什么样的请求是GET

以我们目前所学习的技术来说 , 除了表单提交时method="POST" ,其他的访问方式都是GET请求

例如:
    -    点击超链接 访问
    -    通过js:    window.location.href='' 访问
    -    浏览器中输入网址 + 回车
    -    表单提交时 ,method="GET" 或 默认
    -    ajax的get请求
    -    Java代码的URL类的GET请求.

什么样的请求时PSOT

1.    表单提交时method="POST"

2.    ajax的post请求

3.    Java代码的URL类的POST请求.
请求的乱码问题
解决乱码的两种格式:
    格式1.
        可用于tomcat8版本之前的GET请求乱码 以及 所有版本的POST请求乱码:
        解决方案:    将乱码的文字, 按照乱码的编码ISO-8859-1转换为字节数组, 再按照正常的编码UTF-8组装为 文字;


        案例:
        //1.    接收用户传递的参数
        String username = request.getParameter("username");
        //解决乱码
        {
            //1.    将乱码的文字, 通过ISO-8859-1编码 打碎成字节数组
            byte[] bytes = username.getBytes("ISO-8859-1");
            //2.    通过UTF-8编码, 将字节数组 重新组装为 正常文字
            username = new String(bytes, "UTF-8");

        }

    格式2.
        格式1 解决乱码适用于参数较少的情况, 如果参数过多, 解决起来极其麻烦.
        tomcat为我们提供了 设置请求体编码的方式:



        格式:    request.setCharacterEncoding("UTF-8");

        注意:    只有POST请求 ,才有请求体!
                解决请求乱码的代码, 必须运行在获取参数之前    
响应的乱码问题
方式1.
    设置网页的内容类型, 以及 网页的编码格式:
    response.setContentType("text/html;charset=utf-8");

方式2.
    设置网页的编码格式 (因为没有设置网页内容类型为html , 所以浏览器解析时也是乱码)
    response.setCharacterEncoding("UTF-8");

    注意:
        设置响应乱码的两种方式, 都必须写在 响应内容之前 !

线程安全问题 :

Servlet的service方法, 每次被请求时, 调用.

这个调用很特殊 , 是在新的子线程中调用的 , 当service方法执行完毕, 子线程死亡了.

可以简单的理解为: service方法每次执行都是一个新的线程.


    @WebServlet("/s1.do")
    public class Servlet1 extends HttpServlet {
        //剩余票数
        private int count = 10;
        Object o = new Object();

        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            synchronized (o) {
                if(count>0) {
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println("恭喜你, 有票, 正在出票...");
                    count--;
                    System.out.println("出票完成, 剩余票数:"+count);
                }else {
                    System.out.println("很遗憾, 无票");
                }
            }
        }


    }

请求的 转发

概念:    一个web组件 将未处理完毕的请求, 通过tomcat转交给另一个web组件处理.

步骤:
    1.    获取请求转发器
            RequestDispatcher rd  = request.getRequestDispatcher("转发的地址");
    2.    通过转发器 发起转发
            rd.forward(request,response);
简写步骤:
    request.getRequestDispatcher("转发的地址").forward(request,response);

转发流程:
    步骤1.    当浏览器访问服务器中tomcat时
    步骤2.    tomcat将请求信息, 与响应工具进行封装, 传递给我们的Servlet的service方法进行处理
    步骤3.    我们在service方法中, 得到请求转发器, 通过请求转发器 告知 tomcat , 请求转发的地址.
    步骤4.    tomcat接收到请求转发需求, 会重新封装请求信息, 将请求对象 与 响应对象 传递给 转发地址的Servlet的service方法进行处理

特点:
    1.    转发过程中, 多个Servlet之间共享一份请求信息, 共享一个响应对象.
    2.    转发只能发生在同一个服务器中. (转发无法实现跨域)
    3.    无论转发发生多少次 ,对于浏览器来说! 只发起过一次请求 , 并且只接到了一次响应.
    4.    相对于重定向来说, 效率更高.

请求的 重定向

概念:    响应时 , 告知浏览器新的请求地址, 浏览器接收到 自动请求新的地址 !

步骤:
    response.sendRedirect("重定向地址");

重定向流程:
    步骤1.    当浏览器访问服务时, 服务器对浏览器响应一个302的状态码, 以及一个location的地址
    步骤2.    HTTP协议约定 , 当浏览器接收到302状态码时 ,会自动寻找location地址, 并发起新的请求.
    (相当于 控制用户浏览器 自动完成页面的跳转操作.)

特点
    1.    重定向会产生新的请求 和 新的响应. 
    2.    使用重定向, 可以在多个服务器之间发生( 可以实现跨域操作 )
    3.    浏览器地址栏的内容 会发生改变.
    4.    相对于请求转发而言, 效率较低.

注意:

1.    在一次用户的操作中, 可以无限制的进行转发和重定向, 但是记住: 一定要存在出口.    
2.    当servlet中的请求已经被转发 / 重定向后,  在此servlet后续的代码中不能再进行响应 !

HttpServletRequest 类常用操作:

1.    获取访问的客户端ip地址
    String ip = request.getRemoteAddr();

2.    获取客户端访问的地址 (有可能因为服务器映射了多个域名, 多个用户的访问地址 不同)
    request.getRequestURI();

3.    获取服务器的名称 (通常获取的是ip)
    request.getServerName();

4.    获取端口号
    request.getServerPort();

5.    获取请求的方式
    String method = request.getMethod();

6.    获取get请求的参数列表 (网址中?后面的部分)
    String params = request.getQueryString();


三个将请求对象 作为数据容器使用的方法:

    1.    存储数据
            request.setAttribute(String key,Object value);
    2.    获取数据
            Object value = request.getAttribute(String key);    
    3.    删除数据
            request.removeAttribute(String key);

ServletContext 上下文

每一个Servlet都是一个独立的用于处理请求的 对象.
为了便于多个Servlet之间的数据交流 . javaWeb提供了一个上下文对象ServletContext !
我们在任何的Servlet代码中, 都可以获得这个ServletContext对象 , 且每一个Servlet获取的都是同一份ServletContext对象.
上下文对象, 类似于我们SE所学习的MAP集合, 是一个键值对的容器.  

作用: ServletContext是Servlet之间通信的桥梁, 用于多个Servlet之间信息的共享.

如何从Servlet中得到上下文对象

格式:
    ServletContext context = getServletContext();

ServletContext的常用方法

1.    存储数据
    context.setAttribute(String key,Object value);
2.    获取数据
    Object value = context.getAttribute(String key);
3.    删除数据
    context.removeAttribute(String key);

4.    获取项目运行时的 文件夹 绝对路径 
    String path = context.getRealPath("/");

//因为一个项目 只有一个ServletContext对象, 且在项目启动时创建了,项目销毁时销毁. 
//所以我们在一次项目启动的过程中, 一个Servlet存储的数据, 任何Servlet都可以获取到.


11月      Java

本博客所有文章除特别声明外,均采用 CC BY-SA 3.0协议 。转载请注明出处!