【问题标题】:Apache Tomcat MimeTypes - Any way to fetch them?Apache Tomcat MimeTypes - 有什么方法可以获取它们?
【发布时间】:2011-12-02 05:40:09
【问题描述】:

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

【问题讨论】:

  • 您究竟需要这些信息做什么?可能有比在某些特定于容器的代码中进行黑客攻击更好的方法,这会使您的 web 应用程序不可移植。

标签: jakarta-ee tomcat mime-types servlet-filters


【解决方案1】:

为什么不这样做:

        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 类型的所有文件扩展名。

【讨论】:

    【解决方案2】:

    来自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 类型映射。如果你真的需要 你可以通过这个丑陋的 hack 获得完整的扩展列表:

    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>
    

    【讨论】:

    • 我知道 OP 想要将它们全部提取到一些 Map 或其他东西中。但这确实是我在对该问题的评论中所说的“更好的方法”之一:)
    • @BalusC:是的,我知道,但我不想使用带有反射的容器特定代码,而且我还没有找到任何公共 API。无论如何,我写它只是为了好玩:-)
    • 我需要这些信息来检查请求的资源是否具有服务器已知的 mime 类型,我只是不知道 req.getServletContext().getMimeType() 就是这样做的......我正在使用:URLConnection.getFileNameMap().getContentTypeFor(),但我想要一些特定于服务器的东西......前一个会做我想要的吗?
    • 是的,req.getServletContext().getMimeType() 适用于 webapp 的 tomcat/conf/web.xmlWEB-INF/web.xml
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-02-19
    • 1970-01-01
    • 1970-01-01
    • 2011-10-07
    • 2013-03-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多