• 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>
    
  • 相关阅读:
    Running ASP.NET Applications in Debian and Ubuntu using XSP and Mono
    .net extjs 封装
    ext direct spring
    install ubuntu tweak on ubuntu lts 10.04,this software is created by zhouding
    redis cookbook
    aptana eclipse plugin install on sts
    ubuntu open folderpath on terminal
    ubuntu install pae for the 32bit system 4g limited issue
    EXT Designer 正式版延长使用脚本
    用 Vagrant 快速建立開發環境
  • 原文地址:https://www.cnblogs.com/lyang-a/p/12562951.html
Copyright © 2020-2023  润新知