Serve static resources from within a compressed file using Spring - java

Is it possible to serve static resources from within a compressed file using Spring MVC? Something like this.
I have some data packaged into individual JSON files (e.g. 123.json, 1634.json, etc.) and and currently serving them via
<mvc:resources mapping="/resources/**" location="/resources/" />
The files are under .../resources/dataFiles/. So a user can go to http://mywebsite.com/resources/dataFiles/123.json to retrieve the data for entity 123.
However, I have ~10,000 JSON files. It would be great if I could compress them under one file (.../resources/dataFiles/entities.zip) and tell Spring to serve the individual JSON files from within the compressed file.
So the user would still go to http://mywebsite.com/resources/dataFiles/123.json but the only file under .../resources/dataFiles/ is entities.zip.
I'm using Tomcat 7.0 if this question is outside the scope of the MVC framework.

I'm not sure if there's a Spring out-of-the-box component that does that, but you can create an independent Servlet to handle the incoming requests for static resources, then this servlet would parse the file name, and dynamically read from the zipped file the correct Zip Entry and return the content to the OutputStream of the Response. Take a look at:
sample code

Related

Serving static content from Jersey resource method in a Spring Boot app

I'm using a combination of Spring Boot and JAX-RS for my REST API. In my Spring Java Application I have an image located in my resources directory. I want to serve this picture with an URL, it should be something like this:
localhost:8080/api/get/img/1/imageFileName.png
Like this I should be able to use this URL in my Angular Frontend Application in an img tag:
<img src="localhost:8080/api/get/img/1/imageFileName.png"/>
So the issue is, that I really want to have this stuff in my FileSystem. I definately do not want to return a byte array, but that's the only thing I could find so far. This is the only code I could come up with so far:
#GET
#Path("get/img/1")
public String getFile() {
File file = Paths.get(".", "resources", "Mockup9EventsPageAsMember.png").normalize().toFile();
return file.toString();
}
Obviously this will only return the path to the respective directory and not an URL link which I could use in my img tag.
Any suggestions how I can tell my SpringBoot JAX-RS Application to create an URL for me?
I could give you a solution to what you are trying to do, but it is definitely not recommended. The main reason would be the lack of caching. You would need to implement that yourself, which is already provided by the server if you let it serve all the static content.
In a Spring Boot + Jersey app, to be able to serve static content, you need to have the spring-boot-starter-web dependency. Then after that you can put all your static resources into src/main/resources/static1. If you put a file /images/foobar.png in that directory, then you can access it via localost:8080/images/foobar.png.
If you really really want to serve the static content from the resource method (which again I strongly recommend against), you don't have to return a byte[]. You could just return a File or an InputStream. Or you can use StreamingOutput (just search for some examples - you shouldn't have any problems finding any). But again, with this method, you need to take care of sending all the correct caching headers, or else the browser will not cache the files and they will served each time they are requested, which just uses unnecessary resources.
See also
If you have problems accessing the static content, it might be related to this issue
1. There are also more locations. See the docs

Where does Jersey store the "application.wadl" file?

I am trying to implement a code in our application which needs to monitor the existing registered resources in Jersey and then make decisions accordingly. I know that Jersey provides an application.wadl file which consists of all its resources at runtime.
My question is there a way to look at this file physically? Does Jersey create this file and store it somewhere in the app directory or is it in memory?
Is it possible to call any Jersey api internally on server to get the same info if this particular file is not available like that?
We are using the application class or runtimeconfig. Jersey auto discovers our resources marked with #Path annotation and we are running on Weblogic and Jersey 2.6.
Any help would be appreciated.
Thanks
No WADL file is created on disk. It is created dynamically upon URL request.
http://[host]:[port]/[context_root]/[resource]/application.wadl
E.g.:
http://localhost:8080/rest-jersey/rest/application.wadl
Also, I've found it very useful to inspect the WADL with the SoapUI tool, which can read your WADL from a URL and parse the resources into a tree format. See pic below.

Download file from physical path in java

