简体   繁体   中英

JAX-RS method has no Path or HTTP method annotations

I am implementation another implementation for existing interface using Spring and Apache CXF. When tomcat is starting up, it show below error message :

Method getSomething in ModuleInterface has no JAX-RS Path or HTTP Method annotations

And, both endpoints are returning 404.

I am not sure what am I missing. Any idea anyone?

public interface ModuleInterface {
   public Response getSomething(@Valid RequestObj obj);
}

--

@Service
@Path("/foo")
public class FooClass implements moduleInterface {
public Response getSomething(@Valid Request obj){
// code
}
}

--

@Service
@Path("/new/foo")
public class FooV2Class implements moduleInterface {
public Response getSomething(@Valid Request obj){
// code
}
}

--

@Configuration
@ImportResource({"classpath:/META-INF/cxf/cxf-servlet.xml", "classpath:/META-INF/cxf/cxf.xml"})
public class APIConfig {
@Autowired @Lazy ModuleInterface moduleInterface;

@Bean
public Server initCxfServer(){
    JAXRSServerFactoryBean sf = new JAXRSServerFactoryBean();
    sf.setServiceBeanObjects(getJaxRsResources());
    sf.setProviders(Arrays.asList(
            new JacksonJaxbJsonProvider()
    ));

    return sf.create();
}

private Object[] getJaxRsResources() {
    return new Object[]{
        moduleInterface
    };
}

private HashMap getExtMaps() {
    return new HashMap<String,String>(){{
        put("json","application/json;charset=utf-8");
        put("xml","application/xml;charset=utf-8");
        put("wadl","application/vnd.sun.wadl+xml");
        put("desc","application/vnd.sun.desc+json;charset=utf-8");
       }};
}

This may happend if you annonate the arguments in boths methods, in the interface and in the implementantion class, with @Valid (or even other annotation like @Context ).

Keep the annotation only on the arguments of the method that you annotated with the @Path (either in the interface, either in the implementation class) and it should work.

You need to let CXF know about your services and/or configure CXF.

See: http://cxf.apache.org/docs/jaxrs-services-configuration.html#JAXRSServicesConfiguration-ConfiguringJAX-RSservicesincontainerwithSpringconfigurationfile for CXF JAX-RS configuration with Spring.

EDIT

If you have multiple instances, which one do you expect to be loaded with following line ?

@Autowired @Lazy ModuleInterface moduleInterface;

Shouldn't an array achieve what you want ? Like :

@Autowired @Lazy ModuleInterface[] moduleInterfaces;

Your classes are scanned for methods which can receive requests ( Resource methods ). getSomething is a candidate since it has the parameter annotation @Valid but it does not qualify as resource method since it is missing a JAX-RS Path or HTTP Method annotation.

For instance adding a @GET annotation will do it (if you want to receive HTTP GET requests via this method).

public interface ModuleInterface {
    @GET
    public Response getSomething(@Valid RequestObj obj);
}

I had the same warning. In my case I used CXF 3.1.3 and I missed to add the spring feature within karaf.

For more details see Migration Guide to CXF 3.1.x

Adding name of the bean and using qualifier annotation

@Service("foo")
@Path("/foo")
public class FooClass implements ModuleInterface {
public Response getSomething(@Valid Request obj){
// code
}
}
--

@Service("foov2")
@Path("/new/foo")
public class FooV2Class implements moduleInterface {
public Response getSomething(@Valid Request obj){
// code
}
}

@Component
public class Service {
@Autowired
@Qualifier("foo")
ModuleInterface moduleInterface
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM