嵌入式 Jetty 中的 Struts 1.3.10。 ActionServlet 找不到 /WEB-INF/web.xml
状态:
- 我有一个基于 Struts 1.3 的 Web 应用程序,可以很好地部署到 Tomcat(战争或爆炸)。
- 我将 web 应用程序与一个类结合起来运行嵌入式 jetty 7.x。这一切都放入一个 jar 文件中。
- 我使用 maven- assembly-plugin 将所有依赖项打包到单个 jar 中。我查看了 jar 文件,一切都如您所料。标准 Web 应用程序布局,但所有依赖类均采用标准包布局。 WEB-INF/web.xml 就在您期望的位置。
- Jetty 启动正常并运行我的第一个启动 servlet,该 servlet 进行一些数据库初始化。我的 JspConfiguration 使用路径“WEB-INF/web.xml”来获取 web.xml(注意缺少前导斜杠)。
问题
当 Struts 动作 servlet 初始化时,它专门进行以下调用:
InputStream input = getServletContext().getResourceAsStream("/WEB-INF/web.xml");
这导致:
javax.servlet.ServletException: The /WEB-INF/web.xml was not found.
at org.apache.struts.action.ActionServlet.initServlet(ActionServlet.java:1781)
at org.apache.struts.action.ActionServlet.init(ActionServlet.java:349)
at javax.servlet.GenericServlet.init(GenericServlet.java:212)
at org.eclipse.jetty.servlet.ServletHolder.initServlet(ServletHolder.java:432)
at org.eclipse.jetty.servlet.ServletHolder.doStart(ServletHolder.java:260)
问题:
我想这是由于struts在请求资源时使用前导斜杠。
- 我应该以不同的方式包装吗?
- 我是否应该使用代码来捕获该请求并调整 URI 以删除前导斜杠?如何?
- 如果可能的话,我宁愿不调整 struts 代码...
- 如果您决定提供帮助,谢谢!
信息:
这是我用来启动jetty的类以及两个依赖类。
public class JettyRunner {
public static void main(String[] args) throws Exception {
if (args == null) {
args = new String[0];
}
// Construct the new arguments for jetty-runner
boolean transientState = false;
int port = 8070;
Server server = new Server(port);
WebAppContext webapp = new WebAppContext(".", "");
webapp.setConfigurations(new Configuration[]{new JspConfiguration()});
ClassPathResourceHandler resourceHandler = new ClassPathResourceHandler();
resourceHandler.setContextPath("");
ContextHandlerCollection contexts = new ContextHandlerCollection();
contexts.addHandler(resourceHandler);
contexts.addHandler(webapp);
server.setHandler(contexts);
//server.setHandler(webapp);
URL jettyXmlURL = new JettyRunner().getClass().getClassLoader().getResource("jetty.xml");
XmlConfiguration configuration = new XmlConfiguration(jettyXmlURL); //or use new XmlConfiguration(new FileInputStream("myJetty.xml"));
//XmlConfiguration configuration = new XmlConfiguration(new FileInputStream("jetty.xml"));
configuration.configure(server);
server.start();
server.join();
}
}
public class JspConfiguration extends WebXmlConfiguration {
@Override
public Resource findWebXml(WebAppContext webAppContext) throws IOException, MalformedURLException {
URL path = getClass().getClassLoader().getResource("WEB-INF/web.xml");
return Resource.newResource(path);
}
}
public class ClassPathResourceHandler extends ContextHandler {
Logger log = Logger.getLogger(startupServlet.class.getName());
private ResourceHandler realResourceHandler = null;
public ClassPathResourceHandler() {
realResourceHandler = new ResourceHandlerImplementation();
}
@Override
public void doHandle(String s, Request request, HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws IOException, ServletException {
realResourceHandler.handle(s, request, httpServletRequest, httpServletResponse);
}
private class ResourceHandlerImplementation extends ResourceHandler {
@Override
protected Resource getResource(HttpServletRequest httpServletRequest) throws MalformedURLException {
String requestedFile = httpServletRequest.getRequestURI();
log.debug("getResource(): " + requestedFile);
URL path = getClass().getResource(requestedFile);
try {
Resource resource = Resource.newResource(path);
if (resource != null && resource.exists() && !resource.isDirectory()) {
return resource;
}
else {
return null;
}
}
catch (IOException e) {
return null;
}
}
}
}
The state:
- I have a Struts 1.3 based webapp that deploys just fine to Tomcat (war or exploded).
- I combine the webapp with a class to run embedded jetty 7.x. This all goes into a single jar file.
- I use maven-assembly-plugin to package all dependencies exploded into the single jar. I looked inside the jar file and all is as you would expect. Standard web app layout except all dependent classes are in a standard package layout. WEB-INF/web.xml right where you would expect it.
- Jetty launches fine and runs my first startup servlet that does some database initialization. My JspConfiguration uses the path "WEB-INF/web.xml" to get the web.xml (note missing leading slash).
The problem
When the Struts action servlet initializes, it specifically makes the following call:
InputStream input = getServletContext().getResourceAsStream("/WEB-INF/web.xml");
which results in:
javax.servlet.ServletException: The /WEB-INF/web.xml was not found.
at org.apache.struts.action.ActionServlet.initServlet(ActionServlet.java:1781)
at org.apache.struts.action.ActionServlet.init(ActionServlet.java:349)
at javax.servlet.GenericServlet.init(GenericServlet.java:212)
at org.eclipse.jetty.servlet.ServletHolder.initServlet(ServletHolder.java:432)
at org.eclipse.jetty.servlet.ServletHolder.doStart(ServletHolder.java:260)
The question:
I imagine it's due to struts using the leading slash when requesting the resource.
- Should I package differently?
- Should I have code that captures that request and tweaks the URI to remove the leading slash? How?
- I'd rather not tweak the struts code if possible....
- If you decide to help, thanks!
The info:
Here is the class I'm using to fire up jetty along with the two dependent classes.
public class JettyRunner {
public static void main(String[] args) throws Exception {
if (args == null) {
args = new String[0];
}
// Construct the new arguments for jetty-runner
boolean transientState = false;
int port = 8070;
Server server = new Server(port);
WebAppContext webapp = new WebAppContext(".", "");
webapp.setConfigurations(new Configuration[]{new JspConfiguration()});
ClassPathResourceHandler resourceHandler = new ClassPathResourceHandler();
resourceHandler.setContextPath("");
ContextHandlerCollection contexts = new ContextHandlerCollection();
contexts.addHandler(resourceHandler);
contexts.addHandler(webapp);
server.setHandler(contexts);
//server.setHandler(webapp);
URL jettyXmlURL = new JettyRunner().getClass().getClassLoader().getResource("jetty.xml");
XmlConfiguration configuration = new XmlConfiguration(jettyXmlURL); //or use new XmlConfiguration(new FileInputStream("myJetty.xml"));
//XmlConfiguration configuration = new XmlConfiguration(new FileInputStream("jetty.xml"));
configuration.configure(server);
server.start();
server.join();
}
}
public class JspConfiguration extends WebXmlConfiguration {
@Override
public Resource findWebXml(WebAppContext webAppContext) throws IOException, MalformedURLException {
URL path = getClass().getClassLoader().getResource("WEB-INF/web.xml");
return Resource.newResource(path);
}
}
public class ClassPathResourceHandler extends ContextHandler {
Logger log = Logger.getLogger(startupServlet.class.getName());
private ResourceHandler realResourceHandler = null;
public ClassPathResourceHandler() {
realResourceHandler = new ResourceHandlerImplementation();
}
@Override
public void doHandle(String s, Request request, HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws IOException, ServletException {
realResourceHandler.handle(s, request, httpServletRequest, httpServletResponse);
}
private class ResourceHandlerImplementation extends ResourceHandler {
@Override
protected Resource getResource(HttpServletRequest httpServletRequest) throws MalformedURLException {
String requestedFile = httpServletRequest.getRequestURI();
log.debug("getResource(): " + requestedFile);
URL path = getClass().getResource(requestedFile);
try {
Resource resource = Resource.newResource(path);
if (resource != null && resource.exists() && !resource.isDirectory()) {
return resource;
}
else {
return null;
}
}
catch (IOException e) {
return null;
}
}
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
Struts 被设计为作为 Web 应用程序运行,而不是作为独立应用程序运行。在您的 JettyRunner 类中,您有一个 main 方法来启动 Jetty。这不适用于 Struts。如果您想使用 Struts 1.x,则必须创建一个 Web 应用程序。
Struts was designed to run as a Web application and not as a standalone application. In your
JettyRunner
class, you have amain
method to fire up Jetty. That won't work with Struts. You would have to create a web application if you want to use Struts 1.x.我能够使用 WebAppContext 的
setWar()
方法为我的 struts 1.3 应用程序解决此问题。我的基本码头跑步者版本如下所示:I was able to resolve this for my struts 1.3 app using WebAppContext's
setWar()
method. My version of a basic jetty runner looks like: