I'm using Spark to serve a web page.. For the static files I initialize Spark like stated here:
So I have this structure:
/src/main/resources/public/
|-- foo/
|-- css/
| |-- bootstrap.css
|-- js/
| ...
|-- img/
...
I made the foo
folder to make a trick because my webpage is located under /foo
url..like this:
http://www.example.com/foo/index
So my static files are loaded like this for example:
http://www.example.com/foo/css/bootstrap.css
What I want now is to have this path variable.. Because I have different environments and for example if I deploy this app in another domain I want it to be:
http://www.example2.com/superfoo/css/bootstrap.css
But for this I have to change the release and change the folder...
For the controllers I made this easily:
Example:
Spark.get(this.appBasePath + "/users", (request, response) -> {
return this.getUsersView(request);
}, new FreeMarkerEngine());
this.appBasePath
comes from a configuration that is loaded deciding the environment.
So what I am asking is to set programmatically the static files URL without making any folder. Is there any way to achieve this?
I ended up working around this problem by generating a get route for all my static files. It is entirely possible that there are way easier ways of doing this directly in spark, but it took less time to write this code than to understand the details of the spark.resource
package.
First, I define some helper functions to let me iterate over all files in a particular resource directory (requires Java 8):
/**
* Find all resources within a particular resource directory
* @param root base resource directory. Should omit the leading / (e.g. "" for all resources)
* @param fn Function called for each resource with a Path corresponding to root and a relative path to the resource.
* @throws URISyntaxException
*/
public static void findResources(String root,BiConsumer<Path,Path> fn) throws URISyntaxException {
ClassLoader cl = Main.class.getClassLoader();
URL url = cl.getResource(root);
assert "file".equals(url.getProtocol());
logger.debug("Static files loaded from {}",root);
Path p = Paths.get(url.toURI());
findAllFiles(p, (path) -> fn.accept(p,p.relativize(path)) );
}
/**
* Recursively search over a directory, running the specified function for every regular file.
* @param root Root directory
* @param fn Function that gets passed a Path for each regular file
*/
private static void findAllFiles(Path root, Consumer<Path> fn) {
try( DirectoryStream<Path> directoryStream = Files.newDirectoryStream(root)) {
for(Path path : directoryStream) {
if(Files.isDirectory(path)) {
findAllFiles(path, fn);
} else {
fn.accept(path);
}
}
} catch (IOException ex) {}
}
Then I use this to define a new GET route for each file
String webroot = "/server1";
findResources("static", (root,path) -> {
String route = webroot+"/"+path;
String resourcePath = "/static/"+path.toString();
logger.debug("Mapping {} to {}",route, resourcePath);
get(webroot+"/"+path, (req,res) -> {
Files.copy(root.resolve(path), res.raw().getOutputStream());
AbstractFileResolvingResource resource = new ExternalResource(resourcePath);
String contentType = MimeType.fromResource(resource);
res.type(contentType );
return "";
} );
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With