重用InputStream并遵守Sonar规则
我有下面的方法,它验证一些 xml 内容。当与 rootNameToUnmarshallerClassMap
映射中具有本地名称的元素一起使用时,xml 内容有效。它还必须对 XSD 文件有效。所以这两个验证都是在这个方法中进行的。可能存在符合 XSD 的内容,但开始元素的 localName 不在我的 rootNameToUnmarshallerClassMap
映射中,这意味着从业务角度来看它无效。
下面的实现有两个问题:第一是我将大消息加载到内存两次(ByteArrayInputStream
),第二是Sonar告诉我将尝试更改为try-with-resources,因为他看到可自动关闭的ByteArrayInputStream
用法。
现在向更有经验的开发人员提问 - 我该如何解决这个问题?提前致谢。
public void validate(InputStream content) throws ValidationException {
XMLStreamReader streamReader = null;
try {
byte[] content = createByteArray(content);
XMLInputFactory xmlInputFactory = getXmlInputFactory();
streamReader = xmlInputFactory.createXMLStreamReader(new ByteArrayInputStream(content));
navigateToFirstStartElement(streamReader);
String localPart = streamReader.getName().getLocalPart();
Class<? extends MyClass> jaxbClass = Optional.ofNullable(rootNameToUnmarshallerClassMap.get(localPart))
.orElseThrow(() -> new ValidationException(String.format("Could not validate provided content, root element %s ", localPart)));
JAXBContext context = JAXBContext.newInstance(jaxbClass);
SchemaFactory sf = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
Schema schema = sf.newSchema(this.getClass().getResource("my.xsd"));
Unmarshaller unmarshaller = context.createUnmarshaller();
unmarshaller.setSchema(schema);
ContentValidationEventHandler validationEventHandler = new ContentValidationEventHandler();
unmarshaller.setEventHandler(validationEventHandler);
unmarshaller.unmarshal(new ByteArrayInputStream(content));
streamReader.close();
if (validationEventHandler.getEvents().size() > 0) {
throw new ValidationException(String.format("contnt was not xsd compliant"));
}
} catch (XMLStreamException | JAXBException | SAXException | IOException e) {
log.error(e.getMessage(), e);
throw new IllegalArgumentException(String.format("Could not validate provided content"));
} finally {
try {
if (streamReader != null) {
streamReader.close();
}
} catch (XMLStreamException e) {
log.error(e.getMessage(), e);
}
}
}
I have below method, which validates some xml content. The xml content is valid when in stards with element with local name that I have in rootNameToUnmarshallerClassMap
map. It also must be valid against XSD file. So both validations are made in this method. There can be content that is XSD compliat but localName of start element is not in my rootNameToUnmarshallerClassMap
map, this means that it is not valid from business point of view.
Below implementation has two problems: first is that I load big message to memory twice (ByteArrayInputStream
) and second is that Sonar tells me to change try to try-with-resources as he see autoclosable ByteArrayInputStream
usage.
Now question to more experienced developers - how can I fix it ? Thanks in advance.
public void validate(InputStream content) throws ValidationException {
XMLStreamReader streamReader = null;
try {
byte[] content = createByteArray(content);
XMLInputFactory xmlInputFactory = getXmlInputFactory();
streamReader = xmlInputFactory.createXMLStreamReader(new ByteArrayInputStream(content));
navigateToFirstStartElement(streamReader);
String localPart = streamReader.getName().getLocalPart();
Class<? extends MyClass> jaxbClass = Optional.ofNullable(rootNameToUnmarshallerClassMap.get(localPart))
.orElseThrow(() -> new ValidationException(String.format("Could not validate provided content, root element %s ", localPart)));
JAXBContext context = JAXBContext.newInstance(jaxbClass);
SchemaFactory sf = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
Schema schema = sf.newSchema(this.getClass().getResource("my.xsd"));
Unmarshaller unmarshaller = context.createUnmarshaller();
unmarshaller.setSchema(schema);
ContentValidationEventHandler validationEventHandler = new ContentValidationEventHandler();
unmarshaller.setEventHandler(validationEventHandler);
unmarshaller.unmarshal(new ByteArrayInputStream(content));
streamReader.close();
if (validationEventHandler.getEvents().size() > 0) {
throw new ValidationException(String.format("contnt was not xsd compliant"));
}
} catch (XMLStreamException | JAXBException | SAXException | IOException e) {
log.error(e.getMessage(), e);
throw new IllegalArgumentException(String.format("Could not validate provided content"));
} finally {
try {
if (streamReader != null) {
streamReader.close();
}
} catch (XMLStreamException e) {
log.error(e.getMessage(), e);
}
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论