RESTEasy - javax.ws.rs.NotFoundException: Could no

2019-05-01 20:06发布

问题:

I've tried to implement a REST service with RESTEasy in a GWT project, but when I get into the respective URI the application returns:

Grave: failed to execute
javax.ws.rs.NotFoundException: Could not find resource for full path: http://127.0.0.1:8888/api/matches
    at org.jboss.resteasy.core.registry.ClassNode.match(ClassNode.java:73)
    at org.jboss.resteasy.core.registry.RootClassNode.match(RootClassNode.java:48)
    at org.jboss.resteasy.core.ResourceMethodRegistry.getResourceInvoker(ResourceMethodRegistry.java:444)
    at org.jboss.resteasy.core.SynchronousDispatcher.getInvoker(SynchronousDispatcher.java:234)
    at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:171)
    at org.jboss.resteasy.plugins.server.servlet.ServletContainerDispatcher.service(ServletContainerDispatcher.java:220)
    at org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher.service(HttpServletDispatcher.java:56)
    at org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher.service(HttpServletDispatcher.java:51)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)

My web.xml is:

<?xml version="1.0" encoding="UTF-8" standalone="no"?><web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.5" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee                http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">

  <!-- All REST resources will be prefixed by /api -->
  <context-param>
    <param-name>resteasy.servlet.mapping.prefix</param-name>
    <param-value>/api</param-value>
  </context-param>

  <!-- Servlets -->
  <servlet>
    <servlet-name>Resteasy</servlet-name>
    <servlet-class>org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher</servlet-class>
    <init-param>
        <param-name>javax.ws.rs.Application</param-name>
        <param-value>eii.api.MatchApplication</param-value>
    </init-param>
  </servlet>

  <!-- Servlet mappings -->
  <!-- All calls to /api/xxx will be sent to the reasy servlet -->
  <servlet-mapping>
    <servlet-name>Resteasy</servlet-name>
    <url-pattern>/api/*</url-pattern>
  </servlet-mapping>

</web-app>

The implementation of Application:

public class MatchApplication extends Application {
    private Set<Object> singletons = new HashSet<Object>();
    private Set<Class<?>> classes = new HashSet<Class<?>>();

    public MatchApplication() {
        singletons.add(new MatchServiceImpl());
    }

    @Override
    public Set<Class<?>> getClasses() {
        return classes;
    }

    @Override       
    public Set<Object> getSingletons() {
        return singletons;
    }
}

And here's the class that provide the REST service:

 /* Imports */
    ...
@Path("/matches")
public class MatchResource {
    private static MatchResource _instance = null;
    private MatchRepository repository;

    public MatchResource() {
        repository = new MapMatchRepository(); 
    }

    public static MatchResource getInstance() {
        if (_instance == null)
            _instance = new MatchResource();
        return _instance;
    }

    @GET
    @Path("/{id}")
    @Produces("application/json")
    public Match getMatch(@PathParam("id") int id) {
        return repository.getMatch(id);
    }

    @GET
    @Produces("application/json")
    public Matches getMatchesCurrentRound() {
        return repository.getMatchesCurrentRound();
    }

        ...
}

What I want is to return a JSON file when getting into, for example: http://127.0.0.1:8888/api/matches

Does anyone know what I'm doing wrong?

Edit:

If I access to http://127.0.0.1:8888/api/ or http://127.0.0.1:8888/api/* (where * is whatever you want to write), the browser shows nothing. However, if I access to http://127.0.0.1:8888/oqiwn (where oqiwn is a random string) the browser shows a Error 404.

Also, I tried the RESTClient addon and these are the answers that returns:

With http://127.0.0.1:8888/api/ or http://127.0.0.1:8888/api/*

Status Code: 404 Not Found
Cache-Control: no-cache
Content-Length: 0
Date: Sun, 10 Nov 2013 22:59:57 GMT
Expires: Fri, 01 Jan 1990 00:00:00 GMT
Server: Development/1.0

And with http://127.0.0.1:8888/oqiwn

Status Code: 404 Not Found
Cache-Control: no-cache
Content-Length: 83
Content-Type: text/html; charset=iso-8859-1
Date: Sun, 10 Nov 2013 22:59:05 GMT
Expires: Fri, 01 Jan 1990 00:00:00 GMT
Server: Development/1.0

Note that Content-Type: text/html; charset=iso-8859-1 is not in the first one.

回答1:

You added your resource using a method named getMatches(), which Resteasy knows nothing about. You need to override the getSingletons() method of Application and return your root resources from there as shown below.

Documentation Here

Example:

public class MatchApplication extends Application {
    private Set<Object> singletons = new HashSet<Object>();
    private Set<Class<?>> classes = new HashSet<Class<?>>();

    public MatchApplication() {
        singletons.add(new MatchServiceImpl());
    }

    @Override
    public Set<Class<?>> getClasses() {
        return classes;
    }

    @Override
    public Set<Object> getSingletons() {
        return singletons;
    }
}


回答2:

First, I think your MatchApplication class should be annotated with @ApplicationPath("/api"). I'm sorry if that's already done.

Then, depending on your RESTEasy version, it will scan automatically for classes that are providers or resources, so you don't need to give to implement anything on your MatchApplication for now. Just extend Application and you are done.

If you can update your web-app to use servlet 3.0, you don't need to put any kind of configuration into your web.xml.

Read more on the RESTEasy documentation.



回答3:

This works for all my services.

This is a runtime exception indicating a resource requested by a client was not found on the server.
Add below entry into your web.xml :

<context-param>
        <param-name>resteasy.resources</param-name>
        <param-value>com.org.abc.xyz.MainClassName</param-value>
</context-param>

You can specify fully qualified name of your JAX-RS resource class name you want to register. If you have multiple classes entries, use comma delimiter.