21.9.13所学总结

本文详细介绍了ServletContext对象在Web应用中的作用,包括如何利用它进行数据共享、获取初始化参数、实现请求转发以及读取资源文件。此外,还展示了如何处理文件下载、生成验证码以及执行HTTP重定向操作。通过实例代码,解释了Servlet在实际开发中的应用场景和关键功能。
摘要由CSDN通过智能技术生成

ServletContext对象

web容器在启动的时候,他会为每一个web容器创建一个对应的ServletContext对象,它代表了当前的web应用

他的应用
1.共享数据:我们在这个Servlet中保存的数据可以在另外一个Servlet中使用

在这里插入图片描述
需要一个放置数据的类

public class Hello extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        /*
        this.getInitParameter();初始化参数
        this.getServletConfig();Servlet配置
        获取Servlet上下文
        this.getInitParameterNames();
        */
        ServletContext context = this.getServletContext();
        String username="九怪";//数据
        context.setAttribute("username",username);//将一个数据保存在了servletcontext中
        resp.setContentType("text/html");
        resp.setCharacterEncoding("UTF-8");
    }
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        super.doPost(req, resp);
    }
}

建立一个获取数据的类

public class getServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ServletContext context = this.getServletContext();
        String username = (String) context.getAttribute("username");
        resp.setContentType("text/html");
        resp.setCharacterEncoding("UTF-8");
        resp.getWriter().print(username);
    }

发现可以获取到,但是想要获取那个数据,先得把存放数据的类加载出来,我们才能获取他的数据

2.获取初始化参数
<!--配置一些初始化参数-->
    <context-param>
        <param-name>url</param-name>
        <param-value>jdbc:mysql://localhost:3060/mybatis</param-value>
    </context-param>
  @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ServletContext context = this.getServletContext();
        String url = context.getInitParameter("url");
        resp.getWriter().print(url);
   }
  @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ServletContext context = this.getServletContext();
        String url = context.getInitParameter("url");
        resp.getWriter().print(url);
   }
3.请求转发
 @Override
public class ServletDemo01 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ServletContext context = this.getServletContext();
        System.out.println("进入了demo01");
        RequestDispatcher requestDispatcher = context.getRequestDispatcher("/s3");//转发的请求路径
        requestDispatcher.forward(req,resp);//调用forward实现请求转发
    }
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        super.doPost(req, resp);
    }
}

在这里插入图片描述

4.获取资源文件

Properties
在Java目录下新建properties,如果没有在java下生成配置文件,就是因为资源导出现了问题

 <!--    在build中配置resources , 来防止我们资源导出失败的问题-->
    <build>
        <resources>
            <resource>
                <directory>src/main/resources</directory>
                <includes>
                    <include>**/*.properties</include>
                    <include>**/*.xml</include>
                </includes>
            </resource>
            <resource>
                <directory>src/main/java</directory>
                <includes>
                    <include>**/*.properties</include>
                    <include>**/*.xml</include>
                </includes>
            </resource>
        </resources>
    </build>

在resources目录下新建properties
发现:都被打包到同一路径:classes,我们俗称这个路径为classpath:
思路:需要一个文件流
在这里插入图片描述
先通过输入流读取到这个配置文件,使用load方法加载配置文件内容然后就是通过properties类中的getProperty方法获取配置文件的内容,通过输出流输出到外头,最后访问测试即可

HttpServletResponse

web服务器接收到客户端的http请求,针对这个请求,分别创建一个代表请求的HttpServletResquest对象,代表响应的一个HttpServletResponse ,
如果要获取客户端请求过来的参数:HttpServletResquest
如果给客户端响应信息:找HttpServletResponse
简单分类
向浏览器发送数据的方法
在这里插入图片描述
负责向浏览器发送响应头的方法
在这里插入图片描述

常见应用

1.向浏览器输出消息
2.下载文件
要获取下载文件的路径,下载的文件名,
想办法让浏览器支持下载我们需要的东西,
获取下载文件的输入流,
创建缓冲区,
获取outputstream对象,
使用fileoutputstream文件写入buff缓冲区,
使用OutputStream将缓冲区中的数据输出到客户端!

public class FileServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 1.要获取下载文件的路径
        ServletContext context = this.getServletContext();
        String path = "D:\\DAIMA\\Meavn\\javaweb\\servlet03\\src\\main\\resources\\图片.png";
        System.out.println("获取到下载文件的路径"+path);
        // 2.下载的文件名是啥?
        String fileName = path.substring(path.lastIndexOf("\\") + 1);
        // 3.设置想办法让浏览器能够支持下载我们需要的东西L
        //中文文件名URLEncbder. encode(文件名,编码格式)编码。否则会出现乱码
        resp.setHeader("Content-Disposition","attachment;fileName="+ URLEncoder.encode(fileName,"UTF-8"));
        // 4.获取下载文件的输入流
        FileInputStream fis = new FileInputStream(path);
        // 5.创建缓冲区
        int len=0;
        byte[] buffer = new byte[1024];
        // 6.获取outputStream对象
        ServletOutputStream sos = resp.getOutputStream();
        // 7.将FileOutputStream流 写入到buffer缓冲区,使用outputStream将缓冲区中的数据输出到客户端!
        while ((len=fis.read(buffer))!=-1){
            sos.write(buffer,0,len);
        }
        sos.close();
        fis.close();
    }

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

