[
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.