Configuring velocity within a tomcat web application. (Cookbook wanted) - java

I have recently been introduced to the Velocity project.
I have written a template and have run it as a simple Java application.
Integration within my existing web project has not been that easy.
Can anyone supply a cookbook for integrating Velocity and Tomcat?
Thanks all!

Tomcat is a servlet container; you don't need to integrate Velocity with it but rather with your application. How exactly that should be done depends on your application:
If you're using Spring, it has VelocityViewResolver available along with instructions on how to set it up.
If you're using straight servlets / JSP take a look at VelocityViewServlet
Other frameworks (Struts / etc...) may or may not have built-in Velocity integration; take a look at this page (bottom section) for more details.

The straightforward way is to define a VelocityViewServlet in web.xml
<servlet>
<servlet-name>view</servlet-name>
<servlet-class>org.apache.velocity.tools.view.servlet.VelocityViewServlet</servlet-class>
<init-param>
<param-name>org.apache.velocity.properties</param-name>
<param-value>/WEB-INF/velocity.properties</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>view</servlet-name>
<url-pattern>*.vm</url-pattern>
</servlet-mapping>
In velocity.properties
#resource loaders
resource.loader = production
production.resource.loader.class = org.apache.velocity.tools.view.WebappResourceLoader
Then put your template at the root of your webapp and access it from the web browser using its name as the URL. e.g.
http://localhost:8080/index.vm

Related

Vaadin 19/20 + official gradle plugin - custom servlet subpath to run within existing legacy web application along another Java framework

Environment
Spring 4.3 (no Spring Boot!), JDK 8/11, Tomcat 8.5.x, Vaadin 19/20-SNAPSHOT
I have a legacy webapp running another servlet-api-driven web framework at http://app.com. I want to add a path that adds a Vaadin-driven UI to this application - let's say at http://app.com/vaaadin-app . I'm using the newly developed official Gradle plugin. (Both Vaadin and non-Vaadin web applications should be run from single WAR, effectively sharing single classloader for shared state access, so no proxy/rewrite/etc solutions will help here).
Problem
After adding dependencies the Vaadin app is properly built and war created. Yet as soon as I call http://app.com (not http://app.com/vaadin-app) it looks like Vaadin servlet/whatever is taking over all requests. It looks like it is automatically initialized by (I guess) servlet 3.0 annotations.
Question
How can I enable Vaadin only for http://app.com/vaadin-app and keep it away from altering requests not directed there? I know with Vaadin 8 it was possible to achieve this with:
<servlet>
<servlet-name>vaadinServlet</servlet-name>
<servlet-class>com.vaadin.server.VaadinServlet</servlet-class>
<init-param>
<param-name>UI</param-name>
<param-value>app.vaadin.additem.AddItemUI</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>vaadinServlet</servlet-name>
<url-pattern>/vaadin-app/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>vaadinServlet</servlet-name>
<url-pattern>/VAADIN/*</url-pattern>
</servlet-mapping>
In other words: how to prevent Vaadin 19/20 from spawning itself automatically for /* but to serve application only when user hits the /vaadin-app/* servlet path???
I think in case of maven plugin there was the "disable.automatic.servlet.registration" option to achieve this? But I don't see anything like this in case of Gradle plugin.
Thanks!
The servlet registration in Vaadin should have nothing related to Gradle, so applying the generic instructions should work. The automatic servlet registration is omitted if you define a VaadinServlet manually (extend it and map the servlet to your location of choice using #WebServlet).
Check this part of the documentation for more details: https://vaadin.com/docs/latest/flow/advanced/application-lifecycle/#automatic-servlet-registration

What is the purpose of CXF servlet

I was going through a demo project setup for Restful webservice using Apache CXF, where I happened to come by a piece of code inside web.xml:
<servlet>
<servlet-name>CXFServlet</servlet-name>
<servlet-class>org.apache.cxf.transport.servlet.CXFServlet
</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>CXFServlet</servlet-name>
<url-pattern>/services/*</url-pattern>
</servlet-mapping>
I did not really understand the use of a servlet class in this web.xml. I googled for org.apache.cxf.transport.servlet.CXFServlet and found:
The CXFServlet class, which is defined by Apache CXF, is generated and
registered to handle incoming requests.
Now, I really do not understand what that line means
Does this servlet pose as a front-controller, like in Spring MVC flow?
What is the actual purpose of using this servlet class?
How does CXF use Spring to provide XML configuration of services defined in the project?
Does org.glassfish.jersey.servlet.ServletContainer serve the same purpose in Jersey Implementation as org.apache.cxf.transport.servlet.CXFServlet with Apache CXF?
Help me clarify these questions.
The JAX-RS specification is built on top of the Servlet specification. Each implementation should have a Servlet as an entry point to the application. When a request comes in, it gets processed by that Servlet. CXFServlet is CXF's implementation of that entry point Servlet.
Does this servlet pose as a front-controller, like in Spring MVC flow?
Pretty much. It's analogous to Spring MVC's DispatcherServlet
What is the actual purpose of using this servlet class?
As mentioned above, it's the entry point to the JAX-RS (CXF) application.
How does CXF use Spring to provide XML configuration of services defined in the project?
It uses Spring to wire up components; connect all of them together. But it's not required (see also).
Does org.glassfish.jersey.servlet.ServletContainer serve the same purpose in Jersey Implementation as org.apache.cxf.transport.servlet.CXFServlet with Apache CXF?
Pretty much.

spring web services configuration in web.xml?

I am using spring-ws and I have the below configuration in my web.xml
<servlet>
<servlet-name>spring-ws</servlet-name>
<servlet-class>org.springframework.ws.transport.http.MessageDispatcherServlet</servlet-class>
<init-param>
<param-name>**transformWsdlLocations**</param-name>
<param-value>true</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>spring-ws</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
Here I have transformWsdlLocations configured. Please explain me the use of transformWsdlLocations here. I am using the dynamic WSDL generation concept.
Is transformWsdlLocations really required for dynamic WSDL generation?
Thanks!
Given that it only takes a couple of minutes to remove the value and redeploy your application, I would advise you to do that and see what happens. Just try accessing the WSDL through "localhost" and through "127.0.0.1", and see what differences there are.
However I'll explain what you should see here...
When you read the WSDL that is generated, you should find that there are URLs in there.
i.e. From the local machine you might use:
http://localhost:8080/myservice.wsdl
But when you go live, your service might be:
http://www.<yourdomain>.com/myservice.wsdl
You don't want someone downloading the WSDL from your production domain to have those values populated with "localhost:8080". Likewise, you can't test your service properly if the URL being returned in the WSDL is for your production server. Or you might have multiple production services with different URLs.
transformWsdlLocations ensures that this is generated dynamically based on whatever URL is being used to access the service.
It is not needed for dynamic WSDL generation, but I have always found it very useful to have it. However, it is not enabled by default, so if you do want those URLs to be generated dynamically then it's best to include it.

How to dynamically configure the WebLogicCluster property outside of web.xml

I have a web application deployed as war file in weblogic 10.3.3. Now I want to make this application clusterable. For this I'm using the HttpClusterServlet from Weblogic as a load balancer. According to the documentation I can put this servlet configuration into the web.xml
<servlet>
<servlet-name>HttpClusterServlet</servlet-name>
<servlet-class>weblogic.servlet.proxy.HttpClusterServlet</servlet-class>
<init-param>
<param-name>WebLogicCluster</param-name>
<param-value>server-1:7122|server-1:7123</param-value>
</init-param>
</servlet>
The problem is that this configuration is hard wired at build time and can't be reconfigured at runtime. For instance I would like to be able to add 5 more servers dynamically. I had several ideas to solve that problem:
Extend the weblogic.servlet.proxy.HttpClusterServlet with an own servlet implentation. This is not possible, the class is final.
Use a servlet filter to reconfigure the servlet. The servlet is not accessible anymore through ServletContext().getServlet(String) since Java Servlet API 2.1, with no direct replacement.
Reflection might be an option, but I couldn't figure out a reliable way to access the configuration
All of my attempts to reconfigure this init-param externally failed so far. I'm open to any solutions.
This might help How to externalize web.xml servlet init-param? Spring DelegatingFilterProxy for Servlets? Even if your not using Spring it wouldn't be too hard to port that servlet to another IoC container.

How can I list all deployed jax-ws webservices?

I have deployed some jax-ws webservices in a tomcat:
web.xml:
...
<servlet>
<servlet-name>WebServiceJaxWs</servlet-name>
<servlet-class>...a bean of mine which overwrites WSServletDelegate</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
...
The webservices themselves are defined in the sun-jaxws.xml
They work just fine.
I now need to write a jsp, which displays all deployed webservices. I have access to the servlet context, but I simple cannot find a way to access the WebServiceJaxWs Servlet. My idea was to access it and then enumerate the published endpoints.
Any ideas?
The manual way I can think of is to parse your sun-jaxws.xml and get the information from there.
Maybe you could deploy all those web services as JMX beans and see them using JConsole.

Categories