/*
 * Copyright 2002-2020 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.springframework.http;

import java.io.Serializable;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
import org.springframework.util.InvalidMimeTypeException;
import org.springframework.util.MimeType;
import org.springframework.util.MimeTypeUtils;
import org.springframework.util.StringUtils;

A subclass of MimeType that adds support for quality parameters as defined in the HTTP specification.
Author:Arjen Poutsma, Juergen Hoeller, Rossen Stoyanchev, Sebastien Deleuze, Kazuki Shimizu, Sam Brannen
See Also:
Since:3.0
/** * A subclass of {@link MimeType} that adds support for quality parameters * as defined in the HTTP specification. * * @author Arjen Poutsma * @author Juergen Hoeller * @author Rossen Stoyanchev * @author Sebastien Deleuze * @author Kazuki Shimizu * @author Sam Brannen * @since 3.0 * @see <a href="https://tools.ietf.org/html/rfc7231#section-3.1.1.1"> * HTTP 1.1: Semantics and Content, section 3.1.1.1</a> */
public class MediaType extends MimeType implements Serializable { private static final long serialVersionUID = 2069937152339670231L;
Public constant media type that includes all media ranges (i.e. "*/*").
/** * Public constant media type that includes all media ranges (i.e. "&#42;/&#42;"). */
public static final MediaType ALL;
A String equivalent of ALL.
/** * A String equivalent of {@link MediaType#ALL}. */
public static final String ALL_VALUE = "*/*";
Public constant media type for application/atom+xml.
/** * Public constant media type for {@code application/atom+xml}. */
public static final MediaType APPLICATION_ATOM_XML;
A String equivalent of APPLICATION_ATOM_XML.
/** * A String equivalent of {@link MediaType#APPLICATION_ATOM_XML}. */
public static final String APPLICATION_ATOM_XML_VALUE = "application/atom+xml";
Public constant media type for application/cbor.
Since:5.2
/** * Public constant media type for {@code application/cbor}. * @since 5.2 */
public static final MediaType APPLICATION_CBOR;
A String equivalent of APPLICATION_CBOR.
Since:5.2
/** * A String equivalent of {@link MediaType#APPLICATION_CBOR}. * @since 5.2 */
public static final String APPLICATION_CBOR_VALUE = "application/cbor";
Public constant media type for application/x-www-form-urlencoded.
/** * Public constant media type for {@code application/x-www-form-urlencoded}. */
public static final MediaType APPLICATION_FORM_URLENCODED;
A String equivalent of APPLICATION_FORM_URLENCODED.
/** * A String equivalent of {@link MediaType#APPLICATION_FORM_URLENCODED}. */
public static final String APPLICATION_FORM_URLENCODED_VALUE = "application/x-www-form-urlencoded";
Public constant media type for application/json.
/** * Public constant media type for {@code application/json}. */
public static final MediaType APPLICATION_JSON;
A String equivalent of APPLICATION_JSON.
See Also:
/** * A String equivalent of {@link MediaType#APPLICATION_JSON}. * @see #APPLICATION_JSON_UTF8_VALUE */
public static final String APPLICATION_JSON_VALUE = "application/json";
Public constant media type for application/json;charset=UTF-8.
Deprecated:as of 5.2 in favor of APPLICATION_JSON since major browsers like Chrome now comply with the specification and interpret correctly UTF-8 special characters without requiring a charset=UTF-8 parameter.
/** * Public constant media type for {@code application/json;charset=UTF-8}. * @deprecated as of 5.2 in favor of {@link #APPLICATION_JSON} * since major browsers like Chrome * <a href="https://bugs.chromium.org/p/chromium/issues/detail?id=438464"> * now comply with the specification</a> and interpret correctly UTF-8 special * characters without requiring a {@code charset=UTF-8} parameter. */
@Deprecated public static final MediaType APPLICATION_JSON_UTF8;
A String equivalent of APPLICATION_JSON_UTF8.
Deprecated:as of 5.2 in favor of APPLICATION_JSON_VALUE since major browsers like Chrome now comply with the specification and interpret correctly UTF-8 special characters without requiring a charset=UTF-8 parameter.
/** * A String equivalent of {@link MediaType#APPLICATION_JSON_UTF8}. * @deprecated as of 5.2 in favor of {@link #APPLICATION_JSON_VALUE} * since major browsers like Chrome * <a href="https://bugs.chromium.org/p/chromium/issues/detail?id=438464"> * now comply with the specification</a> and interpret correctly UTF-8 special * characters without requiring a {@code charset=UTF-8} parameter. */
@Deprecated public static final String APPLICATION_JSON_UTF8_VALUE = "application/json;charset=UTF-8";
Public constant media type for application/octet-stream.
/** * Public constant media type for {@code application/octet-stream}. */
public static final MediaType APPLICATION_OCTET_STREAM;
A String equivalent of APPLICATION_OCTET_STREAM.
/** * A String equivalent of {@link MediaType#APPLICATION_OCTET_STREAM}. */
public static final String APPLICATION_OCTET_STREAM_VALUE = "application/octet-stream";
Public constant media type for application/pdf.
Since:4.3
/** * Public constant media type for {@code application/pdf}. * @since 4.3 */
public static final MediaType APPLICATION_PDF;
A String equivalent of APPLICATION_PDF.
Since:4.3
/** * A String equivalent of {@link MediaType#APPLICATION_PDF}. * @since 4.3 */
public static final String APPLICATION_PDF_VALUE = "application/pdf";
Public constant media type for application/problem+json.
See Also:
Since:5.0
/** * Public constant media type for {@code application/problem+json}. * @since 5.0 * @see <a href="https://tools.ietf.org/html/rfc7807#section-6.1"> * Problem Details for HTTP APIs, 6.1. application/problem+json</a> */
public static final MediaType APPLICATION_PROBLEM_JSON;
A String equivalent of APPLICATION_PROBLEM_JSON.
Since:5.0
/** * A String equivalent of {@link MediaType#APPLICATION_PROBLEM_JSON}. * @since 5.0 */
public static final String APPLICATION_PROBLEM_JSON_VALUE = "application/problem+json";
Public constant media type for application/problem+json.
See Also:
Since:5.0
Deprecated:as of 5.2 in favor of APPLICATION_PROBLEM_JSON since major browsers like Chrome now comply with the specification and interpret correctly UTF-8 special characters without requiring a charset=UTF-8 parameter.
/** * Public constant media type for {@code application/problem+json}. * @since 5.0 * @see <a href="https://tools.ietf.org/html/rfc7807#section-6.1"> * Problem Details for HTTP APIs, 6.1. application/problem+json</a> * @deprecated as of 5.2 in favor of {@link #APPLICATION_PROBLEM_JSON} * since major browsers like Chrome * <a href="https://bugs.chromium.org/p/chromium/issues/detail?id=438464"> * now comply with the specification</a> and interpret correctly UTF-8 special * characters without requiring a {@code charset=UTF-8} parameter. */
@Deprecated public static final MediaType APPLICATION_PROBLEM_JSON_UTF8;
A String equivalent of APPLICATION_PROBLEM_JSON_UTF8.
Since:5.0
Deprecated:as of 5.2 in favor of APPLICATION_PROBLEM_JSON_VALUE since major browsers like Chrome now comply with the specification and interpret correctly UTF-8 special characters without requiring a charset=UTF-8 parameter.
/** * A String equivalent of {@link MediaType#APPLICATION_PROBLEM_JSON_UTF8}. * @since 5.0 * @deprecated as of 5.2 in favor of {@link #APPLICATION_PROBLEM_JSON_VALUE} * since major browsers like Chrome * <a href="https://bugs.chromium.org/p/chromium/issues/detail?id=438464"> * now comply with the specification</a> and interpret correctly UTF-8 special * characters without requiring a {@code charset=UTF-8} parameter. */
@Deprecated public static final String APPLICATION_PROBLEM_JSON_UTF8_VALUE = "application/problem+json;charset=UTF-8";
Public constant media type for application/problem+xml.
See Also:
Since:5.0
/** * Public constant media type for {@code application/problem+xml}. * @since 5.0 * @see <a href="https://tools.ietf.org/html/rfc7807#section-6.2"> * Problem Details for HTTP APIs, 6.2. application/problem+xml</a> */
public static final MediaType APPLICATION_PROBLEM_XML;
A String equivalent of APPLICATION_PROBLEM_XML.
Since:5.0
/** * A String equivalent of {@link MediaType#APPLICATION_PROBLEM_XML}. * @since 5.0 */
public static final String APPLICATION_PROBLEM_XML_VALUE = "application/problem+xml";
Public constant media type for application/rss+xml.
Since:4.3.6
/** * Public constant media type for {@code application/rss+xml}. * @since 4.3.6 */
public static final MediaType APPLICATION_RSS_XML;
A String equivalent of APPLICATION_RSS_XML.
Since:4.3.6
/** * A String equivalent of {@link MediaType#APPLICATION_RSS_XML}. * @since 4.3.6 */
public static final String APPLICATION_RSS_XML_VALUE = "application/rss+xml";
Public constant media type for application/x-ndjson.
Since:5.3
/** * Public constant media type for {@code application/x-ndjson}. * @since 5.3 */
public static final MediaType APPLICATION_NDJSON;
A String equivalent of APPLICATION_NDJSON.
Since:5.3
/** * A String equivalent of {@link MediaType#APPLICATION_NDJSON}. * @since 5.3 */
public static final String APPLICATION_NDJSON_VALUE = "application/x-ndjson";
Public constant media type for application/stream+json.
Deprecated:as of 5.3, see notice on APPLICATION_STREAM_JSON_VALUE.
Since:5.0
/** * Public constant media type for {@code application/stream+json}. * @deprecated as of 5.3, see notice on {@link #APPLICATION_STREAM_JSON_VALUE}. * @since 5.0 */
@Deprecated public static final MediaType APPLICATION_STREAM_JSON;
A String equivalent of APPLICATION_STREAM_JSON.
Deprecated:as of 5.3 since it originates from the W3C Activity Streams specification which has a more specific purpose and has been since replaced with a different mime type. Use APPLICATION_NDJSON as a replacement or any other line-delimited JSON format (e.g. JSON Lines, JSON Text Sequences).
Since:5.0
/** * A String equivalent of {@link MediaType#APPLICATION_STREAM_JSON}. * @deprecated as of 5.3 since it originates from the W3C Activity Streams * specification which has a more specific purpose and has been since * replaced with a different mime type. Use {@link #APPLICATION_NDJSON} as * a replacement or any other line-delimited JSON format (e.g. JSON Lines, * JSON Text Sequences). * @since 5.0 */
@Deprecated public static final String APPLICATION_STREAM_JSON_VALUE = "application/stream+json";
Public constant media type for application/xhtml+xml.
/** * Public constant media type for {@code application/xhtml+xml}. */
public static final MediaType APPLICATION_XHTML_XML;
A String equivalent of APPLICATION_XHTML_XML.
/** * A String equivalent of {@link MediaType#APPLICATION_XHTML_XML}. */
public static final String APPLICATION_XHTML_XML_VALUE = "application/xhtml+xml";
Public constant media type for application/xml.
/** * Public constant media type for {@code application/xml}. */
public static final MediaType APPLICATION_XML;
A String equivalent of APPLICATION_XML.
/** * A String equivalent of {@link MediaType#APPLICATION_XML}. */
public static final String APPLICATION_XML_VALUE = "application/xml";
Public constant media type for image/gif.
/** * Public constant media type for {@code image/gif}. */
public static final MediaType IMAGE_GIF;
A String equivalent of IMAGE_GIF.
/** * A String equivalent of {@link MediaType#IMAGE_GIF}. */
public static final String IMAGE_GIF_VALUE = "image/gif";
Public constant media type for image/jpeg.
/** * Public constant media type for {@code image/jpeg}. */
public static final MediaType IMAGE_JPEG;
A String equivalent of IMAGE_JPEG.
/** * A String equivalent of {@link MediaType#IMAGE_JPEG}. */
public static final String IMAGE_JPEG_VALUE = "image/jpeg";
Public constant media type for image/png.
/** * Public constant media type for {@code image/png}. */
public static final MediaType IMAGE_PNG;
A String equivalent of IMAGE_PNG.
/** * A String equivalent of {@link MediaType#IMAGE_PNG}. */
public static final String IMAGE_PNG_VALUE = "image/png";
Public constant media type for multipart/form-data.
/** * Public constant media type for {@code multipart/form-data}. */
public static final MediaType MULTIPART_FORM_DATA;
A String equivalent of MULTIPART_FORM_DATA.
/** * A String equivalent of {@link MediaType#MULTIPART_FORM_DATA}. */
public static final String MULTIPART_FORM_DATA_VALUE = "multipart/form-data";
Public constant media type for multipart/mixed.
Since:5.2
/** * Public constant media type for {@code multipart/mixed}. * @since 5.2 */
public static final MediaType MULTIPART_MIXED;
A String equivalent of MULTIPART_MIXED.
Since:5.2
/** * A String equivalent of {@link MediaType#MULTIPART_MIXED}. * @since 5.2 */
public static final String MULTIPART_MIXED_VALUE = "multipart/mixed";
Public constant media type for multipart/related.
Since:5.2.5
/** * Public constant media type for {@code multipart/related}. * @since 5.2.5 */
public static final MediaType MULTIPART_RELATED;
A String equivalent of MULTIPART_RELATED.
Since:5.2.5
/** * A String equivalent of {@link MediaType#MULTIPART_RELATED}. * @since 5.2.5 */
public static final String MULTIPART_RELATED_VALUE = "multipart/related";
Public constant media type for text/event-stream.
See Also:
Since:4.3.6
/** * Public constant media type for {@code text/event-stream}. * @since 4.3.6 * @see <a href="https://www.w3.org/TR/eventsource/">Server-Sent Events W3C recommendation</a> */
public static final MediaType TEXT_EVENT_STREAM;
A String equivalent of TEXT_EVENT_STREAM.
Since:4.3.6
/** * A String equivalent of {@link MediaType#TEXT_EVENT_STREAM}. * @since 4.3.6 */
public static final String TEXT_EVENT_STREAM_VALUE = "text/event-stream";
Public constant media type for text/html.
/** * Public constant media type for {@code text/html}. */
public static final MediaType TEXT_HTML;
A String equivalent of TEXT_HTML.
/** * A String equivalent of {@link MediaType#TEXT_HTML}. */
public static final String TEXT_HTML_VALUE = "text/html";
Public constant media type for text/markdown.
Since:4.3
/** * Public constant media type for {@code text/markdown}. * @since 4.3 */
public static final MediaType TEXT_MARKDOWN;
A String equivalent of TEXT_MARKDOWN.
Since:4.3
/** * A String equivalent of {@link MediaType#TEXT_MARKDOWN}. * @since 4.3 */
public static final String TEXT_MARKDOWN_VALUE = "text/markdown";
Public constant media type for text/plain.
/** * Public constant media type for {@code text/plain}. */
public static final MediaType TEXT_PLAIN;
A String equivalent of TEXT_PLAIN.
/** * A String equivalent of {@link MediaType#TEXT_PLAIN}. */
public static final String TEXT_PLAIN_VALUE = "text/plain";
Public constant media type for text/xml.
/** * Public constant media type for {@code text/xml}. */
public static final MediaType TEXT_XML;
A String equivalent of TEXT_XML.
/** * A String equivalent of {@link MediaType#TEXT_XML}. */
public static final String TEXT_XML_VALUE = "text/xml"; private static final String PARAM_QUALITY_FACTOR = "q"; static { // Not using "valueOf' to avoid static init cost ALL = new MediaType("*", "*"); APPLICATION_ATOM_XML = new MediaType("application", "atom+xml"); APPLICATION_CBOR = new MediaType("application", "cbor"); APPLICATION_FORM_URLENCODED = new MediaType("application", "x-www-form-urlencoded"); APPLICATION_JSON = new MediaType("application", "json"); APPLICATION_JSON_UTF8 = new MediaType("application", "json", StandardCharsets.UTF_8); APPLICATION_NDJSON = new MediaType("application", "x-ndjson"); APPLICATION_OCTET_STREAM = new MediaType("application", "octet-stream"); APPLICATION_PDF = new MediaType("application", "pdf"); APPLICATION_PROBLEM_JSON = new MediaType("application", "problem+json"); APPLICATION_PROBLEM_JSON_UTF8 = new MediaType("application", "problem+json", StandardCharsets.UTF_8); APPLICATION_PROBLEM_XML = new MediaType("application", "problem+xml"); APPLICATION_RSS_XML = new MediaType("application", "rss+xml"); APPLICATION_STREAM_JSON = new MediaType("application", "stream+json"); APPLICATION_XHTML_XML = new MediaType("application", "xhtml+xml"); APPLICATION_XML = new MediaType("application", "xml"); IMAGE_GIF = new MediaType("image", "gif"); IMAGE_JPEG = new MediaType("image", "jpeg"); IMAGE_PNG = new MediaType("image", "png"); MULTIPART_FORM_DATA = new MediaType("multipart", "form-data"); MULTIPART_MIXED = new MediaType("multipart", "mixed"); MULTIPART_RELATED = new MediaType("multipart", "related"); TEXT_EVENT_STREAM = new MediaType("text", "event-stream"); TEXT_HTML = new MediaType("text", "html"); TEXT_MARKDOWN = new MediaType("text", "markdown"); TEXT_PLAIN = new MediaType("text", "plain"); TEXT_XML = new MediaType("text", "xml"); }
Create a new MediaType for the given primary type.

The subtype is set to "*", parameters empty.

Params:
  • type – the primary type
Throws:
/** * Create a new {@code MediaType} for the given primary type. * <p>The {@linkplain #getSubtype() subtype} is set to "&#42;", parameters empty. * @param type the primary type * @throws IllegalArgumentException if any of the parameters contain illegal characters */
public MediaType(String type) { super(type); }
Create a new MediaType for the given primary type and subtype.

The parameters are empty.

Params:
  • type – the primary type
  • subtype – the subtype
Throws:
/** * Create a new {@code MediaType} for the given primary type and subtype. * <p>The parameters are empty. * @param type the primary type * @param subtype the subtype * @throws IllegalArgumentException if any of the parameters contain illegal characters */
public MediaType(String type, String subtype) { super(type, subtype, Collections.emptyMap()); }
Create a new MediaType for the given type, subtype, and character set.
Params:
  • type – the primary type
  • subtype – the subtype
  • charset – the character set
Throws:
/** * Create a new {@code MediaType} for the given type, subtype, and character set. * @param type the primary type * @param subtype the subtype * @param charset the character set * @throws IllegalArgumentException if any of the parameters contain illegal characters */
public MediaType(String type, String subtype, Charset charset) { super(type, subtype, charset); }
Create a new MediaType for the given type, subtype, and quality value.
Params:
  • type – the primary type
  • subtype – the subtype
  • qualityValue – the quality value
Throws:
/** * Create a new {@code MediaType} for the given type, subtype, and quality value. * @param type the primary type * @param subtype the subtype * @param qualityValue the quality value * @throws IllegalArgumentException if any of the parameters contain illegal characters */
public MediaType(String type, String subtype, double qualityValue) { this(type, subtype, Collections.singletonMap(PARAM_QUALITY_FACTOR, Double.toString(qualityValue))); }
Copy-constructor that copies the type, subtype and parameters of the given MediaType, and allows to set the specified character set.
Params:
  • other – the other media type
  • charset – the character set
Throws:
Since:4.3
/** * Copy-constructor that copies the type, subtype and parameters of the given * {@code MediaType}, and allows to set the specified character set. * @param other the other media type * @param charset the character set * @throws IllegalArgumentException if any of the parameters contain illegal characters * @since 4.3 */
public MediaType(MediaType other, Charset charset) { super(other, charset); }
Copy-constructor that copies the type and subtype of the given MediaType, and allows for different parameters.
Params:
  • other – the other media type
  • parameters – the parameters, may be null
Throws:
/** * Copy-constructor that copies the type and subtype of the given {@code MediaType}, * and allows for different parameters. * @param other the other media type * @param parameters the parameters, may be {@code null} * @throws IllegalArgumentException if any of the parameters contain illegal characters */
public MediaType(MediaType other, @Nullable Map<String, String> parameters) { super(other.getType(), other.getSubtype(), parameters); }
Create a new MediaType for the given type, subtype, and parameters.
Params:
  • type – the primary type
  • subtype – the subtype
  • parameters – the parameters, may be null
Throws:
/** * Create a new {@code MediaType} for the given type, subtype, and parameters. * @param type the primary type * @param subtype the subtype * @param parameters the parameters, may be {@code null} * @throws IllegalArgumentException if any of the parameters contain illegal characters */
public MediaType(String type, String subtype, @Nullable Map<String, String> parameters) { super(type, subtype, parameters); }
Create a new MediaType for the given MimeType. The type, subtype and parameters information is copied and MediaType-specific checks on parameters are performed.
Params:
  • mimeType – the MIME type
Throws:
Since:5.3
/** * Create a new {@code MediaType} for the given {@link MimeType}. * The type, subtype and parameters information is copied and {@code MediaType}-specific * checks on parameters are performed. * @param mimeType the MIME type * @throws IllegalArgumentException if any of the parameters contain illegal characters * @since 5.3 */
public MediaType(MimeType mimeType) { super(mimeType); getParameters().forEach(this::checkParameters); } @Override protected void checkParameters(String parameter, String value) { super.checkParameters(parameter, value); if (PARAM_QUALITY_FACTOR.equals(parameter)) { value = unquote(value); double d = Double.parseDouble(value); Assert.isTrue(d >= 0D && d <= 1D, "Invalid quality value \"" + value + "\": should be between 0.0 and 1.0"); } }
Return the quality factor, as indicated by a q parameter, if any. Defaults to 1.0.
Returns:the quality factor as double value
/** * Return the quality factor, as indicated by a {@code q} parameter, if any. * Defaults to {@code 1.0}. * @return the quality factor as double value */
public double getQualityValue() { String qualityFactor = getParameter(PARAM_QUALITY_FACTOR); return (qualityFactor != null ? Double.parseDouble(unquote(qualityFactor)) : 1D); }
Indicate whether this MediaType includes the given media type.

For instance, text/* includes text/plain and text/html, and application/*+xml includes application/soap+xml, etc. This method is not symmetric.

Simply calls MimeType.includes(MimeType) but declared with a MediaType parameter for binary backwards compatibility.

Params:
  • other – the reference media type with which to compare
Returns:true if this media type includes the given media type; false otherwise
/** * Indicate whether this {@code MediaType} includes the given media type. * <p>For instance, {@code text/*} includes {@code text/plain} and {@code text/html}, * and {@code application/*+xml} includes {@code application/soap+xml}, etc. * This method is <b>not</b> symmetric. * <p>Simply calls {@link MimeType#includes(MimeType)} but declared with a * {@code MediaType} parameter for binary backwards compatibility. * @param other the reference media type with which to compare * @return {@code true} if this media type includes the given media type; * {@code false} otherwise */
public boolean includes(@Nullable MediaType other) { return super.includes(other); }
Indicate whether this MediaType is compatible with the given media type.

For instance, text/* is compatible with text/plain, text/html, and vice versa. In effect, this method is similar to includes, except that it is symmetric.

Simply calls MimeType.isCompatibleWith(MimeType) but declared with a MediaType parameter for binary backwards compatibility.

Params:
  • other – the reference media type with which to compare
Returns:true if this media type is compatible with the given media type; false otherwise
/** * Indicate whether this {@code MediaType} is compatible with the given media type. * <p>For instance, {@code text/*} is compatible with {@code text/plain}, * {@code text/html}, and vice versa. In effect, this method is similar to * {@link #includes}, except that it <b>is</b> symmetric. * <p>Simply calls {@link MimeType#isCompatibleWith(MimeType)} but declared with a * {@code MediaType} parameter for binary backwards compatibility. * @param other the reference media type with which to compare * @return {@code true} if this media type is compatible with the given media type; * {@code false} otherwise */
public boolean isCompatibleWith(@Nullable MediaType other) { return super.isCompatibleWith(other); }
Return a replica of this instance with the quality value of the given MediaType.
Returns:the same instance if the given MediaType doesn't have a quality value, or a new one otherwise
/** * Return a replica of this instance with the quality value of the given {@code MediaType}. * @return the same instance if the given MediaType doesn't have a quality value, * or a new one otherwise */
public MediaType copyQualityValue(MediaType mediaType) { if (!mediaType.getParameters().containsKey(PARAM_QUALITY_FACTOR)) { return this; } Map<String, String> params = new LinkedHashMap<>(getParameters()); params.put(PARAM_QUALITY_FACTOR, mediaType.getParameters().get(PARAM_QUALITY_FACTOR)); return new MediaType(this, params); }
Return a replica of this instance with its quality value removed.
Returns:the same instance if the media type doesn't contain a quality value, or a new one otherwise
/** * Return a replica of this instance with its quality value removed. * @return the same instance if the media type doesn't contain a quality value, * or a new one otherwise */
public MediaType removeQualityValue() { if (!getParameters().containsKey(PARAM_QUALITY_FACTOR)) { return this; } Map<String, String> params = new LinkedHashMap<>(getParameters()); params.remove(PARAM_QUALITY_FACTOR); return new MediaType(this, params); }
Parse the given String value into a MediaType object, with this method name following the 'valueOf' naming convention (as supported by ConversionService.
Params:
  • value – the string to parse
Throws:
See Also:
/** * Parse the given String value into a {@code MediaType} object, * with this method name following the 'valueOf' naming convention * (as supported by {@link org.springframework.core.convert.ConversionService}. * @param value the string to parse * @throws InvalidMediaTypeException if the media type value cannot be parsed * @see #parseMediaType(String) */
public static MediaType valueOf(String value) { return parseMediaType(value); }
Parse the given String into a single MediaType.
Params:
  • mediaType – the string to parse
Throws:
Returns:the media type
/** * Parse the given String into a single {@code MediaType}. * @param mediaType the string to parse * @return the media type * @throws InvalidMediaTypeException if the media type value cannot be parsed */
public static MediaType parseMediaType(String mediaType) { MimeType type; try { type = MimeTypeUtils.parseMimeType(mediaType); } catch (InvalidMimeTypeException ex) { throw new InvalidMediaTypeException(ex); } try { return new MediaType(type); } catch (IllegalArgumentException ex) { throw new InvalidMediaTypeException(mediaType, ex.getMessage()); } }
Parse the comma-separated string into a list of MediaType objects.

This method can be used to parse an Accept or Content-Type header.

Params:
  • mediaTypes – the string to parse
Throws:
Returns:the list of media types
/** * Parse the comma-separated string into a list of {@code MediaType} objects. * <p>This method can be used to parse an Accept or Content-Type header. * @param mediaTypes the string to parse * @return the list of media types * @throws InvalidMediaTypeException if the media type value cannot be parsed */
public static List<MediaType> parseMediaTypes(@Nullable String mediaTypes) { if (!StringUtils.hasLength(mediaTypes)) { return Collections.emptyList(); } // Avoid using java.util.stream.Stream in hot paths List<String> tokenizedTypes = MimeTypeUtils.tokenize(mediaTypes); List<MediaType> result = new ArrayList<>(tokenizedTypes.size()); for (String type : tokenizedTypes) { if (StringUtils.hasText(type)) { result.add(parseMediaType(type)); } } return result; }
Parse the given list of (potentially) comma-separated strings into a list of MediaType objects.

This method can be used to parse an Accept or Content-Type header.

Params:
  • mediaTypes – the string to parse
Throws:
Returns:the list of media types
Since:4.3.2
/** * Parse the given list of (potentially) comma-separated strings into a * list of {@code MediaType} objects. * <p>This method can be used to parse an Accept or Content-Type header. * @param mediaTypes the string to parse * @return the list of media types * @throws InvalidMediaTypeException if the media type value cannot be parsed * @since 4.3.2 */
public static List<MediaType> parseMediaTypes(@Nullable List<String> mediaTypes) { if (CollectionUtils.isEmpty(mediaTypes)) { return Collections.emptyList(); } else if (mediaTypes.size() == 1) { return parseMediaTypes(mediaTypes.get(0)); } else { List<MediaType> result = new ArrayList<>(8); for (String mediaType : mediaTypes) { result.addAll(parseMediaTypes(mediaType)); } return result; } }
Re-create the given mime types as media types.
Since:5.0
/** * Re-create the given mime types as media types. * @since 5.0 */
public static List<MediaType> asMediaTypes(List<MimeType> mimeTypes) { List<MediaType> mediaTypes = new ArrayList<>(mimeTypes.size()); for (MimeType mimeType : mimeTypes) { mediaTypes.add(MediaType.asMediaType(mimeType)); } return mediaTypes; }
Re-create the given mime type as a media type.
Since:5.0
/** * Re-create the given mime type as a media type. * @since 5.0 */
public static MediaType asMediaType(MimeType mimeType) { if (mimeType instanceof MediaType) { return (MediaType) mimeType; } return new MediaType(mimeType.getType(), mimeType.getSubtype(), mimeType.getParameters()); }
Return a string representation of the given list of MediaType objects.

This method can be used to for an Accept or Content-Type header.

Params:
  • mediaTypes – the media types to create a string representation for
Returns:the string representation
/** * Return a string representation of the given list of {@code MediaType} objects. * <p>This method can be used to for an {@code Accept} or {@code Content-Type} header. * @param mediaTypes the media types to create a string representation for * @return the string representation */
public static String toString(Collection<MediaType> mediaTypes) { return MimeTypeUtils.toString(mediaTypes); }
Sorts the given list of MediaType objects by specificity.

Given two media types:

  1. if either media type has a wildcard type, then the media type without the wildcard is ordered before the other.
  2. if the two media types have different types, then they are considered equal and remain their current order.
  3. if either media type has a wildcard subtype, then the media type without the wildcard is sorted before the other.
  4. if the two media types have different subtypes, then they are considered equal and remain their current order.
  5. if the two media types have different quality value, then the media type with the highest quality value is ordered before the other.
  6. if the two media types have a different amount of parameters, then the media type with the most parameters is ordered before the other.

For example:

audio/basic < audio/* < */*
audio/* < audio/*;q=0.7; audio/*;q=0.3
audio/basic;level=1 < audio/basic
audio/basic == text/html
audio/basic == audio/wave
Params:
  • mediaTypes – the list of media types to be sorted
See Also:
/** * Sorts the given list of {@code MediaType} objects by specificity. * <p>Given two media types: * <ol> * <li>if either media type has a {@linkplain #isWildcardType() wildcard type}, then the media type without the * wildcard is ordered before the other.</li> * <li>if the two media types have different {@linkplain #getType() types}, then they are considered equal and * remain their current order.</li> * <li>if either media type has a {@linkplain #isWildcardSubtype() wildcard subtype}, then the media type without * the wildcard is sorted before the other.</li> * <li>if the two media types have different {@linkplain #getSubtype() subtypes}, then they are considered equal * and remain their current order.</li> * <li>if the two media types have different {@linkplain #getQualityValue() quality value}, then the media type * with the highest quality value is ordered before the other.</li> * <li>if the two media types have a different amount of {@linkplain #getParameter(String) parameters}, then the * media type with the most parameters is ordered before the other.</li> * </ol> * <p>For example: * <blockquote>audio/basic &lt; audio/* &lt; *&#047;*</blockquote> * <blockquote>audio/* &lt; audio/*;q=0.7; audio/*;q=0.3</blockquote> * <blockquote>audio/basic;level=1 &lt; audio/basic</blockquote> * <blockquote>audio/basic == text/html</blockquote> * <blockquote>audio/basic == audio/wave</blockquote> * @param mediaTypes the list of media types to be sorted * @see <a href="https://tools.ietf.org/html/rfc7231#section-5.3.2">HTTP 1.1: Semantics * and Content, section 5.3.2</a> */
public static void sortBySpecificity(List<MediaType> mediaTypes) { Assert.notNull(mediaTypes, "'mediaTypes' must not be null"); if (mediaTypes.size() > 1) { mediaTypes.sort(SPECIFICITY_COMPARATOR); } }
Sorts the given list of MediaType objects by quality value.

Given two media types:

  1. if the two media types have different quality value, then the media type with the highest quality value is ordered before the other.
  2. if either media type has a wildcard type, then the media type without the wildcard is ordered before the other.
  3. if the two media types have different types, then they are considered equal and remain their current order.
  4. if either media type has a wildcard subtype, then the media type without the wildcard is sorted before the other.
  5. if the two media types have different subtypes, then they are considered equal and remain their current order.
  6. if the two media types have a different amount of parameters, then the media type with the most parameters is ordered before the other.
Params:
  • mediaTypes – the list of media types to be sorted
See Also:
/** * Sorts the given list of {@code MediaType} objects by quality value. * <p>Given two media types: * <ol> * <li>if the two media types have different {@linkplain #getQualityValue() quality value}, then the media type * with the highest quality value is ordered before the other.</li> * <li>if either media type has a {@linkplain #isWildcardType() wildcard type}, then the media type without the * wildcard is ordered before the other.</li> * <li>if the two media types have different {@linkplain #getType() types}, then they are considered equal and * remain their current order.</li> * <li>if either media type has a {@linkplain #isWildcardSubtype() wildcard subtype}, then the media type without * the wildcard is sorted before the other.</li> * <li>if the two media types have different {@linkplain #getSubtype() subtypes}, then they are considered equal * and remain their current order.</li> * <li>if the two media types have a different amount of {@linkplain #getParameter(String) parameters}, then the * media type with the most parameters is ordered before the other.</li> * </ol> * @param mediaTypes the list of media types to be sorted * @see #getQualityValue() */
public static void sortByQualityValue(List<MediaType> mediaTypes) { Assert.notNull(mediaTypes, "'mediaTypes' must not be null"); if (mediaTypes.size() > 1) { mediaTypes.sort(QUALITY_VALUE_COMPARATOR); } }
Sorts the given list of MediaType objects by specificity as the primary criteria and quality value the secondary.
See Also:
/** * Sorts the given list of {@code MediaType} objects by specificity as the * primary criteria and quality value the secondary. * @see MediaType#sortBySpecificity(List) * @see MediaType#sortByQualityValue(List) */
public static void sortBySpecificityAndQuality(List<MediaType> mediaTypes) { Assert.notNull(mediaTypes, "'mediaTypes' must not be null"); if (mediaTypes.size() > 1) { mediaTypes.sort(MediaType.SPECIFICITY_COMPARATOR.thenComparing(MediaType.QUALITY_VALUE_COMPARATOR)); } } /** * Comparator used by {@link #sortByQualityValue(List)}. */ public static final Comparator<MediaType> QUALITY_VALUE_COMPARATOR = (mediaType1, mediaType2) -> { double quality1 = mediaType1.getQualityValue(); double quality2 = mediaType2.getQualityValue(); int qualityComparison = Double.compare(quality2, quality1); if (qualityComparison != 0) { return qualityComparison; // audio/*;q=0.7 < audio/*;q=0.3 } else if (mediaType1.isWildcardType() && !mediaType2.isWildcardType()) { // */* < audio/* return 1; } else if (mediaType2.isWildcardType() && !mediaType1.isWildcardType()) { // audio/* > */* return -1; } else if (!mediaType1.getType().equals(mediaType2.getType())) { // audio/basic == text/html return 0; } else { // mediaType1.getType().equals(mediaType2.getType()) if (mediaType1.isWildcardSubtype() && !mediaType2.isWildcardSubtype()) { // audio/* < audio/basic return 1; } else if (mediaType2.isWildcardSubtype() && !mediaType1.isWildcardSubtype()) { // audio/basic > audio/* return -1; } else if (!mediaType1.getSubtype().equals(mediaType2.getSubtype())) { // audio/basic == audio/wave return 0; } else { int paramsSize1 = mediaType1.getParameters().size(); int paramsSize2 = mediaType2.getParameters().size(); return Integer.compare(paramsSize2, paramsSize1); // audio/basic;level=1 < audio/basic } } }; /** * Comparator used by {@link #sortBySpecificity(List)}. */ public static final Comparator<MediaType> SPECIFICITY_COMPARATOR = new SpecificityComparator<MediaType>() { @Override protected int compareParameters(MediaType mediaType1, MediaType mediaType2) { double quality1 = mediaType1.getQualityValue(); double quality2 = mediaType2.getQualityValue(); int qualityComparison = Double.compare(quality2, quality1); if (qualityComparison != 0) { return qualityComparison; // audio/*;q=0.7 < audio/*;q=0.3 } return super.compareParameters(mediaType1, mediaType2); } }; }