JavaWeb基础知识点

一、Filter过滤器

1、Filter介绍:

Filter也称之为过滤器,开发人员通过Filter技术,对web服务器管理的所有web资源:例如 Jsp, Servlet, 静态图片文件或静态 html 文件等进行拦截,从而实现一些特殊的功能。例如实现URL级别的权限访问控制、过滤敏感词汇、压缩响应信息等一些高级功能。

通过Filter技术,开发人员可以实现用户在访问某个目标资源之前,对访问的请求和响应进行拦截。简单说,就是可以实现web容器对某资源的访问前截获进行相关的处理,还可以在某资源向web容器返回响应前进行截获进行处理。

2、编写Filter步骤

第一步:创建Filter处理类;

package com.prosay.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;

/**
 * 统一的编码处理程序
 * @author jame
 * 1.实现Filter接口
 * 2.在Web.xml中配置
 */
public class EncodingFilter implements Filter{
    private String encoding;
    /**
     * 过滤器被执行的核心方法
     * tomcat接收的每一个请求都会建立一个子线程处理,子线程创建的调用Dofilter(request response)
     */
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
            System.out.println("编码过滤器开始………………");
            //在前面设置好编码
            request.setCharacterEncoding(encoding);
            response.setContentType("text/html;charset="+encoding);
            response.setCharacterEncoding("UTF-8");
            //EncodingWrapper wrapper = new EncodingWrapper((HttpServletRequest)request);
            //chain.doFilter(wrapper, response);
            //执行下一个步骤(另外一个过滤器或者是真实的资源)
            chain.doFilter(request, response);
            System.out.println("编码过滤器结束………………");

    }
    @Override
    public void init(FilterConfig config){
        encoding = config.getInitParameter("encoding");
        System.out.println("过滤器被初始化!!…………………………");
    }
}
package com.prosay.filter;
/**
 * 用户的权限校验
 * @author jame
 *
 */

import java.io.IOException;

import javax.servlet.FilterChain;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

@SuppressWarnings("serial")
public class UserFilter extends HttpFilter{

    @Override
    public void doFilter(HttpServletRequest request,HttpServletResponse response,FilterChain chain) throws IOException, ServletException{
        //request中去获取session
        HttpSession session = request.getSession();

        ServletContext  application = request.getServletContext();
        String userName = (String)session.getAttribute("userName");
        System.out.println("用户权限过滤器开始………………");
        //说明当前会话中存在用户名(表示已经登陆了)
        if(userName!=null){
            chain.doFilter(request, response);
        }else{
            response.sendRedirect("../index.html");
        }
        System.out.println("用户权限过滤器结束………………");
        //this.getServletContext();
    }
}

第二步:web.xml文件中配置Filter。
配置Filter时要声明filter-name(filter的别名)和filter-class(filter的类路径),也可以设置属性,然后在filter类取出来。


  <filter>
    <filter-name>encodingFilterfilter-name>
    <filter-class>com.prosay.filter.EncodingFilterfilter-class>
    <init-param>
        <param-name>encodingparam-name>
        <param-value>utf-8param-value>
    init-param>
  filter>
  <filter-mapping>
    <filter-name>encodingFilterfilter-name>
    <url-pattern>/*url-pattern>
  filter-mapping>

  <filter>
    <filter-name>userFilterfilter-name>
    <filter-class>com.prosay.filter.UserFilterfilter-class>
  filter>
  <filter-mapping>
    <filter-name>userFilterfilter-name>
    <url-pattern>/chatroom/*url-pattern>
  filter-mapping>

3、过滤器链的形成:

当请求一个资源时,服务器会查询web.xml中所有对此资源路径进行过滤的filter,并根据在web.xml中的先后顺序形成一个filter链(filterchain)。就是按写在web.xml中的filter类顺序执行。

二、监听器

1、监听器介绍:

监听器也叫Listener,是Servlet的监听器,它可以监听客户端的请求、服务端的操作等。通过监听器,可以自动激发一些操作,比如监听在线的用户的数量。

2、ServletContextListener

ServletContextListener是ServletContext的监听者,它能够监听ServletContext对象的生命周期,也就是监听Web应用的生命周期。
当Servlet容器启动或终止Web应用时,会触发ServletContextEvent事件,该事件
由 ServletContextListener 来处理 。

package com.prosay.listener;

import java.util.ArrayList;
import java.util.List;

import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

/**
 * 配置load-on-starup的Servlet可以跟随Tomcat的启动初始化
 * ServletContextListener能够比他更早启动
 * @author jame
 * 1.实现ServletContextListener接口
 * 2.实现对应的方法
 * 监听的是上下文的对象生命周期(初始化和销毁)
 */
public class InitListener implements ServletContextListener{

