Response对象、Cookie对象、Session对象、Context对象、文件上传下载

一、HttpServletResponse对象

1.1 简介

Web服务器收到客户端的http请求,会针对每⼀次请求,分别创建⼀个⽤于代表请求的
request 对象和代表响应的 response 对象。

request 和 response 对象代表请求和响应:获取客户端数据,需要通过 request 对象;向
客户端输出数据,需要通过 response 对象。

1.2 响应数据

/**
 * 响应数据
 *      getWriter()   获取字符流(只能响应回字符)
 * ​		getOutputStream() 获取字节流(能响应一切数据)
 *
 *      两种流不能同时使用!
 */
@WebServlet("/resp01")
public class Response01 extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
       /* // getWriter()  获取字符流(只能响应回字符)
        //得到字符输出流
        PrintWriter writer = resp.getWriter();
        writer.write("你好");// 乱码 ??
        writer.write("<h2>Hello<h2/>"); //原样输出  <h2>Hello<h2/>

        //刷新
        writer.flush();
        //关闭
        writer.close();*/

        //getOutputStream() 获取字节流(能响应一切数据)
        ServletOutputStream out = resp.getOutputStream();
        out.write("你好".getBytes()); // 不乱吗  输出  你好
        out.write("<h2>Hello<h2/>".getBytes());// <h2>Hello<h2/> 没有达到想要的效果 原本是想表示h2标签
        out.flush();
        out.close();
    }
}

1.3 响应乱码问题

/**
 * 响应乱码问题
 *      这是因为服务器响应的数据也会经过网络传输,服务器端有一种编码方式,在客户端也存在一种编码方式,当两端使用的编码方式不同时则出现乱码。
 *
 *      getWriter()
 *          一定会乱码,因为服务器默认的解析编码是ISO-8859-1,该编码不支持中文
 *
 *      getOutputStream()
 *          可能乱码,当服务端的编码格式与客户端的编码不一致时,会出现乱码
 *
 *      解决方案:
 *              1. 设置服务端的编码格式  response.setCharacterEncoding("UTF-8");
 *              2. 设置客户端的编码格式  response.setHeader("content-type","text/html;charset=UTF-8");
 *
 *              3. 同时设置客户端和服务端的编码  resp.setContentType("text/html;charset=UTF-8");(重要)
 *
 *       总结:
 *          设置客户端和服务端的编码格式保持一致,且支持中文。
 *          响应json格式的数据时,设置响应类型为application/json
 *
 */
@WebServlet("/resp02")
public class Response02 extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //同时设置客户端和服务端的编码 设置响应的数据类型是html格式
        //resp.setContentType("text/html;charset=UTF-8");
        /**
         * 字符流
         */
        /*//设置服务端的编码格式
        resp.setCharacterEncoding("UTF-8");
        //设置客户端的编码格式
        resp.setHeader("content-type","text/html;charset=UTF-8");

        // getWriter()   获取字符流(只能响应回字符)
        // 得到字符输出流
        PrintWriter writer = resp.getWriter();
        writer.write("你好");//你好
        writer.write("<h2>Hello</h2>");//Hello
        writer.flush();
        writer.close();*/

        /**
         * 字节流
         */
       /* ServletOutputStream out = resp.getOutputStream();
        out.write("你好".getBytes("UTF-8"));
        out.write("<h2>Hello</h2>".getBytes());
        out.flush();
        out.close();*/

        //设置响应的数据类型是json格式
        resp.setContentType("application/json;charset=UTF-8");

        ServletOutputStream out = resp.getOutputStream();
        out.write("{\"userId\":1,\"uname\":\"admin\", \"upwd\":\"123456\"}".getBytes());
        out.flush();
        out.close();
    }
}

1.4 重定向

重定向是⼀种服务器指导,客户端的⾏为。重定向当中有两个请求存在,并且属于客户端⾏为。

/**
 * 重定向
 */
@WebServlet("/resp03")
public class Response03 extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 重定向跳转到index.jsp
        //resp.sendRedirect("index.jsp");

        // 重定向跳转到百度
        resp.sendRedirect("https://www.baidu.com/");
    }
}

1.5 请求转发与重定向的区别

在这里插入图片描述

二、Cookie对象

Cookie是浏览器提供的⼀种技术,通过服务器的程序能将⼀些只须保存在客户端,或者在
客户端进⾏处理的数据,放在本地的计算机上。

