一、过滤器
1.介绍
Filter 的完整流程: Filter 对用户请求进行预处理,接着将请求交给 Servlet 进行处理并生成响应,最后 Filter 再 对服务器响应进行后处理。在一个 web 应用中,可以开发编写多个Filter,这些 Filter 组合 起来称之为一个 Filter 链。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wsJrVIMB-1582630865316)(C:\Users\Hello Word\AppData\Roaming\Typora\typora-user-images\1582629150766.png)]
2.实现
init(), doFilter(), destroy()分别在相应的时机执行。后期观察生命周期。
Filter 的实现只需要两步:
Step1: 编写 java 类实现 Filter 接口,并实现其 doFilter 方法。
Step2: 在 web.xml 文件中对编写的 filter 类进行注册,并设置它所能拦截的资源
public class Filter01 implements Filter { /** * 初始化 */ @Override public void init(FilterConfig filterConfig) throws ServletException { System.out.println("Filter01 init..."); } /** * 处理请求的拦截方法 */ @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { // 处理请求 System.out.println("Filter01 处理请求..."); // 放行资源 chain.doFilter(request, response); // 处理响应 System.out.println("Filter01 处理响应..."); } /** * 销毁方法 */ @Override public void destroy() { System.out.println("Filter01 destroy..."); } } //web.xml配置 <filter> <filter-name>Filter01</filter-name> <!-- 给服务器看的,与filter-mapping标签中filter-name保持一致 --> <filter-class>com.shsxt.filter.Filter01</filter-class> <!-- 类的全路径 --> </filter> <filter-mapping> <filter-name>Filter01</filter-name> <!-- 给服务器看的,与filter标签中filter-name保持一致 --> <url-pattern>/Servlet01</url-pattern> <!-- 给浏览器看的,需要拦截的资源路径 --> <!-- <servlet-name>Servlet01</servlet-name> --> <!-- 想要拦截的servlet名称,与servlet标签的servlet-name一致 --> </filter-mapping>
3.过滤器的执行顺序
过滤器
拦截请求到达指定资源之前的请求数据
拦截响应到达客户端之前的响应数据
放行资源(chain.doFilter(request,response))
过滤器链
多个过滤器同时执行
执行顺序:web.xml配置文件中,先配置的先执行
拦截顺序:按照指定顺序拦截,按照相反顺序响应
请求:(1 -> 2 -> 3 )
响应:(3 -> 2 -> 1 )
4.过滤器实例
/** * 非法访问拦截 * 当用户访问登录状态才能访问的资源时,如果用户未登录,会被拦截到登录页面 * * 拦截的资源: 拦截所有资源 /* 需要放行的资源: 1、指定页面,放行 无需登录即可访问的页面 (例如:登录页面、注册页面等) 2、静态资源,放行 js文件、css文件及图片(存放在statics目录下的资源) 3、指定操作,放行 无需登录即可执行的操作 (登录操作、注册操作等) 4、登录状态,放行 判断session作用域中是否存在用户数据(有数据=登录状态;无数据=非登录状态) 当用户未登录时访问资源,拦截跳转到登录页面 */ public class LoginAccessFilter implements Filter { public LoginAccessFilter() { } public void destroy() { } public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain chain) throws IOException, ServletException { // 基于HTTP HttpServletRequest request = (HttpServletRequest)arg0; HttpServletResponse response = (HttpServletResponse)arg1; // 获取当前访问的资源路径 String path = request.getRequestURI(); // 从端口号后开始(不包含端口),到"?"前面 /站点名/资源路径 System.out.println(path); // 1、指定页面,放行 无需登录即可访问的页面 (例如:登录页面、注册页面等) if (path.contains("/login.html")) { // 放行资源 chain.doFilter(request, response); return; } // 2、静态资源,放行 js文件、css文件及图片(存放在statics目录下的资源) if (path.contains("/statics")) { // 放行资源 chain.doFilter(request, response); return; } // 3、指定操作,放行 无需登录即可执行的操作 (登录操作、注册操作等) if (path.indexOf("/loginServlet") != -1) { // 放行资源 chain.doFilter(request, response); return; } // 4、登录状态,放行 判断session作用域中是否存在用户数据(有数据=登录状态;无数据=非登录状态) String user = (String) request.getSession().getAttribute("user"); if (user != null && !"".equals(user)) { // 放行资源 chain.doFilter(request, response); return; } // chain.doFilter(request, response); // 拦截请求跳转到登录页面 response.sendRedirect("login.html"); } public void init(FilterConfig fConfig) throws ServletException { } } /** * 用户登录 */ public class LoginServlet extends HttpServlet { private static final long serialVersionUID = 1L; protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { System.out.println("用户登录..."); // 接收参数 System.out.println(request.getParameter("uname")); // 模拟用户在登录状态 request.getSession().setAttribute("user", "zhangsan"); // 登录成功 response.sendRedirect("index.html"); } }
二、监听器
1.介绍
web 监听器是一种Servlet 中的特殊的类,ServletContext,HttpSession,ServletRequest 的创建和销毁;变量的创建、销毁和修改等。
2.实现
public class Listener01 implements HttpSessionListener,HttpSessionAttributeListener { /** * session的创建 */ @Override public void sessionCreated(HttpSessionEvent se) { System.out.println("Session Create..."); } /** * session的销毁 */ @Override public void sessionDestroyed(HttpSessionEvent se) { System.out.println("Session Destroy..."); } /** * 设置域对象 */ @Override public void attributeAdded(HttpSessionBindingEvent se) { System.out.println("attributeAdded..."); } /** * 删除域对象 */ @Override public void attributeRemoved(HttpSessionBindingEvent se) { System.out.println("attributeRemoved..."); } /** * 修改域对象 */ @Override public void attributeReplaced(HttpSessionBindingEvent se) { System.out.println("attributeReplaced..."); } } //servlet protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 创建session对象 HttpSession session = request.getSession(); // 设置域对象 session.setAttribute("uname", "zhangsan"); // 修改域对象 session.setAttribute("uname", "lisi"); // 删除域对象 session.removeAttribute("uname"); // session的销毁 session.invalidate(); }
3.监听器案例
/** * 在线人数统计 * 当有新的session对象被创建,则在线人数+1; * 有session对象被销毁,在线人数-1; * @author Lisa Li * */ public class OnlineListener implements HttpSessionListener { // 默认在线人数 private Integer onlineNumber = 0; /** * 当有新的session对象被创建,则在线人数+1; */ @Override public void sessionCreated(HttpSessionEvent se) { // 人数+1 onlineNumber++; // 将人数存到session作用域中 //se.getSession().setAttribute("onlineNumber", onlineNumber); // 将人数存到application作用域中 se.getSession().getServletContext().setAttribute("onlineNumber", onlineNumber); } /** * 有session对象被销毁,在线人数-1; */ @Override public void sessionDestroyed(HttpSessionEvent se) { // 人数-1 onlineNumber--; // 将人数存到session作用域中 // se.getSession().setAttribute("onlineNumber", onlineNumber); // 将人数存到application作用域中 se.getSession().getServletContext().setAttribute("onlineNumber", onlineNumber); } }
/** * 在线人数统计 */ public class OnlineServlet extends HttpServlet { private static final long serialVersionUID = 1L; //引入日志 //private logger logger=LoggerFactory.getLogger(OnlineServlet.class); protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //得到参数 String key=request.getParameter("key"); //判断是否为空 if(key==null || "".equals(key)){ //创建session对象 HttpSession session=request.getSession(); //获取session作用域中人数application Integer onlineNumber=(Integer) session.getServletContext().getAttribute("onlineNumber"); //当前访问用户的ip及内容 String ip=request.getRemoteAddr(); String content=request.getParameter("content"); System.out.println(ip); System.out.println(content); //输出 response.setContentType("text/html;charset=UTF-8"); response.getWriter().write("<h2>在线人数:"+onlineNumber+"</h2><h4><a href='Servlet01?key=logout'>退出</a><h4>"); }else{ //传递了参数,表示要做用户推出操作 request.getSession().invalidate(); } } }
三、Servlet3.0注释
1.@WebServlet
@WebServlet 注解将一个继承于javax.servlet.http.HttpServlet 的类标注为可以处理用户请求的 Servlet。
//@WebServlet(value="/Servlet01") //@WebServlet(name="Servlet01",value="/Servlet01") //@WebServlet(value={"/Servlet01","/Servlet001"}) //@WebServlet(urlPatterns="/s01") //@WebServlet(urlPatterns={"/Servlet01","/Servlet001"}) @WebServlet("/s01") public class Servlet01 extends HttpServlet { private static final long serialVersionUID = 1L; protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { System.out.println("Servlet..."); } }
2.@WebFilter
使用注解时:过滤器链按照类名的字母排序(大部分情况)
@WebFilter("/*") public class Filter01 implements Filter { /** * Default constructor. */ public Filter01() { // TODO Auto-generated constructor stub } /** * @see Filter#destroy() */ public void destroy() { // TODO Auto-generated method stub } /** * @see Filter#doFilter(ServletRequest, ServletResponse, FilterChain) */ public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { System.out.println("Filter01..."); chain.doFilter(request, response); } /** * @see Filter#init(FilterConfig) */ public void init(FilterConfig fConfig) throws ServletException { // TODO Auto-generated method stub } }
3.@WebListener
Servlet3.0 提供@WebListener 注解将一个实现了特定监听器接口的类定义为监听
器。将实现了 ServletContextListener 接口的 MyServletContextListener 标注为监听器。
@WebListener public class Listener01 implements HttpSessionListener { /** * Default constructor. */ public Listener01() { // TODO Auto-generated constructor stub } /** * @see HttpSessionListener#sessionCreated(HttpSessionEvent) */ public void sessionCreated(HttpSessionEvent se) { // TODO Auto-generated method stub } /** * @see HttpSessionListener#sessionDestroyed(HttpSessionEvent) */ public void sessionDestroyed(HttpSessionEvent se) { // TODO Auto-generated method stub } }
4.@MultipartConfig
文件上传
@MultipartConfig 一定要加注解!!!!!
如果前台的表单类型设置为enctype=” multipart/form-data”,后台servlet一定要加注解,否则所有的参数都为null。
使用注解@MultipartConfig 将一个 Servlet 标识为支持文件上传。 Servlet3.0 将 multipart/form-data 的 POST 请求封装成 Part,通过Part 对上传的文件进行操作。
@MultipartConfig @WebServlet("/uploadServlet") public class UploadServlet extends HttpServlet { private static final long serialVersionUID = 1L; protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 获取参数 String uname = request.getParameter("uname"); System.out.println(uname); // 得到要上传的文件对象 getPart(name):name代表的是表单元素file文件域的name属性值 Part part = request.getPart("myfile"); // 得到文件存放的路径 String path = request.getServletContext().getRealPath("/"); // 得到上传的文件名 String fileName = part.getSubmittedFileName(); // 上传 part.write(path +"/"+fileName); } }
<body> <!-- 表单实现文件上传 第一步:设置表单类型 enctype="multipart/form-data" (文件上传表单) 第二步:表单提交类型 method="POST" 第三步:文件域file元素设置name属性值 --> <form action="uploadServlet" method="POST" enctype="multipart/form-data" > 姓名:<input type="text" name="uname" /> <br> 文件:<input type="file" name="myfile" /> <br> <button>提交</button> </form> </body>
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/121470.html