JavaWeb的Filter过滤器应用

过滤器应用案例

分ip统计网站的访问次数

ip

count

192.168.1.111

2

192.168.1.112

59

 

统计工作需要在所有资源执行前,那么就可以放到Filter中了。

我们这个过滤器不打算做拦截操作!因为我们只是用来做统计的。

用什么东西来装载统计的数据。Map<String,Integer>

Map什么时候创建(使用ServletContextListener,在服务器启动时完成创建,并只在到ServletContext中),Map保存到哪里!(Map保存到ServletContext中!!!)

Ø  Map需要在Filter中用来保存数据

Ø  Map需要在页面使用,打印Map中的数据

 

思路分析

因为一个网站可能有多个页面,无论哪个页面被访问,都要统计访问次数,所以使用过滤器最为方便。

因为需要分IP统计,所以可以在过滤器中创建一个Map,使用IP为key,访问次数为value。当有用户访问时,获取请求的IP,如果IP在Map中存在,说明以前访问过,那么在访问次数上加1,即可;IP在Map中不存在,那么设置次数为1。

把这个Map存放到ServletContext中!

代码描述

index.jsp

  <body>

<h1>分IP统计访问次数</h1>

<table align="center" width="50%" border="1">

    <tr>

       <th>IP地址</th>

       <th>次数</th>

    </tr>

<c:forEach items="${applicationScope.ipCountMap }" var="entry">

    <tr>

       <td>${entry.key }</td>

       <td>${entry.value }</td>

    </tr>

</c:forEach>

</table>

  </body>

 

IPFilter

public class IPFilter implements Filter {

    private ServletContext context;

 

    public void init(FilterConfig fConfig) throws ServletException {

       context = fConfig.getServletContext();

       Map<String, Integer> ipCountMap = Collections

              .synchronizedMap(new LinkedHashMap<String, Integer>());

       context.setAttribute("ipCountMap", ipCountMap);

    }

 

    @SuppressWarnings("unchecked")

    public void doFilter(ServletRequest request, ServletResponse response,

           FilterChain chain) throws IOException, ServletException {

       HttpServletRequest req = (HttpServletRequest) request;

       String ip = req.getRemoteAddr();

 

       Map<String, Integer> ipCountMap = (Map<String, Integer>) context

              .getAttribute("ipCountMap");

 

       Integer count = ipCountMap.get(ip);

       if (count == null) {

           count = 1;

       } else {

           count += 1;

       }

       ipCountMap.put(ip, count);

 

       context.setAttribute("ipCountMap", ipCountMap);

       chain.doFilter(request, response);

    }

 

