Merge branch '6.1.x'
This commit is contained in:
commit
6f6e25bd5b
|
@ -20,11 +20,14 @@ import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||||
|
|
||||||
public class SpringConfiguredWithAutoProxyingTests {
|
/**
|
||||||
|
* @author Ramnivas Laddad
|
||||||
|
* @author Juergen Hoeller
|
||||||
|
*/
|
||||||
|
class SpringConfiguredWithAutoProxyingTests {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void springConfiguredAndAutoProxyUsedTogether() {
|
void springConfiguredAndAutoProxyUsedTogether() {
|
||||||
// instantiation is sufficient to trigger failure if this is going to fail...
|
|
||||||
new ClassPathXmlApplicationContext("org/springframework/beans/factory/aspectj/springConfigured.xml");
|
new ClassPathXmlApplicationContext("org/springframework/beans/factory/aspectj/springConfigured.xml");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2022 the original author or authors.
|
* Copyright 2002-2024 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -154,7 +154,7 @@ final class PersistenceUnitReader {
|
||||||
/**
|
/**
|
||||||
* Validate the given stream and return a valid DOM document for parsing.
|
* Validate the given stream and return a valid DOM document for parsing.
|
||||||
*/
|
*/
|
||||||
protected Document buildDocument(ErrorHandler handler, InputStream stream)
|
Document buildDocument(ErrorHandler handler, InputStream stream)
|
||||||
throws ParserConfigurationException, SAXException, IOException {
|
throws ParserConfigurationException, SAXException, IOException {
|
||||||
|
|
||||||
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
|
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
|
||||||
|
@ -168,9 +168,7 @@ final class PersistenceUnitReader {
|
||||||
/**
|
/**
|
||||||
* Parse the validated document and add entries to the given unit info list.
|
* Parse the validated document and add entries to the given unit info list.
|
||||||
*/
|
*/
|
||||||
protected List<SpringPersistenceUnitInfo> parseDocument(
|
void parseDocument(Resource resource, Document document, List<SpringPersistenceUnitInfo> infos) throws IOException {
|
||||||
Resource resource, Document document, List<SpringPersistenceUnitInfo> infos) throws IOException {
|
|
||||||
|
|
||||||
Element persistence = document.getDocumentElement();
|
Element persistence = document.getDocumentElement();
|
||||||
String version = persistence.getAttribute(PERSISTENCE_VERSION);
|
String version = persistence.getAttribute(PERSISTENCE_VERSION);
|
||||||
URL rootUrl = determinePersistenceUnitRootUrl(resource);
|
URL rootUrl = determinePersistenceUnitRootUrl(resource);
|
||||||
|
@ -179,14 +177,12 @@ final class PersistenceUnitReader {
|
||||||
for (Element unit : units) {
|
for (Element unit : units) {
|
||||||
infos.add(parsePersistenceUnitInfo(unit, version, rootUrl));
|
infos.add(parsePersistenceUnitInfo(unit, version, rootUrl));
|
||||||
}
|
}
|
||||||
|
|
||||||
return infos;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parse the unit info DOM element.
|
* Parse the unit info DOM element.
|
||||||
*/
|
*/
|
||||||
protected SpringPersistenceUnitInfo parsePersistenceUnitInfo(
|
SpringPersistenceUnitInfo parsePersistenceUnitInfo(
|
||||||
Element persistenceUnit, String version, @Nullable URL rootUrl) throws IOException {
|
Element persistenceUnit, String version, @Nullable URL rootUrl) throws IOException {
|
||||||
|
|
||||||
SpringPersistenceUnitInfo unitInfo = new SpringPersistenceUnitInfo();
|
SpringPersistenceUnitInfo unitInfo = new SpringPersistenceUnitInfo();
|
||||||
|
@ -253,7 +249,7 @@ final class PersistenceUnitReader {
|
||||||
/**
|
/**
|
||||||
* Parse the {@code property} XML elements.
|
* Parse the {@code property} XML elements.
|
||||||
*/
|
*/
|
||||||
protected void parseProperties(Element persistenceUnit, SpringPersistenceUnitInfo unitInfo) {
|
void parseProperties(Element persistenceUnit, SpringPersistenceUnitInfo unitInfo) {
|
||||||
Element propRoot = DomUtils.getChildElementByTagName(persistenceUnit, PROPERTIES);
|
Element propRoot = DomUtils.getChildElementByTagName(persistenceUnit, PROPERTIES);
|
||||||
if (propRoot == null) {
|
if (propRoot == null) {
|
||||||
return;
|
return;
|
||||||
|
@ -269,7 +265,7 @@ final class PersistenceUnitReader {
|
||||||
/**
|
/**
|
||||||
* Parse the {@code class} XML elements.
|
* Parse the {@code class} XML elements.
|
||||||
*/
|
*/
|
||||||
protected void parseManagedClasses(Element persistenceUnit, SpringPersistenceUnitInfo unitInfo) {
|
void parseManagedClasses(Element persistenceUnit, SpringPersistenceUnitInfo unitInfo) {
|
||||||
List<Element> classes = DomUtils.getChildElementsByTagName(persistenceUnit, MANAGED_CLASS_NAME);
|
List<Element> classes = DomUtils.getChildElementsByTagName(persistenceUnit, MANAGED_CLASS_NAME);
|
||||||
for (Element element : classes) {
|
for (Element element : classes) {
|
||||||
String value = DomUtils.getTextValue(element).trim();
|
String value = DomUtils.getTextValue(element).trim();
|
||||||
|
@ -282,7 +278,7 @@ final class PersistenceUnitReader {
|
||||||
/**
|
/**
|
||||||
* Parse the {@code mapping-file} XML elements.
|
* Parse the {@code mapping-file} XML elements.
|
||||||
*/
|
*/
|
||||||
protected void parseMappingFiles(Element persistenceUnit, SpringPersistenceUnitInfo unitInfo) {
|
void parseMappingFiles(Element persistenceUnit, SpringPersistenceUnitInfo unitInfo) {
|
||||||
List<Element> files = DomUtils.getChildElementsByTagName(persistenceUnit, MAPPING_FILE_NAME);
|
List<Element> files = DomUtils.getChildElementsByTagName(persistenceUnit, MAPPING_FILE_NAME);
|
||||||
for (Element element : files) {
|
for (Element element : files) {
|
||||||
String value = DomUtils.getTextValue(element).trim();
|
String value = DomUtils.getTextValue(element).trim();
|
||||||
|
@ -295,7 +291,7 @@ final class PersistenceUnitReader {
|
||||||
/**
|
/**
|
||||||
* Parse the {@code jar-file} XML elements.
|
* Parse the {@code jar-file} XML elements.
|
||||||
*/
|
*/
|
||||||
protected void parseJarFiles(Element persistenceUnit, SpringPersistenceUnitInfo unitInfo) throws IOException {
|
void parseJarFiles(Element persistenceUnit, SpringPersistenceUnitInfo unitInfo) throws IOException {
|
||||||
List<Element> jars = DomUtils.getChildElementsByTagName(persistenceUnit, JAR_FILE_URL);
|
List<Element> jars = DomUtils.getChildElementsByTagName(persistenceUnit, JAR_FILE_URL);
|
||||||
for (Element element : jars) {
|
for (Element element : jars) {
|
||||||
String value = DomUtils.getTextValue(element).trim();
|
String value = DomUtils.getTextValue(element).trim();
|
||||||
|
|
|
@ -37,6 +37,8 @@ import java.util.Calendar;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
import java.util.concurrent.locks.Lock;
|
||||||
|
import java.util.concurrent.locks.ReentrantLock;
|
||||||
|
|
||||||
import javax.xml.XMLConstants;
|
import javax.xml.XMLConstants;
|
||||||
import javax.xml.datatype.Duration;
|
import javax.xml.datatype.Duration;
|
||||||
|
@ -192,7 +194,7 @@ public class Jaxb2Marshaller implements MimeMarshaller, MimeUnmarshaller, Generi
|
||||||
@Nullable
|
@Nullable
|
||||||
private ClassLoader beanClassLoader;
|
private ClassLoader beanClassLoader;
|
||||||
|
|
||||||
private final Object jaxbContextMonitor = new Object();
|
private final Lock jaxbContextLock = new ReentrantLock();
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
private volatile JAXBContext jaxbContext;
|
private volatile JAXBContext jaxbContext;
|
||||||
|
@ -204,6 +206,12 @@ public class Jaxb2Marshaller implements MimeMarshaller, MimeUnmarshaller, Generi
|
||||||
|
|
||||||
private boolean processExternalEntities = false;
|
private boolean processExternalEntities = false;
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private volatile SAXParserFactory schemaParserFactory;
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private volatile SAXParserFactory sourceParserFactory;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set multiple JAXB context paths. The given array of context paths gets
|
* Set multiple JAXB context paths. The given array of context paths gets
|
||||||
|
@ -426,6 +434,7 @@ public class Jaxb2Marshaller implements MimeMarshaller, MimeUnmarshaller, Generi
|
||||||
*/
|
*/
|
||||||
public void setSupportDtd(boolean supportDtd) {
|
public void setSupportDtd(boolean supportDtd) {
|
||||||
this.supportDtd = supportDtd;
|
this.supportDtd = supportDtd;
|
||||||
|
this.sourceParserFactory = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -450,6 +459,7 @@ public class Jaxb2Marshaller implements MimeMarshaller, MimeUnmarshaller, Generi
|
||||||
if (processExternalEntities) {
|
if (processExternalEntities) {
|
||||||
this.supportDtd = true;
|
this.supportDtd = true;
|
||||||
}
|
}
|
||||||
|
this.sourceParserFactory = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -497,7 +507,9 @@ public class Jaxb2Marshaller implements MimeMarshaller, MimeUnmarshaller, Generi
|
||||||
if (context != null) {
|
if (context != null) {
|
||||||
return context;
|
return context;
|
||||||
}
|
}
|
||||||
synchronized (this.jaxbContextMonitor) {
|
|
||||||
|
this.jaxbContextLock.lock();
|
||||||
|
try {
|
||||||
context = this.jaxbContext;
|
context = this.jaxbContext;
|
||||||
if (context == null) {
|
if (context == null) {
|
||||||
try {
|
try {
|
||||||
|
@ -521,6 +533,9 @@ public class Jaxb2Marshaller implements MimeMarshaller, MimeUnmarshaller, Generi
|
||||||
}
|
}
|
||||||
return context;
|
return context;
|
||||||
}
|
}
|
||||||
|
finally {
|
||||||
|
this.jaxbContextLock.unlock();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private JAXBContext createJaxbContextFromContextPath(String contextPath) throws JAXBException {
|
private JAXBContext createJaxbContextFromContextPath(String contextPath) throws JAXBException {
|
||||||
|
@ -587,17 +602,24 @@ public class Jaxb2Marshaller implements MimeMarshaller, MimeUnmarshaller, Generi
|
||||||
Assert.notEmpty(resources, "No resources given");
|
Assert.notEmpty(resources, "No resources given");
|
||||||
Assert.hasLength(schemaLanguage, "No schema language provided");
|
Assert.hasLength(schemaLanguage, "No schema language provided");
|
||||||
Source[] schemaSources = new Source[resources.length];
|
Source[] schemaSources = new Source[resources.length];
|
||||||
SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();
|
|
||||||
saxParserFactory.setNamespaceAware(true);
|
SAXParserFactory saxParserFactory = this.schemaParserFactory;
|
||||||
saxParserFactory.setFeature("http://xml.org/sax/features/namespace-prefixes", true);
|
if (saxParserFactory == null) {
|
||||||
|
saxParserFactory = SAXParserFactory.newInstance();
|
||||||
|
saxParserFactory.setNamespaceAware(true);
|
||||||
|
saxParserFactory.setFeature("http://xml.org/sax/features/namespace-prefixes", true);
|
||||||
|
this.schemaParserFactory = saxParserFactory;
|
||||||
|
}
|
||||||
SAXParser saxParser = saxParserFactory.newSAXParser();
|
SAXParser saxParser = saxParserFactory.newSAXParser();
|
||||||
XMLReader xmlReader = saxParser.getXMLReader();
|
XMLReader xmlReader = saxParser.getXMLReader();
|
||||||
|
|
||||||
for (int i = 0; i < resources.length; i++) {
|
for (int i = 0; i < resources.length; i++) {
|
||||||
Resource resource = resources[i];
|
Resource resource = resources[i];
|
||||||
Assert.isTrue(resource != null && resource.exists(), () -> "Resource does not exist: " + resource);
|
Assert.isTrue(resource != null && resource.exists(), () -> "Resource does not exist: " + resource);
|
||||||
InputSource inputSource = SaxResourceUtils.createInputSource(resource);
|
InputSource inputSource = SaxResourceUtils.createInputSource(resource);
|
||||||
schemaSources[i] = new SAXSource(xmlReader, inputSource);
|
schemaSources[i] = new SAXSource(xmlReader, inputSource);
|
||||||
}
|
}
|
||||||
|
|
||||||
SchemaFactory schemaFactory = SchemaFactory.newInstance(schemaLanguage);
|
SchemaFactory schemaFactory = SchemaFactory.newInstance(schemaLanguage);
|
||||||
if (this.schemaResourceResolver != null) {
|
if (this.schemaResourceResolver != null) {
|
||||||
schemaFactory.setResourceResolver(this.schemaResourceResolver);
|
schemaFactory.setResourceResolver(this.schemaResourceResolver);
|
||||||
|
@ -886,11 +908,16 @@ public class Jaxb2Marshaller implements MimeMarshaller, MimeUnmarshaller, Generi
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (xmlReader == null) {
|
if (xmlReader == null) {
|
||||||
SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();
|
SAXParserFactory saxParserFactory = this.sourceParserFactory;
|
||||||
saxParserFactory.setNamespaceAware(true);
|
if (saxParserFactory == null) {
|
||||||
saxParserFactory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", !isSupportDtd());
|
saxParserFactory = SAXParserFactory.newInstance();
|
||||||
String name = "http://xml.org/sax/features/external-general-entities";
|
saxParserFactory.setNamespaceAware(true);
|
||||||
saxParserFactory.setFeature(name, isProcessExternalEntities());
|
saxParserFactory.setFeature(
|
||||||
|
"http://apache.org/xml/features/disallow-doctype-decl", !isSupportDtd());
|
||||||
|
saxParserFactory.setFeature(
|
||||||
|
"http://xml.org/sax/features/external-general-entities", isProcessExternalEntities());
|
||||||
|
this.sourceParserFactory = saxParserFactory;
|
||||||
|
}
|
||||||
SAXParser saxParser = saxParserFactory.newSAXParser();
|
SAXParser saxParser = saxParserFactory.newSAXParser();
|
||||||
xmlReader = saxParser.getXMLReader();
|
xmlReader = saxParser.getXMLReader();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2023 the original author or authors.
|
* Copyright 2002-2024 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -83,9 +83,10 @@ public abstract class AbstractMarshaller implements Marshaller, Unmarshaller {
|
||||||
private boolean processExternalEntities = false;
|
private boolean processExternalEntities = false;
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
private DocumentBuilderFactory documentBuilderFactory;
|
private volatile DocumentBuilderFactory documentBuilderFactory;
|
||||||
|
|
||||||
private final Object documentBuilderFactoryMonitor = new Object();
|
@Nullable
|
||||||
|
private volatile SAXParserFactory saxParserFactory;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -94,6 +95,8 @@ public abstract class AbstractMarshaller implements Marshaller, Unmarshaller {
|
||||||
*/
|
*/
|
||||||
public void setSupportDtd(boolean supportDtd) {
|
public void setSupportDtd(boolean supportDtd) {
|
||||||
this.supportDtd = supportDtd;
|
this.supportDtd = supportDtd;
|
||||||
|
this.documentBuilderFactory = null;
|
||||||
|
this.saxParserFactory = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -118,6 +121,8 @@ public abstract class AbstractMarshaller implements Marshaller, Unmarshaller {
|
||||||
if (processExternalEntities) {
|
if (processExternalEntities) {
|
||||||
this.supportDtd = true;
|
this.supportDtd = true;
|
||||||
}
|
}
|
||||||
|
this.documentBuilderFactory = null;
|
||||||
|
this.saxParserFactory = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -137,14 +142,13 @@ public abstract class AbstractMarshaller implements Marshaller, Unmarshaller {
|
||||||
*/
|
*/
|
||||||
protected Document buildDocument() {
|
protected Document buildDocument() {
|
||||||
try {
|
try {
|
||||||
DocumentBuilder documentBuilder;
|
DocumentBuilderFactory builderFactory = this.documentBuilderFactory;
|
||||||
synchronized (this.documentBuilderFactoryMonitor) {
|
if (builderFactory == null) {
|
||||||
if (this.documentBuilderFactory == null) {
|
builderFactory = createDocumentBuilderFactory();
|
||||||
this.documentBuilderFactory = createDocumentBuilderFactory();
|
this.documentBuilderFactory = builderFactory;
|
||||||
}
|
|
||||||
documentBuilder = createDocumentBuilder(this.documentBuilderFactory);
|
|
||||||
}
|
}
|
||||||
return documentBuilder.newDocument();
|
DocumentBuilder builder = createDocumentBuilder(builderFactory);
|
||||||
|
return builder.newDocument();
|
||||||
}
|
}
|
||||||
catch (ParserConfigurationException ex) {
|
catch (ParserConfigurationException ex) {
|
||||||
throw new UnmarshallingFailureException("Could not create document placeholder: " + ex.getMessage(), ex);
|
throw new UnmarshallingFailureException("Could not create document placeholder: " + ex.getMessage(), ex);
|
||||||
|
@ -179,11 +183,11 @@ public abstract class AbstractMarshaller implements Marshaller, Unmarshaller {
|
||||||
protected DocumentBuilder createDocumentBuilder(DocumentBuilderFactory factory)
|
protected DocumentBuilder createDocumentBuilder(DocumentBuilderFactory factory)
|
||||||
throws ParserConfigurationException {
|
throws ParserConfigurationException {
|
||||||
|
|
||||||
DocumentBuilder documentBuilder = factory.newDocumentBuilder();
|
DocumentBuilder builder = factory.newDocumentBuilder();
|
||||||
if (!isProcessExternalEntities()) {
|
if (!isProcessExternalEntities()) {
|
||||||
documentBuilder.setEntityResolver(NO_OP_ENTITY_RESOLVER);
|
builder.setEntityResolver(NO_OP_ENTITY_RESOLVER);
|
||||||
}
|
}
|
||||||
return documentBuilder;
|
return builder;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -193,11 +197,17 @@ public abstract class AbstractMarshaller implements Marshaller, Unmarshaller {
|
||||||
* @throws ParserConfigurationException if thrown by JAXP methods
|
* @throws ParserConfigurationException if thrown by JAXP methods
|
||||||
*/
|
*/
|
||||||
protected XMLReader createXmlReader() throws SAXException, ParserConfigurationException {
|
protected XMLReader createXmlReader() throws SAXException, ParserConfigurationException {
|
||||||
SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();
|
SAXParserFactory parserFactory = this.saxParserFactory;
|
||||||
saxParserFactory.setNamespaceAware(true);
|
if (parserFactory == null) {
|
||||||
saxParserFactory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", !isSupportDtd());
|
parserFactory = SAXParserFactory.newInstance();
|
||||||
saxParserFactory.setFeature("http://xml.org/sax/features/external-general-entities", isProcessExternalEntities());
|
parserFactory.setNamespaceAware(true);
|
||||||
SAXParser saxParser = saxParserFactory.newSAXParser();
|
parserFactory.setFeature(
|
||||||
|
"http://apache.org/xml/features/disallow-doctype-decl", !isSupportDtd());
|
||||||
|
parserFactory.setFeature(
|
||||||
|
"http://xml.org/sax/features/external-general-entities", isProcessExternalEntities());
|
||||||
|
this.saxParserFactory = parserFactory;
|
||||||
|
}
|
||||||
|
SAXParser saxParser = parserFactory.newSAXParser();
|
||||||
XMLReader xmlReader = saxParser.getXMLReader();
|
XMLReader xmlReader = saxParser.getXMLReader();
|
||||||
if (!isProcessExternalEntities()) {
|
if (!isProcessExternalEntities()) {
|
||||||
xmlReader.setEntityResolver(NO_OP_ENTITY_RESOLVER);
|
xmlReader.setEntityResolver(NO_OP_ENTITY_RESOLVER);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2023 the original author or authors.
|
* Copyright 2002-2024 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -61,6 +61,7 @@ import org.springframework.util.ClassUtils;
|
||||||
* @author Arjen Poutsma
|
* @author Arjen Poutsma
|
||||||
* @author Sebastien Deleuze
|
* @author Sebastien Deleuze
|
||||||
* @author Rossen Stoyanchev
|
* @author Rossen Stoyanchev
|
||||||
|
* @author Juergen Hoeller
|
||||||
* @since 3.0
|
* @since 3.0
|
||||||
* @see MarshallingHttpMessageConverter
|
* @see MarshallingHttpMessageConverter
|
||||||
*/
|
*/
|
||||||
|
@ -70,6 +71,9 @@ public class Jaxb2RootElementHttpMessageConverter extends AbstractJaxb2HttpMessa
|
||||||
|
|
||||||
private boolean processExternalEntities = false;
|
private boolean processExternalEntities = false;
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private volatile SAXParserFactory sourceParserFactory;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Indicate whether DTD parsing should be supported.
|
* Indicate whether DTD parsing should be supported.
|
||||||
|
@ -77,6 +81,7 @@ public class Jaxb2RootElementHttpMessageConverter extends AbstractJaxb2HttpMessa
|
||||||
*/
|
*/
|
||||||
public void setSupportDtd(boolean supportDtd) {
|
public void setSupportDtd(boolean supportDtd) {
|
||||||
this.supportDtd = supportDtd;
|
this.supportDtd = supportDtd;
|
||||||
|
this.sourceParserFactory = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -97,6 +102,7 @@ public class Jaxb2RootElementHttpMessageConverter extends AbstractJaxb2HttpMessa
|
||||||
if (processExternalEntities) {
|
if (processExternalEntities) {
|
||||||
this.supportDtd = true;
|
this.supportDtd = true;
|
||||||
}
|
}
|
||||||
|
this.sourceParserFactory = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -156,11 +162,16 @@ public class Jaxb2RootElementHttpMessageConverter extends AbstractJaxb2HttpMessa
|
||||||
if (source instanceof StreamSource streamSource) {
|
if (source instanceof StreamSource streamSource) {
|
||||||
InputSource inputSource = new InputSource(streamSource.getInputStream());
|
InputSource inputSource = new InputSource(streamSource.getInputStream());
|
||||||
try {
|
try {
|
||||||
SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();
|
SAXParserFactory saxParserFactory = this.sourceParserFactory;
|
||||||
saxParserFactory.setNamespaceAware(true);
|
if (saxParserFactory == null) {
|
||||||
saxParserFactory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", !isSupportDtd());
|
saxParserFactory = SAXParserFactory.newInstance();
|
||||||
String featureName = "http://xml.org/sax/features/external-general-entities";
|
saxParserFactory.setNamespaceAware(true);
|
||||||
saxParserFactory.setFeature(featureName, isProcessExternalEntities());
|
saxParserFactory.setFeature(
|
||||||
|
"http://apache.org/xml/features/disallow-doctype-decl", !isSupportDtd());
|
||||||
|
saxParserFactory.setFeature(
|
||||||
|
"http://xml.org/sax/features/external-general-entities", isProcessExternalEntities());
|
||||||
|
this.sourceParserFactory = saxParserFactory;
|
||||||
|
}
|
||||||
SAXParser saxParser = saxParserFactory.newSAXParser();
|
SAXParser saxParser = saxParserFactory.newSAXParser();
|
||||||
XMLReader xmlReader = saxParser.getXMLReader();
|
XMLReader xmlReader = saxParser.getXMLReader();
|
||||||
if (!isProcessExternalEntities()) {
|
if (!isProcessExternalEntities()) {
|
||||||
|
|
|
@ -63,6 +63,7 @@ import org.springframework.util.StreamUtils;
|
||||||
*
|
*
|
||||||
* @author Arjen Poutsma
|
* @author Arjen Poutsma
|
||||||
* @author Rossen Stoyanchev
|
* @author Rossen Stoyanchev
|
||||||
|
* @author Juergen Hoeller
|
||||||
* @since 3.0
|
* @since 3.0
|
||||||
* @param <T> the converted object type
|
* @param <T> the converted object type
|
||||||
*/
|
*/
|
||||||
|
@ -75,11 +76,7 @@ public class SourceHttpMessageConverter<T extends Source> extends AbstractHttpMe
|
||||||
(publicID, systemID, base, ns) -> InputStream.nullInputStream();
|
(publicID, systemID, base, ns) -> InputStream.nullInputStream();
|
||||||
|
|
||||||
private static final Set<Class<?>> SUPPORTED_CLASSES = Set.of(
|
private static final Set<Class<?>> SUPPORTED_CLASSES = Set.of(
|
||||||
DOMSource.class,
|
DOMSource.class, SAXSource.class, StAXSource.class, StreamSource.class, Source.class);
|
||||||
SAXSource.class,
|
|
||||||
StAXSource.class,
|
|
||||||
StreamSource.class,
|
|
||||||
Source.class);
|
|
||||||
|
|
||||||
|
|
||||||
private final TransformerFactory transformerFactory = TransformerFactory.newInstance();
|
private final TransformerFactory transformerFactory = TransformerFactory.newInstance();
|
||||||
|
@ -88,6 +85,15 @@ public class SourceHttpMessageConverter<T extends Source> extends AbstractHttpMe
|
||||||
|
|
||||||
private boolean processExternalEntities = false;
|
private boolean processExternalEntities = false;
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private volatile DocumentBuilderFactory documentBuilderFactory;
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private volatile SAXParserFactory saxParserFactory;
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private volatile XMLInputFactory xmlInputFactory;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the {@link #setSupportedMediaTypes(java.util.List) supportedMediaTypes}
|
* Sets the {@link #setSupportedMediaTypes(java.util.List) supportedMediaTypes}
|
||||||
|
@ -104,6 +110,9 @@ public class SourceHttpMessageConverter<T extends Source> extends AbstractHttpMe
|
||||||
*/
|
*/
|
||||||
public void setSupportDtd(boolean supportDtd) {
|
public void setSupportDtd(boolean supportDtd) {
|
||||||
this.supportDtd = supportDtd;
|
this.supportDtd = supportDtd;
|
||||||
|
this.documentBuilderFactory = null;
|
||||||
|
this.saxParserFactory = null;
|
||||||
|
this.xmlInputFactory = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -124,6 +133,9 @@ public class SourceHttpMessageConverter<T extends Source> extends AbstractHttpMe
|
||||||
if (processExternalEntities) {
|
if (processExternalEntities) {
|
||||||
this.supportDtd = true;
|
this.supportDtd = true;
|
||||||
}
|
}
|
||||||
|
this.documentBuilderFactory = null;
|
||||||
|
this.saxParserFactory = null;
|
||||||
|
this.xmlInputFactory = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -165,17 +177,21 @@ public class SourceHttpMessageConverter<T extends Source> extends AbstractHttpMe
|
||||||
|
|
||||||
private DOMSource readDOMSource(InputStream body, HttpInputMessage inputMessage) throws IOException {
|
private DOMSource readDOMSource(InputStream body, HttpInputMessage inputMessage) throws IOException {
|
||||||
try {
|
try {
|
||||||
DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
|
DocumentBuilderFactory builderFactory = this.documentBuilderFactory;
|
||||||
documentBuilderFactory.setNamespaceAware(true);
|
if (builderFactory == null) {
|
||||||
documentBuilderFactory.setFeature(
|
builderFactory = DocumentBuilderFactory.newInstance();
|
||||||
"http://apache.org/xml/features/disallow-doctype-decl", !isSupportDtd());
|
builderFactory.setNamespaceAware(true);
|
||||||
documentBuilderFactory.setFeature(
|
builderFactory.setFeature(
|
||||||
"http://xml.org/sax/features/external-general-entities", isProcessExternalEntities());
|
"http://apache.org/xml/features/disallow-doctype-decl", !isSupportDtd());
|
||||||
DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
|
builderFactory.setFeature(
|
||||||
if (!isProcessExternalEntities()) {
|
"http://xml.org/sax/features/external-general-entities", isProcessExternalEntities());
|
||||||
documentBuilder.setEntityResolver(NO_OP_ENTITY_RESOLVER);
|
this.documentBuilderFactory = builderFactory;
|
||||||
}
|
}
|
||||||
Document document = documentBuilder.parse(body);
|
DocumentBuilder builder = builderFactory.newDocumentBuilder();
|
||||||
|
if (!isProcessExternalEntities()) {
|
||||||
|
builder.setEntityResolver(NO_OP_ENTITY_RESOLVER);
|
||||||
|
}
|
||||||
|
Document document = builder.parse(body);
|
||||||
return new DOMSource(document);
|
return new DOMSource(document);
|
||||||
}
|
}
|
||||||
catch (NullPointerException ex) {
|
catch (NullPointerException ex) {
|
||||||
|
@ -197,11 +213,17 @@ public class SourceHttpMessageConverter<T extends Source> extends AbstractHttpMe
|
||||||
|
|
||||||
private SAXSource readSAXSource(InputStream body, HttpInputMessage inputMessage) throws IOException {
|
private SAXSource readSAXSource(InputStream body, HttpInputMessage inputMessage) throws IOException {
|
||||||
try {
|
try {
|
||||||
SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();
|
SAXParserFactory parserFactory = this.saxParserFactory;
|
||||||
saxParserFactory.setNamespaceAware(true);
|
if (parserFactory == null) {
|
||||||
saxParserFactory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", !isSupportDtd());
|
parserFactory = SAXParserFactory.newInstance();
|
||||||
saxParserFactory.setFeature("http://xml.org/sax/features/external-general-entities", isProcessExternalEntities());
|
parserFactory.setNamespaceAware(true);
|
||||||
SAXParser saxParser = saxParserFactory.newSAXParser();
|
parserFactory.setFeature(
|
||||||
|
"http://apache.org/xml/features/disallow-doctype-decl", !isSupportDtd());
|
||||||
|
parserFactory.setFeature(
|
||||||
|
"http://xml.org/sax/features/external-general-entities", isProcessExternalEntities());
|
||||||
|
this.saxParserFactory = parserFactory;
|
||||||
|
}
|
||||||
|
SAXParser saxParser = parserFactory.newSAXParser();
|
||||||
XMLReader xmlReader = saxParser.getXMLReader();
|
XMLReader xmlReader = saxParser.getXMLReader();
|
||||||
if (!isProcessExternalEntities()) {
|
if (!isProcessExternalEntities()) {
|
||||||
xmlReader.setEntityResolver(NO_OP_ENTITY_RESOLVER);
|
xmlReader.setEntityResolver(NO_OP_ENTITY_RESOLVER);
|
||||||
|
@ -217,11 +239,15 @@ public class SourceHttpMessageConverter<T extends Source> extends AbstractHttpMe
|
||||||
|
|
||||||
private Source readStAXSource(InputStream body, HttpInputMessage inputMessage) {
|
private Source readStAXSource(InputStream body, HttpInputMessage inputMessage) {
|
||||||
try {
|
try {
|
||||||
XMLInputFactory inputFactory = XMLInputFactory.newInstance();
|
XMLInputFactory inputFactory = this.xmlInputFactory;
|
||||||
inputFactory.setProperty(XMLInputFactory.SUPPORT_DTD, isSupportDtd());
|
if (inputFactory == null) {
|
||||||
inputFactory.setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, isProcessExternalEntities());
|
inputFactory = XMLInputFactory.newInstance();
|
||||||
if (!isProcessExternalEntities()) {
|
inputFactory.setProperty(XMLInputFactory.SUPPORT_DTD, isSupportDtd());
|
||||||
inputFactory.setXMLResolver(NO_OP_XML_RESOLVER);
|
inputFactory.setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, isProcessExternalEntities());
|
||||||
|
if (!isProcessExternalEntities()) {
|
||||||
|
inputFactory.setXMLResolver(NO_OP_XML_RESOLVER);
|
||||||
|
}
|
||||||
|
this.xmlInputFactory = inputFactory;
|
||||||
}
|
}
|
||||||
XMLStreamReader streamReader = inputFactory.createXMLStreamReader(body);
|
XMLStreamReader streamReader = inputFactory.createXMLStreamReader(body);
|
||||||
return new StAXSource(streamReader);
|
return new StAXSource(streamReader);
|
||||||
|
|
Loading…
Reference in New Issue