在一个简单的 Java EE 8 Web 应用程序中,由于部署描述符不是强制性的,并且由于 aServlet
和 aFilter
可以在带有ServletContextListener
注释的 中注册@WebListener
,我如何在不依赖web.xml
文件的情况下以编程方式定义欢迎页面列表?
3 回答
很难证明是否定的,但我认为答案是您仍然需要 EE 8 的欢迎文件的部署描述符,这等同于 Servlet 4.0。
我无法确定地证明这一点,但强烈建议仔细阅读JSR-369的第10.10 节欢迎文件,即 Servlet 4.0 规范,其中详细介绍了欢迎列表的工作原理:
如果 Web 容器接收到有效的部分请求,则 Web 容器必须检查部署描述符中定义的欢迎文件列表。欢迎文件列表是部分 URL 的有序列表,没有尾随或前导 /。Web 服务器必须按照部署描述符中指定的顺序将每个欢迎文件附加到部分请求,并检查 WAR 中的静态资源是否映射到该请求 URI。如果未找到匹配项,Web 服务器必须再次按照部署描述符中指定的顺序将每个欢迎文件附加到部分请求并检查 servlet 是否映射到该请求 URI。Web 容器必须将请求发送到 WAR 中匹配的第一个资源。容器可以使用转发、重定向或与直接请求无法区分的容器特定机制将请求发送到欢迎资源。
如果以所描述的方式没有找到匹配的欢迎文件,则容器可以以它认为合适的方式处理请求。
特别要注意第一句和最后一句;该规范没有提及开发人员可用的替代方法。如果在欢迎列表中找不到任何匹配项,则容器本身决定要做什么。
因此,虽然部署描述符并不总是强制性的,但如果您想要拥有欢迎文件,即使使用 EE 8,它也是强制性的。第10.13 节在规范中包含 web.xml 部署描述符简要讨论了何时需要部署描述符:
如果 Web 应用程序不包含任何 Servlet、Filter 或 Listener 组件,或者使用注释来声明它们,则它不需要包含 web.xml。换句话说,仅包含静态文件或 JSP 页面的应用程序不需要存在 web.xml。
这些关于 Servlet 3.0 的欢迎列表的 SO 帖子也可能很有趣:
@WebServlet
在 servlet 类上使用注解。
您可以使用它@WebServlet("/Path")
来使 servlet 位于 your.domain/context-root/Path。
如果你想让 servlet 出现在多个 URL 上,那么你可以使用@WebServlet(urlPatterns={"/Path/*", "/APath", "/"}
.
有关注释的更多详细信息,请参见http://www.codejava.net/java-ee/servlet/webservlet-annotation-examples。
您可以添加一个仅映射到 URL“/”的 Servlet 过滤器并转发到您想要的欢迎文件:
import java.io.IOException;
import javax.inject.Inject;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
@WebFilter(filterName = "WelcomeFilter", urlPatterns = { "/" })
public class WelcomeFilter extends Object implements Filter {
@Inject
ServletContext context;
public WelcomeFilter() {
super();
}
@Override
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException {
context.getRequestDispatcher("/welcome-file.html").forward(req, resp);
chain.doFilter(req, resp);
}
}