我怎样才能简化这个解析方法?
How can I simplify this parsing method?
我正在编写代码以从文件中解组 XML。我事先不知道 XML 基于哪个模式,所以我尝试使用不同 Jaxb2Marshaller 实例形式的多个模式对其进行解组。
该方法需要:
- 尝试用每个编组器
解组XML
- 如果成功,return 生成的对象
- 如果失败,尝试下一个编组器
- 如果所有编组器都失败,则抛出异常并显示最后一条错误消息
这是当前代码:
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);
}
我觉得这个方法在不同的抽象层次上做了太多事情:
- 迭代编组器
- 应用编组器
- return 结果
- 捕获异常
- 抛出异常
但我没有找到简化它的方法。每个编组器都需要 try-catch 块(因为除了最后一个之外,我应该捕获并忽略这些 XmlMappingExceptions)。该块 return 是一个结果对象,或者是 lastErrorMessage,这是在迭代下面抛出 MyException 所必需的。
我能想到的唯一解决方案是创建一些人为的结果 class,其中包含结果对象或错误消息,但感觉很笨拙。还有其他见解吗?
我想要像这样粒度的方法:
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;
}
}
但附加结果 class 冗长且笨拙:
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;
}
}
这个怎么样?
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);
}
}
}
我正在编写代码以从文件中解组 XML。我事先不知道 XML 基于哪个模式,所以我尝试使用不同 Jaxb2Marshaller 实例形式的多个模式对其进行解组。
该方法需要:
- 尝试用每个编组器 解组XML
- 如果成功,return 生成的对象
- 如果失败,尝试下一个编组器
- 如果所有编组器都失败,则抛出异常并显示最后一条错误消息
这是当前代码:
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);
}
我觉得这个方法在不同的抽象层次上做了太多事情:
- 迭代编组器
- 应用编组器
- return 结果
- 捕获异常
- 抛出异常
但我没有找到简化它的方法。每个编组器都需要 try-catch 块(因为除了最后一个之外,我应该捕获并忽略这些 XmlMappingExceptions)。该块 return 是一个结果对象,或者是 lastErrorMessage,这是在迭代下面抛出 MyException 所必需的。
我能想到的唯一解决方案是创建一些人为的结果 class,其中包含结果对象或错误消息,但感觉很笨拙。还有其他见解吗?
我想要像这样粒度的方法:
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;
}
}
但附加结果 class 冗长且笨拙:
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;
}
}
这个怎么样?
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);
}
}
}