JAX-RS Resource not found in GlassFish Server

2020-03-18 15:07发布

问题:

I've been trying to create a simple Restful WebService, using NetBeans Ide.
My Java EE Version is: Java EE 7 Web.

I created a new Java Web Application, setting this ContexPath: /DukesAgeService.

Now, running my application, browser display my Index.html page at:

http://localhost:8080/DukesAgeService/

so, everything works fine.

Then, I tried to create a simple restful resource using the RESTful Web Service Wizard.

So, I created this class:

package firstcup.webservice;

import javax.ws.rs.core.Context;
import javax.ws.rs.core.UriInfo;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PUT;

/**
 * REST Web Service
*
* @author nolanof
*/
@Path("dukesAge")
public class DukesAgeResource {

@Context
private UriInfo context;

/**
 * Creates a new instance of DukesAgeResource
 */
public DukesAgeResource() {
}

/**
 * Retrieves representation of an instance of firstcup.webservice.DukesAgeResource
 * @return an instance of java.lang.String
 */
@GET
@Produces("text/plain")
public String getText() {        
    return "hello world";
}
}

But running my application, at url: http://localhost:8080/DukesAgeService/dukesAge I get a 404-not found page.

I exptected that any incoming get request that has the url of "/dukesAge" was handled by DukesAgeResource class getText method. Whats' wrong?

Thanks

回答1:

You're probably missing the JAX-RS application servlet. You can either define it in the web.xml or if you want to go xml-less, you can use a Application subclass. The easiest way IMO is just to use the Application subclass annotated with @ApplicationPath. A servlet will be created and the servlet path will be set the value in the annotation. Something like

@ApplicationPath("/rest")
public class RestApplication extends Application {
    // All request scoped resources and providers
    @Override
    public Set<Class<?>> getClasses() {
        Set<Class<?>> classes = new HashSet<>();
        classes.add(DukesAgeResource.class);
        return classes;
    }

    // all singleton resources and providers
    @Override
    public Set<Object> getSingletons() {
        Set<Object> singletons = new HashSet<>();
        return singletons;
    }
}

Then the resource should be access the resource via

http://localhost:8080/DukesAgeService/rest/dukesAge.

There are other ways, but this is the portable way. Glassfish uses Jersey, but creating a Java EE web application from scratch in Netbeans will only import compile time Java EE standard classes (no Jersey dependencies). So the above is really your bet to start off with.

You can see other deployment options at the Jersey Documentation. For some of the options, you may need to add some Jersey compile-time dependencies. That's why I just mentioned the above. No other jars needed.

Another thing that would cause a 404, is if you specify the JAX-RS servlet path as /*. This will conflict with the default servlet that serves the static resources like your html pages. That's why I set it to /rest.


UPDATE

It is also stated in the JAX-RS spec that if there are empty sets returned in the getClasses() and getSingletons(), implicit package scanning should occur. (provider) Classes annotated withe @Provider will by default be added as singletons and a resource classes annotated with @Path will be per-request objects (meaning a new object is created each request). So you could alternatively just have

@ApplicationPath("/rest")
public class RestApplication extends Application {
    // Left empty
}

And it should work just the same.



回答2:

You may have initialized some path in your web.xml, probably that is why you are getting a 404 error while you call the service. Do check your web.xml and in case it is set to anything rather then * then please append that to your service call to get it working.