- java.lang.Object
-
- jakarta.servlet.GenericServlet
-
- jakarta.servlet.http.HttpServlet
-
- org.omnifaces.servlet.FileServlet
-
- All Implemented Interfaces:
Servlet,ServletConfig,Serializable
public abstract class FileServlet extends HttpServlet
The well known "BalusC FileServlet", as an abstract template, slightly refactored, rewritten and modernized with a.o. fast NIO stuff instead of legacy RandomAccessFile. GZIP support is stripped off as that can be done application wide via
CompressedResponseFilter.This servlet properly deals with
ETag,If-None-MatchandIf-Modified-Sincecaching requests, hereby improving browser caching. This servlet also properly deals withRangeandIf-Rangeranging requests (RFC 7233), which is required by most media players for proper audio/video streaming, and by webbrowsers and for a proper resume of an paused download, and by download accelerators to be able to request smaller parts simultaneously. This servlet is ideal when you have large files like media files placed outside the web application and you can't use the default servlet.Usage
Just extend this class and override the
getFile(HttpServletRequest)method to return the desired file. If you want to trigger a HTTP 400 "Bad Request" error, simply throwIllegalArgumentException. If you want to trigger a HTTP 404 "Not Found" error, simply returnnull, or a non-existent file.Here's a concrete example which serves it via an URL like
/media/foo.ext:@WebServlet("/media/*") public class MediaFileServlet extends FileServlet { private File folder; @Override public void init() throws ServletException { folder = new File("/var/webapp/media"); } @Override protected File getFile(HttpServletRequest request) { String pathInfo = request.getPathInfo(); if (pathInfo == null || pathInfo.isEmpty() || "/".equals(pathInfo)) { throw new IllegalArgumentException(); } return new File(folder, pathInfo); } }You can embed it in e.g. HTML5 video tag as below:
<video src="#{request.contextPath}/media/video.mp4" controls="controls" />Customizing
FileServletIf more fine grained control is desired for handling "file not found" error, determining the cache expire time, the content type, whether the file should be supplied as an attachment and the attachment's file name, then the developer can opt to override one or more of the following protected methods:
handleFileNotFound(HttpServletRequest, HttpServletResponse)getExpireTime(HttpServletRequest, File)getContentType(HttpServletRequest, File)isAttachment(HttpServletRequest, String)getAttachmentName(HttpServletRequest, File)
See also:
- Since:
- 2.2
- Author:
- Bauke Scholtz
- See Also:
- Serialized Form
-
-
Constructor Summary
Constructors Constructor Description FileServlet()
-
Method Summary
All Methods Instance Methods Abstract Methods Concrete Methods Modifier and Type Method Description protected voiddoGet(HttpServletRequest request, HttpServletResponse response)protected voiddoHead(HttpServletRequest request, HttpServletResponse response)protected StringgetAttachmentName(HttpServletRequest request, File file)Returns the file name to be used inContent-Dispositionheader.protected StringgetContentType(HttpServletRequest request, File file)Returns the content type associated with the given HTTP servlet request and file.protected longgetExpireTime(HttpServletRequest request, File file)Returns how long the resource may be cached by the client before it expires, in seconds.protected abstract FilegetFile(HttpServletRequest request)Returns the file associated with the given HTTP servlet request.protected voidhandleFileNotFound(HttpServletRequest request, HttpServletResponse response)Handles the case when the file is not found.protected booleanisAttachment(HttpServletRequest request, String contentType)Returnstrueif we must force a "Save As" dialog based on the given HTTP servlet request and content type as obtained fromgetContentType(HttpServletRequest, File).-
Methods inherited from class jakarta.servlet.http.HttpServlet
doDelete, doOptions, doPost, doPut, doTrace, getLastModified, service, service
-
Methods inherited from class jakarta.servlet.GenericServlet
destroy, getInitParameter, getInitParameterNames, getServletConfig, getServletContext, getServletInfo, getServletName, init, init, log, log
-
-
-
-
Method Detail
-
doHead
protected void doHead(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
- Overrides:
doHeadin classHttpServlet- Throws:
ServletExceptionIOException
-
doGet
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
- Overrides:
doGetin classHttpServlet- Throws:
ServletExceptionIOException
-
getFile
protected abstract File getFile(HttpServletRequest request)
Returns the file associated with the given HTTP servlet request. If this method throwsIllegalArgumentException, then the servlet will return a HTTP 400 error. If this method returnsnull, or ifFile.isFile()returnsfalse, then the servlet will invokehandleFileNotFound(HttpServletRequest, HttpServletResponse).- Parameters:
request- The involved HTTP servlet request.- Returns:
- The file associated with the given HTTP servlet request.
- Throws:
IllegalArgumentException- When the request is mangled in such way that it's not recognizable as a valid file request. The servlet will then return a HTTP 400 error.
-
handleFileNotFound
protected void handleFileNotFound(HttpServletRequest request, HttpServletResponse response) throws IOException
Handles the case when the file is not found.The default implementation sends a HTTP 404 error.
- Parameters:
request- The involved HTTP servlet request.response- The involved HTTP servlet response.- Throws:
IOException- When something fails at I/O level.- Since:
- 2.3
-
getExpireTime
protected long getExpireTime(HttpServletRequest request, File file)
Returns how long the resource may be cached by the client before it expires, in seconds.The default implementation returns 30 days in seconds.
- Parameters:
request- The involved HTTP servlet request.file- The involved file.- Returns:
- The client cache expire time in seconds (not milliseconds!).
-
getContentType
protected String getContentType(HttpServletRequest request, File file)
Returns the content type associated with the given HTTP servlet request and file.The default implementation delegates
File.getName()toServletContext.getMimeType(String)with a fallback default value ofapplication/octet-stream.- Parameters:
request- The involved HTTP servlet request.file- The involved file.- Returns:
- The content type associated with the given HTTP servlet request and file.
-
isAttachment
protected boolean isAttachment(HttpServletRequest request, String contentType)
Returnstrueif we must force a "Save As" dialog based on the given HTTP servlet request and content type as obtained fromgetContentType(HttpServletRequest, File).The default implementation will return
trueif the content type does not start withtextorimage, and theAcceptrequest header is eithernullor does not match the given content type.- Parameters:
request- The involved HTTP servlet request.contentType- The content type of the involved file.- Returns:
trueif we must force a "Save As" dialog based on the given HTTP servlet request and content type.
-
getAttachmentName
protected String getAttachmentName(HttpServletRequest request, File file)
Returns the file name to be used inContent-Dispositionheader. This does not need to be URL-encoded as this will be taken care of.The default implementation returns
File.getName().- Parameters:
request- The involved HTTP servlet request.file- The involved file.- Returns:
- The file name to be used in
Content-Dispositionheader. - Since:
- 2.3
-
-