servlet容器,servlet url模式和请求包装器

时间:2018-04-21 14:58:52

标签: java servlets request wrapper

我正在开发一个项目,基于Web应用程序的请求URL中存在特定字符串,我试图使用请求包装器修改请求的URL。

我了解到,即使我在包装器中覆盖getRequestURI,getRequestURL和getServletPath方法并从过滤器发送包装器,servlet容器仍然使用自己的ServletRequest接口实现来确定要调用的servlet。

我相信容器在ServletRequest的实现类中使用存储的变量作为请求URI,并且实际上并没有调用任何getRequestURI,getRequestURL和getServletPath方法来识别要使用的servlet(匹配URL模式)。

需要您的所有输入和知识来了解有关此主题的更多信息。请帮助我更好地学习这个主题。感谢.. !!

以下是我的实验代码,请求来自http://localhost:8080/RequestResponseListenersWebApp/pages/abcd.jsp

的jsp

过滤器

@WebFilter(filterName = "AllRequestScanFilter", urlPatterns = "/*")
public class AllRequestScanFilter implements Filter {
    public void destroy() {
    }

    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain)
            throws ServletException, IOException {
        HttpServletRequest request = (HttpServletRequest) req;

        EmployerViewTestBusinessWrapper wrapper = new EmployerViewTestBusinessWrapper(request);

        if (request.getRequestURI().contains("abcd.jsp"))
            chain.doFilter(wrapper, resp);
        else {
            chain.doFilter(req, resp);
        }
    }

    public void init(FilterConfig config) throws ServletException {

    }

}

包装

public class EmployerViewTestBusinessWrapper extends HttpServletRequestWrapper {

    public EmployerViewTestBusinessWrapper(HttpServletRequest request) {
        super(request);
    }

    @Override
    public String getPathTranslated() {
        return super.getPathTranslated();
    }

    @Override
    public String getRequestURI() {
        String currentPath=pathModified(super.getRequestURI());
        return currentPath!=null?currentPath:super.getRequestURI();
    }

    @Override
    public StringBuffer getRequestURL() {
        String currentPath=pathModified(super.getRequestURL().toString());
        return currentPath!=null?new StringBuffer(currentPath):new StringBuffer(super.getRequestURL());
    }

    @Override
    public String getServletPath() {
        String currentPath=pathModified(super.getServletPath());
        return currentPath!=null?currentPath:super.getServletPath();
    }

    private String pathModified(String currentPath){
        String returnPath=null;
        if(currentPath.contains("pages")){
            returnPath=currentPath.replaceFirst("/pages/","/pages/myapp/");
        }

        return returnPath;
    }
}

从未到过的Servlet

@WebServlet(name = "EmployerViewTestServlet",urlPatterns = "/pages/myapp/*")
public class EmployerViewTestServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String path=request.getParameter("path");
    }
}

还有一件事。我在此处指定的过滤器是Web应用程序中第一个在请求进入时调用的内容。

我总是可以检查过滤器中的URL模式,并使用RequestDispatcher将请求转发到所需的URL模式。

但是,在我的应用程序中,有一些过滤器被调用类型为FORWARD,我不希望在请求刚来自客户端时调用它们。

1 个答案:

答案 0 :(得分:0)

不是this您要找的是什么?

在这种情况下,request.getRequestDispatcher(newURI).forward(req, res)似乎只使用过滤器。

@WebFilter(filterName = "AllRequestScanFilter", urlPatterns = "/*")
public class AllRequestScanFilter implements Filter {
    public void destroy() {
    }

    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain)
            throws ServletException, IOException {
        HttpServletRequest request = (HttpServletRequest) req;

        //EmployerViewTestBusinessWrapper wrapper = new EmployerViewTestBusinessWrapper(request);

        String URI = request.getRequestURI();

        if (URI.contains("abcd.jsp") && URI.contains("pages")) {
            URI = URI.replaceFirst("/pages/","/pages/myapp/");
            request.getRequestDispatcher(URI).forward(req, res);
        } else {
            chain.doFilter(req, resp);
        }
    }

    public void init(FilterConfig config) throws ServletException {

    }

}