Http之请求对象(小进阶)

目录

请求转发

Request作为域对象

注意事项

request作为域对象,共享范围是当前请求有效。

响应对象:

响应对象之输出内容:

响应对象之定时跳转:

重定向!

资源跳转路径问题(重中之重!!):

Servlet的线程安全问题:


请求转发

概述

  • 跳转资源,站内资源跳转。

@WebServlet("/demo01")
public class Demo01Servlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("Demo01Servlet");
        //①获取请求调度对象
        //RequestDispatcher requestDispatcher = req.getRequestDispatcher("demo02");
        //②执行转发
        //requestDispatcher.forward(req, resp);
		req.getRequestDispatcher("demo02").forward(req, resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}


@WebServlet("/demo02")
public class Demo02Servlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("Demo02Servlet");
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

执行流程:

从图中可知这是站内转发,只发送了一次请求。

Request作为域对象

域对象

  • 存储数据并共享

@WebServlet("/demo03")
public class Demo03Servlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("Demo03Servlet");
        request.setAttribute("msg", "hello");
        //请求转发到Demo04Servlet
        request.getRequestDispatcher("demo04").forward(request, response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request, response);
    }
}

@WebServlet("/demo04")
public class Demo04Servlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("Demo04Servlet");
        //request.removeAttribute("msg");
        Object msg = request.getAttribute("msg");
        System.out.println("msg = " + msg);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request, response);
    }
}

注意事项

  • request作为域对象,共享范围是当前请求有效。

响应对象:

  • ServletResponse对象用于发送响应给客户端,通过Servlet的services方法传递给Servlet;

  • 通过ServletOutputStream对象发送字节数据,通过PrintWriter对象发送字符数据。

响应对象之输出内容:

概述

  • 响应对象操作响应体(响应正文)

@WebServlet("/demo06")
public class Demo06Servlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //告诉服务器,以utf-8编码响应正文
        //response.setCharacterEncoding("utf-8");
        //告诉浏览器,以utf-8解码响应正文
        //response.setHeader("Content-Type","text/html;charset=utf-8");
        //告诉服务器,以utf-8编码响应正文 ;告诉浏览器,以utf-8解码响应正文。
        response.setContentType("text/html;charset=utf-8");
        String content = "你好世界";
        PrintWriter writer = response.getWriter();
        writer.write(content);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request, response);
    }
}

响应对象之定时跳转:

通过ReFresh完成

/**
 * 05-响应对象之定时跳转
 * 需求:3秒后跳转到Demo08Servlet
 */
@WebServlet("/demo07")
public class Demo07Servlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("Demo07Servlet");
        response.setHeader("Refresh", "3;url=demo08");

    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request, response);
    }
}

实现2:在html中实现

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="Refresh" content="3;url=index.html">
    <title>05-响应对象之定时跳转</title>
</head>
<body>

<span id="spn">3</span>秒后跳转,如果没有跳转,<a href="index.html">请点击</a>

</body>
<script>

    window.setInterval("showCount()",1000);

    function showCount() {
        var count = document.getElementById("spn").innerText;
        if (count <= 1) {
            return;
        }
        count--;
        document.getElementById("spn").innerText = count;
    }

</script>
</html>

重定向!

  • 概述

    • 跳转资源,站外资源跳转。

  • 开发步骤

    • ①操作响应状态码301/302

      • 301 : 永久重定向 , 销毁历史记录

      • 302 : 临时重定向,保存历史记录

    • ②操作响应头location

@WebServlet("/demo09")
public class Demo09Servlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("Demo09Servlet");
        //①操作响应状态码
        //resp.setStatus(302);
        //②操作响应头location
        //resp.setHeader("location","demo10");

        resp.sendRedirect("demo10");

    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

由图可知,重定向是需要响应一次,响应携带状态码以及跳转资源路径地址,然后浏览器再请求一次的。

资源跳转路径问题(重中之重!!):

概述

  • 请求转发:站内资源跳转;

    • 相对路径:和原来一样,没有问题

    • 绝对路径 :和原来不一样,"/资源访问路径"

  • 重定向:站外资源跳转。

    • 相对路径:和原来一样,没有问题

    • 绝对路径:和原来一样,"/项目访问路径/资源访问路径"

@WebServlet("/demo11")
public class Demo11Servlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("Demo11Servlet");
        //相对路径 : ok
        //req.getRequestDispatcher("demo12").forward(req,resp);
        //绝对路径
        req.getRequestDispatcher("/day05/demo12").forward(req, resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

@WebServlet("/demo13")
public class Demo13Servlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("Demo13Servlet");
        //相对路径
        //resp.sendRedirect("demo14");
        //绝对路径
        resp.sendRedirect("/day05/demo14");
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

Servlet的线程安全问题:

概述

  • Servlet是多线程单实例的。操作同一个变量容易出现问题。

  • 解决方案1:尽量避免在Servlet中使用成员变量,而使用局部变量

@WebServlet("/demo16")
public class Demo16Servlet extends HttpServlet {

    //private String num;//成员变量,也叫对象变量

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        String num = request.getParameter("num");

        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        //线程1 : num=250
        //线程2 : num=500
        response.getWriter().write("num = " + num);

    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request, response);
    }
}

方案2就是上锁,上锁效率低,一般不建议使用。sleep那更不谈了,直接影响用户使用,我都懒得写出来。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值