I have uploaded files using spring MVC file upload functionality and files are getting uploaded in /home/myfolder/images/ folder. Now I want to download these file from this physical path. For test in my jsp I have written the following line
<a href="<%=request.getSession().getServletContext().getRealPath("/home/images/image.jpg")%>" >download </a>
but when I click on this link it redirects me to the URL
http://localhost:8080/home/myfolder/workspace/.metadata/.plugins/org.eclipse.wst.server.core/tmp0/wtpwebapps/myproject/home/images/image.jpg.
How can I download the image saved. Please let me know if there is anything else you need from me to resolve this.
Try using this:
<!-- Handles HTTP GET requests for /resources/ ** by efficiently serving up static resources -->
<mvc:resources mapping="/images/**" location="file:/home/images"/>
<!-- Allows for mapping the DispatcherServlet to "/" by forwarding static resource requests to the container's default Servlet -->
<mvc:default-servlet-handler/>
In the jsp:
<img src="/images/image.jpg" />
Here is the thread: Spring : serving static resources outside context root
Files outside your Webapps folder can't be served by the application container.
Some possibilities:
1) Upload to a folder that is below your Webapps folder in your application container. E. g.
Given your Webapps folder is /home/myfolder/Tomcat/webapps/myApp/
You could upload to /home/myfolder/Tomcate/webapps/myApp/upload/
This way the uploaded files can be served by the application container.
2) Make the upload folder accessible to the application container by means of symbolic links. You might need to change your container's config in order to make this work.
3) If you use a webserver in front of your application container (like httpd) let the webserver serve the static files.
4) Write your own servlet that reads from an arbitrary file and serves the contents to the client.

Sending Velocity templated Emails with images in them from a Spring MVC application

I'm interested which is the best way to send Emails with images in them from a Spring MVC application which uses Velocity.
The image should be in the application, possibly in the same location as the *.vm template (e.g. src/main/resources/templates) and no absolute paths should be used (e.g. C:\App...), that's why I can't figure it out how to do it.
Suggestions?
You need to understand how images and emails work together. I'm not an expert here, but I think the options are
include the image as an attachment in the email (lame, IMHO; and your bandwidth usage will be very high)
send an HTML email and link to an image hosted on the Internet
Have a look at org.springframework.mail.javamail.MimeMessageHelper
With Spring you can easily load resources from file system or from classpath (even within jar file) without absolute paths. You should use a Resource and its implementations, basically FileSystemResource or ClasspathResource.
This is an example:
Resource fileResource = new FileSystemResource("resources/templates");
After loading you can directly retrieve inputstream from resource instance.
Also, you can inject your relative path to a bean which has an instance attribute of type Resource:
<bean id="mailer" class="test.Mailer">
<property name="templateResource" value="file:resource/templates" />
</bean>
I don't use Velocity but I usually load templates in this way to generate dynamic content with freemarker. You can also attach an image to an email, once you've loaded it.

Streaming Dynamic Files from Spring MVC

I've got a Spring Web MVC application (and also a BlazeDS application, though not as relevant) where files are dynamically generated based on certain client actions.
I'd like to just map a certain directory on the file system to Spring MVC (or the app server) url and let it serve the files in that directory (with streaming and standard last-modified header support). Ideally, the mapped directory would be configured via the spring config, since I already have support per-machine for setting that up.
So, how can I do this? The best I can find so far is to write a controller that reads the file manually and streams it byte-by-byte. However, that seems far less than ideal. Is support for something like this already baked into Spring MVC or the standard application server spec?
Thanks!
If your processing model supports it, why not cut the middleman of the filesystem out of the picture completely and just stream the files back through the response stream as they are generated? Take a look at the AbstractExcelView and AbstractPDFView classes of Spring MVC to see some examples of how this is done.
or the standard application server spec?
Yes, there is. As you didn't mention which one you're using, I'll give a Tomcat-targeted answer. All you basically need to do is to add a Context element for /path/to/your/resources in /conf/server.xml:
<Context docBase="/path/to/your/resources" path="/resources" />
This way they'll be accessible through http://example.com/resources/...
Ideal for this is using an lightweight proxying server in front of your appserver, like a nginx or lighthttpd. You can configure it for serving static content, without calling your app.
If directory and files so dynamic, you can prepare real path to file at your controller and give this filepath to the frontend server, using headers. For example for nginx it's a X-Accel-Redirect header. Read more about this (and follow links for other http servers) there

Categories

Resources