博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
监听器与过滤器
阅读量:2062 次
发布时间:2019-04-29

本文共 7519 字,大约阅读时间需要 25 分钟。

简介

我们知道servlet与jsp的三大主件是什么吗?对了,servlet,listener,filter,servelt我们都快玩烂了,话不多说,咱们来看看listener和filter的使用。

one by one

listener

JavaWeb中的监听器

  事件源:三大域!

ServletContext

生命周期监听:ServletContextListener,它有两个方法,一个在出生时调用,一个在死亡时调用;

void contextInitialized(ServletContextEvent sce):创建SErvletcontext时
void contextDestroyed(ServletContextEvent sce):销毁Servletcontext时

属性监听:ServletContextAttributeListener,它有三个方法,一个在添加属性时调用,一个在替换属性时调用,最后一个是在移除属性时调用。

void attributeAdded(ServletContextAttributeEvent event):添加属性时;
void attributeReplaced(ServletContextAttributeEvent event):替换属性时;
void attributeRemoved(ServletContextAttributeEvent event):移除属性时;

HttpSession

生命周期监听:HttpSessionListener,它有两个方法,一个在出生时调用,一个在死亡时调用;

void sessionCreated(HttpSessionEvent se):创建session时

void sessionDestroyed(HttpSessionEvent se):销毁session时

属性监听:HttpSessioniAttributeListener,它有三个方法,一个在添加属性时调用,一个在替换属性时调用,最后一个是在移除属性时调用。

void attributeAdded(HttpSessionBindingEvent event):添加属性时;
void attributeReplaced(HttpSessionBindingEvent event):替换属性时
void attributeRemoved(HttpSessionBindingEvent event):移除属性时

ServletRequest

生命周期监听:ServletRequestListener,它有两个方法,一个在出生时调用,一个在死亡时调用;

void requestInitialized(ServletRequestEvent sre):创建request时

void requestDestroyed(ServletRequestEvent sre):销毁request时

属性监听:ServletRequestAttributeListener,它有三个方法,一个在添加属性时调用,一个在替换属性时调用,最后一个是在移除属性时调用。

void attributeAdded(ServletRequestAttributeEvent srae):添加属性时
void attributeReplaced(ServletRequestAttributeEvent srae):替换属性时
void attributeRemoved(ServletRequestAttributeEvent srae):移除属性时

javaWeb中完成编写监听器:

写一个监听器类:要求必须去实现某个监听器接口;
注册,是在web.xml中配置来完成注册!

事件对象:

ServletContextEvent:ServletContext getServletContext()
HttpSessionEvent:HttpSession getSession()
ServletRequest:
ServletContext getServletContext();
ServletReques getServletRequest();
ServletContextAttributeEvent:
ServletContext getServletContext();
String getName():获取属性名
Object getValue():获取属性值
HttpSessionBindingEvent:略
ServletRequestAttributeEvent :略
感知监听(都与HttpSession相关)
它用来添加到JavaBean上,而不是添加到三大域上!
这两个监听器都不需要在web.xml中注册!
HttpSessionBindingListener:添加到javabean上,javabean就知道自己是否添加到session中了。

这是如何在xml中部署的形式
cn.itcast.listener.MyServletContextListener
由于listener使用的并不是很多,所以我们就不用代码进行演示了。

filter过滤器

过滤器JavaWeb三大组件之一,它与Servlet很相似!不它过滤器是用来拦截请求的,而不是处理请求的。
当用户请求某个Servlet时,会先执行部署在这个请求上的Filter,如果Filter“放行”,那么会继承执行用户请求的Servlet;如果Filter不“放行”,那么就不会执行用户请求的Servlet。
其实可以这样理解,当用户请求某个Servlet时,Tomcat会去执行注册在这个请求上的Filter,然后是否“放行”由Filter来决定。可以理解为,Filter来决定是否调用Servlet!当执行完成Servlet的代码后,还会执行Filter后面的代码。
我们在编写过滤器时要实现Filter接口该接口形式如下:
public class INFilter implements Filter {	public void destroy() {			}	public void doFilter(ServletRequest request, ServletResponse response,			FilterChain chain) throws IOException, ServletException {			}	public void init(FilterConfig filterConfig) throws ServletException {			} }
我们来看图说一下他的执行流程:
话不多说,我们看两个filter的实现:

解决全站字符乱码(POST和GET中文编码问题)

