diff --git a/core-common/src/main/java/org/glassfish/jersey/message/internal/InboundMessageContext.java b/core-common/src/main/java/org/glassfish/jersey/message/internal/InboundMessageContext.java index 00e453e78b..f729852020 100644 --- a/core-common/src/main/java/org/glassfish/jersey/message/internal/InboundMessageContext.java +++ b/core-common/src/main/java/org/glassfish/jersey/message/internal/InboundMessageContext.java @@ -54,6 +54,7 @@ import org.glassfish.jersey.internal.LocalizationMessages; import org.glassfish.jersey.internal.PropertiesDelegate; +import org.glassfish.jersey.internal.RuntimeDelegateDecorator; import org.glassfish.jersey.message.MessageBodyWorkers; /** @@ -331,7 +332,7 @@ private T singleHeader(String name, Function converter, boolean c } try { - return converter.apply(HeaderUtils.asString(value, null)); + return converter.apply(HeaderUtils.asString(value, configuration)); } catch (ProcessingException ex) { throw exception(name, value, ex); } @@ -450,7 +451,9 @@ public MediaType getMediaType() { @Override public MediaType apply(String input) { try { - return MediaType.valueOf(input); + return RuntimeDelegateDecorator.configured(configuration) + .createHeaderDelegate(MediaType.class) + .fromString(input); } catch (IllegalArgumentException iae) { throw new ProcessingException(iae); } diff --git a/core-common/src/main/java/org/glassfish/jersey/message/internal/OutboundMessageContext.java b/core-common/src/main/java/org/glassfish/jersey/message/internal/OutboundMessageContext.java index d50c929d1e..64a89d7e8e 100644 --- a/core-common/src/main/java/org/glassfish/jersey/message/internal/OutboundMessageContext.java +++ b/core-common/src/main/java/org/glassfish/jersey/message/internal/OutboundMessageContext.java @@ -267,7 +267,8 @@ public Locale getLanguage() { * message entity). */ public MediaType getMediaType() { - return singleHeader(HttpHeaders.CONTENT_TYPE, MediaType.class, MediaType::valueOf, false); + return singleHeader(HttpHeaders.CONTENT_TYPE, MediaType.class, RuntimeDelegateDecorator.configured(configuration) + .createHeaderDelegate(MediaType.class)::fromString, false); } /** diff --git a/tests/e2e-entity/src/test/java/org/glassfish/jersey/tests/e2e/header/HeaderDelegateProviderTest.java b/tests/e2e-entity/src/test/java/org/glassfish/jersey/tests/e2e/header/HeaderDelegateProviderTest.java index a6acb9a55d..8bc9fb0699 100644 --- a/tests/e2e-entity/src/test/java/org/glassfish/jersey/tests/e2e/header/HeaderDelegateProviderTest.java +++ b/tests/e2e-entity/src/test/java/org/glassfish/jersey/tests/e2e/header/HeaderDelegateProviderTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v. 2.0, which is available at @@ -17,8 +17,12 @@ package org.glassfish.jersey.tests.e2e.header; import org.glassfish.jersey.CommonProperties; +import org.glassfish.jersey.client.ClientConfig; import org.glassfish.jersey.internal.ServiceFinder; import org.glassfish.jersey.message.internal.HeaderUtils; +import org.glassfish.jersey.message.internal.HeaderValueException; +import org.glassfish.jersey.message.internal.InboundMessageContext; +import org.glassfish.jersey.message.internal.OutboundMessageContext; import org.glassfish.jersey.spi.HeaderDelegateProvider; import org.junit.Assert; import org.junit.Test; @@ -34,14 +38,18 @@ import javax.ws.rs.container.ContainerResponseFilter; import javax.ws.rs.core.Context; import javax.ws.rs.core.HttpHeaders; +import javax.ws.rs.core.MediaType; import javax.ws.rs.core.MultivaluedHashMap; import javax.ws.rs.core.MultivaluedMap; import javax.ws.rs.core.Response; +import javax.ws.rs.ext.ReaderInterceptor; import java.io.IOException; import java.util.Arrays; import java.util.List; import java.util.Map; +import static org.junit.Assert.fail; + public class HeaderDelegateProviderTest { static final String HEADER_NAME = "BEAN_HEADER"; static final String DISABLED_VALUE = new BeanForHeaderDelegateProviderTest().toString(); @@ -64,6 +72,23 @@ public String toString(BeanForHeaderDelegateProviderTest value) { } } + public static class EmptyContentTypeHandler implements HeaderDelegateProvider { + @Override + public boolean supports(Class type) { + return MediaType.class == type; + } + + @Override + public MediaType fromString(String value) { + return value.isEmpty() ? MediaType.APPLICATION_OCTET_STREAM_TYPE : MediaType.valueOf(value); + } + + @Override + public String toString(MediaType value) { + return value.toString(); + } + }; + public static class BeanForHeaderDelegateProviderTest { public static String getValue() { return "CORRECT_VALUE"; @@ -116,13 +141,18 @@ public void filter(ClientRequestContext requestContext) throws IOException { @Test public void testTheProviderIsFound() { + int found = 0; for (HeaderDelegateProvider provider : ServiceFinder.find(HeaderDelegateProvider.class, true)) { - Assert.assertEquals(provider.getClass(), BeanHeaderDelegateProvider.class); + if (provider.getClass() == BeanHeaderDelegateProvider.class + || provider.getClass() == EmptyContentTypeHandler.class) { + found++; + } } + Assert.assertEquals(2, found); } @Test - public void headerDelegateIsUsedWhenRuntimeDelegateDecoratorIsUsed() { + public void testHeaderDelegateIsUsedWhenRuntimeDelegateDecoratorIsUsed() { MultivaluedHashMap headers = new MultivaluedHashMap(); headers.put(HEADER_NAME, Arrays.asList(new BeanForHeaderDelegateProviderTest())); MultivaluedMap converted = HeaderUtils.asStringHeaders(headers, null); @@ -134,7 +164,7 @@ public void headerDelegateIsUsedWhenRuntimeDelegateDecoratorIsUsed() { } @Test - public void headerDelegateIsNotUsed() { + public void testHeaderDelegateIsNotUsed() { MultivaluedHashMap headers = new MultivaluedHashMap(); headers.put(HEADER_NAME, Arrays.asList(new BeanForHeaderDelegateProviderTest())); @@ -147,6 +177,54 @@ public void headerDelegateIsNotUsed() { testMap(converted, DISABLED_VALUE); } + @Test + public void testGetMediaTypeInInboundMessageContext() { + ClientConfig config = new ClientConfig().property(CommonProperties.METAINF_SERVICES_LOOKUP_DISABLE, true); + InboundMessageContext inboundMessageContext = new InboundMessageContext(config.getConfiguration()) { + @Override + protected Iterable getReaderInterceptors() { + return null; + } + }; + inboundMessageContext.header(HttpHeaders.CONTENT_TYPE, ""); + try { + inboundMessageContext.getMediaType(); + fail("Expected HeaderValueException has not been thrown"); + } catch (HeaderValueException ex) { + // expected + } + + config.property(CommonProperties.METAINF_SERVICES_LOOKUP_DISABLE, false); + inboundMessageContext = new InboundMessageContext(config.getConfiguration()) { + @Override + protected Iterable getReaderInterceptors() { + return null; + } + }; + inboundMessageContext.header(HttpHeaders.CONTENT_TYPE, ""); + MediaType mediaType = inboundMessageContext.getMediaType(); + Assert.assertEquals(MediaType.APPLICATION_OCTET_STREAM_TYPE, mediaType); + } + + @Test + public void testGetMediaTypeInOutboundMessageContext() { + ClientConfig config = new ClientConfig().property(CommonProperties.METAINF_SERVICES_LOOKUP_DISABLE, true); + OutboundMessageContext outboundMessageContext = new OutboundMessageContext(config.getConfiguration()); + outboundMessageContext.getHeaders().add(HttpHeaders.CONTENT_TYPE, ""); + try { + outboundMessageContext.getMediaType(); + fail("Expected HeaderValueException has not been thrown"); + } catch (IllegalArgumentException ex) { + // expected + } + + config.property(CommonProperties.METAINF_SERVICES_LOOKUP_DISABLE, false); + outboundMessageContext = new OutboundMessageContext(config.getConfiguration()); + outboundMessageContext.getHeaders().add(HttpHeaders.CONTENT_TYPE, ""); + MediaType mediaType = outboundMessageContext.getMediaType(); + Assert.assertEquals(MediaType.APPLICATION_OCTET_STREAM_TYPE, mediaType); + } + private void testMap(MultivaluedMap map, String expectedValue) { for (Map.Entry> entry : map.entrySet()) { Assert.assertEquals(HEADER_NAME, entry.getKey()); diff --git a/tests/e2e-entity/src/test/resources/META-INF/services/org.glassfish.jersey.spi.HeaderDelegateProvider b/tests/e2e-entity/src/test/resources/META-INF/services/org.glassfish.jersey.spi.HeaderDelegateProvider index 1cca66463a..73f95b8eaf 100644 --- a/tests/e2e-entity/src/test/resources/META-INF/services/org.glassfish.jersey.spi.HeaderDelegateProvider +++ b/tests/e2e-entity/src/test/resources/META-INF/services/org.glassfish.jersey.spi.HeaderDelegateProvider @@ -1 +1,2 @@ -org.glassfish.jersey.tests.e2e.header.HeaderDelegateProviderTest$BeanHeaderDelegateProvider \ No newline at end of file +org.glassfish.jersey.tests.e2e.header.HeaderDelegateProviderTest$BeanHeaderDelegateProvider +org.glassfish.jersey.tests.e2e.header.HeaderDelegateProviderTest$EmptyContentTypeHandler \ No newline at end of file