XSteam低版本xml转bean多余字段报错问题

XSteam低版本xml转bean多余字段报错问题

对于一些老项目,可能会用到一些低版本的工具,例如XStream就是一款报文与实体类转换的工具,我们之前的报文为xml格式的,正常使用没有问题,如果多了某个字段是bean里面没有的,那么就会报错,对于此问题,特意进行了学习,并记录一下。

多余字段报错

举例说明:现有消费者类:

public class Consumer {
    private String id;
    private String userName;
    private String password;
    private String age;
    private String address;
    private String sex;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getAge() {
        return age;
    }

    public void setAge(String age) {
        this.age = age;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    @Override
    public String toString() {
        return "Consumer{" +
                "id='" + id + '\'' +
                ", userName='" + userName + '\'' +
                ", password='" + password + '\'' +
                ", age='" + age + '\'' +
                ", address='" + address + '\'' +
                ", sex='" + sex + '\'' +
                '}';
    }
}

转换方法:

public Customer xmlToBean(String customerXml) {
    XStream xs = new XStream(new DomDriver());
	xs.alias("Customer",Customer.class);
    Customer customer = (Customer)xs.fromXml(customerXml);
    return customer;
}

如果报文的字段均在Customer类里,则正常转换,如果对接方多传了字段,则会报错,例如我们多传一个字段test

Exception in thread "main" com.thoughtworks.xstream.converters.ConversionException: test : test : test : test
---- Debugging information ----
message             : test : test
cause-exception     : com.thoughtworks.xstream.mapper.CannotResolveClassException
cause-message       : test : test
class               : com.example.websocketdemo1.vo.Consumer
required-type       : com.example.websocketdemo1.vo.Consumer
path                : /Consumer/test
-------------------------------
	at com.thoughtworks.xstream.core.TreeUnmarshaller.convert(TreeUnmarshaller.java:89)
	at com.thoughtworks.xstream.core.AbstractReferenceUnmarshaller.convert(AbstractReferenceUnmarshaller.java:63)
	at com.thoughtworks.xstream.core.TreeUnmarshaller.convertAnother(TreeUnmarshaller.java:76)
	at com.thoughtworks.xstream.core.TreeUnmarshaller.convertAnother(TreeUnmarshaller.java:60)
	at com.thoughtworks.xstream.core.TreeUnmarshaller.start(TreeUnmarshaller.java:137)
	at com.thoughtworks.xstream.core.AbstractTreeMarshallingStrategy.unmarshal(AbstractTreeMarshallingStrategy.java:33)
	at com.thoughtworks.xstream.XStream.unmarshal(XStream.java:923)
	at com.thoughtworks.xstream.XStream.unmarshal(XStream.java:909)
	at com.thoughtworks.xstream.XStream.fromXML(XStream.java:853)
	at com.thoughtworks.xstream.XStream.fromXML(XStream.java:845)
	at com.example.websocketdemo1.proxy.MainTest.main(MainTest.java:44)

如果是高版本的XStream,可以使用ignoreUnknownElements() 方法,忽略多余的字段,如果是低版本的XStream则没有此方法,需要我们重写XStream的 protected MapperWrapper wrapMapper(MapperWrapper next) 方法,例如我们可以新建一个类,继承XStream:

public class XStreamOmitUnknownField extends XStream {

    public XStreamOmitUnknownField() {
        super();
    }

    public XStreamOmitUnknownField(DomDriver domDriver) {
        super(domDriver);
    }

    @Override
    protected MapperWrapper wrapMapper(MapperWrapper next) {
        return new MapperWrapper(next) {
            @Override
            public boolean shouldSerializeMember(Class definedIn, String fieldName) {
                if (definedIn == Object.class) {
                    return false;
                }
                return super.shouldSerializeMember(definedIn, fieldName);
            }
        };
    }

}

也可以直接在 new XStream时重写,例如:

		XStream xStream = new XStream() {
            @Override
            protected MapperWrapper wrapMapper(MapperWrapper next) {
                return new MapperWrapper(next) {
                    @Override
                    public boolean shouldSerializeMember(Class definedIn, String fieldName) {
                        if (definedIn == Object.class) {
                            return false;
                        }
                        return super.shouldSerializeMember(definedIn, fieldName);
                    }
                };
            }
        };
		xStream.fromXml(customerXml);

以上两种均可以解决多余字段报错问题。

转xml时包含包名的问题解决

将实体类转换为xml,有时会多一些我们不想要的包名

例如:

<com.example.websocketdemo1.vo.ConsumerVo>
  <id>213</id>
  <address>中国</address>
  <test>sdf</test>
</com.example.websocketdemo1.vo.ConsumerVo>

如果想要将包名去掉,可以设置别名:

例如:

XStream xStream = new XStream() {
            @Override
            protected MapperWrapper wrapMapper(MapperWrapper next) {
                return new MapperWrapper(next) {
                    @Override
                    public boolean shouldSerializeMember(Class definedIn, String fieldName) {
                        if (definedIn == Object.class) {
                            return false;
                        }
                        return super.shouldSerializeMember(definedIn, fieldName);
                    }
                };
            }
        };
        ConsumerVo consumerVo = new ConsumerVo();
        consumerVo.setTest("sdf");
        consumerVo.setId("213");
        consumerVo.setAddress("中国");
        xStream.alias("ConsumerVo",ConsumerVo.class);
        String s = xStream.toXML(consumerVo);
		System.out.println(s);

这样执行的结果就是:

<ConsumerVo>
  <id>213</id>
  <address>中国</address>
  <test>sdf</test>
</ConsumerVo>

这样就去掉了包名,只保留我们想要的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值