但是由于 Cookie 是服务器端保存在客户端的信息, 所以其安全性也是很差的。

Cookie 的格式:键值对⽤“=”链接,多个键值对间通过“;”隔开。

2.1 Cookie的创建和发送

通过 new Cookie(“key”,“value”);来创建⼀个 Cookie 对象,要想将 Cookie 随响应发送到
客户端,需要先添加到 response 对象中,response.addCookie(cookie);

此时该 cookie 对象则随着响应发送⾄了客户端。在浏览器上可以看⻅。

/**
 * Cookie的创建与发送
 *      Cookie cookie = new Cookie("名称","值");
 *      response.addCookie(cookie对象);
 */
@WebServlet("/cook01")
public class Cookie01 extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //创建Cookie对象
        Cookie cookie = new Cookie("name","zhangsan");
        //响应Cookie(发送cookie对象给客户端)
        resp.addCookie(cookie);

        Cookie cookie2 = new Cookie("name2","lisi");
        resp.addCookie(cookie2);
    }
}

2.2 Cookie的获取

在服务器端只提供了⼀个 getCookies()的⽅法⽤来获取客户端回传的所有 cookie 组成的
⼀个数组,如果需要获取单个 cookie 则需要通过遍历,getName()获取 Cookie 的名称,
getValue()获取 Cookie的值。

/**
 * 获取COokie对象
 *      通过request.getCookies()获取cookie对象,返回的是cookie数组
 *
 */
@WebServlet("/cook02")
public class Cookie02 extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //获取cookie数组
        Cookie[] cookies = req.getCookies();
        //判断cookie是否存在
        if(cookies != null && cookies.length > 0){
            //遍历cookie数组
            for(Cookie cookie : cookies){
                if("name".equals(cookie.getName())){
                    System.out.println(cookie.getValue());
                }
            }
        }
    }
}

2.3 Cookie设置到期时间

/**
 * Cookie的到期时间
 *  到期时间,到期时间用来指定该 cookie 何时失效。默认为当前浏览器关闭即失效。
 *  我们可以手动设定 cookie 的有效时间(通过到期时间计算),通过 setMaxAge(int time);方法设定 cookie 的最大有效时间,以秒为单位。
 *
 *  maxAge的取值:
 *      负整数,表示只在浏览器中存活
 *      正整数,表示会存活指定秒数,关闭浏览器或关闭服务器都不影响
 *      零,表示删除cookie
 *
 */
@WebServlet("/cook03")
public class Cookie03 extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //创建cookie对象
        Cookie cookie = new Cookie("aa","AAA");

        //负整数,表示浏览器关闭即失效
        //cookie.setMaxAge(-1);
        //正整数,表示会存活指定描数
        //cookie.setMaxAge(15);
        //零,表示删除cookie
        cookie.setMaxAge(0);

        //发送cookie对象
        resp.addCookie(cookie);

        //删除已有的cookie
        Cookie cookie1 = new Cookie("bb","BBB");
        cookie1.setMaxAge(0);
        resp.addCookie(cookie1);
    }
}

2.4 Cookie的注意点

1.Cookie保存在当前浏览器中。
在⼀般的站点中常常有记住⽤户名这样⼀个操作,该操作只是将信息保存在本机上,换电脑以后这些信息就⽆效了。⽽且 cookie 还不能跨浏览器。

2.Cookie存中⽂问题

/**
 * Cookie存中文
 *      cookie不支持存中文
 *         如果需要存中文,需要URLencoder.encode(name)进行编码;获取时URLdncoder.dncode(name)进行解码
 */
@WebServlet("/cook04")
public class Cookie04 extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        String name = "姓名";
        String value = "张三";
        //将中文通过URLencoder.encode(name)进行编码
        name = URLEncoder.encode(name);
        value = URLEncoder.encode(value);

        //创建cookie对象
        Cookie cookie = new Cookie(name,value);

        //发送cookie对象
        resp.addCookie(cookie);

        // 获取时通过 URLDecoder.decode()来进行解码
        //URLDecoder.decode(cookie.getName());
        //URLDecoder.decode(cookie.getValue());
    }
}

3.同名Cookie问题

/**
 * Cookie同名问题
 *  如果出现同名,后面的cookie会将前面的覆盖。(在domain和path相同的情况下)
 */
