Update MockServletContext to MediaTypeFactory

This commit changes the `MockServletContext.getMimeType` method to use
`MediaTypeFactory` instead of JAF. It also adds a `addMimeType(String,
MediaType)` method to customize the mime types returned from said
method.

Issue: SPR-14908
This commit is contained in:
Arjen Poutsma 2017-03-15 10:52:19 +01:00 committed by Rossen Stoyanchev
parent 1329ccf1bc
commit d414718467
5 changed files with 64 additions and 56 deletions

View File

@ -29,7 +29,6 @@ import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
import javax.activation.FileTypeMap;
import javax.servlet.Filter;
import javax.servlet.FilterRegistration;
import javax.servlet.RequestDispatcher;
@ -47,9 +46,12 @@ import org.apache.commons.logging.LogFactory;
import org.springframework.core.io.DefaultResourceLoader;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.http.MediaType;
import org.springframework.http.MediaTypeFactory;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.util.WebUtils;
/**
@ -136,6 +138,8 @@ public class MockServletContext implements ServletContext {
private String responseCharacterEncoding;
private final Map<String, MediaType> mimeTypes = new LinkedHashMap<>();
/**
* Create a new {@code MockServletContext}, using no base path and a
@ -256,29 +260,27 @@ public class MockServletContext implements ServletContext {
return this.effectiveMinorVersion;
}
/**
* This method uses the default
* {@link javax.activation.FileTypeMap#getDefaultFileTypeMap() FileTypeMap}
* from the Java Activation Framework to resolve MIME types.
* <p>The Java Activation Framework returns {@code "application/octet-stream"}
* if the MIME type is unknown (i.e., it never returns {@code null}). Thus, in
* order to honor the {@link ServletContext#getMimeType(String)} contract,
* this method returns {@code null} if the MIME type is
* {@code "application/octet-stream"}.
* <p>{@code MockServletContext} does not provide a direct mechanism for
* setting a custom MIME type; however, if the default {@code FileTypeMap}
* is an instance of {@code javax.activation.MimetypesFileTypeMap}, a custom
* MIME type named {@code text/enigma} can be registered for a custom
* {@code .puzzle} file extension in the following manner:
* <pre style="code">
* MimetypesFileTypeMap mimetypesFileTypeMap = (MimetypesFileTypeMap) FileTypeMap.getDefaultFileTypeMap();
* mimetypesFileTypeMap.addMimeTypes("text/enigma puzzle");
* </pre>
*/
@Override
public String getMimeType(String filePath) {
String mimeType = FileTypeMap.getDefaultFileTypeMap().getContentType(filePath);
return ("application/octet-stream".equals(mimeType) ? null : mimeType);
String extension = StringUtils.getFilenameExtension(filePath);
MediaType result;
if (this.mimeTypes.containsKey(extension)) {
result = this.mimeTypes.get(extension);
}
else {
result = MediaTypeFactory.getMediaType(filePath);
}
return result != null ? result.toString() : null;
}
/**
* Adds a mime type mapping for use by {@link #getMimeType(String)}.
* @param fileExtension a file extension, such as {@code txt}, {@code gif}
* @param mimeType the mime type
*/
public void addMimeType(String fileExtension, MediaType mimeType) {
Assert.notNull(fileExtension, "'fileExtension' must not be null");
this.mimeTypes.put(fileExtension, mimeType);
}
@Override

View File

@ -18,16 +18,19 @@ package org.springframework.mock.web;
import java.util.Map;
import java.util.Set;
import javax.activation.FileTypeMap;
import javax.activation.MimetypesFileTypeMap;
import javax.servlet.FilterRegistration;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletRegistration;
import org.junit.Test;
import static org.hamcrest.CoreMatchers.*;
import static org.junit.Assert.*;
import org.springframework.http.MediaType;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
/**
* @author Juergen Hoeller
@ -87,10 +90,7 @@ public class MockServletContextTests {
*/
@Test
public void getMimeTypeWithCustomConfiguredType() {
FileTypeMap defaultFileTypeMap = FileTypeMap.getDefaultFileTypeMap();
assertThat(defaultFileTypeMap, instanceOf(MimetypesFileTypeMap.class));
MimetypesFileTypeMap mimetypesFileTypeMap = (MimetypesFileTypeMap) defaultFileTypeMap;
mimetypesFileTypeMap.addMimeTypes("text/enigma enigma");
sc.addMimeType("enigma", new MediaType("text", "enigma"));
assertEquals("text/enigma", sc.getMimeType("filename.enigma"));
}

