Jax-rs apache-cxf:未找到资源 class 的资源方法

Jax-rs apache-cxf:No resource methods have been found for resource class

我有如下cxf配置文件

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:jaxws="http://cxf.apache.org/jaxws"
       xmlns:jaxrs="http://cxf.apache.org/jaxrs"
       xmlns:jpa="http://www.springframework.org/schema/data/jpa"
       xmlns:cxf="http://cxf.apache.org/core"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
       http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd
       http://cxf.apache.org/jaxrs http://cxf.apache.org/schemas/jaxrs.xsd
       http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa.xsd
       http://cxf.apache.org/core http://cxf.apache.org/schemas/core.xsd">
    <import resource="classpath:META-INF/cxf/cxf.xml"/>
    <import resource="classpath:META-INF/cxf/cxf-servlet.xml"/>

    <context:component-scan base-package="test.stub.rest" />

    <!-- Enable CXF logging -->
    <cxf:bus>
        <cxf:features>
            <cxf:logging/>
        </cxf:features>
    </cxf:bus>

    <!-- CXF Services -->
    <jaxrs:server id="test" address="/stub/postUrl">
        <jaxrs:serviceBeans>
            <ref bean="testClass" />
        </jaxrs:serviceBeans>
    </jaxrs:server>

    <bean id="testClass" class="test.stub.rest.TestClass">
    </bean>
</beans>

web.xml

