Therefore, I spend some time on the Internet, but could not find a solution to this problem. There is a note in the documentation that can be used to output the solution.
http://cxf.apache.org/docs/jax-rs-basics.html#JAX-RSBasics-Customselectionbetweenmultipleresources
Therefore, I wrote a special resource comparator, performed the appropriate configuration of jaxrs: server and Eureka! it worked !. Now I have 2 implementation classes mapped to a single resource / address in javax: rs address.
Note that the logic in the custom resource comparator shown below may vary depending on the URL pattern.
Providing the source of all files. Hope this helps someone in the future :)
web.xml
<web-app> <display-name>Archetype Created Web Application</display-name> <context-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/account-servlet.xml</param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <servlet> <servlet-name>CXF Servlet</servlet-name> <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>CXF Servlet</servlet-name> <url-pattern>/*</url-pattern> </servlet-mapping> </web-app>
account-servlet.xml (applicationContext)
<beans> <jaxrs:server id="accountService" address="/rest"> <jaxrs:serviceBeans> <ref bean="accountServiceImpl" /> <ref bean="transferServiceImpl" /> </jaxrs:serviceBeans> <jaxrs:resourceComparator> <bean id="accountServiceComparator" class="com.etrade.comparator.AccountServiceComparator"/> </jaxrs:resourceComparator> <jaxrs:extensionMappings> <entry key="xml" value="application/xml" /> </jaxrs:extensionMappings> </jaxrs:server> <bean id="accountServiceImpl" class="com.etrade.service.AccountService" /> <bean id="transferServiceImpl" class="com.etrade.service.TransferService" /> </beans>
pom.xml
<modelVersion>4.0.0</modelVersion> <groupId>cxf.rest</groupId> <artifactId>account</artifactId> <packaging>war</packaging> <version>0.0.1-SNAPSHOT</version> <name>account Maven Webapp</name> <url>http://maven.apache.org</url> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>3.8.1</version> <scope>test</scope> </dependency> <dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-bundle-jaxrs</artifactId> <version>2.5.0</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>3.0.5.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>3.0.5.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-beans</artifactId> <version>3.0.5.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>3.0.5.RELEASE</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.mortbay.jetty</groupId> <artifactId>jetty-maven-plugin</artifactId> <version>7.2.0.v20101020</version> </plugin> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>exec-maven-plugin</artifactId> <version>1.1</version> <executions> <execution><goals><goal>java</goal></goals></execution> </executions> </plugin> </plugins> <finalName>account</finalName> </build> </project>
User Resource Builder
package com.etrade.comparator; import java.lang.reflect.Method; import javax.ws.rs.Path; import org.apache.cxf.jaxrs.ext.ResourceComparator; import org.apache.cxf.jaxrs.impl.UriInfoImpl; import org.apache.cxf.jaxrs.model.ClassResourceInfo; import org.apache.cxf.jaxrs.model.OperationResourceInfo; import org.apache.cxf.message.Message; public class AccountServiceComparator implements ResourceComparator{ public int compare(ClassResourceInfo arg0, ClassResourceInfo arg1, Message message) { UriInfoImpl uriInfo = new UriInfoImpl(message); String path = uriInfo.getPath(); String[] pathArray = path.split("/"); String resourceUrlName = pathArray[1]; System.out.println("Path : "+resourceUrlName); Method[] methods = arg0.getServiceClass().getMethods(); int value = 1; String resource = null; for(Method method : methods) { Path annotationPath = method.getAnnotation(javax.ws.rs.Path.class); if(null != annotationPath){ String pathValue = annotationPath.value(); String[] parts = pathValue.split("/"); resource = parts[1]; System.out.println("resource : "+resource); } if(resourceUrlName.contains(resource)){ value = -1; } } return value; } public int compare(OperationResourceInfo arg0, OperationResourceInfo arg1, Message arg2) { return 0; } }
Implementation classes / beans
AccountService.java
package com.etrade.service; import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; @Path("/account") @Produces("application/xml") public class AccountService { @GET @Produces("application/xml") @Path("/balance/{id}") public String accountBalance(@PathParam("id") long id) { System.out.println("id : "+id); StringBuilder response = new StringBuilder(256); response.append("<Response>").append("<id>").append(id) .append("</id>").append("<balance>").append("250.00").append("</balance>") .append("</Response>"); return response.toString(); } }
TransferService.java
package com.etrade.service; import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; @Path("/account") @Produces("application/xml") public class TransferService { @GET @Produces("application/xml") @Path("/transfer/{id}") public String accountTransfer(@PathParam("id") long id) { System.out.println("transfer id : "+id); StringBuilder response = new StringBuilder(256); response.append("<Response>").append("<id>").append(id) .append("</id>").append("<transfer>").append("250.00").append("</transfer>") .append("</Response>"); return response.toString(); } }
Url:
http://localhost:8080/rest/account/balance/12 http://localhost:8080/rest/transfer/balance/13