    @Override
    public void contextDestroyed(ServletContextEvent event){
        System.out.println("项目从容器中卸载了…………");
    }
    @Override
    public void contextInitialized(ServletContextEvent event){
        System.out.println("项目被容器加载…………");
        System.out.println("***********聊天室服务器初始化开始***********");
        ServletContext application = event.getServletContext();
        //第一次访问(初始化)创建一个ArrayList用来存储消息列表,然后将这个ArrayList实例存入Servlet上下文中
        List msgs = new ArrayList();
        //servletContext存属性方式 setAttribute(String attrName,Object attr)
        application.setAttribute("msgs",msgs);
        //servletContext  httpSession 对象的存储 整个应用生命周期中存储属性 httpsession 整个会话中的存储属性
        //在线用户列表
        List userList = new ArrayList();
        application.setAttribute("users",userList);
        System.out.println("***********聊天室服务器初始化完毕***********");
    }

}
package com.prosay.listener;

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

public class SecondListener implements ServletContextListener{

    public void contextInitialized(ServletContextEvent event){
        System.out.println(event.getSource()+"#####");
    }
}
package com.prosay.listener;

import javax.servlet.ServletContextAttributeEvent;
import javax.servlet.ServletContextAttributeListener;

/**
 * 
 * @author jame
 *
 */
public class ApplicationAttrListener implements ServletContextAttributeListener{
        /**
         * 监听servletContext实例的新添加的属性
         */
        public  void attributeAdded(ServletContextAttributeEvent scae) {
            System.out.println("上下文中增加了:"+scae.getName()+":"+scae.getValue());
        }
        /**
         * 监听ServletContext实例移除的属性
         */
        public  void attributeRemoved(ServletContextAttributeEvent scae) {
            System.out.println("上下文中移除了属性:"+scae.getName()+":"+scae.getValue());
        }
        /**
         * 监听ServletContext实例中的属性被替换时发生
         */
        public  void attributeReplaced(ServletContextAttributeEvent scae) {

            System.out.println("上下文中增加了:"+scae.getName()+":"+scae.getValue());
        }
}

  <listener>
    <description>上下文监听器,来替换InitServletdescription>
    <listener-class>com.prosay.listener.InitListenerlistener-class>
  listener>
   <listener>
    <listener-class>com.prosay.listener.SecondListenerlistener-class>
  listener>
 <listener>
    <description>上下文属性监听器description>
    <listener-class>com.prosay.listener.ApplicationAttrListenerlistener-class>
  listener>

web.xml中的listener的这个声明顺序,运行后的输出为:

项目被容器加载…………
*********** 聊天室服务器初始化开始***********
上下文中增加了:msgs:[]
上下文中增加了:users:[]
***********聊天室服务器初始化完毕***********
org.apache.catalina.core.ApplicationContextFacade@4a3631f8#####
过滤器被初始化!!…………………………

如果把SecondListener提到前面输出结果为:

org.apache.catalina.core.ApplicationContextFacade@4a3631f8#####
项目被容器加载…………
*********** 聊天室服务器初始化开始***********
上下文中增加了:msgs:[]
上下文中增加了:users:[]
***********聊天室服务器初始化完毕***********
过滤器被初始化!!…………………………

把ApplicationAttrListener提到前面输出结果为:

项目被容器加载…………
*********** 聊天室服务器初始化开始***********
上下文中增加了:msgs:[]
上下文中增加了:users:[]
***********聊天室服务器初始化完毕***********
过滤器被初始化!!…………………………
org.apache.catalina.core.ApplicationContextFacade@4a3631f8#####

说明,写在web.xml前面的监听器先检测到,代码先运行,但是如果写在前面,监听的内容没有触发的话代码也是不会先运行的。

HttpSessionListner

HttpSessionListener监听HttpSession的操作。
当创建一个Session时,激发session Created(HttpSessionEvent se)方法;
当销毁一个Session时,激发sessionDestroyed (HttpSessionEvent se)方法。

三、重定向和请求转发

1、重定向介绍:

服务器向浏览器发送一个302状态码及一个Location消息头,浏览器在收到后会立即向这个地址发送请求。
sendRedirect(String location)

2、转发介绍:

转发:服务器将客户端的请求转发到另外一个页面
request.getRequestDispatcher(String path)
forward(HttpServletRequest request, HttpServletResponse response)

3、重定向和转发的区别:

1) 重定向时,客户端发送了两个请求;而转发时,客户端只发送了一个请求(本质区别)
2) 重定向时,客户端浏览器的地址栏有变化,而转发时,客户端浏览器的地址栏没有变化
3) 重定向发生在客户端,而转发是发生在服务端,客户端不知道

4、重定向与转发的应用场景:

1) 只是页面跳转的话,且没有业务请求处理参数等,可以使用重定向,也可以使用转发过去。
2,如果请求跳转页面有业务处理,则必须使用转发,但是有两点需要处理:
1)如果我们的action请求的jsp页面的有业务逻辑处理或者请求其他命名空间的action时,在不同的命名空间里面,那么必须使用”../”来跳出当前的路径请求,在进入其他的命名空间+其他的action请求,这样才会使页面的其他导入文件才不会有丢失的情况;
2)当然,如果要跳转到注册,或者表单提交页面时,最后使用重定向比较好,这样不会有属性冲突,造成数据提交异常,但有时候却要转发过去,具体看是否需要当前的request请求参数;

你可能感兴趣的:(Java,web)