zoukankan      html  css  js  c++  java
  • Servlet作用域

    Servlet三大作用域

    ​ 在JSP中存在四大作用域pageContextrequestsessionapplication

    ​  pageContext: PageContext

    ​  request: HttpServletRequest

    ​  session: HttpSession

      application: ServletContext

    在Servlet中只存在三大作用域:

    ​  HttpServletRequest  一次请求

      HttpSession  一次会话

      ServletContext  当前应用

    关于3大作用域使用:

    ​  三大作用域的使用,其本质是根据作用域的范围,生命周期决定其使用的方式.

    ​  当我们的数据只需要在一次请求之间进行传递时,优先HttpServletRequest :例如 : 你的数据需要传递给下一个地址.

    ​  当我们的数据,在多次请求时需要实现共享时,优先使用HttpSession.例如: 用户的多个操作,都需要用户ID或者检查是否存在用户信息时.

      当我们的数据,在整个应用是全局唯一的,且大家都可以访问,使用时,使用ServletContext.: 例如 : 整个应用的访问人数.虽然用户访问的地址不同,但是整个应用的访问人数都应该增长.此时使用ServletContext.

    ​ 例如:全局的常量值,也可以使用ServletContext.

    ServletContext的使用

    获取ServletContext作用域对象.

    // 1. 获取ServletContext
    ServletContext context1 = req.getServletContext();
    System.out.println(context1);
    ServletContext context2 = this.getServletContext();
    System.out.println(context2);
    ServletContext context3 = req.getSession().getServletContext();
    System.out.println(context3);
    ServletContext context4 = this.getServletConfig().getServletContext();
    System.out.println(context4);
    // 在整个项目,全局只有一个ServletContext对象,所有对象都共有它.
    

    ServletContext的核心方法:

    // 1. 获取ServletContext
    ServletContext context = req.getServletContext();
    // 2. ServletContext相关方法
    // 1. 作用域属性相关方法
    // context.setAttribute(name, object); // 设置作用域属性值
    // context.getAttribute(name) // 根据属性名 从作用域中获取值
    // context.getAttributeNames()// 获取作用域中所有的属性名
    // context.removeAttribute(name); // 删除作用域中属性值
    // 2. 作用域初始化属性值相关方法
    // context.getInitParameter(name) // 根据参数名称,获取初始化参数对应的值
    // context.getInitParameterNames() // 获取所有初始化参数的name值集合
    // 获取初始化参数的  name 属性值
    Enumeration<String> initParameterNames = context.getInitParameterNames();
    while(initParameterNames.hasMoreElements()) {
    	String  name = initParameterNames.nextElement();
    	System.out.println(name);
    	System.out.println(context.getInitParameter(name));
    }
    // 获取服务器资源路径 
    String contextPath = context.getContextPath();// 获取项目名称
    System.out.println(contextPath);
    String realPath = context.getRealPath("/");// 获取项目的物理路径
    System.out.println(realPath);
    realPath = context.getRealPath("img");// 获取项目中img文件夹的物理路径,只能获取,webContent下面直接文件夹
    System.out.println(realPath);
    realPath = context.getRealPath("child");// 获取项目的物理路径    返回child物理路径错误的   img/child
    System.out.println(realPath);
    Set<String> resourcePaths = context.getResourcePaths("/"); // 获取webContent文件夹下面文件信息
    for (String string : resourcePaths) {
    	System.out.println(string);
    }
    

    ServletContext案例:应用访问人数

    ​ 每次请求,网站访问人数+1。

    ​ 每次处理请求时,获取ServletContext对象,从中拿到当前网站的访问人数.然后人数加1,且将新的数据放入的ServletContext作用域。

    package com.sxt.servlet;
    
    import java.io.IOException;
    
    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;
    
    @WebServlet(urlPatterns = {"/goods.do"})
    public class ServletContextDemo03 extends HttpServlet {
    
    	private static final long serialVersionUID = -197877897340974325L;
    
    	@Override
    	protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    		//获取ServletContext
    		ServletContext context = req.getServletContext();
    		//获取当前人数
    		Object count = context.getAttribute("count");
    		//判断数据是否合法
    		if(count == null) {
    			// 第一次访问
    			context.setAttribute("count", 1);
    		}else {
    			// 非第一次访问
    			int m = Integer.parseInt(count.toString()) + 1;
    			context.setAttribute("count", m);
    		}
    		resp.sendRedirect("index.jsp");
    	}
    }
    

    jsp:在页面显示访问次数

    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <title>Insert title here</title>
    </head>
    <body>
    访问人数为:${count}
    </body>
    </html>
    

    不足:

    1. 直接访问JSP时,或者某个其他的地址时,人数没有增加.需要在每个地址都进行数据处理.
    2. 当服务器重启时,人数数据就丢失了.

    解决以上问题:

    1. 解决各个地址数据处理问题,需要统一的请求访问处理.需要使用Filter ,过滤器.

    2. 当服务器重启时,数据丢失问题,当服务器关闭时,将此时内存中的数据进行持久化操作,当服务器重新启动时,读取持久化的数据,读到ServletContext中去,需要使用Listener,监听器.

    Servlet中的Filter拦截器

    什么是拦截器?

    ​  拦截器可以简单理解为拒绝你想拒绝的.对HTTP请求进行一个过滤处理,通过获取HTTP请求的信息,进行请求预处理.

    如何使用Servlet拦截器?

    1. 创建一个类

    2. 实现Filter接口,重写方法

    3. 注册拦截器 : 告诉程序存在一个拦截

    4. 配置拦截的地址 : 告诉程序那些地址 不能直接访问,要先走拦截器

       package com.sxt.filter;
       
       import java.io.IOException;
       import java.util.Enumeration;
       
       import javax.servlet.Filter;
       import javax.servlet.FilterChain;
       import javax.servlet.FilterConfig;
       import javax.servlet.ServletException;
       import javax.servlet.ServletRequest;
       import javax.servlet.ServletResponse;
       
       public class MyFilter implements Filter {
       	
       	/**
       	 *	初始化方法
       	 */
       	@Override
       	public void init(FilterConfig filterConfig) throws ServletException {
       		System.out.println("======init========");
       		//filterConfig.getFilterName() : 获取拦截器的名称
       		System.out.println(filterConfig.getFilterName());
       		
       		// filterConfig.getInitParameter(name) // 根据 name值 获取初始化参数
       		//filterConfig.getInitParameterNames() // 获取所有的 初始化参数的name值
       		// 获取配置的初始化参数
       		Enumeration<String> initNames = filterConfig.getInitParameterNames();
       		while(initNames.hasMoreElements()) {
       			String name = initNames.nextElement();
       			System.out.println(name);
       			System.out.println(filterConfig.getInitParameter(name));
       		}
       	}
       	
       	/**
       	 * 	进行拦截处理
       	 */
       	@Override
       	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
       			throws IOException, ServletException {
       		System.out.println("======doFilter=======");
       		//进行预处理
       		//放行
       		System.out.println("放行前");
       		chain.doFilter(request, response);
       		System.out.println("放行后");
       	}
       	/**
       	 * 	销毁  释放资源
       	 */
       	@Override
       	public void destroy() {
       		System.out.println("=======destroy=======");
       	}
       
       }
    

    Filter注册配置

       <?xml version="1.0" encoding="UTF-8"?>
       <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
         <display-name>06filter</display-name>
         <welcome-file-list>
           <welcome-file>index.html</welcome-file>
           <welcome-file>index.htm</welcome-file>
           <welcome-file>index.jsp</welcome-file>
           <welcome-file>default.html</welcome-file>
           <welcome-file>default.htm</welcome-file>
           <welcome-file>default.jsp</welcome-file>
         </welcome-file-list>
         <!-- 注册拦截器 -->
         <filter>
         	<filter-name>myFilter</filter-name>
         	<filter-class>com.sxt.filter.MyFilter</filter-class>
         	<!-- 配置filter初始化参数 -->
         	<init-param>
               <!-- 初始化参数name值 -->
         		<param-name>initName1</param-name>
                <!-- 初始化参数对应的value值 -->
         		<param-value>initValue1</param-value>
         	</init-param>
         	<init-param>
         		<param-name>initName2</param-name>
         		<param-value>initValue2</param-value>
         	</init-param>
         </filter>
         <!-- 配置拦截的地址 -->
         <filter-mapping>
         	<filter-name>myFilter</filter-name>
         	<url-pattern>/*</url-pattern>
         </filter-mapping>
       </web-app>
    

    拦截案例

    编码过滤器案例:所有的请求和响应统一设置编码格式.

    package com.sxt.filter;
    
    import java.io.IOException;
    
    import javax.servlet.Filter;
    import javax.servlet.FilterChain;
    import javax.servlet.FilterConfig;
    import javax.servlet.ServletException;
    import javax.servlet.ServletRequest;
    import javax.servlet.ServletResponse;
    
    /**
     * @ClassName: CharsetFilter 
     * @Description: 编码过滤器   统一设置编码
     * @author: Mr.T
     * @date: 2019年11月4日 下午2:37:53
     */
    public class CharsetFilter implements Filter {
    	
    	private static  String charset;
    
    	@Override
    	public void init(FilterConfig filterConfig) throws ServletException {
    		charset = filterConfig.getInitParameter("charset");
    	}
    
    	@Override
    	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
    			throws IOException, ServletException {
    		System.out.println("======只拦截.do 后缀结尾======");
    		//设置编码
    		request.setCharacterEncoding(charset);
    		response.setCharacterEncoding(charset);
    		//放行
    		System.out.println(".do 放行前");
    		chain.doFilter(request, response);
    		System.out.println(".do 放行后");
    	}
    
    	@Override
    	public void destroy() {	
    	}
    
    }
    
    <!-- 注册编码拦截器 -->
    <filter>
      	<filter-name>charsetFilter</filter-name>
      	<filter-class>com.sxt.filter.CharsetFilter</filter-class>
      	<init-param>
      		<param-name>charset</param-name>
      		<param-value>UTF-8</param-value>
      	</init-param>
    </filter>
    <!-- 配置拦截的地址 -->
    <filter-mapping>
      	<filter-name>charsetFilter</filter-name>
      	<!-- 只拦截.do后缀结尾的 -->
      	<url-pattern>*.do</url-pattern>
    </filter-mapping>
    

    注意点:

    1. 拦截器执行的先后顺序,在web.xml中先配置的优先执行,后配置的后执行.
    2. 当一个地址会被多个拦截器拦截时,先执行的拦截器,最后结束.

    登录拦截

    ​  如果用户没有登录,则跳转到登录界面,让用户登录.

    package com.sxt.filter;
    
    import java.io.IOException;
    
    import javax.servlet.Filter;
    import javax.servlet.FilterChain;
    import javax.servlet.FilterConfig;
    import javax.servlet.ServletException;
    import javax.servlet.ServletRequest;
    import javax.servlet.ServletResponse;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import javax.servlet.http.HttpSession;
    
    /**
     * @ClassName: LoginFilter 
     * @Description: 登录拦截器
     * 	在用户请求一些资源信息时,假如用户没有登录,则让用户登录
     * 	登录拦截器  不拦截静态资源信息,例如:  js文件,css文件 , 图片资源  ,只拦截:  jsp 和 .do后缀
     * 	并且: 一些特殊的动态请求信息,也放行:  验证码   登录请求  注册
     * @author: Mr.T
     * @date: 2019年11月4日 下午3:22:52
     */
    public class LoginFilter implements Filter {
    
    	@Override
    	public void init(FilterConfig filterConfig) throws ServletException {
    		
    	}
    
    	@Override
    	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
    			throws IOException, ServletException {
    		/**
    		 * 1.获取 用户登录状态 : 	从session 拿到当前用户
    		 * 	若当前用户存在,则说明已经登录
    		 * 	若不存在 则没有登录,判断用户的请求信息.
    		 * 		例如: 如果用户请求的验证码,则放行
    		 * 		例如:	 如果用户是登录请求,则也放行
    		 */
    		// 将请求和响应对象 进行转型
    		HttpServletRequest req =  (HttpServletRequest) request;
    		HttpServletResponse resp =  (HttpServletResponse) response;
    		//获取session
    		HttpSession session = req.getSession();
    		//从session中 拿到当前用户信息
    		Object user = session.getAttribute("user");
    		//用户存在
    		if(user != null) {
    			//放行
    			chain.doFilter(request, response);
    			return;
    		}
    		//用户不存在
    		//获取用户的请求信息: 
    		String uri = req.getRequestURI();
    		//请求验证码  
    		String service = req.getParameter("service");
    		if(uri.endsWith("checkCode.do") ) {
    			//放行
    			chain.doFilter(request, response);
    			return;
    		}
    		// 登录请求 放行
    		if(uri.endsWith("user.do")&& "login".equals(service) ) {
    			//放行
    			chain.doFilter(request, response);
    			return;
    		}
    		//注册页面  登录页面放行
    		if(uri.endsWith("register.jsp") || uri.endsWith("login.jsp") ) {
    			//放行
    			chain.doFilter(request, response);
    			return;
    		}
    		// 注册请求放行
    		if(uri.endsWith("user.do")&& "register".equals(service) ) {
    			//放行
    			chain.doFilter(request, response);
    			return;
    		}
    		//其他情况去登录页面
    		resp.sendRedirect("login.jsp");
    	}
    
    	@Override
    	public void destroy() {
    		
    	}
    
    }
    

    web.xml配置

     <!-- 登录拦截器 -->
      <filter>
      	<filter-name>LoginFilter</filter-name>
      	<filter-class>com.sxt.filter.LoginFilter</filter-class>
      </filter>
      <!-- 配置拦截的地址 -->
      <filter-mapping>
      	<filter-name>LoginFilter</filter-name>
      	<!-- 只拦截.do后缀结尾的 -->
      	<url-pattern>*.do</url-pattern>
        <!-- 只拦截jsp 后缀 -->  
      	<url-pattern>*.jsp</url-pattern>
      </filter-mapping>
    
  • 相关阅读:
    02数组基本操作
    01数组创建
    java流程控制
    assignment1
    Lecture 1: Introduction
    Lecture 14:Radial Basis Function Network
    Lecture 13:Deep Learning
    机器学习基石笔记16——机器可以怎样学得更好(4)
    机器学习基石笔记15——机器可以怎样学得更好(3)
    机器学习基石笔记14——机器可以怎样学得更好(2)
  • 原文地址:https://www.cnblogs.com/lyang-a/p/12562951.html
Copyright © 2011-2022 走看看