Simple REST Jersey example in Java not working - java

I wrote a very simple example using Jersey.
I downloaded the latest jar files from the jersey website into lib folder in WEB-INF.
My class and web.xml are below.
When I provide URL localhost:8080/SimpleJersey/rest/test I get 404 error (not found).
However when I use Maven, it works.
I use Eclipse Kepler, Glassfish 4 server and Java 7.
What am I doing wrong in the non-Maven version?
Thanks.
Class:
package com.simplejersey;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
#Path("/test")
public class MyResources
{
#GET
#Produces("text/plain")
public String getIt()
{
return "Hello there!";
}
}
Web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<web-app
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
<display-name>SimpleJersey</display-name>
<servlet>
<servlet-name>jersey-servlet</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>com.sun.jersey.config.property.packages</param-name>
<param-value>com.simplejersey</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>jersey-servlet</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
</web-app>

I found the solution in this post by Michal Gajdos: Jersey REST Web Service, Tomcat, Eclipse and 404's
The issue is (quoting from the abovementioned post):
Jersey 2.0 does not recognize init-param with name com.sun.jersey.config.property.packages (web.xml). Try to change it to jersey.config.server.provider.packages as described in ServerProperties.PROVIDER_PACKAGES (link)."
Be carefeul when you copy web.xml from websites that show older solutions or versions (like I did). Jersey is being updated too...

Related

Java Rest Server

I've tried multiple reinstallations of tomcat and followed this tutorial:
https://www.youtube.com/watch?v=5jQSat1cKMo
However I always get this error:
The origin server did not find a current representation for the target resource or is not willing to disclose that one exists.
Screenshot here:
This is my current Hello.java class:
package test;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
#Path("/hello")
public class Hello {
#GET
#Produces(MediaType.TEXT_PLAIN)
public String sayHello() {
String resource="This is some test return text";
return resource;
}
}
Current web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
<display-name>JavaAPI</display-name>
<servlet>
<servlet-name>JavaAPI</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer.class</servlet-class>
<init-param>
<param-name>jersey.config.server.provider.packages</param-name>
<param-value>test</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>JavaAPI</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
</web-app>
I have tried with and without the extra imports of:
import javax.ws.rs.ApplicationPath;
import javax.ws.rs.core.Application;
What am I missing?
UPDATE:
I'm using plain using IDE
I am also using Jersey JAX-RS 2.1
This line in web.xml doesn't look right:
<servlet-class>org.glassfish.jersey.servlet.ServletContainer.class</servlet-class>
The Java Servlet Specification Version 4.0 (page 14-164) states:
The servlet-class contains the fully qualified class name of the
servlet.
But what you have specified is a hybrid of the servlet's fully qualified class name and the servlet's file name, causing Tomcat to look for a servlet that doesn't exist, so you get a 404 error.
Just remove .class from the <servlet-class> value:
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>

Web service error HTTP Status 404 - Not Found

