阶段四-JavaEE-Day04

一、ServletContext对象

1. 问题

在实际功能中,不同的用户也可能会用到相同的数据,如果使用Session来进行存储,会造成同一份数据在服务器中被存储多份,浪费空间。

2. 解决

ServletContext对象, 在一个web项目中只创建一次,所有用户都可以获取及使用,可以实现不同用户请求的数据共享

3. 特点

  1. ServletContext对象由Tomcat服务器在启动加载项目的时候完成创建

  2. ServletContext对象一个项目中只有一个,以任意方式获取到的都是同一个。

  3. ServletContext对象中保存的数据是所有用户共享的。

4. 使用

@WebServlet("/scs")
public class ServletContextServlet extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //ServletContext创建
        //方式一
        //Servlet配置信息获取
        ServletContext servletContext = getServletConfig().getServletContext();
        System.out.println("===="+servletContext);

        //方式二
        //req请求对象获取
        ServletContext servletContext1 = req.getServletContext();
        System.out.println("===="+servletContext1);

        //方式三
        //session对象获取
        ServletContext servletContext2 = req.getSession().getServletContext();
        System.out.println("===="+servletContext2);

        //使用
        //key 是String  value 是 Object
        servletContext.setAttribute("aa",123);
        servletContext.getAttribute("aa");
        servletContext.removeAttribute("aa");

        //部分方法
        //获取初始化参数值
        String name = servletContext.getInitParameter("name");
        System.out.println("===="+name);

        //获取部署项目名
        String contextPath = servletContext.getContextPath();
        System.out.println("===="+contextPath);

        //获取真实路径名(绝对路径) 后面拼接上参数名
        String test = servletContext.getRealPath("test");
        System.out.println("===="+test);
    }
}

4.1 ServletContext对象获取web.xml中配置的上下文参数

    
    
        name
        admin
    

    
        age
        18
    

使用:


/*
*  ServletContext对象:
*       1.创建: tomcat启动后,加载了当前项目,为项目创建了一个ServletContext对象
*       2.销毁: tomcat关闭,销毁
*       特点:
*           只创建一次,一个项目只有一个ServletContext对象
*           所有用户共享(多个浏览器,多个客户端)
* */
@WebServlet("/scs")
public class ServletContextServlet extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //ServletContext创建
        //方式一
        //Servlet配置信息获取
        ServletContext servletContext = getServletConfig().getServletContext();
        System.out.println("===="+servletContext);

        //方式二
        //req请求对象获取
        ServletContext servletContext1 = req.getServletContext();
        System.out.println("===="+servletContext1);

        //方式三
        //session对象获取
        ServletContext servletContext2 = req.getSession().getServletContext();
        System.out.println("===="+servletContext2);

        //三个方式创建的ServletContext都是同一个
        
        //使用
        //key 是String  value 是 Object
        servletContext.setAttribute("aa",123);
        servletContext.getAttribute("aa");
        servletContext.removeAttribute("aa");

        //部分方法
        //获取初始化参数值
        String name = servletContext.getInitParameter("name");
        System.out.println("===="+name);

        //获取部署项目名
        String contextPath = servletContext.getContextPath();
        System.out.println("===="+contextPath);

        //获取真实路径名(绝对路径) 后面拼接上参数名
        String test = servletContext.getRealPath("test");
        System.out.println("===="+test);

        String name1 = servletContext.getInitParameter("name");
        String age = servletContext.getInitParameter("age");
        System.out.println(name1+" "+age);

        String name2 = servletContext1.getInitParameter("name");
        String age1 = servletContext1.getInitParameter("age");
        System.out.println(name2+" "+age1);
    }
}
4.2 ServletContext对象的生命周期

当服务器启动时会创建ServletContext对象。服务器关闭后该对象销毁。

ServletContext对象的生命周期很长,仅存放所有用户共享的数据。

二、域对象

1.1 什么是域对象

