JavaWeb的Filter过滤器应用

来源:互联网 发布:剑三明教成女捏脸数据 编辑:程序博客网 时间:2024/06/05 19:48

过滤器应用案例

分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>

<tablealign="center"width="50%"border="1">

    <tr>

       <th>IP地址</th>

       <th>次数</th>

    </tr>

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

    <tr>

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

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

    </tr>

</c:forEach>

</table>

  </body>

 

IPFilter

publicclass IPFilter implements Filter {

    private ServletContextcontext;

 

    publicvoid init(FilterConfig fConfig) throws ServletException {

       context = fConfig.getServletContext();

       Map<String, Integer> ipCountMap = Collections

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

       context.setAttribute("ipCountMap", ipCountMap);

    }

 

    @SuppressWarnings("unchecked")

    publicvoid 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);

    }

 

    publicvoid 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

publicclass User {

    private Stringusername;

    private Stringpassword;

    privateint grade;

    //get…set方法

}

 

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

UserService.java

publicclass UserService {

    privatestatic 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) returnnull;

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

    }

}

 

login.jsp

  <body>

  <h1>登录</h1>

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

    <formaction="<c:urlvalue='/LoginServlet'/>"method="post">

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

    密 码:<inputtype="password"name="password"/><br/>

    <inputtype="submit"value="登录"/>

    </form>

  </body>

 

index.jsp

  <body>

    <h1>主页</h1>

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

    <hr/>

    <ahref="<c:urlvalue='/login.jsp'/>">登录</a><br/>

    <ahref="<c:urlvalue='/user/user.jsp'/>">用户页面</a><br/>

    <ahref="<c:urlvalue='/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

publicclass LoginServlet extends HttpServlet {

    publicvoid 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>

publicclass LoginUserFilter implements Filter {

    publicvoid destroy() {}

    publicvoid init(FilterConfig fConfig) throws ServletException {}

 

    publicvoid 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>

publicclass LoginAdminFilter implements Filter {

    publicvoid destroy() {}

    publicvoid init(FilterConfig fConfig) throws ServletException {}

 

    publicvoid 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);

    }

}

 

禁止资源缓存

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

publicclass NoCacheFilter extends HttpFilter {

    publicvoid 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请求参数的问题。

publicclass EncodingFilter extends HttpFilter {

    publicvoid 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

publicclass EncodingRequest extends HttpServletRequestWrapper {

    private Stringcharset;

    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) {}

       } elseif(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

publicclass EncodingFilter extends HttpFilter {

    publicvoid 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 0
原创粉丝点击