@WebServlet("/cook05")
public class Cookie05 extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //创建cookie对象(前面设置过同名的)
        Cookie cookie = new Cookie("name2","wangwu");

        //设置失效时间
        cookie.setMaxAge(1000);
        resp.addCookie(cookie);
    }
}

4.浏览器存放Cookie的数量
不同的浏览器对Cookie也有限定,Cookie的存储有是上限的。Cookie是存储在客户端(浏览器)的,⽽且⼀般是由服务器端创建和设定。后期结合Session来实现回话跟踪。

2.5 Cookie的路径

Cookie的setPath设置cookie的路径,这个路径直接决定服务器的请求是否会从浏览器中
加载某些cookie。

/**
 * Cookie的路径
 *      1. 在当前服务器中,任意资源都可访问
 *      2. 当前项目下的资源可获取Cookie对象 (默认不设置Cookie的path)
 *      3. 当前项目中指定目录下的资源可获取Cookie对象
 *      4. 指定项目下的资源可获取Cookie对象
 *
 *      总结:只要请求的路径中包含Cookie的path值,才能获取到该cookie对象
 */
@WebServlet("/cook06")
public class Cookie06 extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 当前项目下的资源可获取cookie对象(默认不设置cookie的path)
        Cookie cookie01 = new Cookie("a1","A1");
        resp.addCookie(cookie01);

        // 在当前服务器中,任意资源都可访问
        Cookie cookie02 = new Cookie("a2","A2");
        cookie02.setPath("/");
        resp.addCookie(cookie02);

        // 指定目录下的资源可以获取Cookie对象
        Cookie cookie03 = new Cookie("a3","A3");
        cookie03.setPath("/s03/test/cook02");
        resp.addCookie(cookie03);

        // 指定项目下的资源可获取Cookie对象 (指定站点名)
        Cookie cookie04 = new Cookie("a4","A4");
        cookie04.setPath("/s04"); // 某一个项目的访问路径
        resp.addCookie(cookie04);
    }
}

三、HttpSession对象

session ⽆论客户端还是服务器端都可以感知到,若重新打开⼀个新的浏览器,则⽆法取
得之前设置的 session,因为每⼀个 session 只保存在当前的浏览器当中,并在相关的⻚⾯取得。

ssion 的作⽤就是为了标识⼀次会话,或者说确认⼀个⽤户;并且在⼀次会话(⼀个⽤户
的多次请求)期间共享数据。我们可以通过 request.getSession()⽅法,来获取当前会话的 session 对象。

@WebServlet("/se01")
public class Session01 extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //获取session对象(如果session对象不存在,则新建session对象 如果session存在,则获取session对象)
        HttpSession session = req.getSession();

        //获取session的标识符
        System.out.println(session.getId());

        // 获取第一次访问时间
        System.out.println(session.getCreationTime());
        // 获取最后一次访问时间
        System.out.println(session.getLastAccessedTime());
        // 是否是新的session对象
        System.out.println(session.isNew());
    }
}

3.1 标识符 JSESSIONID

Session 既然是为了标识⼀次会话,那么此次会话就应该有⼀个唯⼀的标志,这个标志就
是sessionId。

所以 Session 的底层依赖 Cookie 来实现。

3.2 session域对象

Session ⽤来表示⼀次会话,在⼀次会话中数据是可以共享的,这时 session 作为域对象存在,可以通过 setAttribute(name,value) ⽅法向域对象中添加数据。

通过 getAttribute(name) 从域对象中获取数据,通过 removeAttribute(name) 从域对象中移除数据。

@WebServlet("/se02")
public class Session02 extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 获取session对象 (如果session对象不存在,则新建session对象;如果session存在,则获取session对象
        HttpSession session = req.getSession();

        //设置session域对象(一次会话有效)
        session.setAttribute("uname","admin");

        //获取User对象
        User user = new User(1,"张三","123456");

        //将用户对象存到session作用域中
        session.setAttribute("user",user);

        //设置request作用域(一次请求有效)
        req.setAttribute("name","zhangsan");

        //请求转发(一次请求)
        //req.getRequestDispatcher("se03").forward(req,resp);

        //重定向(两次请求)
        resp.sendRedirect("se03");
    }
}
/**
 * Session作用域
 */
