latest CXF with Spring: WARNING: javax.ws.rs.NotFo

2019-04-12 15:37发布

问题:

I am able to access REST services from the browser url: http://localhost:8080/assignment/services/services/test/test1

From My servlet, I use to call service method as shown below. Now I need to call through REST services but getting below error.

URL url = new URL("http://localhost:8080/assignment/services/services/"+userName+"/"+password);
            System.out.println("URL-->"+url);
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            connection.setRequestMethod("GET");
            connection.setRequestProperty("Accept", "application/xml");
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
            while(bufferedReader.readLine() != null){
                result = bufferedReader.readLine();
            }
//          result = userService.login(userName, password);
            System.out.println(result);

here is the error:

INFO: Reloading Context with name [/assignment] is completed
URL-->http://localhost:8080/assignment/services/test/test1
Jul 30, 2013 12:52:02 PM org.apache.cxf.jaxrs.interceptor.JAXRSInInterceptor processRequest
WARNING: No root resource matching request path /assignment/services/test/test1 has been found, Relative Path: /test/test1. Please enable FINE/TRACE log level for more details.
Jul 30, 2013 12:52:02 PM org.apache.cxf.jaxrs.impl.WebApplicationExceptionMapper toResponse
WARNING: javax.ws.rs.NotFoundException
    at org.apache.cxf.jaxrs.interceptor.JAXRSInInterceptor.processRequest(JAXRSInInterceptor.java:172)
    at org.apache.cxf.jaxrs.interceptor.JAXRSInInterceptor.handleMessage(JAXRSInInterceptor.java:100)
    at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:271)
    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:223)
    at org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:203)
    at org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:137)
    at org.apache.cxf.transport.servlet.CXFNonSpringServlet.invoke(CXFNonSpringServlet.java:158)
    at org.apache.cxf.transport.servlet.AbstractHTTPServlet.handleRequest(AbstractHTTPServlet.java


...


Jul 30, 2013 12:52:02 PM org.apache.catalina.core.StandardWrapperValve invoke
SEVERE: Servlet.service() for servlet [LoginServlet] in context with path [/assignment] threw exception
java.io.FileNotFoundException: http://localhost:8080/assignment/services/services/test/test1
    at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1623)
    at com.viasat.test.login.servlet.LoginServlet.process(LoginServlet.java:77)
    at com.viasat.test.login.servlet.LoginServlet.doPost(LoginServlet.java:52)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:647)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:728)

Service class:

@Service
@Path("/services/")
public class UserServiceImpl implements UserService {

@GET
    @Path("{userName}/{password}")
    @Produces(MediaType.TEXT_XML)
    public String login(@PathParam("userName")String username, @PathParam("password")String password)
            throws JAXBException, PropertyException, FileNotFoundException {

web.xml:

   <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>WEB-INF/beans.xml</param-value>
    </context-param>

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

    <servlet>
        <servlet-name>cxf</servlet-name>        
        <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>        
        <load-on-startup>1</load-on-startup>
    </servlet> 
  <servlet>
    <display-name>LoginServlet</display-name>
    <servlet-name>LoginServlet</servlet-name>
    <servlet-class>com.abc.test.login.servlet.LoginServlet</servlet-class>
</servlet>

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

Update: pom.xml:

  <dependencies>
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>servlet-api</artifactId>
        <version>2.5</version>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>jstl</artifactId>
        <version>1.2</version>
    </dependency>
    <dependency>
    <groupId>org.codehaus.jackson</groupId>
    <artifactId>jackson-jaxrs</artifactId>
    <version>1.9.12</version>
   </dependency>
    <dependency>
        <groupId>org.apache.cxf</groupId>
        <artifactId>cxf-rt-frontend-jaxrs</artifactId>
        <version>2.7.5</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>3.2.3.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-web</artifactId>
        <version>3.2.3.RELEASE</version>
    </dependency>

Now Javax.ws.rs.NotFoundException gone, but, File not found exception still comes.

回答1:

Solution-1

One of the solution is that version issue with CXF and Spring. I have made cxf version to 2.5.2 which avoids javax.ws.rs.NotFoundException.

Now I have updated to

<spring.version>3.2.2.RELEASE</spring.version>
<cxf.version>2.5.2</cxf.version>

I was using 2.7.5 cxf version.

Solution -2

In my service class I have made

@Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) instead of

@Produces(MediaType.TEXT_XML)



回答2:

The URL you are using to fire the GET request has two services levels:

http://localhost:8080/assignment/services/services/"

but in your REST service class, there is only one 'services' level in Path. You may need to change the Path Param to like this:

@Service
@Path("/services/")
public class UserServiceImpl implements UserService {

    @GET
    @Path("services/{userName}/{password}")
    @Produces(MediaType.TEXT_XML)
    public String login(@PathParam("userName")String username, @PathParam("password")String password)
            throws JAXBException, PropertyException, FileNotFoundException {


回答3:

I think "services" is by default the path where CXF exposes the auto-generated WADLs and therefore cannot be used in a resource path.

Try either changing "services" to another word in your web.xml and Service class (@Path) or change the CXF servlet config like so (see the service-list-path param):

<servlet>
    <servlet-name>cxf</servlet-name>
    <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
    <init-param>
        <param-name>service-list-path</param-name>
        <param-value>web-services</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>

Reference: http://cxf.apache.org/docs/jaxrs-services-description.html (section Service listings and WADL queries almost at the end).

Note that you can override the location at which listings are provided (in case you would like '/services' be available to your resources) using 'service-list-path' CXFServlet parameter



回答4:

one common reason for this error is that cxf cannot find a restful implementation for the restful service to match the request to the resource method later. the spec is ambiguious in this area but your jaxrs annotations in the interface must match implementation in cxf. --eliani



回答5:

As described in CXF project throws java.lang.NoClassDefFoundError: javax/ws/rs/NotFoundException the

Error can be solved by adding

<dependency>
    <groupId>javax.ws.rs</groupId>
    <artifactId>javax.ws.rs-api</artifactId>
    <version>2.0-m10</version>
</dependency>