Details
Description
My resource class is as below:
@Path(value = "/GetTest")
public class HttpMethodGetTest {
@GET
@Path(value = "/sub")
public Response getSub()
@GET
@Path(value = "/sub")
@Produces(value = "text/html")
public Response headSub()
@Path("
{id}")
public int getAbstractResource(@PathParam("id") int id)
}
Then if I send an OPTIONS request to http://localhost:9080/xxxx/GetTest/sub it fails with 404 error.
[WARNING ] javax.ws.rs.NotFoundException: HTTP 404 Not Found
at org.apache.cxf.jaxrs.utils.SpecExceptions.toNotFoundException(SpecExceptions.java:89)
at org.apache.cxf.jaxrs.utils.ExceptionUtils.toNotFoundException(ExceptionUtils.java:126)
at org.apache.cxf.jaxrs.utils.InjectionUtils.handleParameter(InjectionUtils.java:389)
at org.apache.cxf.jaxrs.utils.InjectionUtils.createParameterObject(InjectionUtils.java:962)
at org.apache.cxf.jaxrs.utils.JAXRSUtils.readFromUriParam(JAXRSUtils.java:1194)
at org.apache.cxf.jaxrs.utils.JAXRSUtils.createHttpParameterValue(JAXRSUtils.java:877)
at org.apache.cxf.jaxrs.utils.JAXRSUtils.processParameter(JAXRSUtils.java:852)
at org.apache.cxf.jaxrs.utils.JAXRSUtils.processParameters(JAXRSUtils.java:802)
at org.apache.cxf.jaxrs.interceptor.JAXRSInInterceptor.processRequest(JAXRSInInterceptor.java:259)
at org.apache.cxf.jaxrs.interceptor.JAXRSInInterceptor.handleMessage(JAXRSInInterceptor.java:85)
at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:307)
at org.apache.cxf.transport.ChainInitiationObserver.onMessage(ChainInitiationObserver.java:121)
at .....
Caused by: java.lang.NumberFormatException: For input string: "sub"
at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
at java.lang.Integer.parseInt(Integer.java:492)
at java.lang.Integer.valueOf(Integer.java:582)
at org.apache.cxf.common.util.PrimitiveUtils.read(PrimitiveUtils.java:60)
at org.apache.cxf.jaxrs.utils.InjectionUtils.handleParameter(InjectionUtils.java:377)
... 27 more
After analysis, I found out the problem is in org.apache.cxf.jaxrs.utils.JAXRSUtils.findTargetMethod,
We can fix this via below change in this method:
if (!candidateList.isEmpty()) {
Map.Entry<OperationResourceInfo, MultivaluedMap<String, String>> firstEntry =
candidateList.entrySet().iterator().next();
matchedValues.clear();
matchedValues.putAll(firstEntry.getValue());
OperationResourceInfo ori = firstEntry.getKey();
if (headMethodPossible(ori.getHttpMethod(), httpMethod))
if (isFineLevelLoggable)
{ LOG.fine(new org.apache.cxf.common.i18n.Message("OPER_SELECTED", BUNDLE, ori.getMethodToInvoke().getName(), ori.getClassResourceInfo().getServiceClass().getName()).toString()); }if (!ori.isSubResourceLocator())
{ MediaType responseMediaType = intersectSortMediaTypes(acceptContentTypes, ori.getProduceTypes(), false).get(0); message.getExchange().put(Message.CONTENT_TYPE, mediaTypeToString(responseMediaType, MEDIA_TYPE_Q_PARAM, MEDIA_TYPE_QS_PARAM)); } //Propsed Change start
// need to check httpmethod as well for OPTIONS
if (!("OPTIONS".equalsIgnoreCase(httpMethod) && ori.getHttpMethod() == null))
//Proposed Change end
}