cxf-issues mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Frank Ittermann (JIRA)" <j...@apache.org>
Subject [jira] Issue Comment Edited: (CXF-1730) The Exception handling if it is thrown from a RequestHandler is not correct i guess.
Date Fri, 01 Aug 2008 00:24:31 GMT

    [ https://issues.apache.org/jira/browse/CXF-1730?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12618909#action_12618909
] 

pussinboost edited comment on CXF-1730 at 7/31/08 5:23 PM:
---------------------------------------------------------------

This was the original code (class org.apache.cxf.jaxrs.interceptor.JAXRSInInterceptor) :

private void processRequest(Message message) {
        RequestPreprocessor rp = 
            ProviderFactory.getInstance().getRequestPreprocessor();
        if (rp != null) {
            rp.preprocess(message, new UriInfoImpl(message, null));
        }
        
        String path = (String)message.get(Message.PATH_INFO);
        String address = (String)message.get(Message.BASE_PATH);
        String httpMethod = (String)message.get(Message.HTTP_REQUEST_METHOD);
        String requestContentType = (String)message.get(Message.CONTENT_TYPE);
        if (requestContentType == null) {
            requestContentType = "*/*";
        }
        
        if (address.startsWith("http")) {
            int idx = address.indexOf('/', 7);
            if (idx != -1) {
                address = address.substring(idx);
            }
        }

        if (path.startsWith(address)) {
            path = path.substring(address.length());
            if (!path.startsWith("/")) {
                path = "/" + path;
            }
        }

        if (!path.endsWith("/")) {
            path = path + "/";
        }
        
        
        //1. Matching target resource class
        Service service = message.getExchange().get(Service.class);
        List<ClassResourceInfo> resources = ((JAXRSServiceImpl)service).getClassResourceInfos();

        MultivaluedMap<String, String> values = new MetadataMap<String, String>();
        ClassResourceInfo resource = JAXRSUtils.selectResourceClass(resources, path, values);
        if (resource == null) {
            org.apache.cxf.common.i18n.Message errorMsg = 
                new org.apache.cxf.common.i18n.Message("NO_ROOT_EXC", 
                                                   BUNDLE, 
                                                   path);
            LOG.severe(errorMsg.toString());
            throw new Fault(errorMsg);
        }
        
        List<ProviderInfo<RequestHandler>> shs = 
            ProviderFactory.getInstance().getRequestHandlers();
        for (ProviderInfo<RequestHandler> sh : shs) {
            Response response = sh.getProvider().handleRequest(message, resource);
            if (response != null) {
                message.getExchange().put(Response.class, response);
                return;
            }
        }
        
        String acceptTypes = (String)message.get(Message.ACCEPT_CONTENT_TYPE);
        if (acceptTypes == null) {
            acceptTypes = "*/*";
        }
        
        List<MediaType> acceptContentTypes = JAXRSUtils.sortMediaTypes(acceptTypes);
        message.getExchange().put(Message.ACCEPT_CONTENT_TYPE, acceptContentTypes);
        message.getExchange().put(ROOT_RESOURCE_CLASS, resource);
        
        LOG.fine("Request path is: " + path);
        LOG.fine("Request HTTP method is: " + httpMethod);
        LOG.fine("Request contentType is: " + requestContentType);
        LOG.fine("Accept contentType is: " + acceptTypes);
        
        
        OperationResourceInfo ori = 
            JAXRSUtils.findTargetMethod(resource, values.getFirst(URITemplate.FINAL_MATCH_GROUP),

                                       httpMethod, values, requestContentType, acceptContentTypes);

        if (ori == null) {
            org.apache.cxf.common.i18n.Message errorMsg = 
                new org.apache.cxf.common.i18n.Message("NO_OP_EXC", 
                                                   BUNDLE, 
                                                   path,
                                                   requestContentType,
                                                   acceptTypes);
            LOG.severe(errorMsg.toString());
            throw new Fault(errorMsg);
        }
        LOG.fine("Found operation: " + ori.getMethodToInvoke().getName());
        
        message.getExchange().put(OperationResourceInfo.class, ori);
        message.put(RELATIVE_PATH, values.getFirst(URITemplate.FINAL_MATCH_GROUP));
        message.put(URITemplate.TEMPLATE_PARAMETERS, values);
      
        //2. Process parameters
        List<Object> params = JAXRSUtils
            .processParameters(ori, values, message);

        message.setContent(List.class, params);
    }

      was (Author: pussinboost):
    This was the original code (class org.apache.cxf.jaxrs.interceptor.JAXRSInInterceptor)
:

private void processRequest(Message message) {
        RequestPreprocessor rp = 
            ProviderFactory.getInstance().getRequestPreprocessor();
        if (rp != null) {
            rp.preprocess(message, new UriInfoImpl(message, null));
        }
        
        String path = (String)message.get(Message.PATH_INFO);
        String address = (String)message.get(Message.BASE_PATH);
        String httpMethod = (String)message.get(Message.HTTP_REQUEST_METHOD);
        String requestContentType = (String)message.get(Message.CONTENT_TYPE);
        if (requestContentType == null) {
            requestContentType = "*/*";
        }
        
        if (address.startsWith("http")) {
            int idx = address.indexOf('/', 7);
            if (idx != -1) {
                address = address.substring(idx);
            }
        }

        if (path.startsWith(address)) {
            path = path.substring(address.length());
            if (!path.startsWith("/")) {
                path = "/" + path;
            }
        }

        if (!path.endsWith("/")) {
            path = path + "/";
        }
        
        
        //1. Matching target resource class
        Service service = message.getExchange().get(Service.class);
        List<ClassResourceInfo> resources = ((JAXRSServiceImpl)service).getClassResourceInfos();

        MultivaluedMap<String, String> values = new MetadataMap<String, String>();
        ClassResourceInfo resource = JAXRSUtils.selectResourceClass(resources, path, values);
        if (resource == null) {
            org.apache.cxf.common.i18n.Message errorMsg = 
                new org.apache.cxf.common.i18n.Message("NO_ROOT_EXC", 
                                                   BUNDLE, 
                                                   path);
            LOG.severe(errorMsg.toString());
            throw new Fault(errorMsg);
        }
        
        List<ProviderInfo<RequestHandler>> shs = 
            ProviderFactory.getInstance().getRequestHandlers();
{html}<b>
        for (ProviderInfo<RequestHandler> sh : shs) {
            Response response = sh.getProvider().handleRequest(message, resource);
            if (response != null) {
                message.getExchange().put(Response.class, response);
                return;
            }
        }
</b>{html}
        
        String acceptTypes = (String)message.get(Message.ACCEPT_CONTENT_TYPE);
        if (acceptTypes == null) {
            acceptTypes = "*/*";
        }
        
        List<MediaType> acceptContentTypes = JAXRSUtils.sortMediaTypes(acceptTypes);
        message.getExchange().put(Message.ACCEPT_CONTENT_TYPE, acceptContentTypes);
        message.getExchange().put(ROOT_RESOURCE_CLASS, resource);
        
        LOG.fine("Request path is: " + path);
        LOG.fine("Request HTTP method is: " + httpMethod);
        LOG.fine("Request contentType is: " + requestContentType);
        LOG.fine("Accept contentType is: " + acceptTypes);
        
        
        OperationResourceInfo ori = 
            JAXRSUtils.findTargetMethod(resource, values.getFirst(URITemplate.FINAL_MATCH_GROUP),

                                       httpMethod, values, requestContentType, acceptContentTypes);

        if (ori == null) {
            org.apache.cxf.common.i18n.Message errorMsg = 
                new org.apache.cxf.common.i18n.Message("NO_OP_EXC", 
                                                   BUNDLE, 
                                                   path,
                                                   requestContentType,
                                                   acceptTypes);
            LOG.severe(errorMsg.toString());
            throw new Fault(errorMsg);
        }
        LOG.fine("Found operation: " + ori.getMethodToInvoke().getName());
        
        message.getExchange().put(OperationResourceInfo.class, ori);
        message.put(RELATIVE_PATH, values.getFirst(URITemplate.FINAL_MATCH_GROUP));
        message.put(URITemplate.TEMPLATE_PARAMETERS, values);
      
        //2. Process parameters
        List<Object> params = JAXRSUtils
            .processParameters(ori, values, message);

        message.setContent(List.class, params);
    }
  
> The Exception handling if it is thrown from a RequestHandler is not correct i guess.
> ------------------------------------------------------------------------------------
>
>                 Key: CXF-1730
>                 URL: https://issues.apache.org/jira/browse/CXF-1730
>             Project: CXF
>          Issue Type: Bug
>          Components: REST
>    Affects Versions: 2.1.2
>         Environment: Windows XP,  jdk1.6, Apache Tomcat 6.0.16
>            Reporter: Frank Ittermann
>
> Hello again
> i' ve used an implementation of RequestHandler to perform authentication stuff. So
> if the Authentication failed a RuntimeException is thrown.  I've also wrote a ExceptionMapper
implementation to transform occurred Exception into Http Status codes. If the RuntimeException
from the Authentication was thrown than this is translated to an HTTP 403 status code.
> But this Http status code is not send as response. This sends a 200 status code. After
a time of debugging i found the code that is responsible for that. The processResponse method
of the org.apache.cxf.jaxrs.interceptor.JAXRSOutInterceptor work not correct is guess. Because
code with the following code block this methods ends.
> OperationResourceInfo operation = (OperationResourceInfo)exchange.get(OperationResourceInfo.class
>             .getName());
>         if (operation == null) {
>             return;
>         }
> because the operation variable is null. The code after this is responsible to but the
Response from the ExceptionMapper class into the message object so that i received a 403 http
status code.
> I've searched the code again and i found the code block how put the OperationResourceInfo
into the Exchange object. That is done by the processRequest method of the org.apache.cxf.jaxrs.interceptor.JAXRSInInterceptor
class. But before the OperationResourceInfo object is putted in the registered ResourceHandler
are called see the code block below.
>  for (ProviderInfo<RequestHandler> sh : shs) {
>             Response response = sh.getProvider().handleRequest(message, resource);
>             if (response != null) {
>                 message.getExchange().put(Response.class, response);
>                 return;
>             }
>         }
> I guess the code how put in the OperationresourceInfo object could be performed before
the RequestHandlers are called maybe? 
> Or it's forbidden to throw a Runtimeexception inside the RequestHandler ?
> I've also tried to return an Response object from the RequestHandler but the effect was
the same it never arrives the client. It received also the Response object with http code
200.
> The CXF framework is great and very flexible good work. The opportunities to register
own code is very great.
> Good work.

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


Mime
View raw message