I am following a simple webservice tutorial and can't seem to interact with the Java code. I suspect my web.xml has an error but I'm not sure. There are no obvious errors and the index.jsp is server without any problems.
So, when I'm running it on the server, it opens index.jsp and I then try the following urls, but I'm getting 'HTTP 404 Errors'
http://localhost:8080/RestApi/ - works, shows html page
http://localhost:8080/RestApi/rest - http 404 error
http://localhost:8080/RestApi/rest/hello - http 404 error
http://localhost:8080/RestApi/rest/hello/somevalue - http 404 error
Here is what i have
Dynamic web project with jersey libs imported.
A note on this - I got an error for class not found and saw that I had to use Glassfish.org... instead of the com.sun one, don't know why, but there ya go.
My web.xml is as follows. No errors.
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
<display-name>RestApi</display-name>
<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>
<display-name>Rest Web Services App by me</display-name>
<servlet>
<servlet-name>exampleServlet</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>com.sun.jersey.config.property.packages</param-name>
<param-value>com.rest.example</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>exampleServlet</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
</web-app>
My java class is as follows. No errors.
package com.rest.example;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.core.Response;
#Path("/hello")
public class HelloWorld {
#GET
#Path("/{param}")
public Response getMsg(#PathParam("param") String msg){
String output = "Welcome to the world of Rest : "+msg;
return Response.status(200).entity(output).build();
}
}
You are using the old Jersey 1.x property
com.sun.jersey.config.property.packages
For Jersey 2.x it should be
jersey.config.server.provider.packages
As a general rule, anything where you see com.sun.jersey is for Jersey 1.x and org.glassfish.jersey is for 2.x.
try:
http://localhost:8080/rest/RestApi/hello
check my case
the rule seems like this: /{url-pattern}/{project}/{path}
I run my case with jetty
another example
the above issue can occur due to following reasons :
First check the name of your application deployed in the webapps folder of the tomcat, whether it is matching your url or not that is giving 404.But in the above case, as it is showing the welcome page, then it is not the concern here.
Check the url pattern mention in the web.xml as it must be the same as in the url you are hitting.
<url-pattern>/rest/*</url-pattern>
Third thing to check is that the path defined in the rest class with #Path annotation.
Check the web.xml for following entries if you are using jersey jars 2.x as suggested above by #Paul Samsotha
<servlet>
<servlet-name>Jersey RESTful 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.pizzeria</param-value>
</init-param>
</servlet>
There may be a possibility to get this error when your server has been up without any errors but the context of your application hasn't. You can check it in the logs.For further information please refer this Link ---> 404 error due to SEVERE: Context [/example] startup failed due to previous errors

Why is this Simple JAX RS example not working?

I am trying to get working a simple JAX RS example, but I am failing to do so.
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:jsp="http://java.sun.com/xml/ns/javaee/jsp" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
<display-name>PLAYGROUND</display-name>
<servlet-mapping>
<servlet-name>playground.Rest</servlet-name>
<url-pattern>/api/*</url-pattern>
</servlet-mapping>
</web-app>
Rest.java
package playground;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.core.Application;
public class Rest extends Application {
#GET
#Path("hello")
public String helloworld() {
return "Hello World!";
}
}
Accessing http://localhost/{warcontext}/api/hello with the browser (GET) gives me 404 error status
It is probably something very silly but I can't figure out.
Using:
JBoss EAP 6.1.0 (Java EE 6)
web.xml
<servlet>
<servlet-name>RestServlet</servlet-name>
<servlet-class>javax.ws.rs.core.Application</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>RestServlet</servlet-name>
<url-pattern>/api/*</url-pattern>
</servlet-mapping>
Rest.java
public class Rest {
#GET
#Path("hello")
public String helloworld() {
return "Hello World!";
}
}
If you need, you can add
YourApplication.java
package playground;
import javax.ws.rs.core.Application;
...
public class YourApplication extends Application {
#Override
public Set<Class<?>> getClasses()
{
Set<Class<?>> yourResources = new HashSet<Class<?>>();
yourResources.add(InvoiceResource.class);
return yourResources;
}
}
Then
web.xml
<servlet>
<servlet-name>RestServlet</servlet-name>
<servlet-class>playground.YourApplication</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>RestServlet</servlet-name>
<url-pattern>/api/*</url-pattern>
</servlet-mapping>
If you add #ApplicationPath("/api") for YouApplication, then web.xml shouldn't have servlet-mapping.
You need to extend javax.ws.rs.core.Application (it can remain empty) and annotate it with #ApplicationPath("/ide"), then create a JAX-RS resource, ie, a class with an #Path("/hello") annotation. In this class, you'll just need to have your JAX-RS Resource Method annotated with #GET.
#ApplicationPath("/ide")
public class Rest extends Application { }
#Path("/hello")
public class HelloResource {
#GET
#Path("hello")
public String helloworld() {
return "Hello World!";
}
}
You can also take a look at this example: https://github.com/resteasy/Resteasy/tree/master/jaxrs/examples/oreilly-workbook/ex03_1
You need to declare servlet-class in web.xml (servlet name is not the same):
<servlet>
<servlet-name>Playground REST services</servlet-name>
<servlet-class>your.package.playground.Rest</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Playground REST services</servlet-name>
<url-pattern>/api/*</url-pattern>
</servlet-mapping>
Use the full name of your class (including package path name) in servlet-class.
I also had issues getting this to work, so I'm posting a more complete how-to for posterity:
If you're using a standard Tomcat install (or some other servlet container), AFAIK you can't avoid explicitly telling it what servlets to start in the web.xml file*. Since you have to use web.xml anyway, the simplest way to get restful web services working is to forget extending javax.ws.rs.core.Application entirely and just specify the context path there. You can still use standard jax-rs annotations to declare the 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 noteworthy points:
You will need to bundle a REST implementation in your WAR file, since servlet containers don't usually contain one. Since Jersey is the reference implementation for JAX-RS, that's the one I'm using in the servlet-class element above. You can replace this with Apache CXF implementation if you want.
The init-param element tells Jersey which of your packages to search for Java files with web service annotations. Edit this to point to your web services. Note that if you opt to use apache CXF instead of Jersey, the stuff needed in any init-param elements will be different. Someone who knows CXF please post what they would be.
If you're using Maven, just add a dependency to 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 this, declaring your web services is straight forward using the 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's 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);
}
}
This should be all you need. If your Tomcat install is running locally on port 8080 and you deploy your WAR file to the context myContext, going to
http://localhost:8080/myContext/rest/calc/1.0/addTwoNumbers;firstNumber=2;secondNumber=3
...should produce the expected result (5).
Cheers!
* Someone please correct me if you know of a way to a add the Jersey servlet to the context in Tomcat without using web.xml--maybe by using a context or life cycle listener?

Simple REST service with Jersey running on Servlet 3.0 / Tomcat 7.0 not running but http status 500

I am testing a very simple REST server with Jersey and Servlet 3.0 implementation on Tomcat 7.0. I have programmed a simple PoJo:
package toplevel;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
#Path("/pojo")
public class PoJo {
#GET
#Produces("text/plain")
public String hello() {
return "Hello, World";
}
}
I have put the following in the WEB-INF/web.xml file (running on Servlet 3.0):
<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">
<display-name>RestTest</display-name>
<servlet>
<servlet-name>toplevel.PoJo</servlet-name>
</servlet>
<servlet-mapping>
<servlet-name>toplevel.PoJo</servlet-name>
<url-pattern>/pojo</url-pattern>
</servlet-mapping>
</web-app>
When I deploy, I get a HTTP Status 500 response. This seems to me that the webserver is recognizing that something should be served from /pojo, but that the corresponding class PoJo is not found. The jersey specific jars (version 1.17) are in the WEB-INF/lib dir:
activation-1.1.1.jar jersey-client-1.17.jar junit-4.9.jar
asm-3.3.1.jar jersey-core-1.17.jar persistence-api-1.0.2.jar
jaxb-api-2.2.4.jar jersey-server-1.17.jar stax-api-1.0-2.jar
jaxb-impl-2.2.4-1.jar jsr311-api-1.1.1.jar
Does anyone recognize this ?
You need to tell Jersey where to find your REST resource. Your web.xml should look something like this:
<servlet>
<servlet-name>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>toplevel</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Service</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
Adding jersey-servlet:1.17.jar took care of that problem for me.

AppEngine: REST with Jersey not working

Within SpringSource Tool Suite I created a standard google app engine project. I added Jersey for REST support. The development server starts up fine, but when I try to GET a URL (e.g. http://localhost:8888/sibibjersey/api) I'm simply getting a 404. I suppose this is a simple configuration issue, but the solutions seems to hide away from me....
Here the main files:
web.xml looks like this.
<?xml version="1.0" encoding="utf-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5">
<init-param>
<param-name>com.sun.jersey.config.feature.DisableWADL</param-name>
<param-value>true</param-value>
</init-param>
<servlet>
<servlet-name>Jersey Web Application</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.sibib.main</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Jersey Web Application</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
I tried variations of the url-pattern like /* and /rest/*, but none seemed to work.
The only Java class in com.sibib.main is InfoResource.java:
package com.sibib.main;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
#Path("/api")
public class InfoResource {
#GET
public String info() {
return "Hello Jersey on Google App Engine";
}
}
I tried adding #Path to the info function, but no effect. When I start the server and navigate e.g. to http://localhost:8888/sibibjersey/api I'm simply getting a 404.
Loading http://localhost:8888 loads the index.html in the war folder.
These are the lib referenced in the project:
activation-1.1.1.jar
appengine-api-1.0-sdk-1.6.1.jar
appengine-api-labs-1.6.1.jar
appengine-jsr107cache-1.6.1.jar
asm-3.3.1.jar
datanucleus-appengine-1.0.10.final.jar
datanucleus-core-1.1.5.jar
datanucleus-jpa-1.1.5.jar
geronimo-jpa_3.0_spec-1.1.1.jar
geronimo-jta_1.1_spec-1.1.1.jar
google_sql.jar
jackson-core-asl-1.9.2.jar
jackson-jaxrs-1.9.2.jar
jackson-mapper-asl-1.9.2.jar
jaxb-api-2.2.4.jar
jaxb-impl-2.2.4-1.jar
jdo2-api-2.3-eb.jar
jersey-bundle-1.11.jar
jersey-client-1.11.jar
jersey-core-1.11.jar
jersey-json-1.11.jar
jersey-server-1.11.jar
jettison-1.1.jar
jsr107cache-1.1.jar
persistence-api-1.0.2.jar
stax-api-1.0-2.jar
Any hint is greatly appreciated!
Thanks!
Can you try removing sibibjersey from the context path, just try with http: //localhost:8888/api
In my local, I have not seen Google App Engine's application having project path along with http: //localhost:8888
I followed http://tugdualgrall.blogspot.com/2010/02/create-and-deploy-jax-rs-rest-service.html and it worked for me without any issues.

Categories