Wildfly Undertow 文件模仿类型
Wildfly Undertow File Mimetypes
我希望 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" class 转发到 "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>
您可以将您的 mime 类型映射放在 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 post 有处理 mime 类型的 servlet Output an image file from a servlet
我希望 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" class 转发到 "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>
您可以将您的 mime 类型映射放在 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 post 有处理 mime 类型的 servlet Output an image file from a servlet