[ 
https://issues.apache.org/jira/browse/WINK-286?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12872940#action_12872940
 ] 

Bryant Luk commented on WINK-286:
---------------------------------

1)  To fix this immediately, do you have to have a @Consumes on the interface 
or can you add it only to the @POST/@PUT methods that you need it on?

2)  I think we can make it as an optional configuration to fix your case.  I 
think only the following runtime code must be changed in 
wink-server/org.apache.wink.server.internal.registry.ResourceRegistry:

{code}
    /**
     * Checks if the method record matches the media type of the input entity
     * 
     * @param record the method record to check
     * @param context the context of the current request
     * @return true if the method should be filtered, false otherwise
     */
    private boolean filterByConsumes(MethodRecord record, RuntimeContext 
context) {
        Set<MediaType> consumedMimes = record.getMetadata().getConsumes();
        // if not specified, then treat as if consumes */*
        if (consumedMimes.size() == 0) {
            return false;
        }
        MediaType inputMediaType = context.getHttpHeaders().getMediaType();
        if (inputMediaType == null) {
// FIX HERE: change here to return false to not filter out the method
//            inputMediaType = MediaType.APPLICATION_OCTET_STREAM_TYPE;
            return false;
        }
        for (MediaType mediaType : consumedMimes) {
            if (mediaType.isCompatible(inputMediaType)) {
                return false;
            }
        }
        return true;
    }
{code}

Can you see if that fixes your issue?

The reason why I think it should be configurable is because this will change 
the behavior when determining which class or method is used for existing 
applications.

BTW, I think the Wink code as written follows a strict interpretation of the 
JAX-RS spec (section 3.7.2 step 3a, bullet 2) in comparing the @Consumes media 
type to the incoming request entity body media type.  The @Consumes annotation 
indicates what media types of incoming requests are really acceptable (so you 
expect a message body that you can consume).  If the incoming HTTP request does 
not have an incoming Media Type (so by HTTP 1.1 spec 7.2.1 and the change in 
JAX-RS 1.1 for 4.2.1), we'll assume that it's an incoming 
"application/octet-stream" and then do the compatibility check.

> GET methods fail to serve requests without Content-Type if the 
> class/interface has @Consumes
> --------------------------------------------------------------------------------------------
>
>                 Key: WINK-286
>                 URL: https://issues.apache.org/jira/browse/WINK-286
>             Project: Wink
>          Issue Type: Bug
>          Components: Server
>    Affects Versions: 1.1
>            Reporter: Raymond Feng
>
> When the JAX-RS resource (the method with @GET) is accessed from a web 
> browser, the Content-Type is not set and it's default to 
> application/octet-stream. Wink fails to match to the method as it inherits 
> @Consumes (say, application/json) from the class/interface and it is not 
> compatible with application/octet-stream. For example:
> @Produces(MediaType.APPLICATION_JSON)
> @Consumes(MediaType.APPLICATION_JSON)
> public interface Catalog {
>    @GET
>    List<Item> get();
>    @GET
>    @Path("{id}")
>    Item get(@PathParam("id") String id);
> }
> The GET method doesn't have the request entity. Why do we need to compare the 
> media type for the request? I assume we should only check the methods that 
> take the HTTP body. 
> I had to work around this issue for Tuscany to add */* or 
> application/octet-stream to the GET method's consumes set. It's ugly :-(.
>     private synchronized void fixMediaTypes(DeploymentConfiguration config) {
>         if (fixed) {
>             return;
>         }
>         // FIXME: A hacky workaround for 
> https://issues.apache.org/jira/browse/TUSCANY-3572
>         ResourceRecord record = 
> config.getResourceRegistry().getRecord(resourceClass);
>         for (MethodMetadata methodMetadata : 
> record.getMetadata().getResourceMethods()) {
>             String method = methodMetadata.getHttpMethod();
>             if (HttpMethod.GET.equals(method) || 
> HttpMethod.HEAD.equals(method) || HttpMethod.DELETE.equals(method)) {
>                 
> methodMetadata.addConsumes(MediaType.APPLICATION_OCTET_STREAM_TYPE);
>                 methodMetadata.addConsumes(MediaType.WILDCARD_TYPE);
>             }
>             if (HttpMethod.HEAD.equals(method) || 
> HttpMethod.DELETE.equals(method)) {
>                 
> methodMetadata.addProduces(MediaType.APPLICATION_OCTET_STREAM_TYPE);
>                 methodMetadata.addConsumes(MediaType.WILDCARD_TYPE);
>             }
>         }
>         for (MethodMetadata methodMetadata : 
> record.getMetadata().getSubResourceMethods()) {
>             String method = methodMetadata.getHttpMethod();
>             if (HttpMethod.GET.equals(method) || 
> HttpMethod.HEAD.equals(method) || HttpMethod.DELETE.equals(method)) {
>                 
> methodMetadata.addConsumes(MediaType.APPLICATION_OCTET_STREAM_TYPE);
>                 methodMetadata.addConsumes(MediaType.WILDCARD_TYPE);
>             }
>             if (HttpMethod.HEAD.equals(method) || 
> HttpMethod.DELETE.equals(method)) {
>                 
> methodMetadata.addProduces(MediaType.APPLICATION_OCTET_STREAM_TYPE);
>                 methodMetadata.addConsumes(MediaType.WILDCARD_TYPE);
>             }
>         }
>         fixed = true;
>     }

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

Reply via email to