`
zzc1684
  • 浏览: 1231159 次
  • 性别: Icon_minigender_1
  • 来自: 广州
文章分类
社区版块
存档分类
最新评论

对请求和相应的数据进行替换的Filter

阅读更多
留言板程序可能遇到的问题:
     输入HTML代码 破坏了留言板的正常显示 和安全隐患
     输入了不雅的字句
 
不对现有的代码进行修改  可以考虑加入过滤器 过滤器可以截取到请求和响应对象 但是无法直接使用这两个对象对他们的数据进行替换 但是我们可以利用请求和响应的包装类来间接改变请求和响应的信息
 
利用过滤器和包装类就可以解决留言板程序中存在在的这两个问题
第一个问题   编写一个HttpServletRequestWrapper类的子类 然后重写getParameter()方法 在这个方法中 对请求参数的值进行过滤 将特殊字符转换成对应的实体引用或字符引用
第二个问题   编写一个HttpServletResponseWrapper类的子类 响应的内容是通过字符(PrintWrite)或者字节(ServletOutputStream)输出流对象向客户端输出的 而字符和字节输出流对象则是通过HttpServletResponse.getWriter()和 HttpServletResponse.getOutputStream()方法得到的 正常情况下 响应的内容将被容器直接发送到客户端 要想得到响应的内容 就要替换默认的输出流对象 并且 新的输出流对象应该是内存输出流对象 也就是我们在调用输出流对象的write()方法时 数据被写到内存的缓冲区中 我们可以使用java.io包中的ByteArrayOutputStream类 让数据写到字节数组中 同时重写HttpServletResponse类的getWrite()和getOutputStream()方法 返回构建在ByteArrayOutputStream之上的PrintWriter对象和ServletOutputStream对象
 
 
实例开发步骤
1  MyRequestWrapper.java
从HttpServletRequestWrapper类继承 并重写getParameter()方法 对请求参数进行过滤 将特殊字符转换成对应的实体引用或者字符引用
  1. package filter;
  2. import javax.servlet.http.HttpServletRequest;
  3. import javax.servlet.http.HttpServletRequestWrapper;
  4. public final class MyRequestWrapper extends HttpServletRequestWrapper
  5. {
  6.     public MyRequestWrapper(HttpServletRequest request)
  7.     {
  8.         super(request);
  9.     }
  10.     
  11.     /**
  12.      * 覆盖基类的getParameter()方法,对请求参数的值进行过滤。
  13.      */
  14.     public java.lang.String getParameter(java.lang.String name)
  15.     {
  16.         String value=super.getParameter(name);
  17.         if(null!=value)
  18.             return toHtml(value.trim());
  19.         else
  20.             return null;
  21.     }
  22.     
  23.     /**
  24.      * 将特殊字符转换为对应的实体引用或字符引用。
  25.      */
  26.     private String toHtml(String str)
  27.     {
  28.         if(str==null)
  29.             return null;
  30.         StringBuffer sb = new StringBuffer();
  31.         int len = str.length();
  32.         for (int i = 0; i < len; i++)
  33.         {
  34.             char c = str.charAt(i);
  35.             switch(c)
  36.             {
  37.             case ' ':
  38.                 sb.append("&nbsp;");
  39.                 break;
  40.             case '\n':
  41.                 sb.append("<br>");
  42.                break;
  43.             case '\r':
  44.                break;
  45.             case '\'':
  46.                 sb.append("&#39;");
  47.                 break;
  48.             case '<':
  49.                 sb.append("&lt;");
  50.                 break;
  51.             case '>':
  52.                 sb.append("&gt;");
  53.                 break;
  54.             case '&':
  55.                 sb.append("&amp;");
  56.                 break;
  57.             case '"':
  58.                 sb.append("&#34;");
  59.                 break;
  60.             case '\\':
  61.                 sb.append("&#92;");
  62.                 break;
  63.             default:
  64.                 sb.append(c);
  65.             }
  66.         }
  67.         return sb.toString();
  68.     }
  69. }

 

 

2   ByteArrayServletOutputStream.java

这个类从ServletOutputStream类继承 该类的对象用于替换HttpServletResponse.getOutputStream()方法返回的ServletOutputStream对象 其内部使用java.io.ByteArrayOutputStream的write(int b)方法实现ServletOutputStream类的write(int b)方法

  1. package filter;
  2. import java.io.ByteArrayOutputStream;
  3. import java.io.IOException;
  4. import javax.servlet.ServletOutputStream;
  5. public class ByteArrayServletOutputStream extends ServletOutputStream
  6. {
  7.     ByteArrayOutputStream baos;
  8.     
  9.     ByteArrayServletOutputStream(ByteArrayOutputStream baos)
  10.     {
  11.         this.baos = baos;
  12.     }
  13.     public void write(int data) throws IOException
  14.     {
  15.         baos.write(data);
  16.     }
  17. }

 

3  MyResponseWrapper.java

MyResponseWrapper类从HttpServletResponseWrapper类继承 并重写了getWriter() 和getOutputStream()方法 用构建在ByteArrayOutputStream之上的PrintWriter对象和ServletOutputStream对象替换Web容器创建 的PrintWriter和ServletOutputStream对象

  1. package filter;
  2. import java.io.*;
  3. import javax.servlet.*;
  4. import javax.servlet.http.*;
  5. public class MyResponseWrapper extends HttpServletResponseWrapper
  6. {
  7.     private ByteArrayOutputStream baos;
  8.     private ByteArrayServletOutputStream basos;
  9.     private PrintWriter pw;
  10.     
  11.     public MyResponseWrapper(HttpServletResponse response)
  12.     {
  13.         super(response);
  14.         //创建ByteArrayOutputStream对象。
  15.         baos=new ByteArrayOutputStream();
  16.         //用ByteArrayOutputStream对象作为参数,
  17.         //构造ByteArrayServletOutputStream对象。
  18.         basos=new ByteArrayServletOutputStream(baos);
  19.         //用ByteArrayOutputStream对象作为参数,
  20.         //构造PrintWriter对象。
  21.         pw=new PrintWriter(baos);
  22.     }
  23.     
  24.     public PrintWriter getWriter()
  25.     {
  26.         return pw;
  27.     }
  28.     
  29.     public ServletOutputStream getOutputStream()
  30.     {
  31.         return basos;
  32.     }
  33.     
  34.     /**
  35.      * 以字节数组的形式返回输出流缓冲区中的内容。
  36.      */
  37.     public byte[] toByteArray()
  38.     {
  39.         return baos.toByteArray();
  40.     }
  41. }

4  GuestbookFilter.java

这个是过滤器类 利用MyRequestWrapper和MyPesponseWrapper类来替换请求中的特殊中的特殊字符和响应中的不雅字句不雅字句与替换的内容是 以Java属性文件的格式保存到一个文件中 文件的路径名作为过滤器类的初始化参数在web.xml文件中进行配置。

  1. package filter;
  2. import java.io.*;
  3. import java.util.*;
  4. import javax.servlet.*;
  5. import javax.servlet.http.*;
  6. public class GuestbookFilter implements Filter
  7. {
  8.     private static final String WORD_FILE="word_file";
  9.     
  10.     HashMap<String,String> hm=new HashMap<String,String>();
  11.     
  12.     /**
  13.      * 在init()方法中,读取保存了不雅字句和替换内容的文件,
  14.      * 并以不雅字句作为key,替换内容作为value,保存到Hashmap对象中。
  15.      */
  16.     public void init(FilterConfig filterConfig) throws ServletException
  17.     {
  18.         String configPath=filterConfig.getInitParameter(WORD_FILE);
  19.         
  20.         ServletContext sc=filterConfig.getServletContext();
  21.         String filePath=sc.getRealPath(configPath);
  22.         
  23.         try
  24.         {
  25.             FileReader fr=new FileReader(filePath);
  26.             BufferedReader br=new BufferedReader(fr);
  27.             
  28.             String line;
  29.             while(null!=(line=br.readLine()))
  30.             {
  31.                 String[] strTemp=line.split("=");
  32.                 hm.put(strTemp[0],strTemp[1]);
  33.             }
  34.         }
  35.         catch(IOException ie)
  36.         {
  37.             throw new ServletException("读取过滤文件信息出错!");
  38.         }
  39.     }
  40.    
  41.     public void doFilter(ServletRequest request,
  42.                          ServletResponse response,
  43.                          FilterChain chain)
  44.                   throws IOException, ServletException
  45.     {
  46.         
  47.         HttpServletRequest httpReq=(HttpServletRequest)request;
  48.         HttpServletResponse httpResp=(HttpServletResponse)response;
  49.         
  50.         //得到请求和响应对象的封装类对象。
  51.         MyRequestWrapper reqWrapper=new MyRequestWrapper(httpReq);
  52.         MyResponseWrapper respWrapper=new MyResponseWrapper(httpResp);
  53.                 
  54.         chain.doFilter(reqWrapper,respWrapper);
  55.         
  56.         String content = new String(respWrapper.toByteArray());
  57.         String result=replaceText(content);
  58.         httpResp.setContentType("text/html;charset=GB2312");
  59.         PrintWriter out = httpResp.getWriter();
  60.         out.println(result);
  61.         out.close();
  62.     }
  63.     
  64.     /**
  65.      * 对内容中的不雅字句进行过滤。
  66.      */
  67.     public String replaceText(String content) throws IOException
  68.     {
  69.         StringBuffer sb=new StringBuffer(content);
  70.         Set<String> keys=hm.keySet();
  71.         Iterator<String> it=keys.iterator();
  72.         while(it.hasNext())
  73.         {
  74.             String key=(String)it.next();
  75.             int index=sb.indexOf(key);
  76.             while(-1!=index)
  77.             {
  78.                 sb.replace(index,index+key.length(),(String)hm.get(key));
  79.                 index=sb.indexOf(key);
  80.             }
  81.         }
  82.         return sb.toString();
  83.         
  84.     }
  85.     public void destroy(){}
  86. }

 

5  准备留言板程序

say.html

  1. <center>
  2.     <form action="process.jsp" method="post">
  3.     <table bgcolor="#B3B3FF">
  4.       <caption>欢迎访问留言板</caption>
  5.             <tr>
  6.                 <td>用户名:</td>
  7.                 <td><input type="text" name="name"></td>
  8.             </tr>
  9.             <tr>
  10.                 <td>主题:</td>
  11.                 <td><input type="text" name="title" size="40"></td>
  12.             </tr>
  13.             <tr>
  14.                 <td>内容:</td>
  15.                 <td>
  16.                     <textarea name="content" rows="10" cols="40"></textarea>
  17.                 </td>
  18.             </tr>
  19.             <tr>
  20.                 <td><input type="submit" value="提交"></td>
  21.                 <td><input type="reset" value="重填"></td>
  22.             </tr>
  23.         </table>
  24.     </form>
  25. </center>

process.jsp

 

  1. <%@ page contentType="text/html;charset=gb2312" %>
  2. <%@ page import="java.sql.*,javax.sql.*,javax.naming.*" %>
  3. <%
  4.     request.setCharacterEncoding("GBK");
  5.     
  6.     String name=request.getParameter("name");
  7.     String title=request.getParameter("title");
  8.     String content=request.getParameter("content");
  9.     
  10.     if(null==name || null==title || null==content)
  11.     {
  12.      response.sendRedirect("index.jsp");
  13.         return;
  14.     }
  15.     
  16.     if(name.equals("") || title.equals(""))
  17.     {
  18.         response.sendRedirect("say.html");
  19.         return;
  20.     }
  21.     
  22.     String fromIP=request.getRemoteAddr();
  23.     
  24.     Context ctx=new InitialContext();
  25.     DataSource ds=(DataSource)ctx.lookup("java:comp/env/jdbc/bookstore");
  26.     Connection conn=ds.getConnection();
  27.     
  28.     PreparedStatement pstmt=conn.prepareStatement(
  29.         "insert into guestbook(gst_user,gst_title,gst_content,gst_ip) values(?,?,?,?)");
  30.     pstmt.setString(1,name);
  31.     pstmt.setString(2,title);
  32.     pstmt.setString(3,content);
  33.     pstmt.setString(4,fromIP);
  34.     
  35.     pstmt.executeUpdate();
  36.     pstmt.close();
  37.     conn.close();
  38.     response.sendRedirect("index.jsp");
  39. %>

 

index.jsp

  1. <%@ page contentType="text/html;charset=gb2312" %>
  2. <%@ page import="java.sql.*,javax.sql.*,javax.naming.*" %>
  3. <html>
  4.     <head>
  5.         <title>网上书店留言板</title>
  6.     </head>
  7.     <body>
  8.         <a href="say.html">我要留言</a><br>
  9.         <%
  10.             Context ctx=new InitialContext();
  11.             DataSource ds=(DataSource)ctx.lookup("java:comp/env/jdbc/bookstore");
  12.             Connection conn=ds.getConnection();
  13.             
  14.             //创建可滚动的结果集。
  15.             Statement stmt=conn.createStatement(
  16.                 ResultSet.TYPE_SCROLL_INSENSITIVE,
  17.                 ResultSet.CONCUR_READ_ONLY);
  18.             ResultSet rs=stmt.executeQuery("select * from guestbook order by gst_time desc");
  19.             
  20.             //移动游标到结果集的最后一行。
  21.             rs.last();
  22.             
  23.             //得到当前行的行数,也就得到了数据库中留言的总数。
  24.             int rowCount=rs.getRow();
  25.             if(rowCount==0)
  26.             {
  27.                 out.println("当前没有任何留言!");
  28.                 out.flush();
  29.                 return;
  30.             }
  31.             else
  32.          {
  33.      %>
  34.      共有<strong><%=rowCount%></strong>条留言&nbsp;&nbsp;&nbsp;&nbsp;
  35.      <%
  36.      }
  37.             
  38.             String strCurPage=request.getParameter("page");
  39.             
  40.             //表示当前的页数。
  41.             int curPage;
  42.             
  43.             if(strCurPage==null)
  44.                 curPage=1;
  45.             else
  46.                 curPage=Integer.parseInt(strCurPage);
  47.             
  48.             //定义每页显示的留言数。
  49.             int countPerPage=5;
  50.             
  51.             //计算所有留言显示需要的总页数。
  52.             int pageCount=(rowCount+countPerPage-1)/countPerPage;
  53.             
  54.             //移动游标到结果集中指定的行。如果显示的是第一页,curPage=1,
  55.             //游标移动到第1行。
  56.             rs.absolute((curPage-1)*countPerPage+1);
  57.             
  58.          //如果是第1页,则显示不带链接的文字,如果不是第1页,
  59.          //则给用户提供跳转到第一页和上一页的链接。
  60.             if(curPage==1)
  61.             {    
  62.         %>
  63.          第一页&nbsp;&nbsp;&nbsp;&nbsp;
  64.          上一页&nbsp;&nbsp;&nbsp;&nbsp;
  65.         <%
  66.             }
  67.             else
  68.             {
  69.         %>
  70.          <a href="index.jsp?page=<%=1%>">第一页</a>
  71.          &nbsp;&nbsp;&nbsp;&nbsp;
  72.          <a href="index.jsp?page=<%=curPage-1%>">上一页</a>
  73.          &nbsp;&nbsp;&nbsp;&nbsp;
  74.         <%
  75.             }
  76.             //如果当前页是最后一页,则显示不带链接的文字,如果不是最后一页,
  77.             //则给用户提供跳转到最后一页和下一页的链接。
  78.             if(curPage==pageCount)
  79.             {
  80.             
  81.         %>
  82.          下一页&nbsp;&nbsp;&nbsp;&nbsp;
  83.          最后页&nbsp;&nbsp;&nbsp;&nbsp;
  84.         <%
  85.             }
  86.             else
  87.             {
  88.         %>
  89.          <a href="index.jsp?page=<%=curPage+1%>">下一页</a>
  90.          &nbsp;&nbsp;&nbsp;&nbsp;
  91.          <a href="index.jsp?page=<%=pageCount%>">最后页</a>
  92.          &nbsp;&nbsp;&nbsp;&nbsp;
  93.         <%
  94.             }
  95.     
  96.             int i=0;
  97.             
  98.             //以循环的方式取出每页要显示的数据,因为在前面针对要显示的页数,
  99.             //调用了rs.absolute((curPage-1)*countPerPage+1);
  100.             //所以是从游标所在的位置取出当前页要显示的数据。
  101.             while(i<countPerPage && !rs.isAfterLast())
  102.             {
  103.                 out.println("<hr color=\"blue\" size=\"2\"><br>");
  104.                 out.println("用户名:"+rs.getString("gst_user"));
  105.                 out.println("&nbsp;&nbsp;");
  106.                 
  107.                 Timestamp ts=rs.getTimestamp("gst_time");
  108.                 long lms=ts.getTime();
  109.                 Date date=new Date(lms);
  110.                 Time time=new Time(lms);
  111.                 
  112.                 out.println("留言时间:"+date+" "+time);
  113.                 
  114.                 out.println("&nbsp;&nbsp;");
  115.                 out.println("用户IP:"+rs.getString("gst_ip")+"<br>");
  116.                 out.println("主题:"+rs.getString("gst_title")+"<br>");
  117.                 out.println("内容:"+rs.getString("gst_content"));
  118.                 i++;
  119.                 rs.next();    
  120.             }
  121.             rs.close();
  122.             stmt.close();
  123.             conn.close();
  124.         %>
  125.     </body>
  126. </html><%out.flush();%>

26-30行  最后一行 都用到  out.flush()语句的调用非常重要 否则 MyResponseWrapper类的toByteArray()方法将得不到缓冲区中的内容

6  配置JDBC数据源

http://blog.chinaunix.net/space.php?uid=26284395&do=blog&id=3038773

7  创建不雅字句与替换内容文件

文件word.txt存放在WEB-INF目录下 

word.txt

 

  1. 我靠=我*
  2. fuck=****
  3. 他妈的=他**

 

8   配置web.xml

 

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <web-app version="2.5"
  3.     xmlns="http://java.sun.com/xml/ns/javaee"
  4.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  5.     xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
  6.     http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
  7. <filter>
  8.         <filter-name>GuestbookFilter</filter-name>
  9.         <filter-class>filter.GuestbookFilter</filter-class>
  10.         <init-param>
  11.             <param-name>word_file</param-name>
  12.             <param-value>/WEB-INF/word.txt</param-value>
  13.         </init-param>
  14.     </filter>
  15.     
  16.     <filter-mapping>
  17.         <filter-name>GuestbookFilter</filter-name>
  18.         <url-pattern>/process.jsp</url-pattern>
  19.     </filter-mapping>
  20.     
  21.      <filter-mapping>
  22.         <filter-name>GuestbookFilter</filter-name>
  23.         <url-pattern>/index.jsp</url-pattern>
  24.         <dispatcher>REQUEST</dispatcher>
  25.         <dispatcher>FORWARD</dispatcher>
  26.     </filter-mapping>
  27.        
  28. </web-app>
分享到:
评论

相关推荐

    替换敏感词的留言板加filter 和不加filter两种方案

    `filter`则是在`servlet`之上提供的一种机制,它允许我们在数据传递到目标`servlet`之前或之后进行预处理和后处理,比如过滤、转换、日志记录等操作。 对于敏感词的处理,通常是为了防止恶意用户发布不当言论或者...

    Ajax请求和Filter配合案例解析

    当Ajax请求到达服务器后,该Filter会对提交的数据进行校验。如果校验未通过,Filter会拦截并终止请求,然后将请求转发到一个名为`error.jsp`的页面,向用户显示错误信息。Filter的实现示例如下: ```java public ...

    防止SQL注入和XSS攻击Filter

    - **功能描述**:此Filter的主要作用是对HTTP请求进行包装,使用`XssHttpServletRequestWrapper`来替换原始的`HttpServletRequest`对象,从而实现对请求参数的过滤处理。 - **执行流程**:当请求到达时,Filter首先...

    servlet_filter.rar_Servlet filter_重写filter

    在处理乱码时,Filter可以在请求进入Servlet之前,对请求参数进行编码转换,确保数据正确显示。例如,可以设置请求和响应的编码为UTF-8: ```java request.setCharacterEncoding("UTF-8"); response.setContentType...

    cors-filter-1.7.1.jar

    3. **简单请求**:对于GET、POST和HEAD这些简单请求,浏览器会直接发出请求,服务器同样需要在响应头中设置相应的CORS信息。 4. **凭证(Credentials)共享**:如果需要跨域请求携带Cookie或其他认证信息,服务器...

    disk filter driver

    这种驱动程序的主要目的是拦截和处理来自应用程序或系统对磁盘的所有I/O请求,从而实现对磁盘操作的监控、修改或增强。在Windows系统中,磁盘过滤驱动通常通过系统提供的Driver Development Kit (DDK) 或者Windows ...

    过滤器filter和监听器listener的应用总结

    在Java Web开发中,过滤器...在阅读《过滤器filter和监听器listener的应用总结》这篇博客后,相信你对这两个概念会有更深入的认识。在实际工作中,根据具体需求灵活运用它们,可以大大提升应用的健壮性和用户体验。

    XSSFilter源码

    XSSFilter是一种有效的防御XSS攻击的手段,通过对请求参数进行过滤处理,可以有效减少因XSS攻击导致的安全风险。通过上述分析可以看出,XSSFilter的设计思路清晰,逻辑简单易懂,易于集成到现有的Web应用中。开发者...

    ssh框架乱码过滤器Filter

    SSH框架,全称为Struts2、Spring和...同时,对于不同的数据提交方式,如表单和JS,需要采取相应的解决方案。在实际开发中,确保整个数据传输过程中的字符编码一致性至关重要,这能有效避免乱码问题,提高用户体验。

    listener和filter 监听器和过滤器的介绍以及简单使用(csdn)————程序.pdf

    监听器主要用于监听应用程序中的特定事件,而过滤器则用于在请求处理之前和之后对请求和响应进行拦截,进行预处理和后处理。 【监听器】 1. **监听器定义**:监听器是实现了特定接口的Java类,用于监听另一个Java...

    Filter.zip

    首先,**过滤器(Filter)**是Java Servlet技术的一部分,它允许我们在请求到达目标Servlet之前或之后进行预处理和后处理。在这里,过滤器被用来检查用户输入或输出内容,以识别并替换敏感词汇。在Java Web开发中,...

    vue_shop_filter.rar

    总的来说,"vue_shop_filter"项目展示了Vue.js在构建复杂前端应用时的强大能力,通过组件化开发、数据驱动和Mock数据模拟,为用户提供了一个流畅的店铺筛选体验。无论是对Vue.js初学者还是有经验的开发者,这个项目...

    cors-filter-1.7 + java-property-utils-1.10.zip

    `cors-filter-1.7.jar` 是一个用于处理跨域请求的过滤器,它基于Servlet规范,可以在请求进入实际业务处理之前,对请求头进行检查和修改,从而允许或拒绝跨域请求。该过滤器可以配置在Web应用的`web.xml`文件中,...

    Tomcat跨域请求资源解决方案.zip

    综上所述,解决Tomcat跨域请求资源的问题需要理解CORS机制,并结合具体的Web服务器配置进行调整。此压缩包提供的解决方案可能是通过一个预配置的jar包简化这一过程,但具体使用方法需要进一步研究该jar包的文档或...

    服务端解决跨域方法

    上述代码中,`&lt;filter-class&gt;`标签需要替换为你实际的过滤器类路径,`&lt;url-pattern&gt;`标签则指定了哪些URL会被此过滤器拦截。 #### 深入理解配置项 - **Access-Control-Allow-Origin**: 用于指定哪些域名可以访问...

    关于过滤器和监听器的使用模板

    在实际开发中,我们还需要创建对应的Filter和Listener类,实现上述接口,并编写相应的方法。 **总结** 过滤器和监听器在Java Web开发中扮演着不可或缺的角色。过滤器用于在请求处理链中进行预处理和后处理,提供了...

    过滤特殊字符及表情符

    在IT行业中,过滤特殊字符和表情符号是一项常见的需求,特别是在处理用户输入数据或者进行文本解析时。这可以防止潜在的安全问题,比如SQL注入,也可以确保数据的格式正确性,提高用户体验。以下将从标题和描述中...

    Laravel开发-laravel-cache-filter

    `laravel-cache-filter`是一个针对Laravel开发的专门用于缓存响应的路由筛选器,它允许开发者在不修改现有代码的情况下,对某些特定的路由或者控制器方法进行高效地响应缓存。下面将详细介绍这个过滤器的工作原理、...

    JSP过滤器防止Xss漏洞的实现方法(分享).docx

    为了防止XSS攻击,开发人员通常会在页面输出和数据处理阶段对用户输入进行编码,但这需要在每个可能出现的地方都添加相应的编码逻辑,增加了开发复杂性和潜在遗漏的风险。 JSP过滤器提供了一种更为统一和高效的方式...

    Servilet概述

    Filter 可以对请求和响应进行一些预处理和后处理,例如对请求参数的验证、对响应结果的压缩等。 Servlet 是 Java Web 开发的基础理论,掌握 Servlet 的用法非常必要。通过对 Servlet 的分类、用法、监听器、过滤器...

Global site tag (gtag.js) - Google Analytics