ServletContext对象和会话之Cookie

ServletContext对象:

1.概念:代表整个web应用,可以和程序的容器(服务器)进行通信(其实可以看成一个全局对象)。例如,获取文件的 MIME 类型、分发请求或写入日志文件

2.获取ServletContext对象

  • 通过request对象获取:request.getServletContext();
  • 通过HttpServlet获取:this.getServletContext();

3.功能:

a. 获取MIME类型:public String getMimeType(String file) 如果类型未知则返回null,在web.xml里面可以查看相关的mime类型

MIME类型:在互联网通信过程中定义的一种文件数据类型,格式------ 大类型/小类型   text/html   image/jpg

b.域对象:共享数据

  • public void setAttribute(String name, Object object)
  • public Object getAttribute(String name)
  • public void removeAttribute(String name)

c.获取文件的真实(服务器)路径:public String getRealPath(String path) path是路径的字符串格式

如下:分别获取src目录下a.txt,web目录下b.txt,WEB-INF目录下的文件的真实路径c.txt

package com.servletcontext;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;


/**
 * @author 承夕
 * @date 2020/2/18 0018 - 8:44
 * @contact:https://github.com/chengxi0
 */
@WebServlet("/servletContextDemo1")
public class ServletContextDemo1 extends HttpServlet {
        @Override
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            //获取ServletContext对象
            ServletContext context = this.getServletContext();

            //分别获取src目录下,web目录下,WEB-INF目录下的文件的真实路径
            //获取web目录下的a.txt
            String realPath1 = context.getRealPath("b.txt");
            System.out.println("b : " +realPath1);

            String realPath2 = context.getRealPath("WEB-INF/c.txt");
            System.out.println("c : " +realPath2);

            String realPath3 = context.getRealPath("WEB-INF/classes/a.txt");
            System.out.println("a : " +realPath3);

           /* b : G:\Java文件\Tomcat\out\artifacts\Tomcat_war_exploded\b.txt
            c : G:\Java文件\Tomcat\out\artifacts\Tomcat_war_exploded\WEB-INF\c.txt
            a : G:\Java文件\Tomcat\out\artifacts\Tomcat_war_exploded\WEB-INF\classes\a.txt*/
        }

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

输出结果可以看出,String path 只需要填进相对于部署在Tomcat上的路径就ok了,但是因为使用IDEA部署的tomcat因此,真正运行在Tomcat服务器的是“G:\Java文件\Tomcat\out\artifacts\Tomcat_war_exploded”这个目录下的,因此里面也没有src目录,但是在WEB-INF文件夹里面有classes目录,即原项目src目录下的文件会放在这个classes目录下。

案例:文件下载(页面显示超链接,用户点击后弹出下载提示框完成文件下载)

这里有个需要知道的知识点:

超链接指向的资源如果是能够被浏览器解析的话,就会在浏览器上面展示出来,如果不能解释,就会弹出下载提示框,因此如果需要任何资源都弹出下载提示框,那么可以使用响应头设置资源的打开方式:

content-disposition:attachment ;filename=xxx

package com.servletcontext;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;


/**
 * @author 承夕
 * @date 2020/2/18 0018 - 8:44
 * @contact:https://github.com/chengxi0
 */
@WebServlet("/servletContextDemo2")
public class ServletContextDemo2 extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //获取文件名
        String filename = request.getParameter("filename");
        //读取部署在服务器的的文件资源
        String realPath = this.getServletContext().getRealPath("photoes/"+filename);
        File file = new File(realPath);
        FileInputStream fileInputStream = new FileInputStream(file);

        //设置响应头
        response.setHeader("content-type",this.getServletContext().getMimeType(filename) );
        response.setHeader("content-disposition","attachment;filename="+filename);

        //输入输出流之间的操作
        ServletOutputStream outputStream = response.getOutputStream();
        int len =0  ;
        byte[] brr = new byte[1024*8];
        while ((len = fileInputStream.read(brr)) != -1) {
            outputStream.write(brr,0,len);
        }

        fileInputStream.close();
    }

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
       this.doPost(request,response);
    }
}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>下载页面</title>
</head>
<body>
<a href="/Tomcat_war_exploded/servletContextDemo2?filename=codetable.jpg">点击下载文件</a>
</body>
</html>

如果图片名是中文的话出现的乱码问题(本次只对谷歌浏览器)

需要在设置响应头content-disposition之前把filename进行url编码,然后在浏览器以附件的形式显示文件名的时候让浏览器自己根据ulr解码进而显示正确的中文名,而不是乱码。