域对象类似于之前学习的map集合,可以存放键值对的数据。不同的是域对象中数据的使用有一定的区域范围限制。 三大域对象

对象 名称
request域 HttpServeltRequest对象 请求域
session域 HttpSession对象 会话域
application域 ServletContext对象 应用域
1.2 常用API
方法 作用
setAttribute(key, value) 向域中添加|修改数据,无则添加,有则修改
getAttribute(key) 获取域中的数据
removeAttribute(key) 从域中移除指定key的数据

创建一个实体类

2. request域

有效范围 一次请求有效

作用

请求转发,流转业务数据

生命周期 创建:浏览器每次请求,服务器都会重新创建 使用:在请求的Servlet中或者请求转发后的Servlet中使用 销毁:请求响应结束后,该请求对象就会被销毁

3. Session域

有效范围

单次会话内有效,多次请求 作用

一般用来存储用户状态数据,比如:用户的登录信息等

生命周期

创建:从第一次发出请求,会话开始

使用:一次会话内,浏览器和服务器之间发生多次请求都有效

销毁:会话结束,比如:达到最大不活动时间、手动销毁

4. Application域

有效范围

当前web项目内都有效,可以跨请求,跨会话访问 ​作用

一般放一些全局的和项目本身相关所有用户共享的数据,如在线人数,不建议存放业务数据

生命周期

创建:服务器启动

使用:服务器运行期间都有效

销毁:服务器关闭

三、文件上传

1. 介绍

在Servlet3.0之前的版本中如果实现文件上传需要依赖apache的Fileupload组件,在Servlet3.0以及之后的版本中提供了Part对象处理文件上传,所以不在需要额外的添加Fileupload组件。

2. 配置

在Servlet3.0以及之后的版本中实现文件上传时必须要在Servlet中开启多参数配置:

2.1 方式一:

web.xml 配置


    
    
    
    
元素名 类型 描述
int 当数据量大于该值时,内容将被写入临时文件。
String 存放生成的临时文件地址
long 允许上传的文件最大值(byte)。默认值为 -1,表示没有限制
long 一个 multipart/form-data请求能携带的最大字节数(byte),默认值为 -1,表示没有限制。
2.2 方式二:

@MultipartConfig 配置

属性名 类型 描述
fileSizeThreshold int 当数据量大于该值时,内容将被写入临时文件。
location String 存放生临时成的文件地址
maxFileSize long 允许上传的文件最大值(byte)。默认值为 -1,表示没有限制
maxRequestSize long 一个 multipart/form-data请求能携带的最大字节数(byte),默认值为 -1,表示没有限制。

3. Part对象中常用的方法

方法 说明
long getSize() 上传文件的大小
String getSubmittedFileName() 上传文件的原始文件名
String getName() 获取标签中name属性值
InputStream getInputStream() 获取上传文件的输入流
void write(String path) 保存文件至指定位置

4. 实现

<%--
  Created by IntelliJ IDEA.
  User: 86178
  Date: 2023/9/20
  Time: 11:37
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>


    上传


@MultipartConfig
@WebServlet("/down")
public class DownServlet extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        Part photo = req.getPart("photo");

        String fileName = photo.getSubmittedFileName();
        String realPath = getServletContext().getRealPath("upload");

        File file = new File(realPath);
        if (!file.exists()) {
            file.mkdirs();
        }
        photo.write(realPath + "\\" + fileName);
    }
}

四、文件下载

获取文件的输入流,通过输出流响应到浏览器。

<%@ page contentType="text/html;charset=UTF-8" language="java" %>


    下载


下载


