Как пропустить проверку bean, если все поля для объекта пусты?
У меня есть объект-адрес вроде этого:
@Entity
public class Address implements java.io.Serializable {
@Id @GeneratedValue(strategy = IDENTITY)
private Long id;
@Size(max = 100)
private String street;
@Size(max = 15)
private String nr;
@Field
@Size(min = 1, max = 20) @NotBlank
private String city;
}
Это часть нескольких других объектов. Для одного такого объекта адрес является необязательным.
У меня есть представление, где наши пользователи могут редактировать весь объект через несколько входных форматов, включая несколько полей адреса.
Чтобы иметь возможность редактировать адрес, я инициализирую родительский объект пустым узлом адреса.
Теперь проблема заключается в следующем: я не хочу сохранять объект Address
в сущности, когда все поля адреса пустые. Для этого мне нужно пропустить проверку для объекта, если (и только если) все поля Address
пусты. Как мне сделать это самым элегантным способом?
То, что я сейчас делаю, это пропустить проверку bean с помощью <o:validateBean disabled="true" />
для кнопки отправки, установив адрес null
, если он выйдет пустым. Но это звучит как полный взлом, поскольку он отключает все проверки во всех случаях. Как я могу сделать лучше?
Ответы
Ответ 1
Вы можете просто использовать EL в disabled
атрибуте <f:validateBean>
(и <o:validateBean>
). Вы можете использовать EL, чтобы проверить, было ли заполнено какое-либо из этих полей. Вы можете использовать атрибут binding
для ссылки на компонент в EL. Вы можете проверить, было ли поле заполнено, проверяя значение параметра запроса, связанного с идентификатором клиента компонента.
Затем, чтобы отключить проверку bean в тех полях, когда #{addressIsEmpty}
оценивает true
, проще использовать <f:validateBean>
вместо <o:validateBean>
, поскольку первая может использоваться для обертывания нескольких входных компонентов.
Итак, все со всеми, это должно сделать:
<c:set var="addressIsEmpty" value="#{empty param[street.clientId] and empty param[nr.clientId] and empty param[city.clientId]}" />
<f:validateBean disabled="#{addressIsEmpty}">
<h:inputText binding="#{street}" value="#{bean.address.street}" />
<h:inputText binding="#{nr}" value="#{bean.address.nr}" />
<h:inputText binding="#{city}" value="#{bean.address.city}" />
</f:validateBean>
<o:validateBean>
проще использовать, если вы намерены управлять им на основе ввода или каждой команды.
Ответ 2
Перекрестная проверка нескольких полей может быть сложной проблемой. Но в этой ситуации сама по себе не проверка, которая вас беспокоит, а скорее возможность свести на нет какой-либо экземпляр в каком-то состоянии вашего bean до того, как вы сохраните объект.
Самый простой способ - пометить все поля, связанные с Address
сущностью, как required="false"
в вашем представлении, чтобы не заботиться о заполняемых полях (или просто опустить его как значение по умолчанию) и выполнить все проверки, а также модификации заполнителя в вашем действии, прямо перед вызовом службы EJB. Например:
public String save() {
//do some checks
if((entity.getAddress().getStreet() == null) && ...) {
//assign address to null
entity.setAddress(null);
}
entityService.persist(entity);
return "success";
}