I am looking for using jersey with embedded Jetty for implementing web APIs for our service. I see code where ServletContextHandler , ServletHolder and all these classes are used to let Jetty know about the Jersey handlers. I am interested to know under the hood, like what happens when we compile this code, how jetty actually discovers the jersey handlers. I know that if I start reading the documentation, I will be able to figure out, however, looking for some quick links that covers this topic. Is there any such link?
Thanks.
Jetty can act as a http server and also a servlet container who deals with the lifecycle of servlets (init, service, destroy)
etc. A servlet is a java class that extends HttpServlet class and can override init, service, destroy methods etc. Once jetty
receives a request whose URL matches with that of a servlet, it loads the servlet in memory (if not already there), calls
service method, and keeps it in memory until it destroys it.
Jersey library has provided a standard way of writing RESTful APIs where classes are annotated with tags like say GET/POST
etc and the URL. These classes are called resource classes. It has also provided a servlet whose name is ServletContainer
to hook up with Jetty's servlet container, that intercepts Jetty's request to process servlet (like for any servlet request to jetty
this is the one class, that receives the request first).
What this servlet does is it examines the request, matches with the resource classes URL that it is informed about, and then transfers
control to that method of that resource class (i think it uses reflection for this routing). Therefore, the resource
classes are not servlet itself, but the ServletContainer class of jersey is the only servlet active in the system.
The list of resource classes ServletContainer knows about is configured by this property called "com.sun.jersey.config.property.packages"
The benefit of using Jersey is implementing your REST APIs is you are using standard way of writing your code that you can
deploy to any other standard servlet container if needed in future like tomcat, ...
Related
I'm trying to use Spring Web on Tomcat to build an API server. This is just a request-response API, not a full web app - it won't have any web pages or static assets like images. As such, I think SpringWebMVC is the wrong technology since I don't actually want the MVC part of it, so I'm just just trying to use plain old SpringWeb.
Unfortunately, practically every tutorial I've found online uses the org.springframework.web.servlet.DispatcherServlet which is from the MVC package, not from the base package. In the base package, the only viable HttpServlet implementation I found was org.springframework.web.context.support.HttpRequestHandlerServlet. However, this servlet doesn't seem to honor #RequestMapping or #RequestBody or #ResponseBody annotations in the handler.
I thought perhaps I'd just create multiple handler servlets and just use the url-pattern on each of them in the web.xml to route them correctly, but it turns out url-pattern doesn't support path variables either (at least as far as I can tell).
So is there a way to properly set up this servlet to be able to handle request mappings with path variables like so?:
GET /foo/{fooId}
POST /foo/{fooId}/fooOperation
POST /bar/{barId}/barOperationA
POST /bar/{barId}/barOperationB
POST /bar/{barId}/barOperationC
How to implement a clean up method after request finish process in a spring boot application for clean data such as thread locals
I try with ServletRequestListener.requestDestroyed api, but it does not get hit after the request finish
One possible answer is that you have neglected to register the listener. The Servlet javadocs say:
In order to receive these notification events, the implementation class must be either declared in the deployment descriptor of the web application, annotated with WebListener, or registered via one of the addListener methods defined on ServletContext.
There may be other ways to implement this using Spring; e.g. using a handler intercepter; see Remove ThreadLocal object within a Spring MVC website?
If you were using plain servlets (without the Spring MVC infrastructure), another approach would be to do the cleanup in your servlet's service method or the doXxx methods. Or in a Filter in front of the servlet.
I've been reading that the JAX-RS is built on top of servlets. Is this literally true, or it just mean that it is a higher level component? If it is, how does that work? Does JAX-RS create a servlet which parses the request and manually initializes #Path annotated classes and passes the modified parameters to them? The JSR does not seem to specify this, and none of the books that mention it go into any details.
note: I don't have trouble deploying JAX or servlets, I am just curious about the details, as it would provide a better understanding of how the web container works.
I've been reading that the JAX-RS is built on top of servlets. Is this literally true,
Simply put, YES, the JAX-RS specification is built on top of Servlets, and any other deployment method (such as mentioned by #Jilles van Gurp) is implementation specific.
Does JAX-RS create a servlet which parses the request and manually initializes #Path annotated classes and passes the modified parameters to them?
JAX-RS doesn't do anything. It's the implementation (e.g. Jersey, RESTEasy, CXF) that implements the entry point servlet. Does the implementation need to explicitly parse the request? No, not all of it. Most of that stuff is handled by the servlet container. Mainly the implementation will just need to parse the request body (as "request" implies more than just the body, e.g URL, headers).
Basically, everything related to JAX-RS is handled by the implementation. The servlet container has nothing to with anything but passing the HttpServletRequest and HttpServletResponse, just like if you were to implement your own servlet. If you were to make your own JAX-RS implementation, the servlet passing you the HttpServletRequest(Response) is the request entry point, and everything else is up you.
EDIT
as "request" implies more than just the body, e.g URL
Bad example. Actually, the JAX-RS implementation would parse the URL in order to get path parameters and query parameters. Though the Servlet container will parse the URL and add query parameters to the HttpServletRequest parameters map, that map also has form POST parameters, so the implementation will need to do it's own parsing of the query parameters also.
Jax rs does not really use or depend on servlets directly but it is commonly implemented on top of it by frameworks that implement it. In that case your application is wrapped with a servlet that delegates incoming requests to your jax rs endpoints and the whole thing is deployed in a servlet container such as tomcat or jetty.
However, for example jersey (the reference implementation) can run without a servlet wrapper in a standalone server. We use grizzly as our container for this. There is no servlet container in our application and we use the grizzly container instead. Of course the grizzly container provides a very similar execution model but you don't need a full blown application server to run it. go here for more details on grizzly
This is the official documentation of Jboss Resteasy.
RESTeasy is implemented as a ServletContextListener and a Servlet and deployed within a WAR file.
JAX-RS implementations do use ServletAPI for routing and parsing the requests. It is implementation detail and need not be mentioned in the specification.
Is it possible to create a webservice with apache cxf (soap/rest) by "using the servlet transport without Spring and without web.xml file"?
No Its not possible.
The service will be needing the web deployment descriptor.
You can extend
CXFNonSpringJaxrsServlet for REST
and
CXFNonSpringServlet for SOAP
web-services in Apache CXF to avoid using Spring, but then you need to register them in web.xml.
You have to either use Spring configuration or web.xml.
Refer: Apache CXF - How to register a SOAP service without Spring?
It is possible. Took me quite a bit of work to figure this out for my own project and thought I'd share.
In my context, we're using OSGi HTTP Service to publish JAX-RS resources using a Jersey Servlet container and I wanted to do the same thing with CXF for JAX-WS resources.
Your class extending CXFNonSpringServlet should include the following:
private Object obj; // JAX-WS resource singleton
#Override
public void loadBus(ServletConfig conf)
{
super.loadBus(conf);
JaxWsServerFactoryBean factory = new JaxWsServerFactoryBean();
factory.setBus(getBus());
factory.setAddress("/some/path");
factory.setServiceBean(obj);
Server cxfServer = factory.create();
}
Note that you may load as many resources within a single servlet as you find needful. Also note that the path in factory.setAddress() is appended to the path at which you register the servlet.
Also note that I'm using the singleton pattern, rather than the handler-class pattern. I'm sure this could be modified simply to fit the other paradigm.
We know that whenever a request for a servlet comes, servlet container will first check web.xml file for url and corresponding servlet classes. This is fine, But the confusion comes after that. Suppose I am using load-on-startup property. SO, the servlet should be ready before first call comes in. In that case container need servlet Config object to make servlet in work. But again load-on-start up and init-parameter for servlet is defined in web.xml file. So when exactly container uses web.xml?( when load-on-startup property is used then container can not obviously wait for first call, again container has to read web.xml file to know whether that property is used with any servlet.)
It will be better if some one can clear my confusion. Please provide some dependable link also if possible.
Loading and Instantiation:
The servlet container is responsible for loading and instantiating servlets. The loading and instantiation can occur when the container is started, or delayed until the container determines the servlet is needed to service a request.
When the servlet engine is started, needed servlet classes must be located by the servlet container. The servlet container loads the servlet class using normal Java class loading facilities. The loading may be from a local file system, a remote file system, or other network services. And as the servlets are declared in the web.xml, this file is loaded and read by the container during container startup.
Initialization:
After the servlet object is instantiated, the container must initialize the servlet before
it can handle requests from clients.The container initializes the servlet instance by calling the init method of the Servlet interface with a unique (per servlet declaration) object implementing the ServletConfig interface.
Ref: JSR-000315 JavaTM Servlet 3.0
web.xml is read as soon as you deploy your application on a web server. For the sake of understanding, you can assume container is nothing but your web server. Although web server has more than just a web container.
Web server reads the web.xml, and loads the context config, load on startup servelts,etc. web.xml is the file through which you tell your container/server about your application. Your web application sits inside the web server, and server intercepts all the incoming requests, decides to which application the request should be forwarded depending on the context.