WildFly - getting resource from WAR

后端 未结 7 699
既然无缘
既然无缘 2020-12-21 00:13

I am using the following method to get a resource from WAR file in WildFly:

this.getClass().getResource(relativePath)

It works when the app

相关标签:
7条回答
  • 2020-12-21 00:37

    I ran into this same problem, and rather than define the resource as a shared module, I ended up working around this by using a ServletContextListener in my WAR.

    In the contextInitialized method, I got the ServletContext from the ServletContextEvent and used its getResource("/WEB-INF/myResource") to get the URL to the resource inside my WAR file. It appears that in the ServletContextListener, the .getResource() method resolves as expected rather than to the "/modules/system/layers/base/org/jboss/as/ejb3/main/timers/" url. That URL can then be stored in the ServletContext for later use by your servlets or in an injected 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) {}
    }
    

    or

    @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) {}
    }
    
    0 讨论(0)
  • 2020-12-21 00:39

    Had the same issue with Wildfly and not-exploded WAR and using Spring and ServletContextResource I have got around it like this:

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

    In the same @Service class I also had:

    @Inject
    private ServletContext servletContext;
    
    0 讨论(0)
  • 2020-12-21 00:44

    I finally gave up and put my resource files in a new JBoss module, as described in this link.

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

    It works, but the downside is that there are two deployment targets so things are more complicated. On the upside, the size of the WAR file is reduced, and I don't have to redeploy the application if only some of the resources have changed.

    0 讨论(0)
  • 2020-12-21 00:47

    This sample code works for wildfly deployed and tested on openshift. I think it is a wildfly problem I downland wildfly and tried on local I also get the error.

    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();
        }
    }
    
    0 讨论(0)
  • 2020-12-21 00:50

    I was recently trying to figure out how to access a file within my own war in Java. The following is how the java classes and resources are packaged in the war file:

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

    My target file was resourceFile1. To get that file, I just did the following in code:

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

    In this case the resource files would need to be in the same folder as the classes folder containing the java classes. Hopefully others find this helpful.

    0 讨论(0)
  • 2020-12-21 00:53

    I decided so:

    @Autowired
    private final ApplicationContext ctx;
    private final Path path = Paths.get("testfiles/load")
    
    ctx.getRosource("classpath:" + path);
    
    0 讨论(0)
提交回复
热议问题