1. 过滤器
过滤器常作用于servlet,可以在servlet执行service()前后,进行一次过滤,过滤之后的操作内容自己定义,主要目的就是进行统一处理。
过滤基础搭建
新建MyFilter.java,并且实现Filter接口,实现里面的所有抽象方法
public class MyFiler implements Filter{
public void doFilter(ServletRequest req, ServletResponse resp,
FilterChain chain) throws IOException, ServletException {
System.out.println("前置过滤:service()方法执行之前...");
chain.doFilter(request, response);// 放行,去执行目标service()方法
System.out.println("后置过滤:service()方法执行之后...");
}
public void init(FilterConfig arg0) throws ServletException {
System.out.println("MyFilter被创建...");
}
public void destroy() {
System.out.println("MyFilter被销毁...");
}
}
在web.xml中部署这个过滤器,部署过程和servlet部署过程很相似。
<filter>
<filter-name>MyFilter</filter-name>
<filter-class>com.xhh.filter.MyFiler</filter-class>
</filter>
<filter-mapping>
<filter-name>MyFilter</filter-name>
<url-pattern>/servlet/*</url-pattern>//<url-pattern>中规定了什么样的路径,会被过滤器拦截。
</filter-mapping>
过滤案例:统一转码
public class MyFilter implements Filter{
public void doFilter(ServletRequest req, ServletResponse resp,
FilterChain chain) throws IOException, ServletException {
// 通过强转得到请求HttpServletRequest和HttpServletResponse对象;
HttpServletRequest request=(HttpServletRequest)req;
HttpServletResponse response=(HttpServletResponse)resp;
// 拦截响应,统一转码;
request.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=utf-8");
chain.doFilter(request,response);// 放行
}
public void init(FilterConfig arg0) throws ServletException {
System.out.println("MyFilter被创建...");
}
public void destroy() {
System.out.println("MyFilter被销毁...");
}
}
过滤案例:非法登录
如果用户直接地址栏键入"servlet/*"这样的路径,不可以让其直接进入程序,这属于非法入侵,那么此时就需要对请求进行过滤,非法的不允许登录,当然,登录的servlet必须只能放行。
public void doFilter(ServletRequest req, ServletResponse resp,
FilterChain chain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest)req;
HttpServletResponse response = (HttpServletResponse)resp;
request.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=utf-8");
String uri = request.getRequestURI();// 得到请求中的url
if(uri.indexOf("/servlet/LoginServlet") > 0){// 路径中存在/servlet/LoginServlet
chain.doFilter(request, response);// 直接通过,否则登录模块会崩溃
}else{// 判断用户当前是否已经是登录状态
Object userMap = request.getSession().getAttribute("userMap");
if(userMap != null){// 用户当前已经是登录状态
chain.doFilter(request, response);//放行
}else{// 没有登录,转到失败页
request.getRequestDispatcher("/jsp/login/login.jsp").forward(request, response);
}
}
}
**
2. 监听器
**
2.1 监听基础搭建
新建MyListener.java,并且实现ServletContextListener接口,实现里面的所有抽象方法
public class MyListener implements ServletContextListener{
public void contextDestroyed(ServletContextEvent event) {
System.out.println("MyListener销毁:服务器关闭时做的操作...");
}
public void contextInitialized(ServletContextEvent event) {
System.out.println("MyListener启动:服务器开启时做的操作...");
}
}
在web.xml中部署这个监听器
<listener>
<listener-class>com.xhh.listener.MyListener</listener-class>
</listener>
tips:servlet3可以使用@WebListener注解进行搭建监听器。
2.2 监听案例:防止统一ID同时在线
MyListener.java
public class MyListener implements ServletContextListener{
public void contextDestroyed(ServletContextEvent event) {
event.getServletContext().removeAttribute("online_users");
}
public void contextInitialized(ServletContextEvent event) {
// 把一个空list存放到application中,起名为online_users
// 只要服务器不关闭,就一直存在
event.getServletContext().setAttribute("online_users", new ArrayList<String>());
}
}
LoginServlet.java
protected void service(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String loginname = request.getParameter("loginname");
ServletContext application = request.getSession().getServletContext();
List<String> online_users = (List<String>)application.getAttribute("online_users");
boolean flag = false;// false代表不存在(允许登录)、true代表已存在(禁止登录)
if(online_users.isEmpty()){// online_users为空,允许登录
online_users.add(loginname);// 帐号添加到online_users中
application.setAttribute("online_users", online_users);// 更新online_users
request.getSession().setAttribute("loginname",loginname);
request.getRequestDispatcher("/main.jsp").forward(request, response);
}else{// online_users不为空,继续判断
for(String e : online_users){
if(e.equals(loginname)){// 在online_users中搜寻loginid
flag = true;// 如果已存在,禁止登录
break;
}
}
if(flag){// 已存在,禁止登录
request.setAttribute("msg","当前用户已经存在,不要重复登录!");
request.getRequestDispatcher("/middle.jsp").forward(request, response);
}else{// 未存在,允许登录
online_users.add(loginname);// 帐号添加到online_users中
application.setAttribute("online_users", online_users);// 更新online_users
request.getSession().setAttribute("loginname",loginname);
request.getRequestDispatcher("/main.jsp").forward(request, response);
}
}
}
2.3 监听案例:退出服务器登录
login.jsp
<a href="<%=path%>/servlet/ExitServlet">退出登录</a>
ExitServlet.java
public class ExitServlet extends HttpServlet{
protected void service(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 获取到当前登录的loginname
String loginname = (String)request.getSession().getAttribute("loginname");
// 获取当前在线的list
ServletContext application = request.getSession().getServletContext();
List<String> online_users = (List<String>)application.getAttribute("online_users");
// 将Logind从list中移除
online_users.remove(loginname);
request.getRequestDispatcher("/index.jsp").forward(request, response);
}
}