<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app>
  <display-name>Stubby CXF</display-name>

    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
            classpath:spring/stub-cxf-applicationContext.xml
        </param-value>
    </context-param>

    <listener>
        <listener-class>
            org.springframework.web.context.ContextLoaderListener
        </listener-class>
    </listener>

    <servlet>
        <servlet-name>CXFServlet</servlet-name>
        <display-name>CXF Servlet</display-name>
        <servlet-class>
            org.apache.cxf.transport.servlet.CXFServlet
        </servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>CXFServlet</servlet-name>
        <url-pattern>/services/*</url-pattern>
    </servlet-mapping>
</web-app>

服务class

@Path("/test")
public class TestService {
    protected final Logger log = LoggerFactory.getLogger(TestService.class);

    @Path("/hello")
    @Produces("text/html")
    public String hello(@RequestBody String payload) {

        return "OK";
    }
 }

现在,每当我调用此服务时,它都会转到 hello 方法,从该方法返回字符串 "OK" 后,会出现以下错误

13:11:35.142 [http-bio-8080-exec-3] WARN  o.a.cxf.jaxrs.utils.ResourceUtils - No resource methods have been found for resource class java.lang.String
13:11:35.142 [http-bio-8080-exec-3] ERROR org.apache.cxf.jaxrs.JAXRSInvoker - No subresource locator found for path /
13:11:35.142 [http-bio-8080-exec-3] WARN  o.a.c.j.i.WebApplicationExceptionMapper - javax.ws.rs.NotFoundException
    at org.apache.cxf.jaxrs.JAXRSInvoker.invoke(JAXRSInvoker.java:245)
    at org.apache.cxf.jaxrs.JAXRSInvoker.invoke(JAXRSInvoker.java:102)
    at org.apache.cxf.interceptor.ServiceInvokerInterceptor.run(ServiceInvokerInterceptor.java:58)
    at org.apache.cxf.interceptor.ServiceInvokerInterceptor.handleMessage(ServiceInvokerInterceptor.java:94)
    at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:272)
    at org.apache.cxf.transport.ChainInitiationObserver.onMessage(ChainInitiationObserver.java:121)
    at org.apache.cxf.transport.http.AbstractHTTPDestination.invoke(AbstractHTTPDestination.java:239)
    at org.apache.cxf.transport.servlet.ServletController.invokeDestination(ServletController.java:248)
    at org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:222)
    at org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:153)
    at org.apache.cxf.transport.servlet.CXFNonSpringServlet.invoke(CXFNonSpringServlet.java:167)
    at org.apache.cxf.transport.servlet.AbstractHTTPServlet.handleRequest(AbstractHTTPServlet.java:286)
    at org.apache.cxf.transport.servlet.AbstractHTTPServlet.doPost(AbstractHTTPServlet.java:206)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:647)
    at org.apache.cxf.transport.servlet.AbstractHTTPServlet.service(AbstractHTTPServlet.java:262)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:205)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:936)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1004)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589)
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:310)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:745)

13:11:35.142 [http-bio-8080-exec-3] DEBUG o.a.cxf.phase.PhaseInterceptorChain - Invoking handleMessage on interceptor org.apache.cxf.interceptor.OutgoingChainInterceptor@57fc218b
13:11:35.143 [http-bio-8080-exec-3] DEBUG o.a.c.i.OutgoingChainInterceptor - Interceptors contributed by bus: [org.apache.cxf.ws.policy.PolicyOutInterceptor@687bb597, org.apache.cxf.interceptor.LoggingOutInterceptor@11cf0218]
13:11:35.143 [http-bio-8080-exec-3] DEBUG o.a.c.i.OutgoingChainInterceptor - Interceptors contributed by service: []
13:11:35.143 [http-bio-8080-exec-3] DEBUG o.a.c.i.OutgoingChainInterceptor - Interceptors contributed by endpoint: [org.apache.cxf.interceptor.MessageSenderInterceptor@6cc21725]
13:11:35.143 [http-bio-8080-exec-3] DEBUG o.a.c.i.OutgoingChainInterceptor - Interceptors contributed by binding: [org.apache.cxf.jaxrs.interceptor.JAXRSOutInterceptor@3a7db5eb]
13:11:35.143 [http-bio-8080-exec-3] DEBUG o.a.cxf.phase.PhaseInterceptorChain - Chain org.apache.cxf.phase.PhaseInterceptorChain@59741d5f was created. Current flow:
  setup [PolicyOutInterceptor]
  prepare-send [MessageSenderInterceptor]
  pre-stream [LoggingOutInterceptor]
  marshal [JAXRSOutInterceptor]

13:11:35.143 [http-bio-8080-exec-3] DEBUG o.a.cxf.phase.PhaseInterceptorChain - Invoking handleMessage on interceptor org.apache.cxf.ws.policy.PolicyOutInterceptor@687bb597
13:11:35.143 [http-bio-8080-exec-3] DEBUG o.a.c.ws.policy.PolicyOutInterceptor - No binding operation info.
13:11:35.143 [http-bio-8080-exec-3] DEBUG o.a.cxf.phase.PhaseInterceptorChain - Invoking handleMessage on interceptor org.apache.cxf.interceptor.MessageSenderInterceptor@6cc21725
13:11:35.143 [http-bio-8080-exec-3] DEBUG o.a.cxf.phase.PhaseInterceptorChain - Adding interceptor org.apache.cxf.interceptor.MessageSenderInterceptor$MessageSenderEndingInterceptor@275146fe to phase prepare-send-ending
13:11:35.143 [http-bio-8080-exec-3] DEBUG o.a.cxf.phase.PhaseInterceptorChain - Chain org.apache.cxf.phase.PhaseInterceptorChain@59741d5f was modified. Current flow:
  setup [PolicyOutInterceptor]
  prepare-send [MessageSenderInterceptor]
  pre-stream [LoggingOutInterceptor]
  marshal [JAXRSOutInterceptor]
  prepare-send-ending [MessageSenderEndingInterceptor]

13:11:35.143 [http-bio-8080-exec-3] DEBUG o.a.cxf.phase.PhaseInterceptorChain - Invoking handleMessage on interceptor org.apache.cxf.interceptor.LoggingOutInterceptor@11cf0218
13:11:35.143 [http-bio-8080-exec-3] DEBUG o.a.cxf.phase.PhaseInterceptorChain - Invoking handleMessage on interceptor org.apache.cxf.jaxrs.interceptor.JAXRSOutInterceptor@3a7db5eb
13:11:35.143 [http-bio-8080-exec-3] DEBUG o.a.cxf.phase.PhaseInterceptorChain - Invoking handleMessage on interceptor org.apache.cxf.interceptor.MessageSenderInterceptor$MessageSenderEndingInterceptor@275146fe
13:11:35.144 [http-bio-8080-exec-3] INFO  o.a.c.i.LoggingOutInterceptor - Outbound Message
---------------------------
ID: 2
Response-Code: 404
Content-Type: 
Headers: {Date=[Fri, 27 Nov 2015 07:41:35 GMT], Content-Length=[0]}
--------------------------------------
13:11:35.144 [http-bio-8080-exec-3] DEBUG o.a.c.t.servlet.ServletController - Finished servicing http request on thread: Thread[http-bio-8080-exec-3,5,main]

我是不是做错了什么?我正在使用 apache-cxf、spring、jas-rs。如果在其他地方有答案,请告诉我。

您需要一个 HTTP 方法,例如 @GET:

@GET
@Path("/hello")
@Produces("text/html")
public String hello(@RequestBody String payload) {

    return "OK";
}