Important Notice - Forums is archived
To simplify things and help our users to be more productive, we have archived the current forum and focus our efforts on helping developers on Stack Overflow. You can post new questions on Stack Overflow or join our Discord channel.

Vaadin lets you build secure, UX-first PWAs entirely in Java.
Free ebook & tutorial.
Embedding JSP webapp inside Vaadin app
Hi,
I've found some posts here and there about embedding a Vaadin app inside a JSP page, but I'm asking for the opposite: I'd like to know if it is possible to embed a full JSP-based webapp inside a Vaadin app and make it available through some path/url mapping. I need to integrate a report viewer, and I already embedded it inside a Vaadin window using a `BrowserFrame` calling to its own URL as a different Tomcat deployment but it cannot be outside my app because I need to share data between both applications, some of it being sensible in the form off login parameters and session parameters that cannot be shared through url parameters and neither should not be passed by post or similar "insecure" method.
Any help will be really appreciated ;)
I'm not sure if it's applicable in your case, but how about a shared database?
-Olli
Hi Olli and thanks for replying,
In fact, the database is shared between my Vaadin app and the report viewer.
To clarify a bit, I just found a similar question in Stack Overflow (made by someone 6 years ago and, unfortunately, without a successful answer) with a similar requirement:
http://stackoverflow.com/questions/7453811/access-internal-resource-in-vaadin-with-new-browser-window
The report viewer should change its datasource dynamically, depending on the user who is logged in my Vaadin application. The report viewer has such feature, but it needs to be aware of the parameters of which datasource to use for filling data in its report. Report viewer can accept parameters from GET and POST, but of course I don't want any database-related parameters in the calling URL. I'm trying to make my Vaadin app context parameters available in the viewer app, but without any success to this moment. And even if that could be possible, is not a recommended way.
If I could run the viewer (which is a full JSP-based app) inside a folder or so in my Vaadin app, it would be trivial to get there my session app which contain database-related data as user, etc.
Can you use SSL? That should be secure enough to hide any HTTP POST traffic from your Vaadin app to the report viewer.
-Olli
Thanks for suggesting, Olli. I already thought of it, and maybe it could be an option in the future, but for the moment it's a requierement not to use GET/POST :(.
I don't think there's a way you can serve the JSP page from the Vaadin application; I'd be happy to be proven wrong, of course. My current best idea is that you should save all relevant information to the DB, create a single-use token parameter with public-key crypto and fetch the data from the DB if the token evaluates correctly.
-Olli
I get the picture, Olly. The problem here is that the database connection for both the data for the reports and for the Vaadin app is get via user-level authentication; I mean, each user is using his own database credentials. That would impose a new user-independent database connection for storing the tokens/parameters and, in the end, the database authentication credentials themselves... Sounds a bit overcomplicated to me or strange at least.
Okay, I see your point - in that case my proposed solution obviously won't work. I'll have to think about this a bit.
-Olli
Thanks a lot for helping, Olli. In case I find a way (which I doubt), I'll post my solution here.
Hi,
just to better understand: what problems are you facing if you move the whole jsp app in the same Vaadin app war and use a BrowserFrame?
Hi Marco,
How would you do that? If you are familiar with Vaadin apps, you'll already know that they have their own structure. My jsp app has its root index.jsp, well, in the app root directory. If you put it (and the rest of files) in the root Vaadin app directory, when you navigate to http://localhost/yourApp, Vaadin bootstraper, doing its "magic" (which I don't have any interest in knowing how it works), takes care of everything and starts your app, no matter if you explicitly set http://localhost/yourApp/index.jsp in an attempt to start your JSP app instead -- any appended path to the base one will be ignored and redirected to the index Vaadin app; haven't you ever experienced that? I haven't found a way to "run" a JSP by directly calling it if it's placed inside a Vaddin app directory. If I'm missing something very obvious here please explain me, because my own experience and every reference to this problem I've found in the entire net points to being not possible. Not to say that is a very big mess placing the files of a JSP project in the same directory as a Vaadin one, which follow a totally different structure...
Hi,
the only way I know to serve jsp and a Vaadin on the same app is to not map Vaadin servlet /* but on a subpath (ie
@WebServlet(urlPatterns = {"/ui/*", "/VAADIN/*"}, ...); this way the jsp outside /ui/ and /VAADIN should be served by the default mappings of the servlet container.
If you can change this mapping you can maybe put the JSPs inside a WEB-INF subfolder and serve them with a custom servlet or filter forwarding the request to a RequestDispatcher.
But maybe this is not your case
Best regards
Marco
Hi Marco,
Thanks for pointing me in the right way. Well, at one point I thought about messing with mappings but quickly abandoned the idea as I had not much idea about how to do it. I'm already reading about it here, although it's a bit confusing:
https://vaadin.com/docs/-/part/framework/application/application-environment.html#application.environment.servlet-mapping
I'll keep you informed of my progress.
Hi,
for further investigations you can also take a look at how Vaadin Spring Servlet works with root mapping .
Best regards
Marco
Hi again Marco,
I'm following your advise almost literally; i.e., I used the following mapping:
@WebServlet(value={"/app/*", "/VAADIN/*"},asyncSupported = true)
This way now I can access my app with /app insted from the root path as I did previously (let's say http://localhost/myApp/app/ instead of http://localhost/myApp). Anyway, I tried putting my JSP-app in its own directory insyde my Vaadin project (relative to its root) and cannot access it in any way. That is, pointing to http://localhost/myApp/viewer/ returns a 404.
So the part that I'm missing is the "you can maybe put the JSPs inside a WEB-INF subfolder" one. I tried also putting my JSPs in myApp/src/main/webapp/WEB-INF, but of course that doesn't make it visible, too. And if I navigate to http://localhost/, I see three directories available to navigate to (META-INF/, VAADIN/, WEB-INF/), but none of them has contents.
Not to say that the ideal approach would be to keep the root path for displaying my Vaadin app as always was (http://localhost) and to "isolate" one folder somewhere that could be accessed from a custom path.
I'm taking a look at the Spring Servlet sources to see if I can get something...
It's weird that, after changing vaadin servlet url mapping, pointing directly to a jsp (not inside web-inf) gives you a 404.
It is also weird that WEB-INF folder is browsable.
What servlet container are you using? Is there perhaps a reverse proxy in front of the servlet container that does not map correctly?
Hi Marco,
Ok, directory navigation accross META-INF/, VAADIN/ and WEB-INF/ seems to be a matter of Jetty. I tried both with embedded Jetty that comes with Netbeans and with Tomcat. The later one doesn't allow to navigate through those three directories.
Anyway, putting the JSP in the root folder of my Vaadin project doesn't work - answer is a 404. The same result is got putting the folder inside src/main/webapp/WEB-INF or inside src/main/resources. No luck :(
Hi,
changing servlet mapping with jsp on root of the webapp works for me on jetty.
I can create a sample project in the evening, if it can be of help
Hi again Marco,
I'm really surprised that it works for you -- although I'm used to see my attemps fail several times before getting them working :/. I'll try it again, although in fact I'm doing it again at this moment and it fails. This is my directory structure in disk:
c:\projects\my_project --> this is where my Vaadin project is
|
-- viewer --> here is where the .jsp "servlet" is
|
-- src (etc)
|
-- target (etc)
|
pom.xml
So if I navigate to root (http://localhost:8080/), I get the fancy page you can see in the attachment.
If I navigate to http://localhost:8080/app (as I set up my mappings to work this way), my Vaadin app starts. That is the expected result.
Finally, If I navigate to http://localhost:8080/viewer, I get a 404. It should open a JSP page...
Now I noticed that maybe it has something to do with the default served document. I have an index.jsp, but the output message differs a little depending if I call it without or with the /index.jsp. Without it, the error message is:
HTTP ERROR 404
Problem accessing /viewer/.
Reason:Not Found
Powered by Jetty:// 9.3.9.v20160517
When I try to access explicitly setting the /index.jsp part, it says:
HTTP ERROR 404
Problem accessing
/viewer/index.jsp.
Reason:/viewer/index.jsp
Powered by Jetty:// 9.3.9.v20160517
I'll see if I find some logs to see if I can get something.
Hi,
try to move the viewer folder inside src/main/webapp.
This way the jsp should be available at url http://localhost:8080/viewer
HTH
Marco
You did it, Marco! I put it there and voilà! The page was served. In fact, I should have deduced it by myself; shame on me. I had the folder dates, name and structure as yyou can see in my previous attachment...
Anyway, now I'm facing problems that I'm almost sure are fault of the jsp app in 99% cases. It would be great if I could solve them and it would be superb if I could get rid of the /app part for calling the Vadding app.
Thanks a lot for helping, Marco ;)
Nice work, guys :)
It's not a common use case, but maybe there should be a demo for this.
-Olli
Well, it seems this is a recurrent question. I found at least a similar one in Stack Overflow and, unfortunately too late, an entire old thread about this (so old that even Vaadin wasn't called "Vaadin" then) where they already solved this problem:
https://vaadin.com/forum#!/thread/19771
Hi,
this is a hacky solution to run jsps togehter with a Vaadin app mapped to "/*".
Basically we use a filter (that intercepts all requests) to find a an existing servlet mapped to "*.jsp" (there should be at least one, but it is not mandatory by specification);
if there is one we forward all jsp requests to it, otherwise we go with the filter chain.
Maybe it is not the best solution (tested only on jetty and must be improved), but it could be a starting point to resolve your problem.
HTH
Marco
@WebFilter(urlPatterns = "/*", asyncSupported = true,
dispatcherTypes = {DispatcherType.REQUEST, DispatcherType.FORWARD})
public static class JspFilter implements Filter {
private String jspServletName;
@Override
public void init(FilterConfig filterConfig) throws ServletException {
jspServletName = filterConfig.getServletContext()
.getServletRegistrations().entrySet().stream()
.filter(e -> e.getValue().getMappings().contains("*.jsp") )
.map(Map.Entry::getKey)
.findFirst().orElse(null);
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) request;
String path = req.getRequestURI();
if (jspServletName != null && path.matches("(?i).*\\.jsp$")) {
req.getServletContext().getNamedDispatcher(jspServletName).forward(request, response);
} else {
chain.doFilter(request, response);
}
}
@Override
public void destroy() {
}
}
@WebServlet(urlPatterns = {"/*"}, name = "MyUIServlet", asyncSupported = true)
@VaadinServletConfiguration(ui = MyUI.class, productionMode = false)
public static class MyUIServlet extends VaadinServlet {
...
}
Thanks a lot for sharing, Marco. At this moment I'll keep using the prior approach, as I can live for now with accessing the app with his own subpath. Also I still have to solve/configure some things in the "embedded application" in order to get it properly running, as it by default needs some paths to be in the root path and now it resides in its own directory, so it's not time yet to mess with those hacky methods, hehe. But I'll note in case I need it for the future.
Keep up the good work!