在这个练习代码中值得注意的点
中文文件名需要使用URLEncbder. encode(文件名,编码格式)编码。否则会出现乱码
Content-Disposition是为了让浏览器能够支持下载我们需要的东西
3.验证码功能
需要java内置实现类(用到了Random类,BufferedImage,Graphics2D)
这些中最主要的是练习响应头,这个是响应图片类型,内存不缓存

public class imgServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws  IOException {
        //如何让浏览器3s自动刷新一次
        resp.setHeader("refresh","3");
        //在内存中创建一个图片
        BufferedImage image = new BufferedImage(80,20,TYPE_INT_RGB);
        //得到图片
        Graphics2D g = (Graphics2D) image.getGraphics();//new一个笔
        //设置图片的背景颜色
        g.setColor(Color.WHITE);
        g.fillRect(0,0,80,20);
        //给图片写数据
        g.setColor(Color.BLUE);
        g.setFont(new Font(null,Font.BOLD,20));
        g.drawString(makeNum(),0,20);
        //告诉浏览器这个请求用图片的方式打开
        resp.setContentType("image/png");
        //网站存在缓存,我们不让浏览器缓存
        resp.setDateHeader("expires",-1);
        resp.setHeader("Cache-Control","no-cache");
        resp.setHeader("Pragma","no-cache");
        //把图片写给浏览器
         ImageIO.write(image,"png",resp.getOutputStream());

    }
    //生成随机数
    private String makeNum(){
        Random random = new Random();
        String s = random.nextInt(9999999)+"";
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i <7-s.length(); i++) {
            sb.append("0");
        }
        String s1 = sb.toString()+s;
        return s1;
    }
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        super.doPost(req, resp);
    }

4.重定向
在这里插入图片描述
在这里插入图片描述

一个web对象收到客户端请求,他会通知客户端去访问另一个web资源,这个过程叫做重定向
常见场景 :用户登录

面试题:请你聊聊重定向和转发的区别?
相同点
●页面都会实现跳转

不同点
●请求转发的时候,url不会产生变化
●重定向时候,ur|地址栏会发生变化;
从地址栏显示来说
forward是服务器请求资源,服务器直接访问目标地址的URL,把那个URL的响应内容读取过来,然后把这些内容再发给浏览器.浏览器根本不知道服务器发送的内容从哪里来的,所以它的地址栏还是原来的地址.

redirect是服务端根据逻辑,发送一个状态码,告诉浏览器重新去请求那个地址.所以地址栏显示的是新的URL.

从数据共享来说
forward:转发页面和转发到的页面可以共享request里面的数据.
redirect:不能共享数据.

从运用地方来说
forward:一般用于用户登陆的时候,根据角色转发到相应的模块.
redirect:一般用于用户注销登陆时返回主页面和跳转到其它的网站等

从效率来说
forward:高.
redirect:低.

浅显地说就是
请求转发就是a去访问b,但是b没有这个资源,b就去c找,拿到了c的去把他交给a
重定向就是a去b访问资源,b告诉a c有资源让a去访问c。

转发和重定向的选择?
重定向的速度比转发慢,因为浏览器还得发出一个新的请求,如果在使用转发和重定向都无所谓的时候建议使用转发。
因为转发只能访问当前WEB的应用程序,所以不同WEB应用程序之间的访问,特别是要访问到另外一个WEB站点上的资源的情况,这个时候就只能使用重定向了。
六、转发和重定向的应用场景

<html>
<body>
<h2>Hello World!</h2>
<%--这里提交的路径需要寻找到项目的路径--%>
<%--${pageContext.request.ContextPath}代表当前项目--%>
<form action="${pageContext.request.contextPath}/login" method="get">
    用户名:<input type="text" name="username"><br>
    密码:<input type="password" name="password"><br>
    <input type="submit">
</form>
</body>
</html>

public class RequestTest extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setCharacterEncoding("UTF-8");
        resp.setContentType("text/html");
        System.out.println("进入这个请求了");
        //处理请求
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        System.out.println(username+":"+password);
        //重定向是一定要注意路径问题,否则404
        resp.sendRedirect("/s/success.jsp");
    }

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

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<h1>Success</h1>
</body>
</html>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值