Apache Tomcat MimeTypes - 有获取它们的任何方法吗?

3

我正在为Apache Tomcat编写过滤器,想知道是否有一种方法可以在不显式读取xml文件的情况下获取/conf/web.xml文件配置文件中放置的mimetypes。也许Apache Tomcat库中有什么可用的东西吗?


你需要这些信息做什么?可能有更好的方法,而不是在一些容器特定的代码中进行黑客攻击,这会使你的Web应用程序无法移植。 - BalusC
2个回答

12

来自tomcat/conf/web.xml:

<!-- ======================== Introduction ============================== -->
<!-- This document defines default values for *all* web applications      -->
<!-- loaded into this instance of Tomcat.  As each application is         -->
<!-- deployed, this file is processed, followed by the                    -->
<!-- "/WEB-INF/web.xml" deployment descriptor from your own               -->
<!-- applications.                                                        -->

因此,它们可以通过ServletContext.getMimeType方法获取:

@Override
protected void doGet(final HttpServletRequest req, 
        final HttpServletResponse resp) throws ServletException, IOException {
    final ServletContext servletContext = req.getServletContext();
    final String mimeType = servletContext.getMimeType("filename.txt");
    ...
}

我没有找到其他公共API来获取整个MIME类型映射。如果你真的需要,你可以使用这个丑陋的方法来获取所有扩展名的完整列表:

import java.util.Arrays;
import java.lang.reflect.Field;
import org.apache.catalina.connector.Request;
import org.apache.catalina.connector.RequestFacade;
import org.apache.catalina.core.StandardContext;

...

// ugly reflection hack - do NOT use
final RequestFacade tomcatRequestFacade = (RequestFacade) req;
final Class<? extends RequestFacade> requestFacadeClass = 
    tomcatRequestFacade.getClass();
try {
    final Field field = requestFacadeClass.getDeclaredField("request");
    field.setAccessible(true);
    final Request tomcatRequest = (Request) field.get(tomcatRequestFacade);
    final StandardContext standardContext = 
        (StandardContext) tomcatRequest.getContext();
    final String[] mappings = standardContext.findMimeMappings();
    logger.info("mapping list: {}", Arrays.asList(mappings));
} catch (final Exception e) {
    logger.error("", e);
}

它在Tomcat 7.0.21上可以使用。由于它使用了Tomcat的内部类,因此不能保证它能在其他Tomcat版本中正常工作。

请注意,您仍需要调用ServletContext.getMimeType来获取MIME类型。

所需的maven依赖项:

<dependency>
    <groupId>org.apache.tomcat</groupId>
    <artifactId>tomcat-catalina</artifactId>
    <version>7.0.21</version>
    <scope>provided</scope>
</dependency>

1
我理解OP想要将它们全部提取到某个Map或其他东西中。但这确实是我在评论问题时提到的“更好的方法”之一 :) - BalusC
@BalusC:是的,我知道,但我不想使用具有反射的容器特定代码,而且我也没有找到任何公共API。无论如何,我只是为了好玩写了它 :-) - palacsint
我需要这些信息来检查所请求的资源是否对服务器有已知的MIME类型,我之前不知道req.getServletContext().getMimeType()可以做到这一点... 我之前使用的是URLConnection.getFileNameMap().getContentTypeFor(),但我想要一个特定于服务器的东西...之前的方法能实现我想要的吗? - Mikey S.
是的,req.getServletContext().getMimeType() 可以从 tomcat/conf/web.xml 和 webapp 的 WEB-INF/web.xml 中工作。 - palacsint

0
为什么不这样做呢:

        Properties defaultMimeMappings = new Properties();
        InputStream is = null;
        try {
            is = Tomcat.class.getResourceAsStream("MimeTypeMappings.properties");
            defaultMimeMappings.load(is);
            for (Map.Entry<Object, Object>  entry: defaultMimeMappings.entrySet()) {
                // context.addMimeMapping((String) entry.getKey(), (String) entry.getValue());
                // do what you need here or just the use the properties w/o this loop
            }
        } catch (IOException e) {
            throw new IllegalStateException(sm.getString("tomcat.defaultMimeTypeMappingsFail"), e);
        } finally {
            if (is != null) {
                try {
                    is.close();
                } catch (IOException e) {
                    // Ignore
                }
            }
        }

直接从org.apache.catalina.startup.Tomcat.addDefaultMimeTypeMappings()中获取

如果您查看属性文件,它应该包含您需要的所有内容:

https://github.com/apache/tomcat/blob/master/java/org/apache/catalina/startup/MimeTypeMappings.properties

这样你就可以获取特定 MIME 类型的所有文件扩展名。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接