## Session(会话)

 

获取session里的name session如何获取_System


### 1)什么是Session?
服务器为了保存用户状态而创建的一个特殊的对象。

    当浏览器第一次访问服务器时,服务器创建一个session对象(该
    对象有一个唯一的id,一般称之为sessionId),服务器会将sessionId
    以cookie的方式发送给浏览器。
    当浏览器再次访问服务器时,会将sessionId发送过来,服务器依据
    sessionId就可以找到对应的session对象。

在 无连接(HTTP)协议基础之上实现在用户状态管理。

### 2)如何获得session对象?

方式一  HttpSession s = request.getSession(boolean flag);

注:
            HttpSession是一个接口。
            当flag为true时: 先查看请求当中是否有sessionId,如果没有, 则创建一个session对象。如果有,则依据sessionId
            查找对应的session对象,如果找到了,则返回该对象,如果找不到,创建一个新的session对象。
            当flag为false时:
             先查找请求当中是否有sessionId,如果没有, 返回null。如果有,则依据sessionId查找对应的session
             对象,如果找到了,则返回该对象,如果找不到,返回null。

获取session里的name session如何获取_服务器_02

方式二 HttpSession s = request.getSession();

    等价于  request.getSession(true);    

### 3)常用方法

绑订数据:

session.setAttribute(String name,Object obj);

依据绑订名获得绑订值:

Object session.getAttribute(String name);
		注:如果绑订名对应的值不存在,返回null。

解除绑订:

session.removeAttribute(String name);

## Session 的销毁

为了避免Session中存储的数据过大,Session需要销毁:

1. 超时自动销毁。
    1. 从用户最后一次访问网站开始,超过一定时间后,服务器自动销毁Session,以及保存在Session中的数据。
    2. Tomcat 服务器默认的Session超时时间是30分钟
    3. 可以利用web.xml设置超时时间单位是分钟,设置为0表示不销毁。

<session-config>
			<session-timeout>20</session-timeout>
		</session-config>

2. 调用API方法,主动销毁Session

session.invalidate()

获取session里的name session如何获取_获取session里的name_03

 

案例:销毁Servlet

public class DeleteServlet extends HttpServlet {
		private static final long serialVersionUID = 1L;
	
		protected void doGet(HttpServletRequest request, HttpServletResponse response) 
				throws ServletException, IOException {
			HttpSession session = request.getSession();
			session.invalidate();
			response.setContentType(
					"text/html; charset=utf-8");
			response.getWriter().println("呵呵!"); 
		}
	}

## 过滤器 Filter

Servlet 标准中定义了过滤器,可以拦截任意的服务器请求和响应。

获取session里的name session如何获取_获取session里的name_04

实现过滤器的步骤:

1. 创建一个过滤器类实现javax.servlet.Filter接口 
    - 重写(实现)全部抽象方法
    - 业务逻辑写到 doFilter中
    - 如果在doFilter中调用了 chain.doFilter方法则处理后续逻辑,如果不执行这个方法,表示对后续逻辑的拦截。
2. 在web.xml(部署描述文件)配置filter,将filter配置到请求之前。
    - 可以配置多个filter-mapping,这样可以复用同一个Filter
    - 可以使用 *.png 或者 /* 过滤一组url
    - 当有多个过滤器过滤统一个资源时候,按照配置的先后执行。

<filter>
		  	<filter-name>demo</filter-name>
		  	<filter-class>web.DemoFilter</filter-class>
		  </filter>
		  <filter-mapping>
		  	<filter-name>demo</filter-name>
		  	<url-pattern>/img.png</url-pattern>
		  </filter-mapping>

3. 过滤器方法参数  ServletRequest 和 ServletResponse是 HttpServletRequest 和 HttpServletResponse 的父类型,方法比较少! 如果需要使用HttpServletRequest 和 HttpServletResponse 的方法需要进行强制类型转换
    1. 比如需要使用 request.getSession() 方法:

HttpServletRequest req = (HttpServletRequest)request;
			HttpSession session = req.getSession();

4. 利用 web.xml 可以向Filter 传递初始化参数。

<init-param>
	    	<param-name>start</param-name>
	    	<param-value>8</param-value>
	    </init-param>
	    <init-param>
	    	<param-name>end</param-name>
	    	<param-value>17</param-value>
	    </init-param>		

		config.getInitParamter("start");
		config.getInitParamter("end");

5. Filter 对象的生命周期
    1. 在Web容器启动时候创建Filter对象,Filter对象是单例的(只创建一个Filter对象)!
    2. 创建以后,立即执行init()方法,只执行一次
    3. 在有url请求时候,会执行匹配的doFilter(),doFilter()是并发执行的。
    4. Filter对象在容器关闭时候销毁,销毁时候执行destroy()

获取session里的name session如何获取_System_05

基本过滤器步骤:

1. 编写过滤器类:
 

/**
		 * 过滤器 Hello World! 
		 */
		public class DemoFilter implements Filter {
			public void init(FilterConfig cfg) throws ServletException {
			}
			public void destroy() {
			}
			public void doFilter(ServletRequest req,
					ServletResponse res, FilterChain chain)
					throws IOException, ServletException {
				req.setAttribute("test", "试试"); 
				
				System.out.println("Hello World!");
				//处理后续请求:如果执行doFilter就正常处理后续
				//Web请求和响应,如果不执行doFilter就意味着
				//不处理后续请求和响应(也就是请求被拦截了!)
				chain.doFilter(req, res);
			}
		}

2. 配置web.xml:

