Web services 在执行JAXB解组时处理无效的枚举值
我的Jaxb基于XML模式设置创建了一个枚举类Web services 在执行JAXB解组时处理无效的枚举值,web-services,soapui,jaxb2,Web Services,Soapui,Jaxb2,我的Jaxb基于XML模式设置创建了一个枚举类 **enum Fruit { APPLE,ORANGE; }** 我正在使用soapui检查我的web服务。因为它是一个自由形式的条目,如果我给了一个错误的水果,比如说“Guva”,那么它不会抛出异常,而是在进行解组后将其返回为null 我怎样才能避免这种情况?我应该使用自定义枚举类而不是JAXB生成的枚举类吗。请举例说明。i、 e. package forum12147306; import javax.xml.bind.JAXBEx
**enum Fruit {
APPLE,ORANGE;
}**
我正在使用soapui检查我的web服务。因为它是一个自由形式的条目,如果我给了一个错误的水果,比如说“Guva”,那么它不会抛出异常,而是在进行解组后将其返回为null
我怎样才能避免这种情况?我应该使用自定义枚举类而不是JAXB生成的枚举类吗。请举例说明。i、 e.
package forum12147306;
import javax.xml.bind.JAXBException;
import javax.xml.bind.annotation.adapters.XmlAdapter;
public class FruitAdapter extends XmlAdapter<String, Fruit> {
@Override
public String marshal(Fruit fruit) throws Exception {
return fruit.name();
}
@Override
public Fruit unmarshal(String string) throws Exception {
try {
return Fruit.valueOf(string);
} catch(Exception e) {
throw new JAXBException(e);
}
}
}
问候
sri注意:我是专家组的负责人和成员 默认情况下,JAXB(JSR-222)实现不会因任何转换异常而失败。如果使用JAXB API进行解组,那么可以设置
ValidationEventHandler
来捕获任何问题。下面是一个例子
根目录
package forum12147306;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement
public class Root {
private int number;
private Fruit fruit;
public int getNumber() {
return number;
}
public void setNumber(int number) {
this.number = number;
}
public Fruit getFruit() {
return fruit;
}
public void setFruit(Fruit fruit) {
this.fruit = fruit;
}
}
package forum12147306;
public enum Fruit {
APPLE,
ORANGE;
}
Not a number: ABC
javax.xml.bind.JAXBException
- with linked exception:
[java.lang.IllegalArgumentException: No enum const class forum12147306.Fruit.Guva]
水果
package forum12147306;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement
public class Root {
private int number;
private Fruit fruit;
public int getNumber() {
return number;
}
public void setNumber(int number) {
this.number = number;
}
public Fruit getFruit() {
return fruit;
}
public void setFruit(Fruit fruit) {
this.fruit = fruit;
}
}
package forum12147306;
public enum Fruit {
APPLE,
ORANGE;
}
Not a number: ABC
javax.xml.bind.JAXBException
- with linked exception:
[java.lang.IllegalArgumentException: No enum const class forum12147306.Fruit.Guva]
演示
package forum12147306;
import java.io.StringReader;
import javax.xml.bind.*;
public class Demo {
private static final String XML = "<root><number>ABC</number><fruit>Guva</fruit></root>";
public static void main(String[] args) throws Exception {
JAXBContext jc = JAXBContext.newInstance(Root.class);
Unmarshaller unmarshaller = jc.createUnmarshaller();
unmarshaller.setEventHandler(new ValidationEventHandler() {
@Override
public boolean handleEvent(ValidationEvent validationEvent) {
System.out.println(validationEvent.getMessage());
//validationEvent.getLinkedException().printStackTrace();
return true;
}
});
Root root = (Root) unmarshaller.unmarshal(new StringReader(XML));
}
}
解决问题
编写您自己的XmlAdapter
来处理与Fruit
enum的转换:
水果适配器
新输出
package forum12147306;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement
public class Root {
private int number;
private Fruit fruit;
public int getNumber() {
return number;
}
public void setNumber(int number) {
this.number = number;
}
public Fruit getFruit() {
return fruit;
}
public void setFruit(Fruit fruit) {
this.fruit = fruit;
}
}
package forum12147306;
public enum Fruit {
APPLE,
ORANGE;
}
Not a number: ABC
javax.xml.bind.JAXBException
- with linked exception:
[java.lang.IllegalArgumentException: No enum const class forum12147306.Fruit.Guva]
日食JAXB(MOXy) 使用MOXy会引发两个验证事件。要将MOXy指定为JAXB提供程序,请参见:
以原始答复为基础的简短答复。你需要做两件事
package forum12147306;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
@XmlJavaTypeAdapter(FruitAdapter.class)
public enum Fruit {
APPLE,
ORANGE;
}
class FruitAdapter extends XmlAdapter<String, Fruit> {
@Override
public String marshal(Fruit fruit) throws Exception {
return fruit.name();
}
@Override
public Fruit unmarshal(String string) throws Exception {
try {
return Fruit.valueOf(string);
} catch(Exception e) {
throw new JAXBException(e);
}
}
}
另一种方法是生成XSD模式,如下所示: 以下是我从中偷来的片段:
import java.io.IOException;
导入java.io.Reader;
导入java.util.ArrayList;
导入javax.xml.bind.JAXBContext;
导入javax.xml.bind.JAXBException;
导入javax.xml.bind.SchemaOutputResolver;
导入javax.xml.bind.Unmarshaller;
导入javax.xml.transform.Result;
导入javax.xml.transform.dom.DOMResult;
导入javax.xml.transform.dom.DOMSource;
导入javax.xml.validation.Schema;
导入javax.xml.validation.SchemaFactory;
导入org.xml.sax.SAXException;
私有静态列表模式(JAXBContext上下文)引发IOException{
最终列表domResultList=new ArrayList();
generateSchema(新的SchemaOutputResolver(){
@凌驾
公共结果createOutput(字符串ns、字符串文件)引发IOException{
DOMResult DOMResult=新的DOMResult();
domResult.setSystemId(文件);
添加(domResult);
返回结果;
}
});
返回domResultList;
}
私有静态解组器createUnmarshaller(JAXBContext上下文)抛出SAXException、IOException、JAXBEException{
Unmarshaller Unmarshaller=context.createUnmarshaller();
List domSourceList=newarraylist();
for(DOMResult DOMResult:generateJaxbSchemas(上下文)){
添加(新的DOMSource(domResult.getNode());
}
SchemaFactory SchemaFactory=SchemaFactory.newInstance(“http://www.w3.org/2001/XMLSchema");
Schema Schema=schemaFactory.newSchema(domSourceList.toArray(新的DOMSource[0]);
解组器。设置模式(模式);
返回解组器;
}
public void unmarshal(JAXBContext上下文、读卡器)抛出jaxbeexception、SAXException、IOException{
Unmarshaller Unmarshaller=createUnmarshaller(上下文);
对象结果=解组器。解组器(读取器);
}
非常感谢您提供的详细示例。“…JAXB中似乎有一个bug”-这种行为仍然存在。可能不匹配的枚举不是关键错误:-)您的“变通方法”工作正常。我也将此设计用于非枚举。真的很棒!Blaise Doughan自从你发布这个答案后MOXy有什么变化吗?我似乎无法让MOXy 2.6.2触发XML或Json中未知枚举值的事件。我是否也必须将XmlJavaTypeAdapter与MOXy一起使用?JAXB中仍然存在该缺陷!ThanksHow我可以将此解决方案与Spring一起使用,只使用注释吗?