유효성 검사 오류 : 값이 유효하지 않습니다.
ap : selectOneMenu에 문제가 있습니다. 내가 무엇을하든 JSF가 JPA 엔티티에서 setter를 호출하도록 할 수 없습니다. 다음 메시지와 함께 JSF 유효성 검사가 실패합니다.
양식 : 위치 : 유효성 검사 오류 : 값이 유효하지 않습니다.
동일한 유형의 다른 클래스 (예 : 조인 테이블 클래스)에서이 작업을 수행하고 있지만 평생 동안이 작업을 수행 할 수는 없습니다.
누군가가 이런 종류의 문제에 대한 문제 해결 / 디버깅 팁을 던질 수 있다면 대단히 감사하겠습니다.
로그 문을 사용하여 다음을 확인했습니다.
- 에서
Conveter
올바른null
값이 아닌 값을 반환 합니다. - 내 JPA 엔터티에 Bean 유효성 검사가 없습니다.
- setter
setLocation(Location location)
는 호출되지 않습니다.
이것은 내가 할 수있는 가장 간단한 예이며 단순히 작동하지 않을 것입니다.
<h:body>
<h:form id="form">
<p:messages id="messages" autoUpdate="true" />
<p:selectOneMenu id="location" value="#{locationStockList.selected.location}" converter="locationConverter">
<p:ajax event="change" update=":form:lblLocation"/>
<f:selectItems value="#{locationStockList.locationSelection}"/>
</p:selectOneMenu>
</h:form>
</h:body>
변환기:
@FacesConverter(forClass=Location.class, value="locationConverter")
public class LocationConverter implements Converter, Serializable {
private static final Logger logger = Logger.getLogger(LocationConverter.class.getName());
@Override
public Object getAsObject(FacesContext context, UIComponent component, String value) {
if (value.isEmpty())
return null;
try {
Long id = Long.parseLong(value);
Location location = ((LocationManagedBean) context.getApplication().getELResolver().getValue(context.getELContext(), null, "location")).find(id);
logger.log(Level.SEVERE, "Converted {0} to {1}" , new Object[] {value, location});
return location;
} catch (NumberFormatException e) {
return new Location();
}
}
@Override
public String getAsString(FacesContext context, UIComponent component, Object value) {
if (value == null || value.toString().isEmpty() || !(value instanceof Location))
return "";
return String.valueOf(((Location) value).getId());
}
}
콘솔 출력 :
// Getter method
INFO: Current value=ejb.locations.Location[id=null, name=null, latitude=0.0, longitude=0.0]
// Session Bean
INFO: Finding ejb.locations.Location with id=3
// Session Bean
INFO: ### Returning : ejb.locations.Location[id=3, name=mdmd, latitude=4.5, longitude=2.3]
// Converter
SEVERE: Converted 3 to ejb.locations.Location[id=3, name=mdmd, latitude=4.5, longitude=2.3]
// Getter method -> Where did my selected Location go ??
INFO: Current value=ejb.locations.Location[id=null, name=null, latitude=0.0, longitude=0.0]
"form : location : Validation Error : Value is not valid"메시지와 함께 유효성 검사가 실패합니다.
이 오류는 선택한 항목이 <f:selectItem(s)>
양식 제출 요청을 처리하는 동안 중첩 된 태그로 지정된 사용 가능한 선택 항목 값과 일치하지 않기 때문에 귀결됩니다 .
변조 / 해킹 된 요청에 대한 보호의 일환으로 JSF는 사용 가능한 모든 선택 항목 값을 반복하고 하나 이상의 사용 가능한 항목 값이 selectedItem.equals(availableItem)
반환 되는지 테스트 true
합니다. 일치하는 항목 값이없는 경우 정확히이 유효성 검사 오류가 발생합니다.
이 프로세스는 기본적으로 아래와 같이 커버되며,에 bean.getAvailableItems()
의해 정의 된 사용 가능한 선택 항목의 전체 목록을 가상으로 나타냅니다 <f:selectItem(s)>
.
String submittedValue = request.getParameter(component.getClientId());
Converter converter = component.getConverter();
Object selectedItem = (converter != null) ? converter.getAsObject(context, component, submittedValue) : submittedValue;
boolean valid = false;
for (Object availableItem : bean.getAvailableItems()) {
if (selectedItem.equals(availableItem)) {
valid = true;
break;
}
}
if (!valid) {
throw new ValidatorException("Validation Error: Value is not valid");
}
따라서 위의 논리를 기반으로이 문제는 논리적으로 다음과 같은 원인이있을 수 있습니다.
- The selected item is missing in the list of available items.
- The
equals()
method of the class representing the selected item is missing or broken. - If a custom
Converter
is involved, then it has returned the wrong object ingetAsObject()
. Perhaps it's evennull
.
To solve it:
- Ensure that exactly the same list is been preserved during the subsequent request, particularly in case of multiple cascading menus. Making the bean
@ViewScoped
instead of@RequestScoped
should fix it in most cases. Also make sure that you don't perform the business logic in the getter method of<f:selectItem(s)>
, but instead in@PostConstruct
or an action event (listener) method. If you're relying on specific request parameters, then you'd need to explicitly store them in the@ViewScoped
bean, or to re-pass them on subsequent requests by e.g.<f:param>
. See also How to choose the right bean scope? - Ensure that the
equals()
method is implemented right. This is already done right on standard Java types such asjava.lang.String
,java.lang.Number
, etc, but not necessarily on custom objects/beans/entites. See also Right way to implement equals contract. In case you're already usingString
, make sure that the request character encoding is configured right. If it contains special characters and JSF is configured to render the output as UTF-8 but interpret the input as e.g. ISO-8859-1, then it will fail. See also a.o. Unicode input retrieved via PrimeFaces input components become corrupted. - Debug/log the actions of your custom
Converter
and fix it accordingly. For guidelines, see also Conversion Error setting value for 'null Converter' In case you're usingjava.util.Date
as available items with<f:convertDateTime>
, make sure that you don't forget the full time part in the pattern. See also "Validation Error: Value is not valid" error from f:datetimeConverter.
See also:
- Our
selectOneMenu
wiki page - How to populate options of h:selectOneMenu from database?
- Make multiple dependent / cascading selectOneMenu dropdown lists in JSF
If anyone can throw some troubleshooting/debugging tips for this sort of problem it would be greatly appreciated.
Just ask a clear and concrete question here. Do not ask too broad questions ;)
In my case I forgot to implement a correct get/set methods. It happened because I have changed a lot of attributes along the development.
Without a proper get method, JSF can´t recover your selected item, and happens what BalusC said at item 1 of his answer:
1 . The selected item is missing in the list of available items. This can happen if the list of available items is served by a request scoped bean which is not properly reinitialized on subsequent request, or is incorrectly doing the business job inside a getter method which causes it to return a different list in some way.
This can be a Converter Issue or else DTO issue. Try to solve this, by adding hashCode() and equals() methods in your object DTO; In the above scenario you can generate these methods within the Location object class which indicate as the 'DTO' here.
Example:
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + (int) (id ^ (id >>> 32));
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Location other = (Location) obj;
if (id != other.id)
return false;
return true;
}
- Please note that the above example is for an 'id' of type 'long'.
참고URL : https://stackoverflow.com/questions/9069379/validation-error-value-is-not-valid
'Development Tip' 카테고리의 다른 글
C에서 바이트 배열을 16 진수 문자열로 어떻게 변환합니까? (0) | 2020.10.16 |
---|---|
실행 가능한 jar 라이브러리 처리 옵션의 차이점은 무엇입니까? (0) | 2020.10.16 |
바인딩이 클로저보다 느린 이유는 무엇입니까? (0) | 2020.10.16 |
git push to specific branch (0) | 2020.10.16 |
Valgrind는 어떻게 작동합니까? (0) | 2020.10.16 |