Open Tomas-Kraus opened 16 years ago
@glassfishrobot Commented Reported by shelleyb
@glassfishrobot Commented tuukkamustonen said: It's now year 2011 and this ticket was created roughly 2,5 years ago. No comments here, but seems like it has been discussed "many times". See at least http://stackoverflow.com/questions/3844701/jaxb-validation-of-xml-during-unmarshalling and http://old.nabble.com/Using-JAXB2-Commons-with-the-jaxws-maven-plugin--td29108017.html
Despite of this feature being (maybe) not implemented, updating the ticket with the current status of consideration wouldn't be a bad thing?
@glassfishrobot Commented pastafarian said: +1 on the need for better annotation-based validation. Every time we make a change to our data objects, we (re)generate our XSDs from code and share them with other projects / clients.
Without better XML schema validation options, we might as well be using JSON
@glassfishrobot Commented lennartj said: This is a rather important issue, since everyone using annotated POJOs - rather than XML schema - as the model source at present need to create their own custom validation for generated objects due to the lack of validation facilities for this scenario within JAXB.
Validation of JAXB structures should really be part of the JAXB family of tasks; otherwise we condemn project to using XSDs (as opposed to POJOs) as the data model source. POJO entities should also be first-class citizens, without the need to generate intermediary XML Schemas simply to enable some kind of validation).
... which implies we need to provide validation facilities without XML Schema.
@glassfishrobot Commented cruelfate said: Indeed. I'm not looking for much .. heck I'd take something that only regarded XmlElement(required=true) so I wouldn't have to resort to this horror show:
import javax.xml.bind.annotation.XmlElement;
import JaxbValidator.ValidationException;
import org.testng.annotations.Test;
public class JaxbValidatorTest {
static class Llama {
@XmlElement(required = false)
private final String no;
@XmlElement(required = true)
private final String yes;
public Llama(String no, String yes) {
super();
this.no = no;
this.yes = yes;
}
}
@Test
public void validateRequired() {
try {
Llama o = new Llama("a", "b");
// THE MAIN EVENT - see if 'required' is honored
JaxbValidator.validateRequired(o, Llama.class);
} catch (ValidationException e) {
assert false : "Should not have thrown validation exception.";
}
try {
Llama o = new Llama(null, null);
// Again - see if 'required' is honored
JaxbValidator.validateRequired(o, Llama.class);
assert false : "Should have thrown validation exception for 'yes'";
} catch (ValidationException e) {
assert e.getMessage() != null: "Expected validation message, got null." ;
}
}
}
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import javax.xml.bind.annotation.XmlElement;
import org.apache.log4j.Logger;
/**
* oh so minimal consideration of JAXB annotation
*/
public class JaxbValidator {
private static final Logger LOG = Logger.getLogger(JaxbValidator.class);
public static class ValidationException extends Exception {
public ValidationException(String message, Throwable cause) {
super(message, cause);
}
public ValidationException(String message) {
super(message);
}
}
/**
* Enforce 'required' attibute.
*
* Requires either no security manager is used or the default security manager is employed.
* @see {@link Field#setAccessible(boolean)}.
*/
public static <T> void validateRequired(T target, Class<T> targetClass)
throws ValidationException {
StringBuilder errors = new StringBuilder();
Field[] fields = targetClass.getDeclaredFields();
for (Field field : fields) {
XmlElement annotation = field.getAnnotation(XmlElement.class);
if (annotation != null && annotation.required()) {
try {
field.setAccessible(true);
if (field.get(target) == null) {
if (errors.length() != 0) {
errors.append(" ");
}
String message = String.format("%s: required field '%s' is null.",
targetClass.getSimpleName(),
field.getName());
LOG.error(message);
errors.append(message);
}
} catch (IllegalArgumentException e) {
LOG.error(field.getName(), e);
} catch (IllegalAccessException e) {
LOG.error(field.getName(), e);
}
}
}
if (errors.length() != 0) {
throw new ValidationException(errors.toString());
}
}
And yes ... it doesn't do deep inspection. I wasn't sure if JAXB handles cyclic graphs, so I didn't attempt recursion without knowing if I needed to detect loops.
@glassfishrobot Commented roos said: Its 10/2012 now and still nothing.
@glassfishrobot Commented ovy9086 said: now it's 2013... and still no updates on this. I just started with JAXB and in the first day I needed this and... BUMMER. Not available...
@glassfishrobot Commented areami said: please have a look at https://github.com/whummer/jaxb-facets; they may have implemented this there
@glassfishrobot Commented yaroska said: May be MOXy JAXB implementation can help.
@glassfishrobot Commented lennartj said: Actually, being able to validate XSDs generated from annotated POJOs in a simple and useable form is still very important for JAXB. It is puzzling that this is not a trivial operation in the year 2013.
My workaround has been the implementation in
<dependency>
<groupId>se.jguru.nazgul.core.xmlbinding.spi.jaxb</groupId>
<artifactId>nazgul-core-xmlbinding-spi-jaxb</artifactId>
<version>1.5.0</version>
</dependency>
It generates schema from annotated POJOs and performs validation during marshalling and unmarshalling.
@glassfishrobot Commented olmath said: It's now year 2015. This jira issue is open since 2007. Is there a chance to have this improvement implemented in a near future ? Could you please update this ticket with the current status of consideration ?
@glassfishrobot Commented Was assigned to snajper
@glassfishrobot Commented This issue was imported from java.net JIRA JAXB-430
@miaaaooow Commented Aaand, it in year 2018 we are still looking for a solution here.
this topic survived the pandemic. its 2024.
Enhance JAXB to allow validation based on annotations, without requiring a schema.
One of the benefits of JAXB 2 is that a schema is not required; annotating Java classes alone allows for XML serialization/deserialization. With the deprecation of the Unmarshaller.setValidating() in favor of the unmarshaller.setSchema() method, however, validation is only available when an XSD is present. Ideally, validation can occur during unarshalling (or marshalling) without a physical schema file.
Environment
Operating System: All Platform: All
Affected Versions
[2.1.5]