/*
 * Copyright 2002-2018 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
 *
 *      http://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.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 java.util.stream.Collectors;

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
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 * @since 3.0 * @see <a href="http://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/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.
See Also:
/** * Public constant media type for {@code application/json}. * @see #APPLICATION_JSON_UTF8 */
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.

This APPLICATION_JSON variant should be used to set JSON content type because while RFC7159 clearly states that "no charset parameter is defined for this registration", some browsers require it for interpreting correctly UTF-8 special characters.

/** * Public constant media type for {@code application/json;charset=UTF-8}. * * <p>This {@link MediaType#APPLICATION_JSON} variant should be used to set JSON * content type because while * <a href="https://tools.ietf.org/html/rfc7159#section-11">RFC7159</a> * clearly states that "no charset parameter is defined for this registration", some * browsers require it for interpreting correctly UTF-8 special characters. */
public static final MediaType APPLICATION_JSON_UTF8;
A String equivalent of APPLICATION_JSON_UTF8.

This APPLICATION_JSON_VALUE variant should be used to set JSON content type because while RFC7159 clearly states that "no charset parameter is defined for this registration", some browsers require it for interpreting correctly UTF-8 special characters.

/** * A String equivalent of {@link MediaType#APPLICATION_JSON_UTF8}. * * <p>This {@link MediaType#APPLICATION_JSON_VALUE} variant should be used to set JSON * content type because while * <a href="https://tools.ietf.org/html/rfc7159#section-11">RFC7159</a> * clearly states that "no charset parameter is defined for this registration", some * browsers require it for interpreting correctly UTF-8 special characters. */
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
/** * 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_UTF8;
A String equivalent of APPLICATION_PROBLEM_JSON_UTF8.
Since:5.0
/** * A String equivalent of {@link MediaType#APPLICATION_PROBLEM_JSON_UTF8}. * @since 5.0 */
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/stream+json.
Since:5.0
/** * Public constant media type for {@code application/stream+json}. * @since 5.0 */
public static final MediaType APPLICATION_STREAM_JSON;
A String equivalent of APPLICATION_STREAM_JSON.
Since:5.0
/** * A String equivalent of {@link MediaType#APPLICATION_STREAM_JSON}. * @since 5.0 */
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 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 { ALL = valueOf(ALL_VALUE); APPLICATION_ATOM_XML = valueOf(APPLICATION_ATOM_XML_VALUE); APPLICATION_FORM_URLENCODED = valueOf(APPLICATION_FORM_URLENCODED_VALUE); APPLICATION_JSON = valueOf(APPLICATION_JSON_VALUE); APPLICATION_JSON_UTF8 = valueOf(APPLICATION_JSON_UTF8_VALUE); APPLICATION_OCTET_STREAM = valueOf(APPLICATION_OCTET_STREAM_VALUE); APPLICATION_PDF = valueOf(APPLICATION_PDF_VALUE); APPLICATION_PROBLEM_JSON = valueOf(APPLICATION_PROBLEM_JSON_VALUE); APPLICATION_PROBLEM_JSON_UTF8 = valueOf(APPLICATION_PROBLEM_JSON_UTF8_VALUE); APPLICATION_PROBLEM_XML = valueOf(APPLICATION_PROBLEM_XML_VALUE); APPLICATION_RSS_XML = valueOf(APPLICATION_RSS_XML_VALUE); APPLICATION_STREAM_JSON = valueOf(APPLICATION_STREAM_JSON_VALUE); APPLICATION_XHTML_XML = valueOf(APPLICATION_XHTML_XML_VALUE); APPLICATION_XML = valueOf(APPLICATION_XML_VALUE); IMAGE_GIF = valueOf(IMAGE_GIF_VALUE); IMAGE_JPEG = valueOf(IMAGE_JPEG_VALUE); IMAGE_PNG = valueOf(IMAGE_PNG_VALUE); MULTIPART_FORM_DATA = valueOf(MULTIPART_FORM_DATA_VALUE); TEXT_EVENT_STREAM = valueOf(TEXT_EVENT_STREAM_VALUE); TEXT_HTML = valueOf(TEXT_HTML_VALUE); TEXT_MARKDOWN = valueOf(TEXT_MARKDOWN_VALUE); TEXT_PLAIN = valueOf(TEXT_PLAIN_VALUE); TEXT_XML = valueOf(TEXT_XML_VALUE); }
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 parameter.
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 parameter. * @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); } @Override protected void checkParameters(String attribute, String value) { super.checkParameters(attribute, value); if (PARAM_QUALITY_FACTOR.equals(attribute)) { 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 #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 #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.getType(), type.getSubtype(), type.getParameters()); } 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(); } return MimeTypeUtils.tokenize(mediaTypes).stream() .map(MediaType::parseMediaType).collect(Collectors.toList()); }
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) { return mimeTypes.stream().map(MediaType::asMediaType).collect(Collectors.toList()); }
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="http://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); } }; }