    public void destroy() {}

}

  <filter>

    <display-name>IPFilter</display-name>

    <filter-name>IPFilter</filter-name>

    <filter-class>cn.cloud.filter.ip.IPFilter</filter-class>

  </filter>

  <filter-mapping>

    <filter-name>IPFilter</filter-name>

    <url-pattern>/*</url-pattern>

  </filter-mapping>

 

用户权限控制

RBAC à 基于角色的权限控制

l  tb_user

l  tb_role

l  tb_userrole

l  tb_menu(增、删、改、查)

l  tb_rolemenu

需求说明

我们给出三个页面:index.jsp、user.jsp、admin.jsp。

l  index.jsp:谁都可以访问,没有限制;

l  user.jsp:只有登录用户才能访问;

l  admin.jsp:只有管理员才能访问。

 

思路分析

设计User类:username、password、grade,其中grade表示用户等级,1表示普通用户,2表示管理员用户。

当用户登录成功后,把user保存到session中。

创建LoginFilter,它有两种过滤方式:

l  如果访问的是user.jsp,查看session中是否存在user;

l  如果访问的是admin.jsp,查看session中是否存在user,并且user的grade等于2。

 

代码描述

User.java

public class User {

    private String username;

    private String password;

    private int grade;

    //get…set方法

}

 

在UserService中创建一个Map,用来保存所有用户。Map中的key中用户名,value为User对象。

UserService.java

public class UserService {

    private static Map<String,User> users = new HashMap<String,User>();

    static {

       users.put("zhangSan", new User("zhangSan", "123", 1));

       users.put("liSi", new User("liSi", "123", 2));

    }

   

    public User login(String username, String password) {

       User user = users.get(username);

       if(user == null) return null;

       return user.getPassword().equals(password) ? user : null;

    }

}

 

login.jsp

  <body>

  <h1>登录</h1>

    <p style="font-weight: 900; color: red">${msg }</p>

    <form action="<c:url value='/LoginServlet'/>" method="post">

    用户名:<input type="text" name="username"/><br/>

    密 码:<input type="password" name="password"/><br/>

    <input type="submit" value="登录"/>

    </form>

  </body>

 

index.jsp

  <body>

    <h1>主页</h1>

    <h3>${user.username }</h3>

    <hr/>

    <a href="<c:url value='/login.jsp'/>">登录</a><br/>

    <a href="<c:url value='/user/user.jsp'/>">用户页面</a><br/>

    <a href="<c:url value='/admin/admin.jsp'/>">管理员页面</a>

  </body>

 

/user/user.jsp

<body>

<h1>用户页面</h1>

<h3>${user.username }</h3>

<hr/>

</body>

 

/admin/admin.jsp

<body>

  <h1>管理员页面</h1>

  <h3>${user.username }</h3>

  <hr/>

</body>

 

LoginServlet

public class LoginServlet extends HttpServlet {

    public void doPost(HttpServletRequest request, HttpServletResponse response)

           throws ServletException, IOException {

       request.setCharacterEncoding("utf-8");

       response.setContentType("text/html;charset=utf-8");

      

       String username = request.getParameter("username");

       String password = request.getParameter("password");

       UserService userService = new UserService();

       User user = userService.login(username, password);

       if(user == null) {

           request.setAttribute("msg", "用户名或密码错误");

           request.getRequestDispatcher("/login.jsp").forward(request, response);

       } else {

           request.getSession().setAttribute("user", user);

           request.getRequestDispatcher("/index.jsp").forward(request, response);

       }

    }

}

 

LoginUserFilter.java

  <filter>

    <display-name>LoginUserFilter</display-name>

    <filter-name>LoginUserFilter</filter-name>

    <filter-class>cn.cloud.filter.LoginUserFilter</filter-class>

  </filter>

  <filter-mapping>

    <filter-name>LoginUserFilter</filter-name>

    <url-pattern>/user/*</url-pattern>

  </filter-mapping>

public class LoginUserFilter implements Filter {

    public void destroy() {}

    public void init(FilterConfig fConfig) throws ServletException {}

 

    public void doFilter(ServletRequest request, ServletResponse response,

           FilterChain chain) throws IOException, ServletException {

       response.setContentType("text/html;charset=utf-8");

       HttpServletRequest req = (HttpServletRequest) request;

       User user = (User) req.getSession().getAttribute("user");

       if(user == null) {

           response.getWriter().print("您还没有登录");

           return;

       }

       chain.doFilter(request, response);

    }

}

 

LoginAdminFilter.java

  <filter>

    <display-name>LoginAdminFilter</display-name>

    <filter-name>LoginAdminFilter</filter-name>

    <filter-class>cn.itcast.filter.LoginAdminFilter</filter-class>

  </filter>

  <filter-mapping>

    <filter-name>LoginAdminFilter</filter-name>

    <url-pattern>/admin/*</url-pattern>

  </filter-mapping>

public class LoginAdminFilter implements Filter {

    public void destroy() {}

    public void init(FilterConfig fConfig) throws ServletException {}

 

    public void doFilter(ServletRequest request, ServletResponse response,

           FilterChain chain) throws IOException, ServletException {

       response.setContentType("text/html;charset=utf-8");

       HttpServletRequest req = (HttpServletRequest) request;

       User user = (User) req.getSession().getAttribute("user");

       if(user == null) {

           response.getWriter().print("您还没有登录!");

           return;

       }

       if(user.getGrade() < 2) {

           response.getWriter().print("您的等级不够!");

           return;

       }

       chain.doFilter(request, response);

    }

}

 

禁止资源缓存

浏览器只是要缓存页面,这对我们在开发时测试很不方便,所以我们可以过滤所有资源,然后添加去除所有缓存!

public class NoCacheFilter extends HttpFilter {

    public void doFilter(HttpServletRequest request,

           HttpServletResponse response, FilterChain chain)

           throws IOException, ServletException {

       response.setHeader("cache-control", "no-cache");

       response.setHeader("pragma", "no-cache");

       response.setHeader("expires", "0");

       chain.doFilter(request, response);

    }

}

POST和GET中文编码

servlet:

l  POST:request.setCharacterEncoding(“utf-8”);

l  GET:

Ø  String username = request.getParameter(“username”);

Ø  username = new String(username.getBytes(“ISO-8859-1”), “utf-8”);

需求说明

乱码问题:

l  获取请求参数中的乱码问题;

Ø  POST请求:request.setCharacterEncoding(“utf-8”);

Ø  GET请求:newString(request.getParameter(“xxx”).getBytes(“iso-8859-1”), “utf-8”);

l  响应的乱码问题:response.setContextType(“text/html;charset=utf-8”)。

思路分析

全站乱码问题的难点:处理GET请求参数的问题。

public class EncodingFilter extends HttpFilter {

    public void doFilter(HttpServletRequest request,

           HttpServletResponse response, FilterChain chain)

           throws IOException, ServletException {

       String charset = this.getInitParameter("charset");

       if(charset == null || charset.isEmpty()) {

           charset = "UTF-8";

       }

       request.setCharacterEncoding(charset);

       response.setContentType("text/html;charset=" + charset);

       chain.doFilter(request, response);

    }

}

 

如果是POST请求,当执行目标Servlet时,Servlet中调用request.getParameter()方法时,就会根据request.setCharacterEncoding()设置的编码来转码!这说明在过滤器中调用request.setCharacterEncoding()方法会影响在目标Servlet中的request.getParameter()方法的行为!

但是如果GET请求, request只有getParameter(),而没有setParameter()方法

下面是三种对a对象进行增强的手段:

代码描述

EncodingRequest

public class EncodingRequest extends HttpServletRequestWrapper {

    private String charset;

    public EncodingRequest(HttpServletRequest request, String charset) {

       super(request);

       this.charset = charset;

    }

    public String getParameter(String name) {

       HttpServletRequest request = (HttpServletRequest) getRequest();

      

       String method = request.getMethod();

       if(method.equalsIgnoreCase("post")) {

           try {

              request.setCharacterEncoding(charset);

           } catch (UnsupportedEncodingException e) {}

       } else if(method.equalsIgnoreCase("get")) {

           String value = request.getParameter(name);

           try {

              value = new String(name.getBytes("ISO-8859-1"), charset);

           } catch (UnsupportedEncodingException e) {

           }

           return value;

       }

       return request.getParameter(name);

    }

}

 

EncodingFilter

public class EncodingFilter extends HttpFilter {

    public void doFilter(HttpServletRequest request,

           HttpServletResponse response, FilterChain chain)

           throws IOException, ServletException {

       String charset = this.getInitParameter("charset");

       if(charset == null || charset.isEmpty()) {

           charset = "UTF-8";

       }

       response.setCharacterEncoding(charset);

       response.setContentType("text/html;charset=" + charset);

       EncodingRequest res = new EncodingRequest(request, charset);

       chain.doFilter(res, response);

    }

}

 

web.xml

  <filter>

    <filter-name>EncodingFilter</filter-name>

    <filter-class>cn.itcast.filter.EncodingFilter</filter-class>

    <init-param>

        <param-name>charset</param-name>

        <param-value>UTF-8</param-value>

    </init-param>

  </filter>

  <filter-mapping>

    <filter-name>EncodingFilter</filter-name>

    <url-pattern>/*</url-pattern>

  </filter-mapping>

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值