/** * Determines the {@link MediaType} for the given filename. * * <p>The default implementation will check the {@linkplain #setMediaTypes(Map) media types} * property first for a defined mapping. If not present, and if the Java Activation Framework can * be found on the classpath, it will call {@link FileTypeMap#getContentType(String)} * * <p>This method can be overridden to provide a different algorithm. * * @param filename the current request file name (i.e. {@code hotels.html}) * @return the media type, if any */ protected MediaType getMediaTypeFromFilename(String filename) { String extension = StringUtils.getFilenameExtension(filename); if (!StringUtils.hasText(extension)) { return null; } extension = extension.toLowerCase(Locale.ENGLISH); MediaType mediaType = this.mediaTypes.get(extension); if (mediaType == null) { String mimeType = getServletContext().getMimeType(filename); if (StringUtils.hasText(mimeType)) { mediaType = MediaType.parseMediaType(mimeType); } if (this.useJaf && (mediaType == null || MediaType.APPLICATION_OCTET_STREAM.equals(mediaType))) { MediaType jafMediaType = ActivationMediaTypeFactory.getMediaType(filename); if (jafMediaType != null && !MediaType.APPLICATION_OCTET_STREAM.equals(jafMediaType)) { mediaType = jafMediaType; } } if (mediaType != null) { this.mediaTypes.putIfAbsent(extension, mediaType); } } return mediaType; }
/** * Extends the base class {@link PathExtensionContentNegotiationStrategy#getMediaTypeForResource} * with the ability to also look up through the ServletContext. * * @param resource the resource to look up * @return the MediaType for the extension or {@code null}. * @since 4.3 */ public MediaType getMediaTypeForResource(Resource resource) { MediaType mediaType = super.getMediaTypeForResource(resource); if (mediaType == null) { String mimeType = this.servletContext.getMimeType(resource.getFilename()); if (StringUtils.hasText(mimeType)) { mediaType = MediaType.parseMediaType(mimeType); } } if (MediaType.APPLICATION_OCTET_STREAM.equals(mediaType)) { mediaType = null; } return mediaType; }
@Override protected MediaType handleNoMatch(NativeWebRequest webRequest, String extension) throws HttpMediaTypeNotAcceptableException { if (this.useJaf && JAF_PRESENT) { MediaType mediaType = JafMediaTypeFactory.getMediaType("file." + extension); if (mediaType != null && !MediaType.APPLICATION_OCTET_STREAM.equals(mediaType)) { return mediaType; } } if (this.ignoreUnknownExtensions) { return null; } throw new HttpMediaTypeNotAcceptableException(getAllMediaTypes()); }
/** * A public method exposing the knowledge of the path extension strategy to resolve file * extensions to a MediaType in this case for a given {@link Resource}. The method first looks up * any explicitly registered file extensions first and then falls back on JAF if available. * * @param resource the resource to look up * @return the MediaType for the extension or {@code null}. * @since 4.3 */ public MediaType getMediaTypeForResource(Resource resource) { Assert.notNull(resource); MediaType mediaType = null; String filename = resource.getFilename(); String extension = StringUtils.getFilenameExtension(filename); if (extension != null) { mediaType = lookupMediaType(extension); } if (mediaType == null && JAF_PRESENT) { mediaType = JafMediaTypeFactory.getMediaType(filename); } if (MediaType.APPLICATION_OCTET_STREAM.equals(mediaType)) { mediaType = null; } return mediaType; }
/** * Resolve file extension via {@link ServletContext#getMimeType(String)} and also delegate to base * class for a potential JAF lookup. */ @Override protected MediaType handleNoMatch(NativeWebRequest webRequest, String extension) throws HttpMediaTypeNotAcceptableException { MediaType mediaType = null; if (this.servletContext != null) { String mimeType = this.servletContext.getMimeType("file." + extension); if (StringUtils.hasText(mimeType)) { mediaType = MediaType.parseMediaType(mimeType); } } if (mediaType == null || MediaType.APPLICATION_OCTET_STREAM.equals(mediaType)) { MediaType superMediaType = super.handleNoMatch(webRequest, extension); if (superMediaType != null) { mediaType = superMediaType; } } return mediaType; }
/** * Add default headers to the output message. * * <p>This implementation delegates to {@link #getDefaultContentType(Object)} if a content type * was not provided, calls {@link #getContentLength}, and sets the corresponding headers * * @since 4.2 */ protected void addDefaultHeaders(HttpHeaders headers, T t, MediaType contentType) throws IOException { if (headers.getContentType() == null) { MediaType contentTypeToUse = contentType; if (contentType == null || contentType.isWildcardType() || contentType.isWildcardSubtype()) { contentTypeToUse = getDefaultContentType(t); } else if (MediaType.APPLICATION_OCTET_STREAM.equals(contentType)) { MediaType mediaType = getDefaultContentType(t); contentTypeToUse = (mediaType != null ? mediaType : contentTypeToUse); } if (contentTypeToUse != null) { headers.setContentType(contentTypeToUse); } } if (headers.getContentLength() == -1) { Long contentLength = getContentLength(t, headers.getContentType()); if (contentLength != null) { headers.setContentLength(contentLength); } } }