0x00 起源
网上缺少适合java初学者的优秀的内存马调试学习的教程,自己也想把知识做一个提炼总结记录下来,特次打算做一个系列教程。
本文是通过实例让大家对内存马有一个初步清晰的认知,理解Java Servlet 与 Filter的 使用。
前置知识:会发布一个IDEA web项目,具体操作参考我上一篇博客 IDEA tomcat远程调试_leeezp的博客-CSDN博客
0x01 实践
IDEA需要引入一些依赖jar包,这些jar包在tomcat9的lib目录下。
catalina.jar、servlet-api.jar、tomcat-api.jar、tomcat-util.jar、tomcat-util-scan.jar
新建一个 Servlet 页面
MyServlet.java
import javax.servlet.*;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet(urlPatterns = "/Filter1")
public class MyServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.getWriter().println("执行MyServlet--doPost方法<br/><br/>");
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
}
发布项目,并问:
使用 Filter 过滤器 和 Servlet
新建过滤器 MyFilter.java
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;
@WebFilter(urlPatterns = "/Filter1")
public class MyFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("WOW Filter init");
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
servletResponse.setCharacterEncoding("utf-8");
servletRequest.setCharacterEncoding("utf-8");
servletResponse.setContentType("text/html;Charset=UTF-8");
servletResponse.getWriter().println("MyFilter接收到了请求,开始过滤<br/><br/>");
filterChain.doFilter(servletRequest, servletResponse); //chain.doFilter将请求转发给过滤器链下一个filter,如果没有filter那就是转发给Servlet
servletResponse.getWriter().println("回到MyFilter--doFilter方法<br/><br/>");
}
@Override
public void destroy() {
System.out.println("WOW Filter destroy");
}
}
注意,chain.doFilter将请求转发给过滤器链下一个filter,如果没有filter那就是转发给Servlet。 如果使用了 filterChain.doFilter(servletRequest, servletResponse) ,则必须有 Servlet 且 Servlet 和 Filter 过滤的URL相同,分别用 @WebFilter 和 @WebServlet 注解。
使用 Filter 过滤器 不使用 Servlet
MyFilter.java
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;
@WebFilter(urlPatterns = "/Filter1")
public class MyFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("WOW Filter init");
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
servletResponse.setCharacterEncoding("utf-8");
servletRequest.setCharacterEncoding("utf-8");
servletResponse.setContentType("text/html;Charset=UTF-8");
servletResponse.getWriter().println("MyFilter接收到了请求,开始过滤<br/><br/>");
//filterChain.doFilter(servletRequest, servletResponse); //chain.doFilter将请求转发给过滤器链下一个filter,如果没有filter那就是转发给Servlet
servletResponse.getWriter().println("回到MyFilter--doFilter方法<br/><br/>");
}
@Override
public void destroy() {
System.out.println("WOW Filter destroy");
}
}
上面的代码改动只是将 filterChain.doFilter(servletRequest, servletResponse) 注释掉,则请求不会转给 Servlet 。
后记
可见destroy()只有在服务器关闭的时候才开始调用