<filter>
		    <filter-name>demo</filter-name>
		    <filter-class>web.DemoFilter</filter-class>
		  </filter>
		  <filter-mapping>
		    <filter-name>demo</filter-name>
		    <url-pattern>/img.png</url-pattern>
		  </filter-mapping>
		  <filter-mapping>
		    <filter-name>demo</filter-name>
		    <url-pattern>/test.html</url-pattern>
		  </filter-mapping>
		  <filter-mapping>
		    <filter-name>demo</filter-name>
		    <url-pattern>*.png</url-pattern>
		  </filter-mapping>

3. 测试

多个过滤可以连接使用:

 

获取session里的name session如何获取_服务器_06

1. 编写Servlet

/**
		 * 演示过滤器执行顺序
		 */
		public class TestFilter implements Filter {
		
			public void destroy() {
			}
		
			public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
				String test = 
						(String)request.getAttribute("test");
				System.out.println("Test Filter:"+test);
				
				chain.doFilter(request, response); 
			}
		
			public void init(FilterConfig fConfig) throws ServletException {
			}
		
		}

2. 配置web.xml:

<filter>
		    <display-name>TestFilter</display-name>
		    <filter-name>TestFilter</filter-name>
		    <filter-class>web.TestFilter</filter-class>
		  </filter>
		  <filter-mapping>
		    <filter-name>TestFilter</filter-name>
		    <url-pattern>*.png</url-pattern>
		  </filter-mapping>

3. 测试

利用过滤器限制图片的访问:

 

 

获取session里的name session如何获取_获取session里的name_07

1. 编写过滤器

public class ImageFilter implements Filter {
			private int start, end; 
			public void destroy() {
				System.out.println("我还会回来的!");
			}
			public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
				//获取当前的时间
				Calendar cal = Calendar.getInstance();
				//获取小时分量
				int hour = cal.get(Calendar.HOUR_OF_DAY);
				//在start到下午end之前,可以看见图片
				if(hour>start && hour<end) {
					chain.doFilter(request, response);
				}else {
					response.setContentType(
							"text/html; charset=UTF-8");
					response.getWriter().println("系统繁忙!"); 
				}
			}
		
			public void init(FilterConfig fConfig) throws ServletException {
				//读取web.xml文件中的配置参数
				String s1=fConfig.getInitParameter("start");
				String s2=fConfig.getInitParameter("end");
				start = Integer.parseInt(s1);
				end = Integer.parseInt(s2);
				System.out.println(start+","+end); 
			}
		
		}

2. 配置 web.xml

<filter>
		    <display-name>ImageFilter</display-name>
		    <filter-name>ImageFilter</filter-name>
		    <filter-class>web.ImageFilter</filter-class>
		    <init-param>
		      <param-name>start</param-name>
		      <param-value>8</param-value>
		    </init-param>
		    <init-param>
		      <param-name>end</param-name>
		      <param-value>17</param-value>
		    </init-param>
		  </filter>
		  <filter-mapping>
		    <filter-name>ImageFilter</filter-name>
		    <url-pattern>*.png</url-pattern>
		  </filter-mapping>

## 监听器

在Web容器的工作时候,在出现特定情况下,会自动的执行用户定义的监听器程序。利用监听器程序,可以将用户程序嵌入到Web容器中工作。

特定情况包括:

1. 对象创建情况:
    1. request对象,response对象,session对象,ServletContext对象等。
    2. 对象的创建和销毁时候执行 事件代码。
2. 在对象中添加、删除数据时候(setAttribute,removeAttribute)
3. 其他的工作状态改变的时候。

如使用: HttpSessionListener
    
1. 创建 类 实现HttpSessionListener
    - 重写方法 sessionCreated()
    - 重写方法 sessionDestroyed()
2. 在web.xml 中配置
3. 启动web容器
    1. 当web容器工作期间创建了session对象时候,会自动执行 sessionCreated()
    2. 当web容器工作期间销毁了session对象时候, 会自动执行sessionDestroyed()

案例:

/**
	 * 监听器演示案例 
	 */
	public class DemoListener 
		implements  HttpSessionListener {
		//在Session对象创建以后执行
		public void sessionCreated(HttpSessionEvent e) {
			System.out.println("Hello Session Created");
			//e 代表当前事件发生时候的相关数据。
			HttpSession s = e.getSession();
			System.out.println("SID:"+s.getId()); 
		}
		//在Session对象销毁以后执行
		public void sessionDestroyed(HttpSessionEvent e) {
			System.out.println("Hello Session Destroyed");
		}
	}

	  <listener>
	    <listener-class>web.DemoListener</listener-class>
	  </listener>

 如上功能的意义:在session创建销毁时候插入用户自定义的代码

最重要的监听器:ServletContextListener

1. contextInitialized() 会在Web服务器启动时候执行。 在软件中需要初始化的程序写到这个方法中。
2. contextDestoryed() 会在Web服务器关闭时候执行。如果需要在关闭时候清除的资源,可以写到这个方法中。

案例:

public class InitListener implements ServletContextListener {
	
		//在web服务器关闭时候执行
	    public void contextDestroyed(ServletContextEvent e)  { 
	       	System.out.println("Hello contextDestroyed");
	    }
	    //在web服务器启动时候执行,用于初始化资源
	    public void contextInitialized(ServletContextEvent e)  { 
	    	System.out.println("Hello contextInitialized");
	    }
		
	}
<listener>
	    <listener-class>web.InitListener</listener-class>
	  </listener>