我已经设置了许多Java Server Pages,我想通过添加Process Servlet(扩展HttpServlet)来使用Controller / View系统。
我只是想在ProcessServlet添加一些属性之后正常处理所请求的JSP。
假设我的所有JSP都在名为/ content /的目录中,并且我的web.xml文件有一条规则将/content/*.jsp映射到我的ProcessServlet
我无法找到将所有JSP移动到不同目录(/ content-JSPs /)的方法,这样就可以无需经过ProcessServlet就可以调度它们。
有没有办法基本上将#forward()(其他一些方法?)发送到请求的JSP而不再通过ProcessServlet?
有点难以相信这种缺乏灵活性的存在。为什么Servlet不能仅仅作为JSP的传递?
我的目标是设置所有内容,以便Web服务器不必为所有JSP创建单独的目录,而为其他所有内容创建另一个目录,即CSS,JavaScript和图像。我想保持目录结构(和URL结构)不变。
答案 0 :(得分:5)
将它们放在/WEB-INF
文件夹中。这也有效地使JSP远离直接访问。您只需更改RequestDispatcher#forward()
来电,在路径中添加/WEB-INF
。
request.getRequestDispatcher("/WEB-INF/content" + request.getPathInfo()).forward(request, response);
请注意/content/*.jsp
的网址格式在语法上无效。它应该是/content/*
。也许你也真的用过它。要跳过像images / css / JS这样的静态资源,您不应该将它们放在/content
中,而应放在/resources
,/static
等中。
答案 1 :(得分:3)
您也可以使用Servlet Filter而不是Server。如果您的servlet仅添加一些参数来请求,这是一个不错的选择。而且您不必手动将请求分派给JSP。
答案 2 :(得分:1)
为什么不,而不是映射到* .jsp,映射到类似* .page(或任何你喜欢的术语),然后你的进程servlet可以进行处理,并用.jsp替换.page并指示该页面的RequestDispatcher
到forward()
。
只要您希望通过ProcessServlet的页面上的所有链接都使用.page名称,那么它可能会起作用。
答案 3 :(得分:1)
许多人建议在这种情况下更好地使用过滤器。
将以下摘录放入web.xml
过滤器定义
<filter>
<filter-name>ProcessFilter</filter-name>
<filter-class>my.filter.ProcessFilter</filter-class>
</filter>
过滤映射
<!-- Map all ".jsp" that should go through the filter-->
<filter-mapping>
<filter-name>ProcessFilter</filter-name>
<url-pattern>/content/*.jsp</url-pattern>
</filter-mapping>
<!-- If you have Any servlets that needs to go through ProcessFilter -->
<filter-mapping>
<filter-name>ProcessFilter</filter-name>
<servlet-name>MyServlet</servlet-name>
</filter-mapping>
<强> OncePerRequestFilter 强>
如果您只想在第一次将请求范围存储在属性中时执行过滤器,下次可以检查属性是否已设置,在哪种情况下不再进一步处理。
如果您使用的是Spring框架,则可以使用OncePerRequestFilter
的子类之一或扩展它,只需实现doFilterInternal()
。
否则,您可以参考OncePerRequestFilter.java
:raw并实施/扩展您的过滤器。
以下是它的简化版本。
public class ProcessFilter extends Filter {
public final void doFilter(ServletRequest request, ServletResponse response,
FilterChain filterChain)
throws ServletException, IOException {
if (!(request instanceof HttpServletRequest) ||
!(response instanceof HttpServletResponse)) {
throw new ServletException("OncePerRequestFilter just supports HTTP requests");
}
HttpServletRequest httpRequest = (HttpServletRequest) request;
HttpServletResponse httpResponse = (HttpServletResponse) response;
String alreadyFilteredAttributeName = "ALREADY_PROCESSED_BY_PROCESS_FILTER";
if (request.getAttribute(alreadyFilteredAttributeName) != null) {
// Proceed without invoking this filter...
filterChain.doFilter(request, response);
}
else {
// Do invoke this filter...
request.setAttribute(alreadyFilteredAttributeName, Boolean.TRUE);
try {
doFilterInternal(httpRequest, httpResponse, filterChain);
}
finally {
// Remove the "already filtered" request attribute for this request.
request.removeAttribute(alreadyFilteredAttributeName);
}
}
}
protected void doFilterInternal(
HttpServletRequest request, HttpServletResponse response,
FilterChain filterChain) {
throws ServletException, IOException
/*
*
*
* Put your processing logic here
*
*
*/
}
}
答案 4 :(得分:0)
据我所知,你应该尝试在你的web.xml中使用<filter>
来使你的一些请求绕过servlet。