WildFly – 从WAR获取资源

我使用以下方法从WildFly中的WAR文件获取资源:

this.getClass().getResource(relativePath) 

当应用程序部署为爆炸WAR时,它可以工作。 它曾经用于压缩WAR。 昨天,我在Eclipse中完成了项目的清理和重建,它刚刚停止工作。

当我检查资源根目录时:

 logger.info(this.getClass().getResource("/").toExternalForm()); 

我明白了:

 file:/C:/JBoss/wildfly8.1.0.CR1/modules/system/layers/base/org/jboss/as/ejb3/main/timers/ 

所以,难怪它不起作用。 它可能与JBoss模块加载有关,但我不知道这是一个错误还是正常行为。

我在StackOverflow上发现了各种类似的问题,但没有适用的解决方案。 其中一个建议是使用ServletContext,如下所示:

 @Resource private WebServiceContext wsContext; ... ServletContext servletContext = (ServletContext)this.wsContext.getMessageContext() .get(MessageContext.SERVLET_CONTEXT); servletContext.getResource(resourcePath); 

但是,当我尝试以这种方式获取MessageContext时,我得到一个IllegalStateException。 所以我基本上卡住了。 有任何想法吗?

我遇到了同样的问题,而不是将资源定义为共享模块,我最后通过在WAR中使用ServletContextListener来解决这个问题。

在contextInitialized方法中,我从ServletContextEvent获取了ServletContext,并使用其getResource(“/ WEB-INF / myResource”)来获取WAR文件中的资源的URL。 似乎在ServletContextListener中,.getResource()方法按预期解析而不是“/ modules / system / layers / base / org / jboss / as / ejb3 / main / timers /”url。 然后,该URL可以存储在ServletContext中,以供servlet稍后使用或在注入的ApplicationScoped CDI bean中使用。

 @WebListener public class ServletInitializer implements ServletContextListener { @Override public void contextInitialized(ServletContextEvent sce) { try { final ServletContext context = sce.getServletContext(); final URL resourceUrl = context.getResource("/WEB-INF/myResource"); context.setAttribute("myResourceURL", resourceUrl); } catch (final MalformedURLException e) { throw new AssertionError("Resource not available in WAR file", e); } } @Override public void contextDestroyed(ServletContextEvent sce) {} } 

要么

 @WebListener public class ServletInitializer implements ServletContextListener { @Inject private SomeApplicationScopedBean myBean; @Override public void contextInitialized(ServletContextEvent sce) { try { final ServletContext context = sce.getServletContext(); final URL resourceUrl = context.getResource("/WEB-INF/myResource"); myBean.setResourceUrl(resourceUrl); } catch (final MalformedURLException e) { throw new AssertionError("Resource not available in WAR file", e); } } @Override public void contextDestroyed(ServletContextEvent sce) {} } 

我们遇到了类似的问题,我们的错是我们尝试通过原始路径访问静态资源而不是使用资源提供的输入流 – 即使在部署非爆炸的.war文件时,以下代码也适用于我们。

 final URL resource = this.getClass().getResource(FILE); try (final InputStream inputStream = resource.openStream(); final InputStreamReader inputStreamReader = new InputStreamReader(inputStream); final BufferedReader bufferedReader = new BufferedReader(inputStreamReader)) { // Use bufferedReader to read the content } catch (IOException e) { // ... } 

我最终放弃并将我的资源文件放在一个新的JBoss模块中,如此链接中所述。

https://community.jboss.org/wiki/HowToPutAnExternalFileInTheClasspath

它有效,但缺点是有两个部署目标,所以事情更复杂。 从好的方面来说,WAR文件的大小会减少,如果只有部分资源发生了变化,我不必重新部署应用程序。

我最近试图弄清楚如何在我自己的Java战争中访问文件。 以下是如何在war文件中打包java类和资源:

 WAR `-- WEB-INF `-- classes (where all the java classes are) `-- resourcefiles `-- resourceFile1 

我的目标文件是resourceFile1。 要获取该文件,我只是在代码中执行以下操作:

 InputStream inStream = this.class.getClassLoader().getResourceAsStream("resourcefiles/resourceFile1"); 

在这种情况下,资源文件需要与包含java类的classes文件夹位于同一文件夹中。 希望其他人觉得这很有帮助。

此示例代码适用于在openshift上部署和测试的wildfly。 我认为这是一个野生蝇问题,我是野生蝇并在当地尝试我也得到了错误。

检查github上的示例项目

 import org.springframework.web.bind.annotation.RequestMethod; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.net.URLConnection; @Controller @RequestMapping public class FileDownloadController { private static final Logger logger = LoggerFactory.getLogger(FileDownloadController.class); private static final String DOC_FILE = "file/ibrahim-karayel.docx"; private static final String PDF_FILE = "file/ibrahim-karayel.pdf"; @RequestMapping(value = "/download/{type}", method = RequestMethod.GET) public void downloadFile(HttpServletRequest request, HttpServletResponse response, @PathVariable("type") String type) throws IOException { File file = null; InputStream inputStream; if (type.equalsIgnoreCase("doc")) { inputStream = getClass().getClassLoader().getResourceAsStream(DOC_FILE); file = new File(Thread.currentThread().getContextClassLoader().getResource(DOC_FILE).getFile()); } else if (type.equalsIgnoreCase("pdf")) { inputStream = getClass().getClassLoader().getResourceAsStream(PDF_FILE); file = new File(Thread.currentThread().getContextClassLoader().getResource(PDF_FILE).getFile()); } else{ throw new FileNotFoundException(); } if (file == null && file.getName() == null) { logger.error("File Not Found -> " + file); throw new FileNotFoundException(); } String mimeType = URLConnection.guessContentTypeFromName(file.getName()); if (mimeType == null) { System.out.println("mimetype is not detectable, will take default"); mimeType = "application/octet-stream"; } System.out.println("mimetype : " + mimeType); response.setContentType(mimeType); /* "Content-Disposition : inline" will show viewable types [like images/text/pdf/anything viewable by browser] right on browser while others(zip eg) will be directly downloaded [may provide save as popup, based on your browser setting.]*/ response.setHeader("Content-Disposition", String.format("inline; filename=\"" + file.getName() + "\"")); /* "Content-Disposition : attachment" will be directly download, may provide save as popup, based on your browser setting*/ //response.setHeader("Content-Disposition", String.format("attachment; filename=\"%s\"", file.getName())); response.setContentLength(inputStream.available()); IOUtils.copy(inputStream, response.getOutputStream()); response.flushBuffer(); inputStream.close(); } }