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.
Related
So here I am writing my first REST Service and one thing regarding which my understanding is not clear is that there is an entry for a servlet in my web.xml file as follows:
<servlet>
<servlet-name>CXFServlet</servlet-name>
<servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
So how is my service using this servlet?As in what's the use of a servlet in a REST Service?Is the service just a framework that uses the servlet's built in HTTP methods?
CXFServlet is one of the transport Apache CXF uses in order to publish rest services. In other words CXF uses under the hood when publishing a Rest services JAXRS annotated (#Path) a simple Java Servlet.
So the final URL where your rest services will be deployed is a concatenation between CXFServlet mapping and your rest services path.
There are other kind of transport. See http://cxf.apache.org/docs/transports.html just to understand that they are more options.
Hope this clarify you.
From the textbook "RESTful Java with JAX-RS" we can read:
If our application server is JAX-RS-aware or, in other words, is tightly integrated with JAX-RS declare our ShoppingApplication class as a servlet:
<?xml version="1.0"?>
<web-app>
<servlet>
<servlet-name>Rest</servlet-name>
<servlet-class>
com.restfully.shop.services.ShoppingApplication
</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Rest</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
</web-app>
If our application server is not JAX-RS-aware, you will have to specify the JAX-RS provider's servlet that handles JAX-RS invocations. The Application class should be specified as an init-param of the servlet:
Now my question is: Is Tomcat a JAX-RS aware Servlet container? How do you distinguish a servlet container JAX-RS aware from one which is not JAX-RS aware? Why in the first case it's possible to use your custom class which extends javax.ws.rs.core.Application as a Servlet?
"Is Tomcat a JAX-RS aware Servlet container?"
No.
"How do you distinguish a servlet container JAX-RS aware from one wich is not JAX-RS aware?"
The fact this it is only a Servlet container, should tell you that it is not "JAX-RS aware". JAX-RS is part of the Java EE specification. Servlet containers supports exactly what their name implies; a container for Servlets. They might have support for other little features like JSP, but will not support the entire EE spec. This is not part of their design. If you want to use JAX-RS in a Servlet container, you need to add an implementation, like Jersey or Resteasy
When you say Servlet container you think of servers like Jetty, Tomcat, Undertow, Grizzly. If you want full Java EE support then you need to get an actual Java EE application server that supports the entire spec, like JBoss/Wildfly, Glassfish, TomEE, WebSphere, WebLogic.
"Why in the first case it's possible to use your custom class wich extends javax.ws.rs.core.Application as a Servlet?"
I was not able to produce a working example with either Glassfish 4.0 or Wildfly 8.1, nor is this specified anywhere in the JAX-RS specification. In Glassfish, I'll get an exception about ShoppingApplication not being a Servlet, and in Wildfly I'll just get a NotFoundException, meaning the application is never loaded.
The closest thing I could find to what the book states, is to specify the name of the application class as the <servlet-name> (which is part of the JAX-RS spec, but is not at all dependent on being deployed to a Java EE server)
<servlet>
<servlet-name>com.restfully.shop.services.ShoppingApplication</servlet-name>
</servlet>
<servlet-mapping>
<servlet-name>com.restfully.shop.services.ShoppingApplication</servlet-name>
<url-pattern>/api/*</url-pattern>
</servlet-mapping>
This is from the JAX-RS spec
If an Application subclass is present that is not being handled by an existing servlet, then the servlet added by the ContainerInitializer MUST be named with the fully qualified name of the Application subclass.
Read JAX-RS spec - Plublication - 2.3.2 Servlet for the completely specification on standard JAX-RS deployment options. Any other deployment/configuration option not specified is implementation specific.
I have a Spring MVC web application which provides RESTful web services via a controller class (annotated with #Controller) which has methods mapped to specific request types and signatures via #RequestMapping annotations.
I have attempted to integrate a BlazeDS service destination into the mix by 1) adding the HttpFlexSession listener to the web.xml, 2) adding the flex:message-broker and flex:remoting-destination declarations to my Spring application context configuration file, and 3) adding a generic /WEB-INF/flex/services-config.xml.
The above BlazeDS integration steps appear to have hosed my RESTful web services, in that it appears that requests are no longer being routed to the controller methods.
Is it even possible to do this, i.e, to have a single web application which 1) services HTTP requests via request mapped controller methods and 2) services remote object method calls (i.e. from a Flex client) via a BlazeDS service? If so then can anyone tell me what it may be that I'm doing wrong?
Thanks in advance for your help.
Yes, it's possible, but it requires a little extra configuration.
Essentially you need to create two seperate dispatchers, each with a different path.
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/applicationContext.xml</param-value>
</context-param>
<servlet>
<name>flex</name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet>
<name>spring-mvc</name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>flex</servlet-name>
<url-pattern>/messagebroker/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>spring-mvc</servlet-name>
<url-pattern>/app/*</url-pattern>
</servlet-mapping>
Now requests to http://yourapp/app/somewhere are routed to Spring MVC, and requests to http://yourapp/messagebroker are routed through BlazeDS.
Also, you'll need to split out your spring context files into three:
A common context (named applicationContext.xml in the above example)
One for Spring MVC (named spring-mvc-servlet.xml in the above example)
One for Flex (named flex-servlet.xml in the above example)
Check out this section from the Spring/BlazeDS docs for more info.
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.
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