Currently, it seems like my jax-rs services is using with Jersey ServletContainer but running on Tomcat. This baffled me because according to my understanding, Jersey is a server that have more functionality than Tomcat, and don't contain Tomcat, but now, my project is using Jersey's library but running on Tomcat, how could this happen?
Below is my web.xml
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
<!-- Jersey Servlet -->
<servlet>
<servlet-name>jersey-servlet</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>jersey.config.server.provider.packages</param-name>
<param-value>main.java</param-value>
</init-param>
<init-param>
<param-name>jersey.config.server.provider.classnames</param-name>
<param-value>org.glassfish.jersey.media.multipart.MultiPartFeature</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>jersey-servlet</servlet-name>
<url-pattern>/services/*</url-pattern>
</servlet-mapping>
Below is my pom.xml(I used Maven):
<modelVersion>4.0.0</modelVersion>
<packaging>war</packaging>
<build>
<sourceDirectory>src</sourceDirectory>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>2.6</version>
<configuration>
<warSourceDirectory>web</warSourceDirectory>
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>asm</groupId>
<artifactId>asm</artifactId>
<version>3.3.1</version>
</dependency>
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20140107</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.40</version>
</dependency>
<!-- servlet dependencies -->
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-servlet</artifactId>
<version>2.19</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.core</groupId>
<artifactId>jersey-server</artifactId>
<version>2.19</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.core</groupId>
<artifactId>jersey-client</artifactId>
<version>2.19</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-multipart</artifactId>
<version>2.19</version>
</dependency>
</dependencies>
Tomcat is a Java web server, which implements several, but not all, Java EE specifications. Another Java web server would be Jetty. They differ from full application servers like Glassfish or JBoss / WildFly in the number of Java EE specifications they implement. The rather minimal Tomcat implements JavaServer Pages and Java Servlets, which is enough for a lot of applications.
Jersey is a Java library for both serving and calling REST (or mainly HTTP, since not everything is REST) APIs. It's build on top of Java EE specifications, so it can be used on any server that implements these specifications, e.g. Tomcat.
In your web.xml file you can define multiple servlets. What the servlet does is defined by the <servlet-class> element. You could pass your own implementation on top of the HttpServlet. In your case, you are using the Jersey servlet, which then manages all requests to the URLs it is mapped to (<servlet-mapping>). You can now learn to work with Jersey, implemented your desired API behaviour and build a web archive (.war). This web archive can then be deployed to any web server, that implements the required specifications, e.g. Tomcat. If you start using other Java EE technologies like Enterprise JavaBeans, you need to check which server implementation implements this technology. You could use Glassfish, there would be no difference for Jersey.
EDIT: I forgot to say that Jersey is one possible (the reference) implementation for the JAX-RS specification, like Tomcat is one possible Java Servlet (and others) implementation. Nevertheless, one is a web server and the other is a web service library, so its not possible to compare them or say that one has "more functionality than" the other.
Tomcat is a Servlet container. If Jersey has a Servlet, Jersey can run in Tomcat.
Related
I´ve created an maven project with the jersey archetype and attached a tomcat server to it. My tomcat server is running, but when i try to access to a resource, it does not appear (Error 404:Not found,
The required resource is not available.)
I already have tried to change the server path to use tomcat installation option. Also, i added a project facet with a dynamic project module.
web.xml
<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.telusko.pablo</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Jersey Web Application</servlet-name>
<url-pattern>/webapi/*</url-pattern>
</servlet-mapping>
pom.xml
<dependencies>
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-servlet-core</artifactId>
<!-- use the following artifactId if you don't need servlet 2.x compatibility -->
<!-- artifactId>jersey-container-servlet</artifactId -->
</dependency>
<!-- uncomment this to get JSON support
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-binding</artifactId>
</dependency>
-->
</dependencies>
<properties>
<jersey.version>2.26-b03</jersey.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
</project>
I only expect to can access the resources and not get the error 404.
I am trying to set up a simple Java web application using jersey for web services. However I have de following problem.
The tomcat server can’t find the resource http://localhost:8081/OnlineShop/rest/books/list but it can find my simple servlet http://localhost:8081/OnlineShop/index
I have the following web.xml
In the other hand I noticed that com.sun.jersey.spi.container.servlet.ServletContainer is present in my project because I added the dependency using maven however jersey.config.server.provider.packages is not present. Maybe that is the problem but I don’t know the exact dependency which I have to add.
My BookRest.java has the following code and is on the com.shop.rest package.
Finally my pom.xml has the following dependencies.
<dependencies>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-server</artifactId>
<version>1.19</version>
</dependency>
<dependency>
<groupId>net.sf.json-lib</groupId>
<artifactId>json-lib-ext-spring</artifactId>
<version>1.0.2</version>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-servlet</artifactId>
<version>1.18</version>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-core</artifactId>
<version>1.19</version>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-client</artifactId>
<version>1.19</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.core</groupId>
<artifactId>jersey-common</artifactId>
<version>2.17</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-servlet-core</artifactId>
<version>2.17</version>
</dependency>
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-web-api</artifactId>
<version>7.0</version>
<scope>provided</scope>
</dependency>
</dependencies>
Please, please get rid of this whole project. You're obviously a beginner and seem to be just putting random configurations and dependencies together, maybe from different tutorials. Your dependencies are incompatible and your web.xml configuration is wrong. Like i said, scrap the whole project and start from scratch. If you are just beginning, you should use one of the startup apps.
You're in Netbeans, so just do the following
File → New Project
Maven → Project from Archetype
Search jersey-quickstart-webapp
Select the one with the Group ID org.glassfish.jersey.archetypes
The latest version should be displayed.
Should be self explanitory from there
You will that the only dependency added is
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-servlet-core</artifactId>
<!-- use the following artifactId if you don't need servlet 2.x compatibility -->
<!-- artifactId>jersey-container-servlet</artifactId -->
</dependency>
And the web.xml will look something like
<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.stackoverflow.jersey</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Jersey Web Application</servlet-name>
<url-pattern>/api/*</url-pattern>
</servlet-mapping>
This will get you a simple app up and running. You will see a dependency that you need to un-comment for JSON support. Un-comment it. Or better yet, un-comment it, then change jersey-media-moxy to jersey-media-json-jackson. Jackson is IMO a better JSON library.
Also keep the Jersey Documentation handy for some good reading and reference material for working with Jersey
I have a project with multiple modules.
Two of them generate war files.
One war file is a REST application and provides a couple of resources.
The Other war file is a Angular JS web application (static content only) to talk to the REST backend.
For demo purposes I'd like to deploy both war-files very easily with mvn jetty:run
For development purposes I'd like to deploy them from my IDE (e.g. Eclipse Servers View).
When I do the deployment on a single Jetty Server (v9.0.7.v20131107) manually by starting the server and copiing the war-files to the deployment folder everything comes up.
When starting the jetty by mvn jetty:run both war files get deployed, but somehow the REST Resources do not get deployed.
I am using Jersey 2. When deploying manually I get a log message like
Nov 14, 2013 10:44:37 PM org.glassfish.jersey.server.ApplicationHandler initialize
INFO: Initiating Jersey application, version Jersey: 2.4 2013-10-24 18:25:49...
However this message is not been shown when starting with mvn jetty:run. Therefore I assume that Jersey does not kick in.
For Dependency-Injection I use spring.
This is the parent pom in /pom.xml with the jetty-maven-plugin configuration
<project ...>
...
<build>
<plugins>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<version>9.0.7.v20131107</version>
<configuration>
<scanIntervalSeconds>2</scanIntervalSeconds>
<contextHandlers>
<contextHandler implementation="org.eclipse.jetty.webapp.WebAppContext">
<war>module1/target/module1-${project-version}.war</war>
<contextPath>/module1</contextPath>
</contextHandler>
<contextHandler implementation="org.eclipse.jetty.webapp.WebAppContext">
<war>module2/target/module2-${project.version}.war</war>
<contextPath>/module2/contextPath>
</contextHandler>
</contextHandlers>
</configuration>
</plugins>
</build>
...
</project>
This is the pom for module1 (the REST module)
<parent>
...
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>module1</artifactId>
<packaging>war</packaging>
<dependencies>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<springVersion>3.1.4.RELEASE</springversion>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-servlet</artifactId>
<version>2.4</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.ext</groupId>
<artifactId>jersey-spring3</artifactId>
<version>2.4</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-moxy</artifactId>
<version>2.4</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-multipart</artifactId>
<version>2.4</version>
</dependency>
<!-- Dependencies to internal modules -->
...
<!-- Depenencies to internal modules END -->
</dependencies>
</project>
This is the web.xml for module1
<web-app ...
version="3.0">
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>WEB-INF/applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
</web-app>
This is the applicationContext.xml for module1
<beans ...>
<context:annotation-config/>
<context:component-scan base-package="com.stackoverflow.zip"/>
<aop:aspectj-autoproxy/>
</beans>
This is the Module1Application class for module1
import org.glassfish.jersey.media.multipart.MultiPartFeature;
import javax.ws.rs.ApplicationPath;
import javax.ws.rs.core.Application;
import java.util.HashSet;
import java.util.Set;
#ApplicationPath("/rest")
public class Module1Application extends Application {
#Override
public Set<Class<?>> getClasses() {
Set<Class<?>> classes = new HashSet<Class<?>>();
classes.add(Resource1.class);
classes.add(Resource2.class);
classes.add(MultiPartFeature.class);
return classes;
}
}
This is the pom for module2 (the AngularJS app)
Very light :)
<project ...>
<parent>
...
</parent>
...
<modelVersion>4.0.0</modelVersion>
<artifactId>module2</artifactId>
<packaging>war</packaging>
</project>
Do you have any idea why the Jersey Application does not get instantiated while running with mvn jetty:run but when running it manually?
I appreciate any input on this topic.
Kind regards
- zip
Your javax.servlet version is 2.5 in pom.xml, but 3.0 in web.xml. Try upgrading it to 3.0 in pom.xml. Is it possible that the IDE provides a servlet 3.0 for you?
Also, since Jetty provides a javax.servlet container, try putting the Servlet Api into provided scope in pom.xml. Something like this:
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.0.1</version>
<!-- http://stackoverflow.com/a/15601606 http://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html#Dependency_Scope -->
<!-- This allows us to compile the application locally but does not include the jar in the package step -->
<scope>provided</scope>
</dependency>
It's possible that you want to add a <load-on-startup>1</load-on-startup> element to your web.xml. Check out http://tutorials.jenkov.com/java-servlets/web-xml.html#load-on-startup
That's whole tutorial is pretty good.
Disclaimer: I'm not familiar with what the Spring dependencies are doing to help your application bootstrap itself. You can always try removing dependencies on a separate branch, and adding them back in as you get things running
I haven't had a chance to play with Jersey 2.x so far, but from what I see in your web.xml, it doesn't look like you have Jersey setup correctly.
In a non-Spring application, you would have something like the following:
<web-app ...>
...
<servlet>
<servlet-name>Jersey REST Service</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.your.foo.rest</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Jersey REST Service</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
...
</web-app>
In a Spring-based one, you would use:
<web-app ...>
...
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>jersey-serlvet</servlet-name>
<servlet-class>com.sun.jersey.spi.spring.container.servlet.SpringServlet</servlet-class>
<init-param>
<param-name>com.sun.jersey.config.property.packages</param-name>
<param-value>com.your.foo</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>jersey-serlvet</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
...
</web-app>
Furthermore, check that you have these Maven dependencies:
<dependency>
<groupId>com.sun.jersey.contribs</groupId>
<artifactId>jersey-spring</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
</dependency>
I'm trying to set up some REST services on Jetty using Jersey JAXRS. I can't get json data through to my REST service class though. My ajax requests keep getting the "Unsupported Media Type" error and status. I get this regardless of what #Produces and #Consumes annotations I add to my methods though they should both be MediaType.APPLICATION_JSON.
I can't find decent documentation on Jersey and the loads of questions, blogs, and other resources all seem to be out of date. Looks like Jersey has undergone a lot of changes recently and I'm at a loss as to where I should be looking. I set up the following based on the jersey webapp archetype:
web.xml:
<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.my.package.rest</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Jersey Web Application</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
Code snippet:
#Path("/users")
public class UserService {
// Plain text works!
#GET
#Consumes(MediaType.TEXT_PLAIN)
public String list(){
return "Got it!";
}
// JSON doesn't work! >:(
#POST
#Consumes(MediaType.APPLICATION_JSON)
#Produces(MediaType.APPLICATION_JSON)
public User create(User user) {
Mocks.USERS.add(user);
return user;
}
My parent pom manages these dependencies ahd the second of these two is a dependency in my jax-rs project pom.
<dependency>
<groupId>org.glassfish.jersey</groupId>
<artifactId>jersey-bom</artifactId>
<version>2.2</version>
<type>pom</type>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-servlet-core</artifactId>
<version>2.2</version>
</dependency>
Do I need something to add support for JSON?
Have you read a chapter dedicated to JSON in the Users Guide? The easiest way would be adding a dependency on MOXy and JSON support would work out-of-the-box (you don't need to explicitly register features the modules provides to make it work as opposed to other JSON modules in Jersey):
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-moxy</artifactId>
<version>2.2</version>
</dependency>
Anyways Jersey provides more modules that would help you with handling JSON media type:
MOXy (examples: json-moxy, bean-validation-webapp)
Jackson (example: json-jackson)
Java API for JSON Processing (JSON-P) (example: json-processing-webapp)
Jettison (example: json-jettison)
Seems Drew was on the right track in his comment. But the answer (for Jersey 2.2 + Jackson at least) was a more up-to-date provider
<dependency>
<groupId>com.fasterxml.jackson.jaxrs</groupId>
<artifactId>jackson-jaxrs-json-provider</artifactId>
<version>2.2.3</version>
</dependency>
Using this required no configuration. Use this with the two dependencies in the original questions and you're in business.
JSON start working for me just with 2 dependencies:
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-servlet</artifactId>
<version>2.3</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.jaxrs</groupId>
<artifactId>jackson-jaxrs-json-provider</artifactId>
<version>2.2.3</version>
</dependency>
I am trying to build a simple java-based REST web-service using JSON. I am also using Maven for dependency management.
Since I am new to this, I have been thoroughly following a nice 5-step-tutorial on http://www.mkyong.com/webservices/jax-rs/json-example-with-jersey-jackson/, however I don't get this easy example to run.
Maven ran fine, and all necessary dependencies were downloaded and integrated in the project (the libraries are contained in the deployed .war-file). Only problem is, that when I want to open the URL given in the tutorial (localhost:8080/RESTfulExample/rest/json/metallica/get) after having deployed the project, I am getting a 404 Error without any additional information.
Edit:
Here is my pom.xml
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.8.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-server</artifactId>
<version>1.8</version>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-json</artifactId>
<version>1.8</version>
</dependency>
</dependencies>
<build>
<finalName>RESTfulExample</finalName>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
</plugins>
</build>
As I said, the build ran fine and dependencies are loaded and integrated into the project.
Now, here is the content of my web.xml
Restful Web Application
<servlet>
<servlet-name>jersey-serlvet</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.mkyong.rest</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>jersey-serlvet</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
Next to this, I use a class JSON-Service and a model class Track. My JSON Service looks like this:
#Path("/json/metallica")
public class JSONService {
#GET
#Path("/get")
#Produces(MediaType.APPLICATION_JSON)
public Track getTrackInJSON() {
Track track = new Track();
track.setTitle("Enter Sandman");
track.setSinger("Metallica");
return track;
}
#POST
#Path("/post")
#Consumes(MediaType.APPLICATION_JSON)
public Response createTrackInJSON(Track track) {
String result = "Track saved : " + track;
return Response.status(201).entity(result).build();
}
}
I am not sure how to check for server-side exceptions, any hint on this is also kindly appreciated... :-)
you defined in your servlet mapping
<servlet-mapping>
<servlet-name>jersey-serlvet</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
so your url should be correctly called localhost:8080/rest/json/metallica/get