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>
Related
Similar question exists but none of the answers helped.
Starting Tomcat Server 9 on my Eclipse Project gives the error
java.lang.ClassNotFoundException: org.glassfish.jersey.servlet.ServletContainer.class
at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1364)
at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1187)
at org.apache.catalina.core.DefaultInstanceManager.loadClass(DefaultInstanceManager.java:539)
Even though I can clearly see ServletContainer.class under org.glassfish.jersey.servlet under jersey-container-servlet-core.jar under Web App Libraries.
All the required jars were added to /src/main/webapp/WEB-INF/lib, they seem to be properly imported.
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_4_0.xsd" id="WebApp_ID" version="4.0">
<display-name>JavaAPI</display-name>
<servlet>
<servlet-name>JAVA API</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> <!-- Tried Removing this, no difference -->
</servlet>
<servlet-mapping>
<servlet-name>JAVA API</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
</web-app>
Hello.java:
package test;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.ApplicationPath;
import javax.ws.rs.core.Application;
#Path("/hello")
public class Hello {
#GET
#Produces(MediaType.TEXT_XML)
public String sayHello() {
String resource = "<? xml version='1.0' ?>" +
"<hello>Hi Varun! This is the sayHello call.</hello>";
return resource;
}
#GET
#Produces(MediaType.APPLICATION_JSON)
public String sayHelloJSON() {
String resource = null;
return resource;
}
#GET
#Produces(MediaType.TEXT_HTML)
public String sayHelloHTML() {
String resource = "<h1>Hi Varun! This is the sayHelloHTML call.</h1>";
return resource;
}
}
Project Structure:
Using:
Eclipse: 2021-03
Tomcat: 9
Java: 1.8 (set under BuildPath, ProjectFacets)
JAX-RS 2.0 / Jersey 2.25.x
No Maven, Gradle involved, simply web project, with every jar hand-picked and imported.
Was following this tutorial step-by-step.
Remove the .class suffix
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
instead of
<servlet-class>org.glassfish.jersey.servlet.ServletContainer.class</servlet-class>
You specifiy the class name, not the class object.
I am trying to implement a very simple REST API in Eclipse.
Following is my project Structure:
project Structure
Hello.java:
package test;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.ApplicationPath;
import javax.ws.rs.core.Application;
#Path("/hello")
public class Hello {
#GET
#Produces(MediaType.TEXT_XML)
public String sayHelloXML() {
String responseString = "<? xml version='1.0' ?>" +
"<hello> Hello World XML</hello>";
return responseString;
}
#GET
#Produces(MediaType.APPLICATION_JSON)
public String sayHelloJSON() {
String responseString = null;
return responseString;
}
#GET
#Produces(MediaType.TEXT_HTML)
public String sayHelloHTML() {
String responseString = "<h1> Hello World HTML</h1>";
return responseString;
}
}
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_4_0.xsd" id="WebApp_ID" version="4.0">
<display-name>JavaApiEdu</display-name>
<servlet>
<servlet-name>JAVA API</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>JAVA API</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
</web-app>
To Run, I right-click on the project and choose Run on Server which is Tomcat 8.5.
I am unable to access this and see this page:
Error
It seems like you have to specify Path for each #GET. E.g.,
#Path("/hello")
public class Hello {
#Path("xml")
#GET
#Produces(MediaType.TEXT_XML)
...
Then browse to http://localhost:8080/test/rest/hello/xml?
After struggling a lot there are generally small things that solve the issues.
I did two things:
I removed the .class from this servlet class name in my web.xml and it started working:
web.xml
I also gave a path to all my methods as GyuHyeon suggested. Although if I don't do this then also it's working after doing step 1. It will just go to one of the methods as opposed to a specific one. Giving path to each method is a good step to follow.
Note: to access the API the project name should be in the URL and not the package, so in my case, this worked: http://localhost:8080/JavaApiEdu1/hello/html
Thanks #GyuHyeonChoi & #tgdavies for replying.
I've been struggling with this for the past two hours. I've looked at many different StackOverflow answers (a lot of questions appear like this one) but not one of them worked for me.
I have a simple 'CountryResources' class, that uses the #Path("/countries"), but when I navigate to localhost:8080/restservices/countries it just gives me a 404 error.
CountryResource class, located in a worldmap.services package:
package worldmap.services;
import model.Country;
import model.CountryService;
import model.ServiceProvider;
import javax.json.Json;
import javax.json.JsonArray;
import javax.json.JsonArrayBuilder;
import javax.json.JsonObjectBuilder;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
#Path("/countries")
public class CountryResource {
#GET
#Produces("application/json")
public String getCountries() {
System.out.println("Opgehaald");
CountryService cs = ServiceProvider.getWorldService();
JsonArrayBuilder jab = Json.createArrayBuilder();
for(Country c : cs.getAllCountries()) {
JsonObjectBuilder job = Json.createObjectBuilder();
job.add("code", c.getCode());
job.add("name", c.getName());
job.add("continent", c.getContinent());
job.add("region", c.getRegion());
job.add("surface", c.getSurface());
job.add("population", c.getPopulation());
job.add("government", c.getGovernment());
jab.add(job);
}
JsonArray array = jab.build();
return array.toString();
}
}
Web XML:
<?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"
metadata-complete="false">
<servlet>
<servlet-name>Jersey REST Service</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>jersey.config.server.provider.packages</param-name>
<param-value>worldmap.services</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Jersey REST Service</servlet-name>
<url-pattern>/restservices/*</url-pattern>
</servlet-mapping>
</web-app>
The problem has been found: Maven is not copying the dependencies of the program to the target's lib folder. Will have to try and figure out how to fix that.
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...
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.