(显示是由浏览器去解码的,我们在servlet内部把中文按照url编码即可)但是需要注意的是,在不同的浏览器,对文件名的解码方式不一样,比如火狐使用的是64为的编码,因此这就需要了解浏览器不一样解码引起的兼容性问题。

POST方式提交的表单参数是中文的乱码问题

Tomcat8已经支持了GET方式获取表单参数是中文的情况了,但是POST方式还没支持。因此需要正确获取到这些带中文的表单参数,需要在开头就设置。

利用response对象往页面打印东西时的乱码问题

往页面写有中文的数据,那就需要建议浏览器以上面格式去读取这些数据,因此只需要在写数据之前设置,浏览器的编码就行.

会话

概念:一次会话包含多次请求和响应,从浏览器第一次给服务器发出请求,到有一方断开为止.

功能:在一次会话范围内的多次请求和响应之间共享数据

方式:

  • 客户端会话技术:Cookie
  • 服务器会话技术:Session

Cookie

概念:客户端绘画技术,把数据保存到客户端.

主要步骤:

  1. 创建Cookie对象,绑定数据 : new  Cookie(String name, String value)
  2. 发送Cookie对象: void addCookie(Cookie cookie) 利用response对象的addCookie方法
  3. 获取Cookie:  Cookie[] getCookies() 可以是多个Cookie

还有一些Cookie对象常用方法

  • 获取Cookie的名称 :String getName()
  • 返回 cookie 的值 :String getValue()
  • 设置 cookie 的最大生存时间,以秒为单位 :void setMaxAge(int expiry) expiry负值意味着 cookie 不会被持久存储,将在 Web 浏览器退出时删除。0 值会导致删除 cookie,正整数表示该Cookie生存的最长时间.

特点和作用:

  • Cookie存储数据是在客户端,因此一般用于存储少量的不太敏感的数据
  • 浏览器对于单个Cookie的大小有限制(4kb),以及同一个域名下的总Cookie数量也有限制(20)
  • 在不登录的情况下,完成服务器对客户端的身份识别.

注意点:

  • Cookie是可以存储中文数据,这个特性这Tomcat8之后支持了.
  • Cookie默认下是本项目下共享数据的,但是如果需要多个项目共享数据,那么需要使用setPath(String path)方法进行设置,把path设置为"/"表示根目录就ok了

案例:记住上一次的访问时间.如果是第一次访问打印"你好,欢迎首次访问"如果不是第一次访问,"欢迎回来,你上一次访问的时间为:显示时间字符串"

package com.cookie;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.atomic.DoubleAccumulator;

/**
 * @author 承夕
 * @date 2020/2/18 0018 - 8:44
 * @contact:https://github.com/chengxi0
 */
@WebServlet("/cookiedemo1")
public class CookieDemo1 extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //设置编码
        response.setContentType("text/html;charset=utf-8");

        //获取cookies
        Cookie[] cookies = request.getCookies();
        //遍历cookies看看是否已经创建
        Cookie cc = null ;
        boolean flag = false ;
        if(cookies != null && cookies.length > 0) {
            for (Cookie c : cookies) {
                String name = c.getName();
                if (name.equals("time")) {
                    cc = c ;
                    flag = true ;
                    break ;
                }
            }
        }
        //创建时间对象
        Date date = new Date();
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy年MM月dd日 hh时mm分ss秒");
        String format = simpleDateFormat.format(date);

       //设置编码格式
        format = URLEncoder.encode(format, "utf-8");

        if (flag) {
            String ccValue = cc.getValue();
            String ccdecode = URLDecoder.decode(ccValue, "utf-8");
            response.getWriter().println("欢迎再次访问,上次访问时间为 :" + ccdecode);
            cc.setValue(format);
            cc.setMaxAge(60*60*24*30);
            //一定要在设置cookie的数据之后进行response.addCookie()不然浏览器不会保存的
            response.addCookie(cc);
        }
        else {
            //创建cookie,绑定数据
            Cookie cookie = new Cookie("time", format);
            cookie.setMaxAge(60*60*24*30);
            String ccdecode1 = URLDecoder.decode(format, "utf-8");
            System.out.println(ccdecode1);
            //还要添加到响应
            response.addCookie(cookie);
            response.getWriter().println("欢迎首次访问");
        }
    }

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request,response);
    }
}
发布了55 篇原创文章 · 获赞 4 · 访问量 1056

猜你喜欢

转载自blog.csdn.net/weixin_45062761/article/details/104387233