Wildfly Undertow 文件 Mimetypes

Posted

技术标签:

【中文标题】Wildfly Undertow 文件 Mimetypes【英文标题】:Wildfly Undertow File Mimetypes 【发布时间】:2018-07-17 11:02:59 【问题描述】:

我希望 Undertow 提供静态文件,如 .jpg、.png、.js、.css、.txt 等...

我在standalone.xml 中编辑了undertow 子系统:

<subsystem xmlns="urn:jboss:domain:undertow:4.0">
        <buffer-cache name="default"/>
        <server name="default-server">
            <http-listener name="default" socket-binding="http" redirect-socket="https" enable-http2="true"/>
            <https-listener name="https" socket-binding="https" security-realm="ApplicationRealm" enable-http2="true"/>
            <host name="default-host" alias="localhost">
                <location name="/images" handler="sh-resources"/>
                <filter-ref name="server-header"/>
                <filter-ref name="x-powered-by-header"/>
                <filter-ref name="content-png" predicate="path-suffix['.png']"/>
                <http-invoker security-realm="ApplicationRealm"/>
            </host>
        </server>
        <servlet-container name="default">
            <jsp-config/>
            <websockets/>
        </servlet-container>
        <handlers>
            <file name="sh-resources" path="/resource" directory-listing="true"/>
        </handlers>
        <filters>
            <response-header name="server-header" header-name="Server" header-value="WildFly/11"/>
            <response-header name="x-powered-by-header" header-name="X-Powered-By" header-value="Undertow/1"/>
            <response-header name="content-png" header-name="Content-Type" header-value="image/png"/>
        </filters>
    </subsystem>

我的“/resource”文件夹“1.jpg”、“2.png”、“js.js”、“c.css”中有一些文件:

http://localhost:8080/resource/1.jpg --> 在浏览器中不显示任何内容

http://localhost:8080/resource/2.png --> 在浏览器中不显示任何内容

http://localhost:8080/resource/js.js --> 在浏览器中不显示任何内容

http://localhost:8080/resource/c.css --> 在浏览器中显示文件内容

http://localhost:8080/resource/test.html --> 在浏览器中显示文件内容

为什么我看不到图片但可以看到 css & html 内容?我认为是因为 mimetype 设置不正确?

PS: 我尝试通过 Servlet 提供静态文件并设置正确的 Mimetypes -> 在浏览器(chrome)中一切正常我可以看到图像和 .js 内容(以及所有其他文件结尾)。

我的 Servlet 代码(应用程序在服务器的“/”处运行):

@WebFilter("/*")  //get all requests
public class MasterFilter implements javax.servlet.Filter 
        //...
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
        throws IOException, ServletException 

    HttpServletRequest req = (HttpServletRequest) request;
    String path = req.getRequestURI();

    if (path.startsWith("/resource"))          
        String mimetype = "text/html;charset=UTF-8";

        mimetype = path.contains(".png") ? "image/png" : mimetype;
        mimetype = path.contains(".jpg") || path.contains(".jpeg") ? "image/jpeg" : mimetype;
        mimetype = path.contains(".js") ? "text/javascript" : mimetype;
        mimetype = path.contains(".css") ? "text/css" : mimetype;
        response.setContentType(mimetype);
        chain.doFilter(request, response); // Goes to static resource in local folder "webapp/resource/"

    

有什么建议吗? 提前致谢。

编辑:

上述带有 Servlet 过滤器的解决方案可以正常工作。但感谢@JGlass 的回答,我还找到了另一个解决方案。 (请记住,我绝对需要我的 Servlet 过滤器):

    “MasterFilter”类转发到“ServeResource”servlet:

    @WebFilter("/*") public class MasterFilter implements javax.servlet.Filter /*...*/ public void doFilter(..) /*...*/ if (path.startsWith("/resource")) //forward to "ServeResource" servlet

2."ServeResource" servlet 服务静态文件:

@WebServlet("/resource/*")
public class ServeResource extends HttpServlet 
private static final long serialVersionUID = 1L;

/**
 * @see HttpServlet#HttpServlet()
 */
public ServeResource() 
    super();


/**
 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse 
   response)
 */
protected void doGet(HttpServletRequest req, HttpServletResponse resp) 
throws ServletException, IOException 

  ServletContext cntx= req.getServletContext();
  String fileUri = req.getRequestURI();
  System.out.println("fileUri: "+fileUri);
  // Get the absolute path of the image (or any file)
  String filename = cntx.getRealPath(fileUri);
  System.out.println("file realPath: "+filename);
  // retrieve mimeType dynamically
  String mime = cntx.getMimeType(filename);
  System.out.println("mime type: "+mime);
  if (mime == null) 
    resp.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
    return;
  

  resp.setContentType(mime);
  File file = new File(filename);
  resp.setContentLength((int)file.length());

  FileInputStream in = new FileInputStream(file);
  OutputStream out = resp.getOutputStream();

  // Copy the contents of the file to the output stream
   byte[] buf = new byte[1024];
   int count = 0;
   while ((count = in.read(buf)) >= 0) 
     out.write(buf, 0, count);
   
    out.close();
    in.close();


/**
 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
 */
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException 
    doGet(request, response);



