Hello,
I want to create an audio polymer template with a server sie java class. My MP3 files are placed in my frontend directory (src/main/webapp/frontend). The question is how to import these files into my application?
Greetings!
Hello,
I want to create an audio polymer template with a server sie java class. My MP3 files are placed in my frontend directory (src/main/webapp/frontend). The question is how to import these files into my application?
Greetings!
Without knowing exactly how you handle the files in the frontend I would say that you could have the files registered as StreamReasources from where the client can get them.
see: [Dynamic Content]
(https://vaadin.com/docs/v10/flow/advanced/tutorial-dynamic-content.html)
I would expect to register the resources to the session and give the url:s to the client to use like
StreamRegistration resource = ui.getSession().getResourceRegistry().registerResource(new StreamResource(name, streamFactory));
URI resourceUri = resource.getResourceUri();
// send the resourceUri.toString() to the client component
Note for register resource
/**
* Registers a stream resource in the session and returns registration
* handler.
* <p>
* You can get resource URI to use it in the application (e.g. set an
* attribute value or property value) via the registration handler. The
* registration handler should be used to unregister resource when it's not
* needed anymore. Note that it is the developer's responsibility to
* unregister resources. Otherwise resources won't be garbage collected
* until the session expires which causes memory leak.
*
* @param resource
* stream resource to register
* @return registration handler
*/
Thanks for your reply!
This solution don’t solved my problem. I want to use a solution like the ThemeResource
from Vaadin 8. But ThemeResource
don’t exist anymore.
To get the servlet context path to the file use
String url = "frontend://{path_to_file}";
String resolvedUrl = VaadinServlet.getCurrent().resolveResource(url);
This should be close to the same that ThemeResource in V8 returned.
The resource should be available for a request from the application.
src/main/webapp/frontend
URL normally is handled by the webserver itself (as a static resource).
If you don’t have a custom unusual configuration then src/main/webapp/
is the root folder for static Web resources that may be referenced directly and they are handled by the Web server.
This means that they are not handled by the Vaadin application. It’s the web server which just return
the content of the file without any servlets involving.
So if your web server has URL like http://example.com/
then file src/main/webapp/myfile.ext
may be access directly as http://example.com/myfile.ext
. In the same way file src/main/webapp/frontend/my.txt
may be accessed via the http://example.com/frontend/myfile.ext
URL.
Vaadin servlet won’t handle those files anyhow at all. Those are static resource handled by the web server.
So to be able to access those files you just may create a Java URL
class and get them as any other HTTP resource from the web.
The question is why you want to access those files inside your application?
If those files are not intended to be accesible as a Web resource then you may just put them as a classpath resource and access them via Class::getResource
or Class::getResourceAsStream
.
If you want them available in the Web and also inside the application then you may use StreamResource
as Mikael mentioned.
There is no such thing as ThemeResource
in Flow, that’s true.
You may create a ticket to make functionality to solve your need in a simpler way.
Thanks for your reply!
I don’t want use the resource on server side, but on client side. I want to implement an audio
component to play a notification sound on a user action. The MP3 file isn’t played by the audio
HTML tag. My tag looks like:
<link rel="import" href="../../bower_components/polymer/polymer.html">
<dom-module id="sound-template">
<template>
<audio controls autoplay>
<source src="[[sourcePath]
]" type="[[type]
]">
</audio>
</template>
<script>
class SoundTemplate extends Polymer.Element {
static get is() {
return 'sound-template';
}
}
customElements.define(SoundTemplate.is, SoundTemplate);
</script>
</dom-module>
The Java class is looking like:
@Tag("sound-template")
@HtmlImport("src/instruction/sound-template.html")
public class Sound extends PolymerTemplate<Sound.SoundModel>
{
private static final long serialVersionUID = 3385584228063340684L;
public void setSource(String sourcePath)
{
getModel().setSourcePath("sounds/" + sourcePath);
getModel().setType("audio/mpeg");
}
public interface SoundModel extends TemplateModel
{
void setSourcePath(String sourcePath);
void setType(String type);
}
}
```
As I understand you need URL of the audio file to be able to send it from the server side to the client side where they are used in the template, right ?
So the question is just about constructing the URL of the resource.
I think you may use the same logic which we are using to access to the template files on the server side.
There is a method VaadinServlet::resolveResource
which returns a path to get resource via the ServletContext::getResource
method.
Here is the example how we use it in our code:
https://github.com/vaadin/flow/blob/master/flow-server/src/main/java/com/vaadin/flow/component/polymertemplate/DefaultTemplateParser.java#L102
https://github.com/vaadin/flow/blob/master/flow-server/src/main/java/com/vaadin/flow/component/polymertemplate/DefaultTemplateParser.java#L108
The second link referers to the servlet.getResourceAsStream
call but it just simply delegates to the ServletContext::getResourceAsStream
. Since you don’t need the content itself you may just call ServletContext::getResource
which return a URL.
Thanks for your reply!
Yes, I want to load the resource on server side and pass the URI to the client!
I have tried it now with VaadinServlet::resolveResource
. The HTML in production looks like this now:
<sound-template id="notificationSound">
<audio id="audioElement" controls="" autoplay="">
<source type="audio/mpeg" src="/./frontend/sounds/notification.mp3">
</audio>
</sound-template>
My Java class looks like this:
public void setSource(String sourcePath)
{
String path = VaadinServlet.getCurrent().resolveResource("frontend://sounds/" + sourcePath);
getModel().setSourcePath(path);
getModel().setType("audio/mpeg");
}
But the audio source is not playing in my browser (Google Chrome).
You are using only resolceResource
method. Which just returns path.
You need URL, not a path. As I said to get the correct URL you should use ServletContext::getResource
with path
as an argument.
The other thing which I don’t really understand: why you don’t want to use relative URL in your template file?
If your component navigation target URL is http://example.com/myview
then <source src="frontend/path_to_audio/[[audioName] ]" ...
where audioName
or sourcePath
is a name of your audio file will work just fine.
My sound file was corrupt.
But your solution is good and I have edit my code. Now all is working fine! Thank you a lot!
Very good.