I\'m using CXF RS 2.5.1 with Spring 3.0.6-RELEASE. I would like to have multiple implementation classes for \"a single endpoint\". I see that this issue was reported and fix
So I spend some time searching the internet but found no solution to this problem. There is a note written in the documentation that can be used to deduce the solution.
http://cxf.apache.org/docs/jax-rs-basics.html#JAX-RSBasics-Customselectionbetweenmultipleresources
Hence I wrote a custom resource comparator, did the appropriate jaxrs:server configuration and Eureka! it worked!. Now, I have 2 implementation classes mapped to a single resource/address in javax:rs address.
Please be advised that logic in custom resource comparator shown below may vary based on the URL pattern.
Providing source of all the files. Hope that this will help someone in future :)
Archetype Created Web Application
contextConfigLocation
/WEB-INF/account-servlet.xml
org.springframework.web.context.ContextLoaderListener
CXF Servlet
org.apache.cxf.transport.servlet.CXFServlet
1
CXF Servlet
/*
4.0.0
cxf.rest
account
war
0.0.1-SNAPSHOT
account Maven Webapp
http://maven.apache.org
junit
junit
3.8.1
test
org.apache.cxf
cxf-bundle-jaxrs
2.5.0
org.springframework
spring-core
3.0.5.RELEASE
org.springframework
spring-test
3.0.5.RELEASE
org.springframework
spring-beans
3.0.5.RELEASE
org.springframework
spring-context
3.0.5.RELEASE
org.mortbay.jetty
jetty-maven-plugin
7.2.0.v20101020
org.codehaus.mojo
exec-maven-plugin
1.1
java
account
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;
}
}
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("").append("").append(id)
.append(" ").append("").append("250.00").append(" ")
.append(" ");
return response.toString();
}
}
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("").append("").append(id)
.append(" ").append("").append("250.00").append(" ")
.append(" ");
return response.toString();
}
}
http://localhost:8080/rest/account/balance/12
http://localhost:8080/rest/transfer/balance/13