@MultipartConfig
@WebServlet("/down")
public class DownServlet extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String fileName = req.getParameter("fileName");

        resp.setHeader("Content-Disposition","attachment;fileName="+ new String(fileName.getBytes(),"ISO-8859-1"));

        String upload = req.getServletContext().getRealPath("upload");

        FileInputStream fis = new FileInputStream(upload + "\\" + fileName);

        BufferedInputStream bis = new BufferedInputStream(fis);

        ServletOutputStream sos = resp.getOutputStream();
        BufferedOutputStream bos = new BufferedOutputStream(sos);

        byte[] bytes = new byte[1024];
        //当不等于-1时循环读取
        while (bis.read(bytes) != -1){
            //边读边写
            //防止出现错误,写的时候只写拥有的数据
            bos.write(bytes,0,bytes.length);
        }

        //刷新并释放资源,只有输出缓冲流有flush
        bos.flush();
        bis.close();
        bos.close();
    }
}

 

五、监听器(Listener)

1. 监听器的需求

目前我们在web项目中,可以使用三大域对象request、session、application作为数据流转的载体。而这三个域对象都不是我们创建的,也不是我们销毁的。

但是我们想要像Servlet一样,Servlet虽然不是我们创建的,但是在Servlet中我们可以使用init和destroy方法在Servlet被创建及销毁的时候完成一系列其他的操作,怎么办?

我们可以给三大域对象添加监听,监听三大域对象的创建及销毁,监听到他们有动态的时候,执行对应的方法。这就是监听器。

2. 监听器的介绍

作用:

监听三大域对象的创建、销毁及数据的变更。

特点:

  1. 监听方法由tomcat根据监听结果来调用执行。

  2. 监听方法中的逻辑代码由我们根据需要编写。

3. 监听器的使用

监听器的使用步骤:

  1. 创建一个类,实现监听器接口(Listener)。

  2. 实现里面的方法。

  3. 在web.xml中配置监听器。

监听器接口:

  1. ServletRequestListenter 监听request对象的创建销毁

  2. ServletRequestAttributeListener 监听request域中数据的变更

  3. HttpSessionListener 监听Session对象的创建销毁

  4. HttpSessionAttributeListener 监听Session对象中数据的变更

  5. ServletContextListener 监听ServletContext对象的创建销毁

  6. ServletContextAttributeListener 监听ServletContext对象中数据的变更

public class MyListener implements ServletRequestListener, ServletRequestAttributeListener,
        HttpSessionListener, HttpSessionAttributeListener, ServletContextListener, ServletContextAttributeListener {
    //监听ServletContext对象中数据的添加
    @Override
    public void attributeAdded(ServletContextAttributeEvent servletContextAttributeEvent) {
        System.out.println("ServletContext对象中被添加了数据");
    }
    //监听ServletContext对象中数据的删除
    @Override
    public void attributeRemoved(ServletContextAttributeEvent servletContextAttributeEvent) {
        System.out.println("ServletContext对象中被删除了数据");
    }
    //监听ServletContext对象中数据的修改
    @Override
    public void attributeReplaced(ServletContextAttributeEvent servletContextAttributeEvent) {
        System.out.println("ServletContext对象中被修改了数据");
    }
    //监听ServletContext对象的初始化
    @Override
    public void contextInitialized(ServletContextEvent servletContextEvent) {
        System.out.println("ServletContext对象初始化");
    }
    //监听ServletContext对象的销毁
    @Override
    public void contextDestroyed(ServletContextEvent servletContextEvent) {
        System.out.println("ServletContext对象被销毁了");
    }
    //监听ServletRequest对象中数据的添加
    @Override
    public void attributeAdded(ServletRequestAttributeEvent servletRequestAttributeEvent) {
        System.out.println("request对象中添加的数据!");
    }
    //监听ServletRequest对象中数据的删除
    @Override
    public void attributeRemoved(ServletRequestAttributeEvent servletRequestAttributeEvent) {
        System.out.println("request对象中删除了数据!");
    }
    //监听ServletRequest对象中数据的修改
    @Override
    public void attributeReplaced(ServletRequestAttributeEvent servletRequestAttributeEvent) {
        System.out.println("request对象中修改了数据!");
    }
    //监听ServletRequest对象中数据的销毁
    @Override
    public void requestDestroyed(ServletRequestEvent servletRequestEvent) {
        System.out.println("request对象被销毁!");
    }
    //监听ServletRequest对象的初始化
    @Override
    public void requestInitialized(ServletRequestEvent servletRequestEvent) {
        System.out.println("request对象被初始化!");
    }
    //监听HttpSession对象中数据的添加
    @Override
    public void attributeAdded(HttpSessionBindingEvent httpSessionBindingEvent) {
        System.out.println("session对象被添加了");
    }
    //监听HttpSession对象中数据的删除
    @Override
    public void attributeRemoved(HttpSessionBindingEvent httpSessionBindingEvent) {
        System.out.println("session对象被删除了");
    }
    //监听HttpSession对象中数据的修改
    @Override
    public void attributeReplaced(HttpSessionBindingEvent httpSessionBindingEvent) {
        System.out.println("session对象被修改了");
    }
    //监听HttpSession对象的创建
    @Override
    public void sessionCreated(HttpSessionEvent httpSessionEvent) {
        System.out.println("session对象被创建了");
    }
    //监听HttpSession对象的销毁
    @Override
    public void sessionDestroyed(HttpSessionEvent httpSessionEvent) {
        System.out.println("session对象被销毁了");
    }
}

