-
- All Implemented Interfaces:
ClientBehaviorHolder
,EditableValueHolder
,PartialStateHolder
,StateHolder
,TransientStateHolder
,ValueHolder
,ComponentSystemEventListener
,FacesListener
,SystemEventListenerHolder
,EventListener
public class InputFile extends HtmlInputFile
The
<o:inputFile>
is a component that extends the standard<h:inputFile>
and adds support formultiple
,directory
,accept
andmaxsize
attributes, along with built-in server side validation onaccept
andmaxsize
attributes. Additionally, it makes sure that the value of HTML file input element is never rendered. The standard<h:inputFile>
rendersPart#toString()
to it which is unnecessary.Usage
You can use it the same way as
<h:inputFile>
, you only need to changeh:
intoo:
to get the extra support formultiple
,directory
andaccept
attributes. Here's are some usage examples.Single file selection
It is basically not different from
<h:inputFile>
. You might as good use it instead.<h:form enctype="multipart/form-data"> <o:inputFile value="#{bean.file}" /> <h:commandButton value="Upload" action="#{bean.upload}" /> </h:form>
private Part file; // +getter+setter public void upload() { if (file != null) { String name = Servlets.getSubmittedFileName(file); String type = file.getContentType(); long size = file.getSize(); InputStream content = file.getInputStream(); // ... } }
Note that it's strongly recommended to use
Servlets.getSubmittedFileName(Part)
to obtain the submitted file name to make sure that any path is stripped off. Some browsers are known to incorrectly include the client side path or even a fake path along with the file name.Multiple file selection
The
multiple
attribute can be set totrue
to enable multiple file selection. With this setting the enduser can use control/command/shift keys to select multiple files.<h:form enctype="multipart/form-data"> <o:inputFile value="#{bean.files}" multiple="true" /> <h:commandButton value="Upload" action="#{bean.upload}" /> </h:form>
private List<Part> files; // +getter+setter public void upload() { if (files != null) { for (var file : files) { var name = Servlets.getSubmittedFileName(file); var type = file.getContentType(); var size = file.getSize(); var content = file.getInputStream(); // ... } } }
Folder selection
The
directory
attribute can be set totrue
to enable folder selection. This implicitly also setsmultiple
attribute totrue
and renders an additionalwebkitdirectory
attribute to HTML for better browser compatibility.<h:form enctype="multipart/form-data"> <o:inputFile value="#{bean.files}" directory="true" /> <h:commandButton value="Upload" action="#{bean.upload}" /> </h:form>
private List<Part> files; // +getter+setter public void upload() { if (files != null) { for (var file : files) { var name = Servlets.getSubmittedFileName(file); var type = file.getContentType(); var size = file.getSize(); var content = file.getInputStream(); // ... } } }
Do note that this does not send physical folders, but only files contained in those folders.
Media type filtering
The
accept
attribute can be set with a comma separated string of media types of files to filter in browse dialog. An overview of all registered media types can be found at IANA.<h:form enctype="multipart/form-data"> <o:inputFile id="file" value="#{bean.losslessImageFile}" accept="image/png,image/gif" /> <h:commandButton value="Upload" action="#{bean.upload}" /> <h:message for="file" /> </h:form>
<h:form enctype="multipart/form-data"> <o:inputFile id="file" value="#{bean.anyImageFile}" accept="image/*" /> <h:commandButton value="Upload" action="#{bean.upload}" /> <h:message for="file" /> </h:form>
<h:form enctype="multipart/form-data"> <o:inputFile id="file" value="#{bean.anyMediaFile}" accept="audio/*,image/*,video/*" /> <h:commandButton value="Upload" action="#{bean.upload}" /> <h:message for="file" /> </h:form>
This will also be validated in the server side using a built-in validator. Do note that the
accept
attribute only filters in client side and validates in server side based on the file extension, and this does thus not strictly validate the file's actual content. To cover that as well, you should in the bean's action method parse the file's actual content using the tool suited for the specific media type, such asImageIO#read()
for image files, and then checking if it returns the expected result.The default message for server side validation of
accept
attribute is:{0}: Media type of file ''{1}'' does not match ''{2}''
Where
{0}
is the component's label and{1}
is the submitted file name and{2}
is the value ofaccept
attribute.You can override the default message by the
acceptMessage
attribute:<h:form enctype="multipart/form-data"> <o:inputFile id="file" value="#{bean.anyImageFile}" accept="image/*" acceptMessage="File {1} is unacceptable!" /> <h:commandButton value="Upload" action="#{bean.upload}" /> <h:message for="file" /> </h:form>
Or by the custom message bundle file as identified by
<application><message-bundle>
infaces-config.xml
. The message key isorg.omnifaces.component.input.InputFile.accept
.org.omnifaces.component.input.InputFile.accept = File {1} is unacceptable!
File size validation
The
maxsize
attribute can be set with the maximum file size in bytes which will be validated on each selected file in the client side if the client supports HTML5 File API. This validation will be performed by custom JavaScript in client side instead of by Faces in server side. This only requires that there is a<h:message>
or<h:messages>
component and that it has itsid
set.<o:inputFile id="file" ... /> <h:message id="messageForFile" for="file" /> <!-- This must have 'id' attribute set! -->
This way the client side can trigger Faces via an ajax request to update the message component with the client side validation message. Noted should be that the file(s) will not be sent, hereby saving network bandwidth.
<h:form enctype="multipart/form-data"> <o:inputFile id="file" value="#{bean.file}" maxsize="#{10 * 1024 * 1024}" /> <!-- 10MiB --> <h:commandButton value="Upload" action="#{bean.upload}" /> <h:message id="messageForFile" for="file" /> </h:form>
This will also be validated in the server side using a built-in validator.
The default message for both client side and server side validation of
maxsize
attribute is:{0}: Size of file ''{1}'' is larger than maximum of {2}
Where
{0}
is the component's label and{1}
is the submitted file name and{2}
is the value ofmaxsize
attribute.You can override the default message by the
maxsizeMessage
attribute:<h:form enctype="multipart/form-data"> <o:inputFile id="file" value="#{bean.file}" maxsize="#{10 * 1024 * 1024}" maxsizeMessage="File {1} is too big!" /> <h:commandButton value="Upload" action="#{bean.upload}" /> <h:message id="messageForFile" for="file" /> </h:form>
Or by the custom message bundle file as identified by
<application><message-bundle>
infaces-config.xml
. The message key isorg.omnifaces.component.input.InputFile.maxsize
.org.omnifaces.component.input.InputFile.maxsize = File {1} is too big!
- Since:
- 2.5
- Author:
- Bauke Scholtz
-
-
Field Summary
Fields Modifier and Type Field Description static String
COMPONENT_TYPE
The component type, which is "org.omnifaces.component.input.InputFile".-
Fields inherited from class jakarta.faces.component.UIInput
ALWAYS_PERFORM_VALIDATION_WHEN_REQUIRED_IS_TRUE, COMPONENT_FAMILY, CONVERSION_MESSAGE_ID, EMPTY_STRING_AS_NULL_PARAM_NAME, REQUIRED_MESSAGE_ID, UPDATE_MESSAGE_ID, VALIDATE_EMPTY_FIELDS_PARAM_NAME
-
Fields inherited from class jakarta.faces.component.UIComponent
ATTRS_WITH_DECLARED_DEFAULT_VALUES, BEANINFO_KEY, bindings, COMPOSITE_COMPONENT_TYPE_KEY, COMPOSITE_FACET_NAME, CURRENT_COMPONENT, CURRENT_COMPOSITE_COMPONENT, FACETS_KEY, HONOR_CURRENT_COMPONENT_ATTRIBUTES_PARAM_NAME, VIEW_LOCATION_KEY
-
-
Constructor Summary
Constructors Constructor Description InputFile()
The constructor instructs Faces to register all scripts during the render response phase if necessary.
-
Method Summary
All Methods Instance Methods Concrete Methods Modifier and Type Method Description void
decode(FacesContext context)
This override checks if client side validation on maxsize has failed and if multi file upload is enabled.void
encodeEnd(FacesContext context)
This override will rendermultiple
,directory
andaccept
attributes accordingly.String
getAccept()
Returns comma separated string of mime types of files to filter in client side file browse dialog.String
getAcceptMessage()
Returns validation message to be displayed when the condition inaccept
attribute is violated.protected Object
getConvertedValue(FacesContext context, Object submittedValue)
This override will convert the individual parts if multi file upload is enabled and collect only non-null parts having a non-empty file name and a file size above zero.Long
getMaxsize()
Returns maximum size in bytes for each selected file.String
getMaxsizeMessage()
Returns validation message to be displayed when the condition inmaxsize
attribute is violated.Object
getSubmittedValue()
An override which ensures that the Faces implementation being used doesn't save it in the state.Object
getValue()
This override returns null during render response as it doesn't make sense to renderPart#toString()
as value of file input, moreover it's for HTML security reasons discouraged to prefill the value of a file input even though browsers will ignore it.boolean
isDirectory()
Returns whether or not to enable directory selection.boolean
isMultiple()
Returns whether or not to allow multiple file selection.void
setAccept(String accept)
Sets comma separated string of media types of files to filter in client side file browse dialog.void
setAcceptMessage(String acceptMessage)
Sets validation message to be displayed when the condition inaccept
attribute is violated.void
setDirectory(boolean directory)
Sets whether or not to enable directory selection.void
setMaxsize(Long maxsize)
Sets maximum size in bytes for each selected file.void
setMaxsizeMessage(String maxsizeMessage)
Sets validation message to be displayed when the condition inmaxsize
attribute is violated.void
setMultiple(boolean multiple)
Sets whether or not to allow multiple file selection.void
setSubmittedValue(Object submittedValue)
An override which ensures that the Faces implementation being used doesn't save it in the state.protected void
validateHierarchy(FacesContext context)
Validate the component hierarchy.protected void
validateValue(FacesContext context, Object convertedValue)
This override will server-side validate anyaccept
andmaxsize
for each part.-
Methods inherited from class jakarta.faces.component.html.HtmlInputFile
getAccesskey, getAlt, getAutocomplete, getDefaultEventName, getDir, getEventNames, getLabel, getLang, getMaxlength, getOnblur, getOnchange, getOnclick, getOndblclick, getOnfocus, getOnkeydown, getOnkeypress, getOnkeyup, getOnmousedown, getOnmousemove, getOnmouseout, getOnmouseover, getOnmouseup, getOnselect, getRole, getSize, getStyle, getStyleClass, getTabindex, getTitle, isDisabled, isReadonly, saveState, setAccesskey, setAlt, setAutocomplete, setDir, setDisabled, setLabel, setLang, setMaxlength, setOnblur, setOnchange, setOnclick, setOndblclick, setOnfocus, setOnkeydown, setOnkeypress, setOnkeyup, setOnmousedown, setOnmousemove, setOnmouseout, setOnmouseover, setOnmouseup, setOnselect, setReadonly, setRole, setSize, setStyle, setStyleClass, setTabindex, setTitle
-
Methods inherited from class jakarta.faces.component.UIInput
addValidator, addValueChangeListener, clearInitialState, compareValues, getConverterMessage, getFamily, getRequiredMessage, getValidator, getValidatorMessage, getValidators, getValueChangeListener, getValueChangeListeners, isEmpty, isImmediate, isLocalValueSet, isRequired, isValid, markInitialState, processDecodes, processUpdates, processValidators, removeValidator, removeValueChangeListener, resetValue, restoreState, setConverterMessage, setImmediate, setLocalValueSet, setRequired, setRequiredMessage, setValid, setValidator, setValidatorMessage, setValue, setValueChangeListener, updateModel, validate
-
Methods inherited from class jakarta.faces.component.UIOutput
getConverter, getLocalValue, setConverter
-
Methods inherited from class jakarta.faces.component.UIComponentBase
addClientBehavior, addFacesListener, broadcast, encodeBegin, encodeChildren, findComponent, getAttributes, getChildCount, getChildren, getClientBehaviors, getClientId, getFacesContext, getFacesListeners, getFacet, getFacetCount, getFacets, getFacetsAndChildren, getId, getListenersForEventClass, getParent, getPassThroughAttributes, getRenderer, getRendererType, getRendersChildren, getValueBinding, invokeOnComponent, isRendered, isTransient, processRestoreState, processSaveState, queueEvent, removeFacesListener, restoreAttachedState, saveAttachedState, setId, setParent, setRendered, setRendererType, setTransient, setValueBinding, subscribeToEvent, unsubscribeFromEvent
-
Methods inherited from class jakarta.faces.component.UIComponent
encodeAll, getClientId, getCompositeComponentParent, getContainerClientId, getCurrentComponent, getCurrentCompositeComponent, getNamingContainer, getPassThroughAttributes, getResourceBundleMap, getStateHelper, getStateHelper, getTransientStateHelper, getTransientStateHelper, getValueExpression, initialStateMarked, isCompositeComponent, isInView, isVisitable, popComponentFromEL, processEvent, pushComponentToEL, restoreTransientState, saveTransientState, setInView, setValueExpression, visitTree
-
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
-
Methods inherited from interface jakarta.faces.component.behavior.ClientBehaviorHolder
addClientBehavior, getClientBehaviors
-
Methods inherited from interface jakarta.faces.component.ValueHolder
getConverter, getLocalValue, setConverter
-
-
-
-
Field Detail
-
COMPONENT_TYPE
public static final String COMPONENT_TYPE
The component type, which is "org.omnifaces.component.input.InputFile".- See Also:
- Constant Field Values
-
-
Method Detail
-
decode
public void decode(FacesContext context)
This override checks if client side validation on maxsize has failed and if multi file upload is enabled. If client side validation on maxsize has failed, then it will render the message. If multi file upload is enabled, then it will set all parts as submitted value instead of only the last part as done in h:inputFile.
-
getConvertedValue
protected Object getConvertedValue(FacesContext context, Object submittedValue)
This override will convert the individual parts if multi file upload is enabled and collect only non-null parts having a non-empty file name and a file size above zero.- Overrides:
getConvertedValue
in classUIInput
-
validateValue
protected void validateValue(FacesContext context, Object convertedValue)
This override will server-side validate anyaccept
andmaxsize
for each part.- Overrides:
validateValue
in classUIInput
-
getValue
public Object getValue()
This override returns null during render response as it doesn't make sense to renderPart#toString()
as value of file input, moreover it's for HTML security reasons discouraged to prefill the value of a file input even though browsers will ignore it.- Specified by:
getValue
in interfaceValueHolder
- Overrides:
getValue
in classUIInput
-
encodeEnd
public void encodeEnd(FacesContext context) throws IOException
This override will rendermultiple
,directory
andaccept
attributes accordingly. As thedirectory
attribute is relatively new, for better browser compatibility thewebkitdirectory
attribute will also be written along it.They're written as passthrough attributes because in Mojarra the
startElement()
takes place inencodeEnd(FacesContext)
instead ofUIComponentBase.encodeBegin(FacesContext)
.- Overrides:
encodeEnd
in classUIComponentBase
- Throws:
IOException
-
validateHierarchy
protected void validateHierarchy(FacesContext context)
Validate the component hierarchy. This should only be called when project stage isDevelopment
.- Throws:
IllegalStateException
- When component hierarchy is wrong.
-
getSubmittedValue
public Object getSubmittedValue()
An override which ensures that the Faces implementation being used doesn't save it in the state. ThePart
does namely not belong there.- Specified by:
getSubmittedValue
in interfaceEditableValueHolder
- Overrides:
getSubmittedValue
in classUIInput
-
setSubmittedValue
public void setSubmittedValue(Object submittedValue)
An override which ensures that the Faces implementation being used doesn't save it in the state. ThePart
does namely not belong there.- Specified by:
setSubmittedValue
in interfaceEditableValueHolder
- Overrides:
setSubmittedValue
in classUIInput
-
isMultiple
public boolean isMultiple()
Returns whether or not to allow multiple file selection. This implicitly defaults totrue
whendirectory
attribute istrue
.- Returns:
- Whether or not to allow multiple file selection.
-
setMultiple
public void setMultiple(boolean multiple)
Sets whether or not to allow multiple file selection.- Parameters:
multiple
- Whether or not to allow multiple file selection.
-
isDirectory
public boolean isDirectory()
Returns whether or not to enable directory selection.- Returns:
- Whether or not to enable directory selection.
-
setDirectory
public void setDirectory(boolean directory)
Sets whether or not to enable directory selection. Whentrue
, this implicitly defaults themultiple
attribute totrue
.- Parameters:
directory
- Whether or not to enable directory selection.
-
getAccept
public String getAccept()
Returns comma separated string of mime types of files to filter in client side file browse dialog. This is also validated in server side.- Returns:
- Comma separated string of mime types of files to filter in client side file browse dialog.
-
setAccept
public void setAccept(String accept)
Sets comma separated string of media types of files to filter in client side file browse dialog.- Parameters:
accept
- Comma separated string of mime types of files to filter in client side file browse dialog.
-
getAcceptMessage
public String getAcceptMessage()
Returns validation message to be displayed when the condition inaccept
attribute is violated.- Returns:
- Validation message to be displayed when the condition in
accept
attribute is violated.
-
setAcceptMessage
public void setAcceptMessage(String acceptMessage)
Sets validation message to be displayed when the condition inaccept
attribute is violated.- Parameters:
acceptMessage
- Validation message to be displayed when the condition inaccept
attribute is violated.
-
getMaxsize
public Long getMaxsize()
Returns maximum size in bytes for each selected file. This is validated in both client and server side.- Returns:
- Maximum size in bytes for each selected file.
-
setMaxsize
public void setMaxsize(Long maxsize)
Sets maximum size in bytes for each selected file.- Parameters:
maxsize
- Maximum size in bytes for each selected file.
-
getMaxsizeMessage
public String getMaxsizeMessage()
Returns validation message to be displayed when the condition inmaxsize
attribute is violated.- Returns:
- Validation message to be displayed when the condition in
maxsize
attribute is violated.
-
setMaxsizeMessage
public void setMaxsizeMessage(String maxsizeMessage)
Sets validation message to be displayed when the condition inmaxsize
attribute is violated.- Parameters:
maxsizeMessage
- Validation message to be displayed when the condition inmaxsize
attribute is violated.
-
-