上代码:
public void doFilter(ServletRequest request, 			ServletResponse response,			FilterChain chain) throws IOException, ServletException {				HttpServletRequest req = (HttpServletRequest)request;				if(req.getMethod().equalsIgnoreCase("post")) {			req.setCharacterEncoding("utf-8");			chain.doFilter(req, response);		}else {			//如果是get请求的话我们怎么进行转码,我们可以使用装饰者模式,对request的getParamter()、			//方法进行增强,实现转化。我们在给servlet传递一个我们装饰过后的request酒神不知鬼不觉的解决了			EncodingRequest enreq = new EncodingRequest(req);			chain.doFilter(enreq, response);		}			}
/* * 我们直接继承HttpServletRequestWrapper,因为他也只是实现了HttpServletRequest接口 * 如果我们自己实现是不是傻呢。我们只需要对我们要加强的方法进行重写即可 */public class EncodingRequest extends HttpServletRequestWrapper{		public EncodingRequest(HttpServletRequest request) {		super(request);			}	@Override	public String getParameter(String name) {		String param = super.getParameter(name);		if(param != null && !param.trim().isEmpty()){			byte[] b;			try {				b = param.getBytes("iso-8859-1");				param = new String(b,"utf-8");			} catch (UnsupportedEncodingException e) {				throw new RuntimeException(e);			}		}		return param;	}}
好了,万事具备,只欠东风,我们就差部署filter了
encodingFilter
filter.EncodingFilter
encodingFilter
/AServlet
哦了,第一个案例就算完事了。
第二个

动态页面静态化

所谓动态页面静态化其实就是当我们初次访问时将response的printwriter指向我们本地硬盘,为了实现这一点,我们就对使用对response的getWriter() 方法的装饰了,带到下一次访问时直接跳转到该静态页面即可。
上代码:
public void doFilter(ServletRequest request,			ServletResponse response,			FilterChain chain) throws IOException, ServletException {		/*		 * 我们使用这个过滤器来进行页面的静态化		 * 1 我们判断是否是第一次访问该页面,如果是则调用doFilter方法并写入硬盘		 * 否则读入该文件		 */		//进行类型转化		HttpServletRequest req = (HttpServletRequest) request;		HttpServletResponse resp = (HttpServletResponse) response;				String name = req.getParameter("category");		name = name + ".html";		String path = filterConfig.getServletContext().getRealPath("/htmls");		path = path + "\\" + name;		File file = new File(path);		if(file.exists()) {			resp.sendRedirect(req.getContextPath() + "/htmls/" + name);			return;		}		else{			StaticResponse s = new StaticResponse(resp, path);			chain.doFilter(req, s);			s.sendRedirect(req.getContextPath() + "/htmls/" + name);			return ;		}	}
public class StaticResponse extends HttpServletResponseWrapper{	private PrintWriter pw;	public StaticResponse(HttpServletResponse response, String path) {		super(response);		try {			this.pw = new PrintWriter(path, "utf-8");		} catch (Exception e) {			throw new RuntimeException(e);		}	}	public PrintWriter getWriter() {				return pw;	}}
哦了,在部署一下就实现了!!

对了,我们中途在插入一点,那就是

国际化的内容

国际化所涉及的类有Locale类和ResourceBundle类
我们先来说一下Locale类
我一一般常见的形如   en_US   下划线前是语言,下划线后是国家
Locale类的构造器如下:
Locale(String language, String country)
我们在来看一下ResourceBundle类
我们如何得到ResourceBundle类的对象呢?使用如下静态方法;
getBundle(String baseName, Locale locale)
好了,我们得到了资源类的对象就可以使用如下方法获得属性了:
getString(String key)
我们下面来演示一下过滤器中进行国际化的步骤:
/* * 我们首先从request中获取名为request_locale的参数,如果存在则使用参数值创建locale对象, * 并将其保存到session中 * 如果没有,则到session中获取, * 如果还没有,那摩我们只能使用浏览器的推荐类型了,即使用request.getLocale()方法,并保存到session中 *  */	public void doFilter(ServletRequest request, ServletResponse response,			FilterChain chain) throws IOException, ServletException {		HttpServletRequest req = (HttpServletRequest) request;		HttpServletResponse resp = (HttpServletResponse) response;		Locale locale = null;		String l = req.getParameter("request_locale");		if(l != null && !l.trim().isEmpty()) {			String[] strs = l.split("_");			locale = new Locale(strs[0], strs[1]);			req.getSession().setAttribute("locale", locale);		}else{			HttpSession session = req.getSession();			locale = (Locale) session.getAttribute("locale");		}		if(locale == null) {			locale  = req.getLocale();			req.getSession().setAttribute("locale",locale);		}		I18N.setLocale(locale);		chain.doFilter(req, resp);			}
好了,让我们写一下I18N类:
public class I18N {	/*	 * res是有我们指定的,这是基本名称,我们需要创建几个属性文件,文件名为:language_语言_国家.properties	 * 我们通过filter来设置locale静态对象,继而创建了bundle对象。	 */	private static Locale locale ;	private static String res = "language";	private static ResourceBundle bundle;		public static String getText(String key) {		return I18N.bundle.getString(key);	}	public static void setLocale(Locale locale) {		I18N.locale = locale;		setBundle();	}	private static void setBundle() {		ResourceBundle bundle = ResourceBundle.getBundle(res, locale);		I18N.bundle = bundle;	}}
我们来写一个登录界面吧:
<%=I18N.getText("name") %>
<%=I18N.getText("password") %>
">
">
好了,在来写N个配置文件就哦了。

你可能感兴趣的文章
(PAT 1061) Dating (字符串处理)
查看>>
(PAT 1118) Birds in Forest (并查集)
查看>>
数据结构 拓扑排序
查看>>
(PAT 1040) Longest Symmetric String (DP-最长回文子串)
查看>>
(PAT 1145) Hashing - Average Search Time (哈希表冲突处理)
查看>>
(1129) Recommendation System 排序
查看>>
PAT1090 Highest Price in Supply Chain 树DFS
查看>>
(PAT 1096) Consecutive Factors (质因子分解)
查看>>
(PAT 1019) General Palindromic Number (进制转换)
查看>>
(PAT 1073) Scientific Notation (字符串模拟题)
查看>>
(PAT 1080) Graduate Admission (排序)
查看>>
Play on Words UVA - 10129 (欧拉路径)
查看>>
mininet+floodlight搭建sdn环境并创建简答topo
查看>>
【UML】《Theach yourself uml in 24hours》——hour2&hour3
查看>>
【linux】nohup和&的作用
查看>>
【UML】《Theach yourself uml in 24hours》——hour4
查看>>
Set、WeakSet、Map以及WeakMap结构基本知识点
查看>>
【NLP学习笔记】(一)Gensim基本使用方法
查看>>
【NLP学习笔记】(二)gensim使用之Topics and Transformations
查看>>
【深度学习】LSTM的架构及公式
查看>>