@WebServlet("/se03")
public class Session03 extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        HttpSession session = req.getSession();

        //获取session作用域
        String uname = (String)session.getAttribute("uname");
        System.out.println("Session作用域:" + uname);

        // 获取session作用域中的user对象
        User user = (User) session.getAttribute("user");
        System.out.println(user.toString());

        // 获取request作用域
        String name = (String) req.getAttribute("name");
        System.out.println("request作用域:" + name);
    }
}

3.3 session对象的销毁

/**
 * Session的销毁
 *      1. 默认到期时间
 *          Tomcat中默认到期时间是30分钟,单位分钟。可以在Tomcat的解压目录中的conf目录的web.xml中修改 session-config标签的值
 *      2. 手动设置失效时间
 *          单位是秒,通过 session.setMaxInactiveInterval(int) 来设定失效时间。通过getMaxInactiveInterval()获取当前失效时间。
 *      3. 手动销毁
 *          session.invalidate();
 *      4. 关闭浏览器
 *          session底层依赖cookie,cookie默认关闭浏览器失效。
 *      5. 关闭服务器
 */
@WebServlet("/se04")
public class Session04 extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //获取session对象
        HttpSession session = req.getSession();
        System.out.println(session.getId());

        //1.默认到期时间

        // 2. 手动设置失效时间
        // 获取当前最大不活动时间
        System.out.println("最大不活动时间:" + session.getMaxInactiveInterval());
        //设置最大不活动时间
        session.setMaxInactiveInterval(15);
        System.out.println("修改后最大不活动时间:" + session.getMaxInactiveInterval());

        // 3. 手动销毁
        //session.invalidate();

        // 4. 关闭浏览器

        // 5. 关闭浏览器
    }
}

四、ServletContext对象

每⼀个 web 应⽤都有且仅有⼀个ServletContext 对象,⼜称 Application 对象,从名称中
可知,该对象是与应⽤程序相关的。在 WEB 容器启动的时候,会为每⼀个 WEB 应⽤程
序创建⼀个对应的ServletContext 对象。

该对象有两⼤作⽤:
第⼀、作为域对象⽤来共享数据,此时数据在整个应⽤程序中共享。

第⼆、该对象中保存了当前应⽤程序相关信息。例如可以通过 getServerInfo() ⽅法获取当
前服务器信息 ,getRealPath(String path) 获取资源的真实路径等。

4.1 ServletContext对象的获取

@WebServlet("/con01")
public class Context01 extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //通过request获取对象
        ServletContext servletContext = req.getServletContext();

        //通过session获取
        ServletContext servletContext1 = req.getSession().getServletContext();

        //通过servletconfig对象获取
        ServletContext servletContext2 = getServletConfig().getServletContext();

		//常用方法
		//获取服务器的版本信息
        String serverInfo = servletContext.getServerInfo();
        System.out.println("获取服务器的版本信息:" + serverInfo);

        //获取项目的真实路径
        String realPath = servletContext.getRealPath("/");
        System.out.println("获取项目的真实路径:" + realPath);
}

4.2 ServletContext域对象

// 获取ServletContext对象
ServletContext servletContext = request.getServletContext();
// 设置域对象
servletContext.setAttribute("name","zhangsan");
// 获取域对象
String name = (String) servletContext.getAttribute("name");
// 移除域对象
servletContext.removeAttribute("name");

Servlet的三⼤域对象:

  1. request域对象
    在⼀次请求中有效。请求转发有效,重定向失效。
  2. session域对象
    在⼀次会话中有效。请求转发和重定向都有效,session销毁后失效。
  3. servletContext域对象
    在整个应⽤程序中有效。服务器关闭后失效。

五、文件上传和下载

5.1 文件上传

前台⻚⾯:

<!--
    通过表单实现文件上传的功能
        1. 请求方式设置为POST  method="post"
        2. 文件上传表单要设置表单类型为二进制表单
            普通表单   enctype="application/x-www-form-urlencoded"
            二进制表单 enctype="multipart/form-data"
        3. 设置文件上传的文件域,并设置name属性值
-->
<form action="uploadServlet" method="post" enctype="multipart/form-data">
    文件:<input type="file" name="myfile"><br>
    姓名:<input type="text" name="uname"><br>
    <button>上传文件</button>

后台实现:

/**
 * 文件上传
 *      如果是文件上传表单(二进制表单),对应的Servlet需要添加注解 @MutlipartConfig
 *      使用注解  @MultipartConfig 将一个 Servlet 标识为支持文件上传。
 *      Servlet 将 multipart/form-data 的 POST 请求封装成 Part,通过 Part 对上传的文件进行操作。
 */
@WebServlet("/uploadServlet")
@MultipartConfig // 文件一定要加注解!!!
public class UploadServlet extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //设置请求的编码格式
        req.setCharacterEncoding("UTF-8");

        // 获取普通的表单项数据(获取参数)
        String uname = req.getParameter("uname");

        // 获取上传的文件
        // 通过request.getPart(name)方法,获取Part对象; name代表的是表单中的file文件域的name属性值
        Part part = req.getPart("myfile");

        //获取上传文件的文件名
        String fileName = part.getSubmittedFileName();
        System.out.println("上传文件名:" + fileName);

        //设置文件的存放路径(获取项目的真实路径)
        String realPath = req.getServletContext().getRealPath("/upload/");

        //上传文件
        part.write(realPath + fileName);
    }
}

5.2 文件下载

⽂件下载,即将服务器上的资源下载(拷⻉)到本地,我们可以通过两种⽅式下载。第⼀种是通过超链接本身的特性来下载;第⼆种是通过代码下载。

5.2.1 超链接下载

<!--
    超链接下载
        当浏览器遇到能够识别的资源,会进行跳转;
        当浏览器遇到无法识别的资源,则会进行下载。

        download属性
            表示当前超链接的资源会被下载;
            如果download属性没有设置属性值,则默认的下载名为为文件名;也可通过设置download属性的值来指定下载的文件名
 -->
<!--浏览器能够识别的资源-->
<a href="index.jsp">JSP页面</a> <br>
<a href="upload.html">HTML页面</a> <br>
<a href="play.png">图片</a> <br>
<a href="test.txt">TXT文件</a> <br>
<!--浏览器不能够识别的资源-->
<hr>
<a href="红蜘蛛软件.lnk">快捷方式</a> <br>
<hr>
<!-- download属性-->
<a href="play.png" download>图片</a> <br>
<a href="test.txt" download="测试.txt">TXT文件</a> <br>
<hr>
<form action="downloadServlet">
    要下载的文件名:<input type="text" name="fileName">
    <button>下载</button>
</form>

</body>
</html>

5.2.2 后台实现下载

/**
 * 文件下载
 *  1. 需要通过 response.setContentType 方法设置 Content-type 头字段的值, 为浏览器无法使用某种方式或激活某个程序来处理的 MIME 类型,例 如 "application/octet-stream" 或 "application/x-msdownload" 等。
 *  2. 需要通过 response.setHeader 方法设置 Content-Disposition 头的值 为 "attachment;filename=文件名"
 *  3. 读取下载文件,调用 response.getOutputStream 方法向客户端写入附件内容。
 */
@WebServlet("/downloadServlet")
public class DownloadServlet extends HttpServlet  {

    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 设置请求的编码格式
        request.setCharacterEncoding("UTF-8");
        // 得到要下载的文件名
        String fileName = request.getParameter("fileName");
        // 得到文件所存放的路径(项目的存放路径)
        String path = request.getServletContext().getRealPath("/");
        // 通过路径得到file对象
        File file = new File(path + "/" + fileName);
        // 判断文件是否存在,且是一个标准文件
        if (file.exists() && file.isFile()) {
            // 如果文件存在,则下载
            // 设置响应类型 (浏览器无法使用某种方式或激活某个程序来处理的类型)
            response.setContentType("application/x-msdownload");
            // 设置头信息
            response.setHeader("Content-Disposition", "attachment;filename=" + fileName);
            // 得到文件的输入流
            InputStream inputStream = new FileInputStream(file);
            // 得到字节输出流
            ServletOutputStream outputStream = response.getOutputStream();

            byte[] ch = new byte[1024];
            int len = 0;
            while((len = inputStream.read(ch)) != -1) {
                outputStream.write(ch, 0 ,len);
            }
            outputStream.close();
            inputStream.close();
        } else {
            response.setContentType("text/html;charset=UTF-8");
            response.getWriter().write("<h2>要下载的文件不存在,请重试!<a href='download.html'>返回下载</a></h2>");
            response.getWriter().close();
        }
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值