Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using REST root resource class as interface, getting "no operation matching request"

Problem: Root resource class defined as interface with all annotations. CXFServlet is not able to see the POST operation on the impl class, though it's defined on the interface. When all the annotations are copied into the impl class, it works fine.

Note: The GET works fine when only defined on the interface, only the POST is causing the problem.

@Path("foo/")
public interface TestService {
    @Path("foo/{id}")
    @GET
    @Produces("text/plain")
    public String getIt(String id);

@Path("foo")
@POST
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
@ElementClass(response = Bar.class)
public Response createStuff(@Context MessageContext context,
        Bar bar);

}

@Features(features = "org.apache.cxf.feature.LoggingFeature")  
public class TestServiceImpl implements TestService {
    @Override
    public String getIt(String id) {
        return "Hi there!";
    }
@Override
public Response createStuff(@Context MessageContext context,
        Bar bar) {
    bar.set...
    bar.set...
    return Response.ok(bar).build();

}

Beans.xml {

<jaxrs:server id="testService" address="/test">
        <jaxrs:serviceBeans>
            <ref bean="testservice1"/>
        </jaxrs:serviceBeans>
    </jaxrs:server>
    <bean id="testservice1" class="foo.bar.TestServiceImpl"/>

}

Web.xml

    <listener>
        <listener-class>
            org.springframework.web.context.ContextLoaderListener
        </listener-class>
    ……..
    </listener>
        <servlet-name>CXFServlet</servlet-name>
        <url-pattern>/*</url-pattern>
    </servlet-mapping>

Reuest printed from Tomcat7.0 server: Using Chrome Postman

INFO: Inbound Message

ID: 1

Address: http://localhost:8080/<war-name>/test/foo/foo
Encoding: ISO-8859-1
Http-Method: POST
Content-Type: application/json
Headers: {Accept=[*/*], accept-encoding=[gzip,deflate,sdch], accept-language=[en-US,en;q=0.8], cache-control=[no-cache], connection=[keep-alive], Content-Length=[144], content-type=[application/json], host=[localhost:8080], origin=[chrome-extension://fdmmgilgnpjigdojojpjoooidkmcomcm], user-agent=[Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1547.76 Safari/537.36]}
Payload: {
    "bar": {
        "create_time": "Fri Sep 20 17:51:40 PDT 2013",
        "update_time": "e0739141-1e8c-48ad-b8ad-410331b3dba3",
    }
}

Error: Sep 21, 2013 12:13:05 PM org.apache.cxf.jaxrs.utils.JAXRSUtils findTargetMethod WARNING: No operation matching request path "//test/foo/foo" is found, Relative Path: /foo, HTTP Method: POST, ContentType: application/json, Accept: /,. Please enable FINE/TRACE log level for more details. Sep 21, 2013 12:13:05 PM org.apache.cxf.interceptor.LoggingOutInterceptor

INFO: Outbound Message
---------------------------
ID: 1
Response-Code: 404
Content-Type: text/xml
Headers: {Allow=[GET, OPTIONS, HEAD], Date=[Sat, 21 Sep 2013 19:13:05 GMT], Content-Length=[0]}

like image 257
Nordicstar Avatar asked Aug 09 '26 04:08

Nordicstar


1 Answers

I figured out the problem myself. In the imll class methods, don't re-declare the params with annotations.

In this snippet inside the Impl class

@Override
public Response createStuff(*@Context* MessageContext context,
        Bar bar) {

I used the @Context annotation unnecessarily, which is throwing it off. Once I remove the annotation from the impl class, it works just fine. And rightly so, why to decorate the method params again when you specified it in the interface.

like image 91
Nordicstar Avatar answered Aug 11 '26 07:08

Nordicstar



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!