六、过滤器(Filter)

1. 过滤器的介绍

1.1 目前请求处理中存在的安全问题

通过前面的Servlet学习,我们了解到Tomcat服务器一直是在被动的接收请求,而且Tomcat服务器收到请求后需要调用Servlet的service方法进行处理。

目前,只要在浏览器中输入正确的url地址,不管此次请求是否合理,Tomcat服务器在接收到请求后就会直接调用对应的资源完成请求的处理。有些场景, 需要对请求进行相关处理, 处理完成后, 在访问请求的资源。

比如:

我们写的登录案例,大家发现,如果用户没有登录也可以直接输入主界面的地址访问到主界面。登录其实就像个摆设一样。

1.2 解决方案

在浏览器发起请求,Tomcat服务器收到后,调用资源处理请求之前添加拦截。

拦截后发现请求不合理,可以拒绝访问;如果合理,可以进行相关的设置, 然后放行,继续访问请求的资源。

这个其实就是过滤器(Filter)。

1.3 过滤器的作用

Tomcat收到客户端请求后, 调用资源前会对请求进行拦截, 完成相关的处理。

阶段四-JavaEE-Day04_第1张图片

1.4 过滤器的编写步骤
  1. 创建一个类,实现过滤器接口(Filter)。

  2. 实现接口中的方法,编写自己的代码。

  3. 在web.xml中配置过滤器或通过注解配置。

2. 过滤器的使用


@WebFilter("/filter")
public class MyFilter implements Filter {

    public MyFilter(){
        System.out.println("过滤器被创建!");
    }

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        /*
        *    处理化方法,执行一些初始化的操作,一般不用
        *       filterConfig
        * */
        System.out.println("过滤器被初始化!");
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        /*
        * 过滤器的核心方法,过滤器拦截到请求后,就是在该方法中对请求进行判断,看是否让其继续访问我们的资源
         * servletRequest    封装的请求信息
         * servletResponse   封装的响应对象
         * filterChain       过滤器链,用来放行的
        * */
        System.out.println("开始对请求进行判断处理!");
        filterChain.doFilter(servletRequest, servletResponse);//放行
    }

    @Override
    public void destroy() {
        /*销毁方法,用来做一些释放资源的操作,一般不用
        * */
        System.out.println("过滤器被销毁!");
    }
}

过滤器的配置

1.在web.xml中配置 

    
    
        CharacterFilter
        
        com.sh.filter.MyFilter
    

    
    
        CharacterFilter
        /*
    

2.注解配置

@WebFilter("/filter")

3. 过滤器链

阶段四-JavaEE-Day04_第2张图片

你可能感兴趣的:(java学习之路,java-ee,java,服务器)