为了账号安全,请及时绑定邮箱和手机立即绑定

如何简化这种解析方法?

如何简化这种解析方法?

白猪掌柜的 2022-10-12 15:37:24
我正在编写代码以从文件中解组 XML。我事先不知道 XML 基于哪个模式,所以我尝试使用不同 Jaxb2Marshaller 实例形式的多个模式来解组它。该方法需要:尝试使用每个编组器解组 XML如果成功,则返回结果对象如果失败,请尝试下一个 marshaller如果所有编组器都失败,则抛出带有最后一条错误消息的异常这是当前代码:private Object getObject(final byte[] data) throws MyException {    String lastErrorMessage = "";    for (final Jaxb2Marshaller marshaller : this.marshallers) {        try {            return marshaller.unmarshal(new StreamSource(new ByteArrayInputStream(data)));        } catch (final XmlMappingException e) {            LOGGER.warn("Invalid XML", e);            lastErrorMessage = e.getMessage();        }    }    throw new MyException(lastErrorMessage);}我觉得这种方法在不同的抽象层次上做了太多的事情:迭代编组器应用编组器返回结果捕捉异常抛出异常但我看不到简化它的方法。每个编组器都需要 try-catch 块(因为除了最后一个之外,我应该捕获并忽略这些 XmlMappingExceptions)。该块要么返回一个结果对象,要么返回 lastErrorMessage,在迭代下面需要它来抛出 MyException。我能想到的唯一解决方案是创建一些人为的 Result 类,其中包含结果对象或错误消息,但感觉很笨拙。还有其他见解吗?
查看完整描述

2 回答

?
料青山看我应如是

TA贡献1772条经验 获得超8个赞

这个怎么样?


public class MultiUnmarshaller {


    private final List<Jaxb2Marshaller> marshallers;

    private Object value;

    private String error;


    public MultiUnmarshaller(List<Jaxb2Marshaller> marshallers) {

        this.marshallers = marshallers;

    }


    private void init() {

        error = "No marshallers available";

        value = null;

    }


    public Object getObject(byte[] data) throws MyException {

        init();

        Iterator<Jaxb2Marshaller> it = marshallers.iterator();           

        while(it.hasNext() && errorMessage != null) {

            unmarshalObject(marshaller, data);

        }

        return produceResult();

    }


    private void unmarshalObject(Jaxb2Marshaller marshaller, byte[] data) {

        try {

            value = marshaller.unmarshal(new StreamSource(new     ByteArrayInputStream(data)));

            error = null;

        } catch (final XmlMappingException e) {

            LOGGER.warn("Invalid XML", e);

            error = e.getMessage();

        }

    }


    private Object produceResult() {

        if (error == null) {

            return value;        

        }

        else {

            throw new MyException(error);

        }

    }

    

}


查看完整回答
反对 回复 2022-10-12
?
精慕HU

TA贡献1845条经验 获得超8个赞

我想要具有如下粒度的方法:


private Object getObject(byte[] data) throws MyException {

    Result result;

    for (Jaxb2Marshaller marshaller : this.marshallers) {

        result = getObject(marshaller, data);

    }

    return handleError(result);

}


private Result getObject(Jaxb2Marshaller marshaller, byte[] data) {

    try {

        return Result.value(marshaller.unmarshal(new StreamSource(new ByteArrayInputStream(data))));

    } catch (final XmlMappingException e) {

        LOGGER.warn("Invalid XML", e);

        return Result.error(e.getMessage());

    }

}


private Object handleError(Result result) {

    if (result.isError()) {

        throw new MyException(result.errroMessage);

    }

    else {

        return result.value;        

    }

}

但是附加的 Result 类是冗长而笨拙的:


private class Result {

    String errorMessage;

    Object value;


    static Result error(String errorMessage) {

        Result result = new Result();

        result.errorMessage = errorMessage;

        return result;

    }


    static Result value(Object value) {

        Result result = new Result();

        result.value = value;

        return result;

    }


    boolean isError() {

        return errorMessage != null;

    }

}


查看完整回答
反对 回复 2022-10-12
  • 2 回答
  • 0 关注
  • 84 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信