3.web.xml 包含扩展映射:

    <mime-mapping>
    <extension>html</extension>
    <mime-type>text/html</mime-type>
</mime-mapping>
<mime-mapping>
    <extension>txt</extension>
    <mime-type>text/plain</mime-type>
</mime-mapping>
<mime-mapping>
    <extension>js</extension>
    <mime-type>text/javascript</mime-type>
</mime-mapping>
<mime-mapping>
    <extension>jpg</extension>
    <mime-type>image/jpeg</mime-type>
</mime-mapping>
<mime-mapping>
    <extension>jpeg</extension>
    <mime-type>image/jpeg</mime-type>
</mime-mapping>
<mime-mapping>
    <extension>png</extension>
    <mime-type>image/png</mime-type>
</mime-mapping>
<mime-mapping>
    <extension>css</extension>
    <mime-type>text/css</mime-type>
</mime-mapping>
<mime-mapping>
    <extension>zip</extension>
    <mime-type>application/zip</mime-type>
</mime-mapping>

【问题讨论】:

“我认为是因为 mimetype 设置不正确?” 换句话说,您甚至没有检查实际的响应标头..??为什么不呢? 您使用 servlet 过滤器来处理 mime 类型而不是只允许链中的最终 servlet 处理它们的任何原因,在这种情况下您不需要 servlet 过滤器?我在下面的回答有两个方面 - 我想你需要 web.xml 中的 mime 类型映射用于静态页面,然后是用于让 servlet 处理 mime 类型的 SO 链接 @JGlass 我的路由设置需要 servlet 过滤器。如果我收到“/resource”请求 -> 提供静态文件 -> 否则将请求转发给其他一些 servlet 哦,我现在明白了。您是否尝试过 BalusC 的评论,您知道如何在 FF 或 IE 中正确执行此操作吗?和愚蠢的问题,但尝试 sys out'ing path 以确保它包含您期望它包含的内容 - 您没有 else .. 所以 可能 IF 语句甚至没有被击中另一个想法,如果这是一个静态资源...好吧我不知道,但也许尝试添加 web.xml 条目,看看它们是否有帮助? 根据Javax servlet filterchain setting contenttype as text plain in firefox,我会尝试 web.xml 中的 mime 类型,因为它是正确的答案 【参考方案1】:

您可以将您的 mime-types 映射放在您的 web.xml 中。这是一个例子:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://xmlns.jcp.org/xml/ns/javaee"
    xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
    id="WebApp_ID" version="3.1">
    <display-name>TestDynamicWAR</display-name>
    <welcome-file-list>
        <welcome-file>index.html</welcome-file>
        <welcome-file>index.htm</welcome-file>
        <welcome-file>index.jsp</welcome-file>
        <welcome-file>default.html</welcome-file>
        <welcome-file>default.htm</welcome-file>
        <welcome-file>default.jsp</welcome-file>
    </welcome-file-list>

    <servlet>
        <servlet-name>testServlet</servlet-name>
        <servlet-class>com.mycompany.test.TestServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>testServlet</servlet-name>
        <url-pattern>/test</url-pattern>
    </servlet-mapping>

    <mime-mapping>
        <extension>html</extension>
        <mime-type>text/html</mime-type>
    </mime-mapping>
    <mime-mapping>
        <extension>txt</extension>
        <mime-type>text/plain</mime-type>
    </mime-mapping>
    <mime-mapping>
        <extension>jpg</extension>
        <mime-type>image/jpeg</mime-type>
    </mime-mapping>
    <mime-mapping>
        <extension>png</extension>
        <mime-type>image/png</mime-type>
    </mime-mapping>
    <mime-mapping>
        <extension>js</extension>
        <mime-type>text/plain</mime-type>
    </mime-mapping>
    <mime-mapping>
        <extension>css</extension>
        <mime-type>text/css</mime-type>
    </mime-mapping> 

</web-app>

注意:您可能不需要 css 和 js,因为它们已经在工作了。 html 和 txt mime 类型也只是一个示例 如果您只想处理 mime 类型,我认为您不需要处理 servlet 过滤器。这个 SO 帖子有处理 mime 类型的 servlet Output an image file from a servlet

【讨论】:

我会接受这个作为答案,因为它帮助我找到了解决方案。 这行得通吗?我希望它做到了!根据我找到的最后一条评论和链接,似乎它可能会有所帮助。很高兴为您提供帮助! 看看我更新的帖子。您的回答有助于找到另一个解决方案,但第一个解决方案(使用 servlet 过滤器 ans chain.doFilter() 具有相同的结果):) 啊,我明白了,两者兼而有之!不错,干得好!很高兴我们成功了!赛亚!

以上是关于Wildfly Undertow 文件 Mimetypes的主要内容,如果未能解决你的问题,请参考以下文章

使用 WildFly (Undertow) 托管多个域

如何在 WildFly 中设置 Undertow MAX_ENTITY_SIZE

Wildfly / Undertow:一台主机的多个别名

Wildfly 8.2/undertow 读取超时

Wildfly Undertow 中的 HTTPS 重定向

以编程方式在 Wildfly/Undertow 中创建虚拟主机