I want to access static files, which are outside my web application in a known directory. I have read many options over the www, but I have still some questions about this.
Basically I want to declare a context for the defaultservlet of my application server. In my case I'm trying with the Tapestry Tutorial, which is a Maven based project and imported to eclipse.
The idea was to create a httpservlet, which gets the file from the location. Do someone of you know where I can grab an example of such a servlet and how I can call him? I know that the servlet must be probably declared as a service, because all pages of the application need to access the files, but I could also be mistaken and it is enough to import it, let say, in the layout page (All pages use the layout.tml file). I basically don't have any clue how to do it with a servlet. Can someone show me the light?
Tank you very much.
Another simpler solution is to create a page which returns a stream response
public class StaticFile {
StreamResponse onActivate(String fileName) {
return new StaticFileStreamResponse(fileName);
}
}
Then in another component / page
#Inject ComponentResources resources;
public Link getStaticFileLink() {
return resources.createPageRenderLinkWithContext("StaticFile", "path/to/myFile.jpg");
}
TML
<img src="${StaticFileLink}" />
But then you won't take advantage of tapestry's 304 NOT_MODIFIED response as in my other solution.
The tapestry way of doing this is by contributing an AssetRequestHandler and an AssetFactory.
AppModule.java
public static void contributeAssetDispatcher(
MappedConfiguration<String, AssetRequestHandler> config,
ResourceStreamer streamer)
{
config.add("staticfile", new StaticFileAssetRequestHandler(streamer));
}
public void contributeAssetSource(
MappedConfiguration<String, AssetFactory> config)
{
config.add("staticfile", new StaticFileAssetFactory());
}
Then in your tml you can use
<img src="${asset:staticfile:path/to/myFile.jpg}" />
Take a look at the ContextAssetRequestHandler, ClasspathAssetRequestHandler, ContextAssetFactory and ClasspathAssetFactory for inspiration.
Be careful not to open up a security hole where a hacker can access any file on your server by passing file paths prefixed with ../../
Related
So I have been trying hard to get a simple app to run with populating an HTML file through a controller without using a template engine.
I thought I would take some time to post about my findings related to the subject above. See answer below
Soo the question here is How to access HTML files through a controller in Spring boot without a template engine?
This is a very simplistic answer to a simple issue, this is not meant to scale and does not take into account the entirety of your project
Please keep in mind this is not the norm in a business environment but it was really bothering me how I cannot get a simple HTML to populate from a controller without using a template engine. I got it to work with thymeleaf dependency but I wanted to just get it to work as bare bones as possible. I read a lot of posts with ViewResolver Config classes or things a like but nothing worked. It would conflict with the internal resolvers of Spring boot.
Simple answer is once spring boot is initialized...all your static files must be in resources/static/
Templates folder is specific to use for Thymeleaf, based on my findings and it wont work if you just put it in the resource folders.
With your files in resources/static/ you can access it by going to localhost:8080/yourfilename.html
But if you want to access it through a controller you create a controller with the following:
#Controller
public class IndexController {
#RequestMapping("/")
public String getIndex(){
return " index.html";
}
}
If you want to remove the .html in your return value then you must add the following to your application.properties file
spring.mvc.view.suffix=.html
Then you can use the following
#Controller
public class IndexController {
#RequestMapping("/")
public String getIndex(){
return " index";
}
}
Once again this is a simple research I did on my own just to get it to work.
I wrote an MVC application and I wanted to create an option of editing the photo. I serve image as div which background is the image and div has click listener that post suitable requests to application.
Then on the application side works another program that edits photo as client asked and saves it and override a old one. The problem is that until I redeploy an application it serves an old file even though it has changed. I think the problem is because I serve photos from resources folder and it’s cold “static resources” so I should not change it. Another think is that IntelliJ is not refreshing the photo. Do you have any idea what I do wrong or know how should I serve that photos in better way?
So as Prashant mentioned in comment all I had to do was setCachePeriod to 0.
EDIT:
Following are two ways of doing it:
Either set in the application.properties file:
spring.resources.cache-period = 0
Or, add in the ResourceHandler:
#Component
public class WebConfigurations extends WebMvcConfigurerAdapter {
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registy.addResourceHandler("/static/**")
.addResourceLocations("classpath:/static/")
.setCachePeriod(0);
}
}
I am working on Spring Boot application. The general problem is the following: I've created REST API, a few controllers. However, I also have some static HTML files, located in "resources/static".
What I want to achieve, is to configure Spring resolvers so that I could access static content without appending ".html". On practise, I expect to access static HTML by path "ip:port/htmlPage" instead of "ip:port/htmlPage.html"
However, I don't want to create methods like this one:
#Controller
public class ViewMaster {
#RequestMapping("/home")
public String home() {
return "home";
}
So, properties like
spring.mvc.view.suffix=.html
not working for me. Any possibilities to avoid creation per page endpoint in a controller?
After reading your question i have tried a lot but unable to serve html from static folder without extention. What works for me is to create an #RequestMapping like this:
#RequestMapping(value="/static/{htmlName}")
String getStaticHtml(#PathVariable String htmlName){
return htmlName;
}
And moved html files to templates folder. So there is no need to create different end points to access html pages, just pass the name of html without extention and this will do the trick
I'm using Spark's (http://sparkjava.com/) static file routing, set up via:
externalStaticFileLocation('.../public');
for serving, amongst others, the index.html page placed in the public directory. So effectively, when you hit the server's URL, you get your index.html back. So far so good...
However, I would like to override this behavior when the request contains a specific Accept header, e.g., application/rdf+xml (basically different from the default text/html). In that case I would like to return some specific data rather than the index.html page.
Is there a simple way of achieving this in Spark? I couldn't find any solution to this in the documentation... Thanks for any tips!
Due to the change in the behavior you'd like to make, the content you want to serve now is no longer static, but dynamic.
You'll need to remove index.html from the static content directory and move it to resources directory (typically src/main/resources/templates).
Then, you'll need to create a route for the root of your domain name (/) and using a template engine serve the content.
When using a template engine you usually inject the dynamic data into a static template. Typically you do it using some sort of map.
In the case of text/html your map will be empty, and then it's like before -
serving a static page. If it's application/rdf+xml you'll fill the map with the relevant data and then serve the resulting dynamic page.
Example:
get("/", (request, response) -> {
if (isTextHtml(request)) {
// serve the index.html template as is (empty map, not null though)
// In this case index.html functinos as a static page
} else {
// use a map to have all relevant data for the index.html template
// In this case index.html functinos as a "real" template
}
});
How can we embed and show an InputStream as dynamic image in JSF 2.0 with OmniFaces?
OmniFaces does not offer any utility for this — yet.
If the image files are located on the disk file system, then you need to create a virtual context in the servletcontainer configuration so that they can be accessed by a normal URL. See also Load images from outside of webapps / webcontext / deploy folder using <h:graphicImage> or <img> tag.
If the image files are stored in the DB, then you need to create a simple servlet which just writes the InputStream of the image from the DB to the OutputStream of the HTTP response. See also How to retrieve and display images from a database in a JSP page? (note that this doesn't require JSP/HTML, you can as good just use <h:graphicImage> as it merely generates a HTML <img> element).
There's the PrimeFaces <p:graphicImage>, but this is a bit unintuitive to implement. See also Display dynamic image from database with p:graphicImage and StreamedContent.
Update: since OmniFaces 2.0 (for JSF 2.2) there's a <o:graphicImage> component which supports among others directly referencing a byte[] or InputStream property in an #ApplicationScoped managed bean in an intuitive way like below:
<o:graphicImage value="#{imageStreamer.getById(bean.imageId)}" />
#Named
#ApplicationScoped
public class ImageStreamer {
#Inject
private ImageService service;
public InputStream getById(Long id) { // byte[] is also supported.
return service.getContent(id);
}
}
In contrary to PrimeFaces <p:graphicImage>, no <f:param> is needed and the EL method arguments are evaluated during render response phase, but the EL method itself is only invoked when the browser actually requests the image. See also the showcase and the blog on the subject.