View File

@ -29,7 +29,6 @@ import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
import javax.activation.FileTypeMap;
import javax.servlet.Filter;
import javax.servlet.FilterRegistration;
import javax.servlet.RequestDispatcher;
@ -47,9 +46,12 @@ import org.apache.commons.logging.LogFactory;
import org.springframework.core.io.DefaultResourceLoader;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.http.MediaType;
import org.springframework.http.MediaTypeFactory;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.util.WebUtils;
/**
@ -136,6 +138,7 @@ public class MockServletContext implements ServletContext {
private String responseCharacterEncoding;
private final Map<String, MediaType> mimeTypes = new LinkedHashMap<>();
/**
* Create a new {@code MockServletContext}, using no base path and a
@ -256,29 +259,27 @@ public class MockServletContext implements ServletContext {
return this.effectiveMinorVersion;
}
/**
* This method uses the default
* {@link javax.activation.FileTypeMap#getDefaultFileTypeMap() FileTypeMap}
* from the Java Activation Framework to resolve MIME types.
* <p>The Java Activation Framework returns {@code "application/octet-stream"}
* if the MIME type is unknown (i.e., it never returns {@code null}). Thus, in
* order to honor the {@link ServletContext#getMimeType(String)} contract,
* this method returns {@code null} if the MIME type is
* {@code "application/octet-stream"}.
* <p>{@code MockServletContext} does not provide a direct mechanism for
* setting a custom MIME type; however, if the default {@code FileTypeMap}
* is an instance of {@code javax.activation.MimetypesFileTypeMap}, a custom
* MIME type named {@code text/enigma} can be registered for a custom
* {@code .puzzle} file extension in the following manner:
* <pre style="code">
* MimetypesFileTypeMap mimetypesFileTypeMap = (MimetypesFileTypeMap) FileTypeMap.getDefaultFileTypeMap();
* mimetypesFileTypeMap.addMimeTypes("text/enigma puzzle");
* </pre>
*/
@Override
public String getMimeType(String filePath) {
String mimeType = FileTypeMap.getDefaultFileTypeMap().getContentType(filePath);
return ("application/octet-stream".equals(mimeType) ? null : mimeType);
String extension = StringUtils.getFilenameExtension(filePath);
MediaType result;
if (this.mimeTypes.containsKey(extension)) {
result = this.mimeTypes.get(extension);
}
else {
result = MediaTypeFactory.getMediaType(filePath);
}
return result != null ? result.toString() : null;
}
/**
* Adds a mime type mapping for use by {@link #getMimeType(String)}.
* @param fileExtension a file extension, such as {@code txt}, {@code gif}
* @param mimeType the mime type
*/
public void addMimeType(String fileExtension, MediaType mimeType) {
Assert.notNull(fileExtension, "'fileExtension' must not be null");
this.mimeTypes.put(fileExtension, mimeType);
}
@Override

View File

@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 the original author or authors.
* Copyright 2002-2017 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.
@ -45,7 +45,11 @@ import org.springframework.web.accept.ContentNegotiationManager;
import org.springframework.web.accept.ContentNegotiationManagerFactoryBean;
import org.springframework.web.servlet.HandlerMapping;
import static org.junit.Assert.*;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
/**
* Unit tests for ResourceHttpRequestHandler.
@ -243,7 +247,7 @@ public class ResourceHttpRequestHandlerTests {
@Test // SPR-13658
public void getResourceWithRegisteredMediaType() throws Exception {
ContentNegotiationManagerFactoryBean factory = new ContentNegotiationManagerFactoryBean();
factory.addMediaType("css", new MediaType("foo", "bar"));
factory.addMediaType("bar", new MediaType("foo", "bar"));
factory.afterPropertiesSet();
ContentNegotiationManager manager = factory.getObject();
@ -254,7 +258,7 @@ public class ResourceHttpRequestHandlerTests {
handler.setContentNegotiationManager(manager);
handler.afterPropertiesSet();
this.request.setAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE, "foo.css");
this.request.setAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE, "foo.bar");
handler.handleRequest(this.request, this.response);
assertEquals("foo/bar", this.response.getContentType());

View File

@ -0,0 +1 @@
h1 { color:red; }