PrimeFaces <p: fileUpload mode = "advanced" > валидатор не запущен
так как fileLimit не существует в прайс-листах 3.4. Я пытаюсь работать над внедрением валидатора, проблема в том, что проверка метода никогда не вызывается. Это мой валидатор:
@FacesValidator(value ="fileLimitValidator")
public class FileLimitValidator implements Validator {
@Override
public void validate(final FacesContext context, final UIComponent component,
final Object value) throws ValidatorException {
final String fileLimit = (String)component.getAttributes().get("fileLimit");
final String size = (String)component.getAttributes().get("size");
if (fileLimit!=null && size!=null) {
if (Integer.valueOf(size) >= Integer.valueOf(fileLimit)) {
FacesUtils.throwErrorExceptionFromComponent(component,"fichero_confidencialidad_error");
}
}
}
}
и в моем лице я пробовал:
<p:fileUpload id="#{id}FileUpload"
fileUploadListener="#{bean[metodoTratarFichero]}" mode="advanced"
multiple="true" allowTypes="#{allowTypes}" showButtons="false"
update="#{id}ListaDocs #{id}MsgError" auto="true"
label="#{fileuploadmsg.label_boton}"
invalidFileMessage="#{fileuploadmsg.tipo_incorrecto}" >
<f:validator validatorId="fileLimitValidator"/>
<f:attribute name="fileLimit" value="#{fileLimit}"/>
<f:attribute name="size" value="#{listaDocumentos.size}"/>
</p:fileUpload>
и
<p:fileUpload id="#{id}FileUpload"
fileUploadListener="#{bean[metodoTratarFichero]}" mode="advanced"
multiple="true" allowTypes="#{allowTypes}" showButtons="false"
update="#{id}ListaDocs #{id}MsgError" auto="true"
label="#{fileuploadmsg.label_boton}"
invalidFileMessage="#{fileuploadmsg.tipo_incorrecto}"
validator="fileLimitValidator">
<f:attribute name="fileLimit" value="#{fileLimit}"/>
<f:attribute name="size" value="#{listaDocumentos.size}"/>
</p:fileUpload>
и
<p:fileUpload id="#{id}FileUpload"
fileUploadListener="#{bean[metodoTratarFichero]}" mode="advanced"
multiple="true" allowTypes="#{allowTypes}" showButtons="false"
update="#{id}ListaDocs #{id}MsgError" auto="true"
label="#{fileuploadmsg.label_boton}"
invalidFileMessage="#{fileuploadmsg.tipo_incorrecto}"
validator="#{fileLimitValidator}">
<f:attribute name="fileLimit" value="#{fileLimit}"/>
<f:attribute name="size" value="#{listaDocumentos.size}"/>
</p:fileUpload>
и
<p:fileUpload id="#{id}FileUpload"
fileUploadListener="#{bean[metodoTratarFichero]}" mode="advanced"
multiple="true" allowTypes="#{allowTypes}" showButtons="false"
update="#{id}ListaDocs #{id}MsgError" auto="true"
label="#{fileuploadmsg.label_boton}"
invalidFileMessage="#{fileuploadmsg.tipo_incorrecto}"
validator="#{fileLimitValidator.validate}">
<f:attribute name="fileLimit" value="#{fileLimit}"/>
<f:attribute name="size" value="#{listaDocumentos.size}"/>
</p:fileUpload>
но метод проверки не вызывается. Каков правильный способ сделать это?
Ответы
Ответ 1
В соответствии с FileUpload
и FileUploadRenderer
, валидатор вызывается только при использовании mode="simple"
(обратите внимание: для этого требуется команда ajax="false"
). В расширенном режиме не будет установлен загруженный файл в качестве переданного компонента, поэтому он останется null
до тех пор, пока не будет вызван метод прослушивателя. Пока переданное значение null
, валидаторы не вызываются.
Я не уверен, что это намеренно. Теоретически, можно установить UploadedFile
в качестве представленного значения и заставить валидатор полагаться на него. Возможно, вы захотите создать отчет об улучшении в отслеживании проблем PrimeFaces.
Между тем, несмотря на то, что это была плохая практика, ваш лучший выбор действительно выполняет валидацию в методе fileUploadListener
. Вы можете просто инициировать отказ в проверке с помощью сообщений face face через FacesContext
следующим образом:
if (fail) {
context.validationFailed();
context.addMessage(event.getComponent().getClientId(context), new FacesMessage(
FacesMessage.SEVERITY_ERROR, messageSummary, messageDetail));
}
В противном случае вам нужно создать собственный рендерер для <p:fileUpload>
, который устанавливает переданное значение во время decode()
(однако я не гарантирую, что он будет работать на практике, вы, возможно, наткнетесь на которая может оказаться причиной того, почему PrimeFaces изначально не реализовал ее).
Кстати, ваша первая и вторая попытки проверки правильны. Третья попытка работает только в том случае, если вы использовали @ManagedBean
вместо @FacesValidator
(, что часто делается, когда инъекция @EJB
обязательна — которая невозможна в @FacesValidator
). Четвертая попытка недействительна.
Ответ 2
Для проверки требуемой загрузки файлов в формате advanced (ajax) можно использовать следующее:
<f:metadata>
<f:event listener="#{bean.processValidations()}" type="postValidate" />
</f:metadata>
Где реализация метода bean.processValidations()
была бы чем-то вроде:
public void processValidations() {
FacesContext context = FacesContext.getCurrentInstance();
UIInput fileUploadComponent = fileUploadsBean.getFileUploadComponent();
if (fileUploadComponent!=null && !isFileUploaded()) {
fileUploadComponent.setValid(false);
context.addMessage(fileUploadComponent.getClientId(context), new FacesMessage(FacesMessage.SEVERITY_ERROR, messageSummary, messageDetail));
context.validationFailed();
}
}
Где fileUploadsBean
будет CDID bean с запросом REQUEST (не будет работать со стандартными JSF ManagedBeans), который вы вводите в свой bean, который имеет метод processValidations()
, метод fileUploadsBean.getFileUploadComponent()
возвращает (например, для этого используется <p:fileUpload binding="#{fileUploadsBean.fileUploadComponent}" ...>
). Метод isFileUploaded()
будет определять, был ли файл загружен или нет (возможно, это просто нулевая проверка переменной-члена, которую вы заполняете из fileUploadListener).
Если вы хотите выделить кнопку загрузки файла, вы можете, конечно, условно добавить styleClass, который затем можно использовать для добавления красной границы, например.
styleClass="#{fileUploadsBean.fileUploadComponent.valid ? '' : 'validationFailed'}"
В результате будет выведено сообщение об ошибке с подтверждением для загрузки файлов в виде шрифтов вместе со всеми другими сообщениями проверки jsf. У вас может возникнуть проблема с поддержанием порядка сообщений проверки (всегда будет в конце), но он по-прежнему демонстрирует неудачную проверку файла загрузки после того, как пользователь обрабатывает все стандартные сообщения проверки jsf из разных полей и ваши действия в резервной копии bean наконец-то достигнут.