JAX-RS application deployment using web.xml, Servlet 3.0 and Jersey

I am trying to deploy my application using web.xml, servlet 3.0 and jersey API. Unfortunately, it does not work.

This is MyApplication.class:

package com.example; public class MyApplication extends Application { public Set<Class<?>> getClasses() { Set<Class<?>> s = new HashSet<Class<?>>(); s.add(MyResource.class); return s; } } 

This is MyResource:

 @Path("/helloworld") @Produces(MediaType.TEXT_PLAIN) public class MyResource { @GET public String getHello() { return "HelloWorld !"; } } 

And my web.xml:

  <web-app> <servlet> <servlet-name>com.example.MyApplication</servlet-name> </servlet> <servlet-mapping> <servlet-name>com.example.MyApplication</servlet-name> <url-pattern>/webapi/*</url-pattern> </servlet-mapping> </web-app> 

On the client side, I use this URL: HTTP: // local: 8080 / [project_name] / WebAPI / HelloWorld

And I have this error:

 java.lang.NullPointerException sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:294) java.lang.ClassLoader.loadClass(ClassLoader.java:247) org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1629) org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1559) org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:491) org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99) org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:953) org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408) org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1023) org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589) org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.run(AprEndpoint.java:1852) java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:895) java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:918) java.lang.Thread.run(Thread.java:662) 

What happened?: / I am using Tomcat 7.

PS: with servlet 2.x it works:

  <servlet> <servlet-name>Jersey Web Application</servlet-name> <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class> <init-param> <param-name>jersey.config.server.provider.packages</param-name> <param-value>com.example</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>Jersey Web Application</servlet-name> <url-pattern>/webapi/*</url-pattern> </servlet-mapping> 

but I will need asynchronous mode later.

Thanks!

+4
source share
4 answers

Update:. After writing this answer, I figured out how to avoid using web.xml on Tomcat using the official Glassfish Jersey implementation. See here for more details.

If you are using a standard Tomcat installation (or some other servlet container), AFAIK you cannot explicitly prevent servlets from running in the web.xml . Since you need to use web.xml in any case, the easiest way to make serviced work services completely forget about the javax.ws.rs.core.Application extension and just specify the context path. You can use standard jax-rs annotations to declare actual web services.

web.xml:

 <?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0" > <servlet> <servlet-name>rest-test</servlet-name> <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class> <init-param> <param-name>com.sun.jersey.config.property.packages</param-name> <param-value>com.domain.mypackage</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name> rest-test</servlet-name> <url-pattern>/rest/*</url-pattern> </servlet-mapping> </web-app> 

Two points worth noting:

  • You will need to link the REST implementation in your WAR file, as servlet containers usually do not contain. Since Jersey is the reference implementation of JAX-RS, this is the one I use in the servlet-class element above. You can replace this with the Apache CXF implementation if you want.

  • The init-param element tells Jersey which of your packages is looking for Java files with web service annotations. Edit this to point to your web services. Please note that if you decide to use apache CXF instead of Jersey, the material needed in any init-param elements will be different. Someone who knows CXF, write what they will be.

If you are using Maven, just add the dependency to the jersey-servlet in the dependencies section of your pom.xml file:

 <dependencies> <dependency> <groupId>com.sun.jersey</groupId> <artifactId>jersey-servlet</artifactId> <version>1.18.2</version> </dependency> ... </dependencies> 

After that, your web services are advertised using standard JAX-RS annotations in your Java classes:

 package com.domain.mypackage; import javax.ws.rs.Consumes; import javax.ws.rs.Produces; import javax.ws.rs.GET; import javax.ws.rs.MatrixParam; import javax.ws.rs.Path; // It good practice to include a version number in the path so you can have // multiple versions deployed at once. That way consumers don't need to upgrade // right away if things are working for them. @Path("calc/1.0") public class CalculatorV1_0 { @GET @Consumes("text/plain") @Produces("text/plain") @Path("addTwoNumbers") public String add(@MatrixParam("firstNumber") int n1, @MatrixParam("secondNumber") int n2) { return String.valueOf(n1 + n2); } } 

That should be all you need. If your Tomcat installation is performed locally on port 8080 and you deploy your WAR file to the myContext context, go to

 http://localhost:8080/myContext/rest/calc/1.0/addTwoNumbers;firstNumber=2;secondNumber=3 

... should produce the expected result (5).

Hooray!

* Someone please correct me if you know a way to add a Jersey servlet to a context in Tomcat without using web.xml - perhaps using a context or a lifecycle listener?

+7
source
 package com.example; @ApplicationPath("/webapi") public class MyApplication extends Application { public Set<Class<?>> getClasses() { Set<Class<?>> s = new HashSet<Class<?>>(); s.add(MyResource.class); return s; } } 
0
source

You need to create web.xml in the WEB-INF folder with the following line of code

 <?xml version="1.0" encoding="UTF-8"?> <web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"> <servlet> <servlet-name>ServletAdaptor</servlet-name> <servlet-class> org.glassfish.jersey.servlet.ServletContainer </servlet-class> <init-param> <param-name>jersey.config.server.provider.packages</param-name> <param-value>package where MyResource resides</param-value> </init-param> <init-param> <param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name> <param-value>true</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>ServletAdaptor</servlet-name> <url-pattern>/webresources/*</url-pattern> </servlet-mapping> <session-config> <session-timeout> 30 </session-timeout> </session-config> </web-app> 

Now you can remove your MyApplication class. Web service deployment and testing. he will work

-one
source

Visit this link may help: https://jersey.java.net/documentation/latest/deployment.html#deployment.servlet.2

: 4.7.1. Servlet Container 2.x

 <web-app> <servlet> <servlet-name>MyApplication</servlet-name> <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class> <init-param> ... </init-param> </servlet> ... <servlet-mapping> <servlet-name>MyApplication</servlet-name> <url-pattern>/myApp/*</url-pattern> </servlet-mapping> ... </web-app> 
-one
source

Source: https://habr.com/ru/post/1500323/


All Articles