jboss WildFly -从WAR获取资源

ffvjumwh  于 2022-11-08  发布在  其他
关注(0)|答案(8)|浏览(230)

我正在使用以下方法从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模块加载有关,但我不知道这是一个bug还是正常行为。
我在StackOverflow上发现了许多类似的问题,但没有适用的解决方案。其中一个建议是使用ServletContext,如下所示:

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

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

92vpleto

92vpleto1#

我遇到了同样的问题,我没有将资源定义为共享模块,而是通过在WAR中使用ServletContextListener来解决这个问题。
在contextInitialized方法中,我从ServletContextEvent获取ServletContext并使用其getResource(“/WEB-INF/myResource”)来取得我的WAR档案内资源的URL。获取资源()方法会依预期解析,而不是解析为“/modules/system/layers/base/org/jboss/as/ejb 3/main/timers/”URL。然后,可以将该URL存储在ServletContext中,以供servlet或注入的ApplicationScoped CDIbean以后使用。

@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) {}
}
dsf9zpds

dsf9zpds2#

我们遇到了类似的问题,我们的错误在于我们试图通过原始路径访问静态资源,而不是使用资源提供的输入流-即使在部署未展开的. 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) {
    // ...
}
fhity93d

fhity93d3#

我最终放弃了,并将我的资源文件放在一个新的JBoss模块中,如本链接中所述。
https://community.jboss.org/wiki/HowToPutAnExternalFileInTheClasspath
它可以工作,但缺点是有两个部署目标,因此事情会更复杂。优点是,WAR文件的大小减小了,而且如果只是一些资源发生了变化,我也不必重新部署应用程序。

l7wslrjt

l7wslrjt4#

我最近尝试弄清楚如何在我自己的Java war中访问一个文件。下面是java类和资源在war文件中是如何打包的:

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

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

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

在这种情况下,资源文件需要与包含java类的classes文件夹在同一个文件夹中。希望其他人会发现这有帮助。

xzv2uavs

xzv2uavs5#

这个示例代码适用于在openshift上部署和测试的wildfly。我认为这是一个wildfly问题,我下载了wildfly,并在本地尝试,我也得到了错误。
Check sample project on 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 e.g) 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();
    }
}
3b6akqbq

3b6akqbq6#

Wildfly和未爆炸的WAR也有同样的问题,我使用Spring和ServletContextResource解决了这个问题:

[org.springframework.core.io.]Resource resource = new ServletContextResource(servletContext, "WEB-INF/classes/resource.png");

在同一个 @Service 课程中,我还参加了:

@Inject
private ServletContext servletContext;
rt4zxlrg

rt4zxlrg7#

我于是决定:

@Autowired
private final ApplicationContext ctx;
private final Path path = Paths.get("testfiles/load")

ctx.getRosource("classpath:" + path);
fumotvh3

fumotvh38#

我阅读了this解决方案,它引导我们在Wildfly中使用getResourceAsStream(...)而不是getResource()。我只是在Wildfly 19上测试了它,并从控制台部署了 myApp.ear

相关问题