diff --git a/spring-core/src/test/java/org/springframework/util/xml/AbstractStaxHandlerTests.java b/spring-core/src/test/java/org/springframework/util/xml/AbstractStaxHandlerTests.java index 76d55709d1..71cfe38c33 100644 --- a/spring-core/src/test/java/org/springframework/util/xml/AbstractStaxHandlerTests.java +++ b/spring-core/src/test/java/org/springframework/util/xml/AbstractStaxHandlerTests.java @@ -21,6 +21,8 @@ import java.io.StringWriter; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.SAXParser; +import javax.xml.parsers.SAXParserFactory; import javax.xml.stream.XMLStreamException; import javax.xml.transform.Result; import javax.xml.transform.dom.DOMResult; @@ -63,9 +65,11 @@ abstract class AbstractStaxHandlerTests { @BeforeEach - @SuppressWarnings("deprecation") // on JDK 9 void createXMLReader() throws Exception { - xmlReader = org.xml.sax.helpers.XMLReaderFactory.createXMLReader(); + SAXParserFactory saxParserFactory = SAXParserFactory.newInstance(); + saxParserFactory.setNamespaceAware(true); + SAXParser saxParser = saxParserFactory.newSAXParser(); + xmlReader = saxParser.getXMLReader(); xmlReader.setEntityResolver((publicId, systemId) -> new InputSource(new StringReader(""))); } diff --git a/spring-core/src/test/java/org/springframework/util/xml/AbstractStaxXMLReaderTests.java b/spring-core/src/test/java/org/springframework/util/xml/AbstractStaxXMLReaderTests.java index 317a88b9eb..504e69d6c7 100644 --- a/spring-core/src/test/java/org/springframework/util/xml/AbstractStaxXMLReaderTests.java +++ b/spring-core/src/test/java/org/springframework/util/xml/AbstractStaxXMLReaderTests.java @@ -19,6 +19,8 @@ package org.springframework.util.xml; import java.io.ByteArrayInputStream; import java.io.InputStream; +import javax.xml.parsers.SAXParser; +import javax.xml.parsers.SAXParserFactory; import javax.xml.stream.XMLInputFactory; import javax.xml.stream.XMLStreamException; import javax.xml.transform.Transformer; @@ -64,10 +66,12 @@ abstract class AbstractStaxXMLReaderTests { @BeforeEach - @SuppressWarnings("deprecation") // on JDK 9 void setUp() throws Exception { inputFactory = XMLInputFactory.newInstance(); - standardReader = org.xml.sax.helpers.XMLReaderFactory.createXMLReader(); + SAXParserFactory saxParserFactory = SAXParserFactory.newInstance(); + saxParserFactory.setNamespaceAware(true); + SAXParser saxParser = saxParserFactory.newSAXParser(); + standardReader = saxParser.getXMLReader(); standardContentHandler = mockContentHandler(); standardReader.setContentHandler(standardContentHandler); } diff --git a/spring-core/src/test/java/org/springframework/util/xml/DomContentHandlerTests.java b/spring-core/src/test/java/org/springframework/util/xml/DomContentHandlerTests.java index 40cef21184..b069809b44 100644 --- a/spring-core/src/test/java/org/springframework/util/xml/DomContentHandlerTests.java +++ b/spring-core/src/test/java/org/springframework/util/xml/DomContentHandlerTests.java @@ -20,6 +20,8 @@ import java.io.StringReader; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.SAXParser; +import javax.xml.parsers.SAXParserFactory; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -62,13 +64,15 @@ class DomContentHandlerTests { @BeforeEach - @SuppressWarnings("deprecation") // on JDK 9 void setUp() throws Exception { DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance(); documentBuilderFactory.setNamespaceAware(true); documentBuilder = documentBuilderFactory.newDocumentBuilder(); result = documentBuilder.newDocument(); - xmlReader = org.xml.sax.helpers.XMLReaderFactory.createXMLReader(); + SAXParserFactory saxParserFactory = SAXParserFactory.newInstance(); + saxParserFactory.setNamespaceAware(true); + SAXParser saxParser = saxParserFactory.newSAXParser(); + xmlReader = saxParser.getXMLReader(); } diff --git a/spring-oxm/src/main/java/org/springframework/oxm/jaxb/Jaxb2Marshaller.java b/spring-oxm/src/main/java/org/springframework/oxm/jaxb/Jaxb2Marshaller.java index 78b4ca23e4..32f544067d 100644 --- a/spring-oxm/src/main/java/org/springframework/oxm/jaxb/Jaxb2Marshaller.java +++ b/spring-oxm/src/main/java/org/springframework/oxm/jaxb/Jaxb2Marshaller.java @@ -42,6 +42,9 @@ import javax.xml.XMLConstants; import javax.xml.datatype.Duration; import javax.xml.datatype.XMLGregorianCalendar; import javax.xml.namespace.QName; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.parsers.SAXParser; +import javax.xml.parsers.SAXParserFactory; import javax.xml.stream.XMLEventReader; import javax.xml.stream.XMLEventWriter; import javax.xml.stream.XMLStreamReader; @@ -575,8 +578,7 @@ public class Jaxb2Marshaller implements MimeMarshaller, MimeUnmarshaller, Generi } } - @SuppressWarnings("deprecation") - private Schema loadSchema(Resource[] resources, String schemaLanguage) throws IOException, SAXException { + private Schema loadSchema(Resource[] resources, String schemaLanguage) throws IOException, SAXException, ParserConfigurationException { if (logger.isDebugEnabled()) { logger.debug("Setting validation schema to " + StringUtils.arrayToCommaDelimitedString(this.schemaResources)); @@ -584,8 +586,11 @@ public class Jaxb2Marshaller implements MimeMarshaller, MimeUnmarshaller, Generi Assert.notEmpty(resources, "No resources given"); Assert.hasLength(schemaLanguage, "No schema language provided"); Source[] schemaSources = new Source[resources.length]; - XMLReader xmlReader = org.xml.sax.helpers.XMLReaderFactory.createXMLReader(); - xmlReader.setFeature("http://xml.org/sax/features/namespace-prefixes", true); + SAXParserFactory saxParserFactory = SAXParserFactory.newInstance(); + saxParserFactory.setNamespaceAware(true); + saxParserFactory.setFeature("http://xml.org/sax/features/namespace-prefixes", true); + SAXParser saxParser = saxParserFactory.newSAXParser(); + XMLReader xmlReader = saxParser.getXMLReader(); for (int i = 0; i < resources.length; i++) { Resource resource = resources[i]; Assert.isTrue(resource != null && resource.exists(), () -> "Resource does not exist: " + resource); @@ -854,7 +859,6 @@ public class Jaxb2Marshaller implements MimeMarshaller, MimeUnmarshaller, Generi } } - @SuppressWarnings("deprecation") private Source processSource(Source source) { if (StaxUtils.isStaxSource(source) || source instanceof DOMSource) { return source; @@ -881,17 +885,20 @@ public class Jaxb2Marshaller implements MimeMarshaller, MimeUnmarshaller, Generi try { if (xmlReader == null) { - xmlReader = org.xml.sax.helpers.XMLReaderFactory.createXMLReader(); + SAXParserFactory saxParserFactory = SAXParserFactory.newInstance(); + saxParserFactory.setNamespaceAware(true); + saxParserFactory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", !isSupportDtd()); + String name = "http://xml.org/sax/features/external-general-entities"; + saxParserFactory.setFeature(name, isProcessExternalEntities()); + SAXParser saxParser = saxParserFactory.newSAXParser(); + xmlReader = saxParser.getXMLReader(); } - xmlReader.setFeature("http://apache.org/xml/features/disallow-doctype-decl", !isSupportDtd()); - String name = "http://xml.org/sax/features/external-general-entities"; - xmlReader.setFeature(name, isProcessExternalEntities()); if (!isProcessExternalEntities()) { xmlReader.setEntityResolver(NO_OP_ENTITY_RESOLVER); } return new SAXSource(xmlReader, inputSource); } - catch (SAXException ex) { + catch (SAXException | ParserConfigurationException ex) { logger.info("Processing of external entities could not be disabled", ex); return source; } diff --git a/spring-oxm/src/main/java/org/springframework/oxm/support/AbstractMarshaller.java b/spring-oxm/src/main/java/org/springframework/oxm/support/AbstractMarshaller.java index 4803cfada4..906159e8c9 100644 --- a/spring-oxm/src/main/java/org/springframework/oxm/support/AbstractMarshaller.java +++ b/spring-oxm/src/main/java/org/springframework/oxm/support/AbstractMarshaller.java @@ -26,6 +26,8 @@ import java.io.Writer; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; +import javax.xml.parsers.SAXParser; +import javax.xml.parsers.SAXParserFactory; import javax.xml.stream.XMLEventReader; import javax.xml.stream.XMLEventWriter; import javax.xml.stream.XMLStreamReader; @@ -188,12 +190,15 @@ public abstract class AbstractMarshaller implements Marshaller, Unmarshaller { * Create an {@code XMLReader} that this marshaller will when passed an empty {@code SAXSource}. * @return the XMLReader * @throws SAXException if thrown by JAXP methods + * @throws ParserConfigurationException if thrown by JAXP methods */ - @SuppressWarnings("deprecation") - protected XMLReader createXmlReader() throws SAXException { - XMLReader xmlReader = org.xml.sax.helpers.XMLReaderFactory.createXMLReader(); - xmlReader.setFeature("http://apache.org/xml/features/disallow-doctype-decl", !isSupportDtd()); - xmlReader.setFeature("http://xml.org/sax/features/external-general-entities", isProcessExternalEntities()); + protected XMLReader createXmlReader() throws SAXException, ParserConfigurationException { + SAXParserFactory saxParserFactory = SAXParserFactory.newInstance(); + saxParserFactory.setNamespaceAware(true); + saxParserFactory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", !isSupportDtd()); + saxParserFactory.setFeature("http://xml.org/sax/features/external-general-entities", isProcessExternalEntities()); + SAXParser saxParser = saxParserFactory.newSAXParser(); + XMLReader xmlReader = saxParser.getXMLReader(); if (!isProcessExternalEntities()) { xmlReader.setEntityResolver(NO_OP_ENTITY_RESOLVER); } @@ -431,7 +436,7 @@ public abstract class AbstractMarshaller implements Marshaller, Unmarshaller { try { saxSource.setXMLReader(createXmlReader()); } - catch (SAXException ex) { + catch (SAXException | ParserConfigurationException ex) { throw new UnmarshallingFailureException("Could not create XMLReader for SAXSource", ex); } } diff --git a/spring-oxm/src/test/java/org/springframework/oxm/AbstractUnmarshallerTests.java b/spring-oxm/src/test/java/org/springframework/oxm/AbstractUnmarshallerTests.java index 9f0eb47435..18376987fa 100644 --- a/spring-oxm/src/test/java/org/springframework/oxm/AbstractUnmarshallerTests.java +++ b/spring-oxm/src/test/java/org/springframework/oxm/AbstractUnmarshallerTests.java @@ -22,6 +22,8 @@ import java.io.StringReader; import javax.xml.namespace.QName; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.SAXParser; +import javax.xml.parsers.SAXParserFactory; import javax.xml.stream.XMLEventReader; import javax.xml.stream.XMLInputFactory; import javax.xml.stream.XMLStreamReader; @@ -98,9 +100,11 @@ public abstract class AbstractUnmarshallerTests { } @Test - @SuppressWarnings("deprecation") // on JDK 9 public void unmarshalSAXSource() throws Exception { - XMLReader reader = org.xml.sax.helpers.XMLReaderFactory.createXMLReader(); + SAXParserFactory saxParserFactory = SAXParserFactory.newInstance(); + saxParserFactory.setNamespaceAware(true); + SAXParser saxParser = saxParserFactory.newSAXParser(); + XMLReader reader = saxParser.getXMLReader(); SAXSource source = new SAXSource(reader, new InputSource(new StringReader(INPUT_STRING))); Object flights = unmarshaller.unmarshal(source); testFlights(flights); diff --git a/spring-web/src/main/java/org/springframework/http/converter/xml/Jaxb2RootElementHttpMessageConverter.java b/spring-web/src/main/java/org/springframework/http/converter/xml/Jaxb2RootElementHttpMessageConverter.java index a1acfda553..5100061cac 100644 --- a/spring-web/src/main/java/org/springframework/http/converter/xml/Jaxb2RootElementHttpMessageConverter.java +++ b/spring-web/src/main/java/org/springframework/http/converter/xml/Jaxb2RootElementHttpMessageConverter.java @@ -18,6 +18,9 @@ package org.springframework.http.converter.xml; import java.io.StringReader; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.parsers.SAXParser; +import javax.xml.parsers.SAXParserFactory; import javax.xml.transform.Result; import javax.xml.transform.Source; import javax.xml.transform.sax.SAXSource; @@ -149,21 +152,23 @@ public class Jaxb2RootElementHttpMessageConverter extends AbstractJaxb2HttpMessa } } - @SuppressWarnings("deprecation") protected Source processSource(Source source) { if (source instanceof StreamSource streamSource) { InputSource inputSource = new InputSource(streamSource.getInputStream()); try { - XMLReader xmlReader = org.xml.sax.helpers.XMLReaderFactory.createXMLReader(); - xmlReader.setFeature("http://apache.org/xml/features/disallow-doctype-decl", !isSupportDtd()); + SAXParserFactory saxParserFactory = SAXParserFactory.newInstance(); + saxParserFactory.setNamespaceAware(true); + saxParserFactory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", !isSupportDtd()); String featureName = "http://xml.org/sax/features/external-general-entities"; - xmlReader.setFeature(featureName, isProcessExternalEntities()); + saxParserFactory.setFeature(featureName, isProcessExternalEntities()); + SAXParser saxParser = saxParserFactory.newSAXParser(); + XMLReader xmlReader = saxParser.getXMLReader(); if (!isProcessExternalEntities()) { xmlReader.setEntityResolver(NO_OP_ENTITY_RESOLVER); } return new SAXSource(xmlReader, inputSource); } - catch (SAXException ex) { + catch (SAXException | ParserConfigurationException ex) { logger.warn("Processing of external entities could not be disabled", ex); return source; } diff --git a/spring-web/src/main/java/org/springframework/http/converter/xml/SourceHttpMessageConverter.java b/spring-web/src/main/java/org/springframework/http/converter/xml/SourceHttpMessageConverter.java index 94d4b0d751..3f6be8788b 100644 --- a/spring-web/src/main/java/org/springframework/http/converter/xml/SourceHttpMessageConverter.java +++ b/spring-web/src/main/java/org/springframework/http/converter/xml/SourceHttpMessageConverter.java @@ -27,6 +27,8 @@ import java.util.Set; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; +import javax.xml.parsers.SAXParser; +import javax.xml.parsers.SAXParserFactory; import javax.xml.stream.XMLInputFactory; import javax.xml.stream.XMLResolver; import javax.xml.stream.XMLStreamException; @@ -197,19 +199,21 @@ public class SourceHttpMessageConverter extends AbstractHttpMe } } - @SuppressWarnings("deprecation") private SAXSource readSAXSource(InputStream body, HttpInputMessage inputMessage) throws IOException { try { - XMLReader xmlReader = org.xml.sax.helpers.XMLReaderFactory.createXMLReader(); - xmlReader.setFeature("http://apache.org/xml/features/disallow-doctype-decl", !isSupportDtd()); - xmlReader.setFeature("http://xml.org/sax/features/external-general-entities", isProcessExternalEntities()); + SAXParserFactory saxParserFactory = SAXParserFactory.newInstance(); + saxParserFactory.setNamespaceAware(true); + saxParserFactory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", !isSupportDtd()); + saxParserFactory.setFeature("http://xml.org/sax/features/external-general-entities", isProcessExternalEntities()); + SAXParser saxParser = saxParserFactory.newSAXParser(); + XMLReader xmlReader = saxParser.getXMLReader(); if (!isProcessExternalEntities()) { xmlReader.setEntityResolver(NO_OP_ENTITY_RESOLVER); } byte[] bytes = StreamUtils.copyToByteArray(body); return new SAXSource(xmlReader, new InputSource(new ByteArrayInputStream(bytes))); } - catch (SAXException ex) { + catch (SAXException | ParserConfigurationException ex) { throw new HttpMessageNotReadableException( "Could not parse document: " + ex.getMessage(), ex, inputMessage); }