eclipse-ee4j / eclipse-ee4j/jersey
Request.selectVariant selects wrong mediatype when parameters are present
- Dominant language
- Java
- Stars
- 730
- Forks
- 382
- PR merge metrics
- No merged PRs in 30d
Description
Here's some code demonstrating the problem:
```java
public class AcceptHeaderTest {
@Path("resource/subresource/sub")
public static class AnotherSubResource {
public static final MediaType MT_JSONLD = new MediaType("application","ld+json");
public static final MediaType MT_TTL = new MediaType("text","turtle");
public static final MediaType MT_JSONLD_WA = MediaType.valueOf("application/ld+json; profile=\"http://www.w3.org/ns/anno.jsonld\"");
public static final MediaType MT_JSONLD_OA = MediaType.valueOf("application/ld+json; profile=\"http://www.w3.org/ns/oa.jsonld\"");
public static final List variants1 = Variant.mediaTypes(
MT_JSONLD_WA, MT_TTL, MT_JSONLD, MT_JSONLD_OA).add().build();
public static final List variants2 = Variant.mediaTypes(
MT_JSONLD, MT_TTL, MT_JSONLD_WA, MT_JSONLD_OA).add().build();
@GET
public String postTextStar(@Context Request request) {
Variant variant = request.selectVariant(variants1);
System.out.println(variant.getMediaType());
variant = request.selectVariant(variants2);
System.out.println(variant.getMediaType());
return "";
}
}
@Test
public void testSubResource() throws Exception {
final ResourceConfig resourceConfig = new ResourceConfig(AnotherSubResource.class);
final ApplicationHandler applicationHandler = new ApplicationHandler(resourceConfig);
System.out.println("first request:");
String accept = "application/ld+json, text/turtle ; q=0.5 , application/ld+json;profile=\"http://www.w3.org/ns/anno.jsonld\";q=0.1";
applicationHandler.apply(
RequestContextBuilder.from("/resource/subresource/sub", "GET").header("Accept", accept).build()).get();
System.out.println("\nsecond request:");
accept = "application/ld+json ; q=0.1, text/turtle ; q=0.5 , application/ld+json;profile=\"http://www.w3.org/ns/anno.jsonld\"";
applicationHandler.apply(
RequestContextBuilder.from("/resource/subresource/sub", "GET").header("Accept", accept).build()).get();
System.out.println("\nthird request:");
accept = "application/ld+json;profile=\"http://www.w3.org/ns/oa.jsonld\" ; q=0.1, text/turtle ; q=0.5 , application/ld+json;profile=\"http://www.w3.org/ns/anno.jsonld\"";
applicationHandler.apply(
RequestContextBuilder.from("/resource/subresource/sub", "GET").header("Accept", accept).build()).get();
System.out.println("\nfourth request");
accept = "application/ld+json;profile=\"http://www.w3.org/ns/oa.jsonld\" ; q=0.2, text/turtle ; q=0.5 , application/ld+json;q=0.1 , application/ld+json;profile=\"http://www.w3.org/ns/anno.jsonld\"";
applicationHandler.apply(
RequestContextBuilder.from("/resource/subresource/sub", "GET").header("Accept", accept).build()).get();
}
}
```
(you need [RequestContextBuilder](https://github.com/eclipse-ee4j/jersey/blob/master/core-server/src/test/java/org/glassfish/jersey/server/RequestContextBuilder.java) to make this work) giving the following results:
```
first request:
application/ld+json;profile="http://www.w3.org/ns/anno.jsonld"
application/ld+json
second request:
application/ld+json;profile="http://www.w3.org/ns/anno.jsonld"
application/ld+json
third request:
application/ld+json;profile="http://www.w3.org/ns/anno.jsonld"
application/ld+json
fourth request
application/ld+json;profile="http://www.w3.org/ns/anno.jsonld"
application/ld+json
```
While I agree the [spec](https://tools.ietf.org/html/rfc7231#section-5.3.2) is not crystal clear on the first 3 cases, the 4th seems quite wrong to common sense. This also show that the algorithm is dependent on the order of the list given to selectVariant instead of being consistent (choosing the most determined for instance, the one with the most parameters?).
Note that these mediatypes are [real-life use cases](https://www.w3.org/TR/annotation-protocol/).
Contributor guide
Assessment
This issue has not been assessed yet.