本文共 7519 字,大约阅读时间需要 25 分钟。
我们知道servlet与jsp的三大主件是什么吗?对了,servlet,listener,filter,servelt我们都快玩烂了,话不多说,咱们来看看listener和filter的使用。
one by one
生命周期监听:ServletContextListener,它有两个方法,一个在出生时调用,一个在死亡时调用;
void contextInitialized(ServletContextEvent sce):创建SErvletcontext时 void contextDestroyed(ServletContextEvent sce):销毁Servletcontext时 属性监听:ServletContextAttributeListener,它有三个方法,一个在添加属性时调用,一个在替换属性时调用,最后一个是在移除属性时调用。 void attributeAdded(ServletContextAttributeEvent event):添加属性时; void attributeReplaced(ServletContextAttributeEvent event):替换属性时; void attributeRemoved(ServletContextAttributeEvent event):移除属性时;生命周期监听:HttpSessionListener,它有两个方法,一个在出生时调用,一个在死亡时调用;
void sessionCreated(HttpSessionEvent se):创建session时void sessionDestroyed(HttpSessionEvent se):销毁session时
属性监听:HttpSessioniAttributeListener,它有三个方法,一个在添加属性时调用,一个在替换属性时调用,最后一个是在移除属性时调用。
void attributeAdded(HttpSessionBindingEvent event):添加属性时; void attributeReplaced(HttpSessionBindingEvent event):替换属性时 void attributeRemoved(HttpSessionBindingEvent event):移除属性时生命周期监听:ServletRequestListener,它有两个方法,一个在出生时调用,一个在死亡时调用;
void requestInitialized(ServletRequestEvent sre):创建request时void requestDestroyed(ServletRequestEvent sre):销毁request时
属性监听:ServletRequestAttributeListener,它有三个方法,一个在添加属性时调用,一个在替换属性时调用,最后一个是在移除属性时调用。
void attributeAdded(ServletRequestAttributeEvent srae):添加属性时 void attributeReplaced(ServletRequestAttributeEvent srae):替换属性时 void attributeRemoved(ServletRequestAttributeEvent srae):移除属性时这是如何在xml中部署的形式由于listener使用的并不是很多,所以我们就不用代码进行演示了。cn.itcast.listener.MyServletContextListener
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 { } }我们来看图说一下他的执行流程:
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
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(String language, String country)我们在来看一下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; }}
好了,在来写N个配置文件就哦了。