This is an automated email from the ASF dual-hosted git repository.
markt-asf pushed a commit to branch 10.1.x
in repository https://gitbox.apache.org/repos/asf/tomcat.git
The following commit(s) were added to refs/heads/10.1.x by this push:
new 25677f90fd Fix xml output of webxml
25677f90fd is described below
commit 25677f90fd721c26ef0f613d34ef8275b1aafc31
Author: Mark Thomas <[email protected]>
AuthorDate: Mon Jun 8 17:22:18 2026 +0100
Fix xml output of webxml
Missing entries, formatting, correct URI encoding
---
.../apache/tomcat/util/descriptor/web/WebXml.java | 157 ++++++++++++++-----
.../tomcat/util/descriptor/web/TestWebXml.java | 172 +++++++++++++++++++++
webapps/docs/changelog.xml | 6 +
3 files changed, 297 insertions(+), 38 deletions(-)
diff --git a/java/org/apache/tomcat/util/descriptor/web/WebXml.java
b/java/org/apache/tomcat/util/descriptor/web/WebXml.java
index 6b6648484b..231bec45b4 100644
--- a/java/org/apache/tomcat/util/descriptor/web/WebXml.java
+++ b/java/org/apache/tomcat/util/descriptor/web/WebXml.java
@@ -16,10 +16,9 @@
*/
package org.apache.tomcat.util.descriptor.web;
+import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URL;
-import java.net.URLEncoder;
-import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Collection;
import java.util.EnumSet;
@@ -29,6 +28,7 @@ import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
+import java.util.Locale;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
@@ -45,6 +45,8 @@ import org.apache.juli.logging.Log;
import org.apache.juli.logging.LogFactory;
import org.apache.tomcat.util.buf.B2CConverter;
import org.apache.tomcat.util.buf.UDecoder;
+import org.apache.tomcat.util.buf.UEncoder;
+import org.apache.tomcat.util.buf.UEncoder.SafeCharsSet;
import org.apache.tomcat.util.descriptor.XmlIdentifiers;
import org.apache.tomcat.util.digester.DocumentProperties;
import org.apache.tomcat.util.res.StringManager;
@@ -73,6 +75,8 @@ public class WebXml extends XmlEncodingBase implements
DocumentProperties.Charse
private final Log log = LogFactory.getLog(WebXml.class); // must not be
static
+ private final UEncoder urlEncoder = new UEncoder(SafeCharsSet.WITH_SLASH);
+
/**
* Global defaults are overridable but Servlets and Servlet mappings need
to be unique. Duplicates normally trigger
* an error. This flag indicates if newly added Servlet elements are
marked as overridable.
@@ -1344,6 +1348,7 @@ public class WebXml extends XmlEncodingBase implements
DocumentProperties.Charse
private static final String INDENT2 = " ";
private static final String INDENT4 = " ";
private static final String INDENT6 = " ";
+ private static final String INDENT8 = " ";
/**
* Generate a web.xml in String form that matches the representation
stored in this object.
@@ -1438,7 +1443,9 @@ public class WebXml extends XmlEncodingBase implements
DocumentProperties.Charse
appendElement(sb, INDENT4, "param-value", entry.getValue());
sb.append(" </context-param>\n");
}
- sb.append('\n');
+ if (!contextParams.isEmpty()) {
+ sb.append('\n');
+ }
// Filters were introduced in Servlet 2.3
if (getMajorVersion() > 2 || getMinorVersion() > 2) {
@@ -1461,7 +1468,9 @@ public class WebXml extends XmlEncodingBase implements
DocumentProperties.Charse
}
sb.append(" </filter>\n");
}
- sb.append('\n');
+ if (!filters.isEmpty()) {
+ sb.append('\n');
+ }
for (FilterMap filterMap : filterMaps) {
sb.append(" <filter-mapping>\n");
@@ -1491,7 +1500,9 @@ public class WebXml extends XmlEncodingBase implements
DocumentProperties.Charse
}
sb.append(" </filter-mapping>\n");
}
- sb.append('\n');
+ if (!filterMaps.isEmpty()) {
+ sb.append('\n');
+ }
}
// Listeners were introduced in Servlet 2.3
@@ -1501,7 +1512,9 @@ public class WebXml extends XmlEncodingBase implements
DocumentProperties.Charse
appendElement(sb, INDENT4, "listener-class", listener);
sb.append(" </listener>\n");
}
- sb.append('\n');
+ if (!listeners.isEmpty()) {
+ sb.append('\n');
+ }
}
for (Map.Entry<String,ServletDef> entry : servlets.entrySet()) {
@@ -1552,7 +1565,9 @@ public class WebXml extends XmlEncodingBase implements
DocumentProperties.Charse
}
sb.append(" </servlet>\n");
}
- sb.append('\n');
+ if (!servlets.isEmpty()) {
+ sb.append('\n');
+ }
for (Map.Entry<String,String> entry : servletMappings.entrySet()) {
sb.append(" <servlet-mapping>\n");
@@ -1560,21 +1575,44 @@ public class WebXml extends XmlEncodingBase implements
DocumentProperties.Charse
appendElement(sb, INDENT4, "url-pattern",
encodeUrl(entry.getKey()));
sb.append(" </servlet-mapping>\n");
}
- sb.append('\n');
+ if (!servletMappings.isEmpty()) {
+ sb.append('\n');
+ }
- if (sessionConfig != null) {
+ if (sessionConfig.getSessionTimeout() != null ||
sessionConfig.getCookieName() != null ||
+ !sessionConfig.getCookieAttributes().isEmpty() ||
!sessionConfig.getSessionTrackingModes().isEmpty()) {
sb.append(" <session-config>\n");
appendElement(sb, INDENT4, "session-timeout",
sessionConfig.getSessionTimeout());
if (majorVersion >= 3) {
- sb.append(" <cookie-config>\n");
- appendElement(sb, INDENT6, "name",
sessionConfig.getCookieName());
- appendElement(sb, INDENT6, "domain",
sessionConfig.getCookieDomain());
- appendElement(sb, INDENT6, "path",
sessionConfig.getCookiePath());
- appendElement(sb, INDENT6, "comment",
sessionConfig.getCookieComment());
- appendElement(sb, INDENT6, "http-only",
sessionConfig.getCookieHttpOnly());
- appendElement(sb, INDENT6, "secure",
sessionConfig.getCookieSecure());
- appendElement(sb, INDENT6, "max-age",
sessionConfig.getCookieMaxAge());
- sb.append(" </cookie-config>\n");
+ if (sessionConfig.getCookieName() != null ||
!sessionConfig.getCookieAttributes().isEmpty()) {
+ sb.append(" <cookie-config>\n");
+ appendElement(sb, INDENT6, "name",
sessionConfig.getCookieName());
+ appendElement(sb, INDENT6, "domain",
sessionConfig.getCookieDomain());
+ appendElement(sb, INDENT6, "path",
sessionConfig.getCookiePath());
+ appendElement(sb, INDENT6, "comment",
sessionConfig.getCookieComment());
+ appendElement(sb, INDENT6, "http-only",
sessionConfig.getCookieHttpOnly());
+ appendElement(sb, INDENT6, "secure",
sessionConfig.getCookieSecure());
+ appendElement(sb, INDENT6, "max-age",
sessionConfig.getCookieMaxAge());
+ for (Map.Entry<String,String> entry :
sessionConfig.getCookieAttributes().entrySet()) {
+ switch (entry.getKey().toLowerCase(Locale.ROOT)) {
+ case "domain":
+ case "path":
+ case "comment":
+ case "http-only":
+ case "secure":
+ case "max-age":
+ // NO-OP - handled above
+ break;
+ default: {
+ sb.append(" <attribute>\n");
+ appendElement(sb, INDENT8, "attribute-name",
entry.getKey());
+ appendElement(sb, INDENT8, "attribute-value",
entry.getValue());
+ sb.append(" </attribute>\n");
+ }
+ }
+ }
+ sb.append(" </cookie-config>\n");
+ }
for (SessionTrackingMode stm :
sessionConfig.getSessionTrackingModes()) {
appendElement(sb, INDENT4, "tracking-mode", stm.name());
}
@@ -1588,7 +1626,9 @@ public class WebXml extends XmlEncodingBase implements
DocumentProperties.Charse
appendElement(sb, INDENT4, "mime-type", entry.getValue());
sb.append(" </mime-mapping>\n");
}
- sb.append('\n');
+ if (!mimeMappings.isEmpty()) {
+ sb.append('\n');
+ }
if (!welcomeFiles.isEmpty()) {
sb.append(" <welcome-file-list>\n");
@@ -1612,10 +1652,12 @@ public class WebXml extends XmlEncodingBase implements
DocumentProperties.Charse
} else if (errorPage.getErrorCode() > 0) {
appendElement(sb, INDENT4, "error-code",
Integer.toString(errorCode));
}
- appendElement(sb, INDENT4, "location", errorPage.getLocation());
+ appendElement(sb, INDENT4, "location", errorPage.getLocation(),
true);
sb.append(" </error-page>\n");
}
- sb.append('\n');
+ if (!errorPages.isEmpty()) {
+ sb.append('\n');
+ }
// jsp-config was added in Servlet 2.4. Prior to that, tag-libs was
used
// directly and jsp-property-group did not exist
@@ -1673,7 +1715,9 @@ public class WebXml extends XmlEncodingBase implements
DocumentProperties.Charse
appendElement(sb, INDENT4, "lookup-name",
resourceEnvRef.getLookupName());
sb.append(" </resource-env-ref>\n");
}
- sb.append('\n');
+ if (!resourceEnvRefs.isEmpty()) {
+ sb.append('\n');
+ }
}
for (ContextResource resourceRef : resourceRefs.values()) {
@@ -1696,7 +1740,9 @@ public class WebXml extends XmlEncodingBase implements
DocumentProperties.Charse
appendElement(sb, INDENT4, "lookup-name",
resourceRef.getLookupName());
sb.append(" </resource-ref>\n");
}
- sb.append('\n');
+ if (!resourceRefs.isEmpty()) {
+ sb.append('\n');
+ }
for (SecurityConstraint constraint : securityConstraints) {
sb.append(" <security-constraint>\n");
@@ -1719,12 +1765,20 @@ public class WebXml extends XmlEncodingBase implements
DocumentProperties.Charse
}
sb.append(" </web-resource-collection>\n");
}
- if (constraint.findAuthRoles().length > 0) {
+ if (constraint.findAuthRoles().length > 0 ||
constraint.getAllRoles() || constraint.getAuthenticatedUsers()) {
sb.append(" <auth-constraint>\n");
for (String role : constraint.findAuthRoles()) {
appendElement(sb, INDENT6, "role-name", role);
}
+ if (constraint.getAllRoles()) {
+ appendElement(sb, INDENT6, "role-name",
SecurityConstraint.ROLE_ALL_ROLES);
+ }
+ if (constraint.getAuthenticatedUsers()) {
+ appendElement(sb, INDENT6, "role-name",
SecurityConstraint.ROLE_ALL_AUTHENTICATED_USERS);
+ }
sb.append(" </auth-constraint>\n");
+ } else if (constraint.getAuthConstraint()) {
+ sb.append(" <auth-constraint/>\n");
}
if (constraint.getUserConstraint() != null) {
sb.append(" <user-data-constraint>\n");
@@ -1733,7 +1787,9 @@ public class WebXml extends XmlEncodingBase implements
DocumentProperties.Charse
}
sb.append(" </security-constraint>\n");
}
- sb.append('\n');
+ if (!securityConstraints.isEmpty()) {
+ sb.append('\n');
+ }
if (loginConfig != null) {
sb.append(" <login-config>\n");
@@ -1741,8 +1797,8 @@ public class WebXml extends XmlEncodingBase implements
DocumentProperties.Charse
appendElement(sb, INDENT4, "realm-name",
loginConfig.getRealmName());
if (loginConfig.getErrorPage() != null ||
loginConfig.getLoginPage() != null) {
sb.append(" <form-login-config>\n");
- appendElement(sb, INDENT6, "form-login-page",
loginConfig.getLoginPage());
- appendElement(sb, INDENT6, "form-error-page",
loginConfig.getErrorPage());
+ appendElement(sb, INDENT6, "form-login-page",
loginConfig.getLoginPage(), true);
+ appendElement(sb, INDENT6, "form-error-page",
loginConfig.getErrorPage(), true);
sb.append(" </form-login-config>\n");
}
sb.append(" </login-config>\n\n");
@@ -1770,7 +1826,9 @@ public class WebXml extends XmlEncodingBase implements
DocumentProperties.Charse
appendElement(sb, INDENT4, "lookup-name",
envEntry.getLookupName());
sb.append(" </env-entry>\n");
}
- sb.append('\n');
+ if (!envEntries.isEmpty()) {
+ sb.append('\n');
+ }
for (ContextEjb ejbRef : ejbRefs.values()) {
sb.append(" <ejb-ref>\n");
@@ -1790,7 +1848,9 @@ public class WebXml extends XmlEncodingBase implements
DocumentProperties.Charse
appendElement(sb, INDENT4, "lookup-name", ejbRef.getLookupName());
sb.append(" </ejb-ref>\n");
}
- sb.append('\n');
+ if (!ejbRefs.isEmpty()) {
+ sb.append('\n');
+ }
// ejb-local-ref was introduced in Servlet 2.3
if (getMajorVersion() > 2 || getMinorVersion() > 2) {
@@ -1812,7 +1872,9 @@ public class WebXml extends XmlEncodingBase implements
DocumentProperties.Charse
appendElement(sb, INDENT4, "lookup-name",
ejbLocalRef.getLookupName());
sb.append(" </ejb-local-ref>\n");
}
- sb.append('\n');
+ if (!ejbLocalRefs.isEmpty()) {
+ sb.append('\n');
+ }
}
// service-ref was introduced in Servlet 2.4
@@ -1860,7 +1922,9 @@ public class WebXml extends XmlEncodingBase implements
DocumentProperties.Charse
appendElement(sb, INDENT4, "lookup-name",
serviceRef.getLookupName());
sb.append(" </service-ref>\n");
}
- sb.append('\n');
+ if (!serviceRefs.isEmpty()) {
+ sb.append('\n');
+ }
}
if (!postConstructMethods.isEmpty()) {
@@ -1903,7 +1967,9 @@ public class WebXml extends XmlEncodingBase implements
DocumentProperties.Charse
appendElement(sb, INDENT4, "lookup-name", mdr.getLookupName());
sb.append(" </message-destination-ref>\n");
}
- sb.append('\n');
+ if (!messageDestinationRefs.isEmpty()) {
+ sb.append('\n');
+ }
for (MessageDestination md : messageDestinations.values()) {
sb.append(" <message-destination>\n");
@@ -1914,7 +1980,9 @@ public class WebXml extends XmlEncodingBase implements
DocumentProperties.Charse
appendElement(sb, INDENT4, "lookup-name", md.getLookupName());
sb.append(" </message-destination>\n");
}
- sb.append('\n');
+ if (!messageDestinations.isEmpty()) {
+ sb.append('\n');
+ }
}
// locale-encoding-mapping-list was introduced in Servlet 2.4
@@ -1950,12 +2018,21 @@ public class WebXml extends XmlEncodingBase implements
DocumentProperties.Charse
}
- private String encodeUrl(String input) {
- return URLEncoder.encode(input, StandardCharsets.UTF_8);
+ private synchronized String encodeUrl(String input) {
+ try {
+ return urlEncoder.encodeURL(input, 0, input.length()).toString();
+ } catch (IOException e) {
+ throw new IllegalArgumentException(input, e);
+ }
}
- private static void appendElement(StringBuilder sb, String indent, String
elementName, String value) {
+ private void appendElement(StringBuilder sb, String indent, String
elementName, String value) {
+ appendElement(sb, indent, elementName, value, false);
+ }
+
+ private void appendElement(StringBuilder sb, String indent, String
elementName, String value, boolean encodeValue) {
+
if (value == null) {
return;
}
@@ -1969,14 +2046,18 @@ public class WebXml extends XmlEncodingBase implements
DocumentProperties.Charse
sb.append('<');
sb.append(elementName);
sb.append('>');
- sb.append(Escape.xml(value));
+ if (encodeValue) {
+ sb.append(Escape.xml(encodeUrl(value)));
+ } else {
+ sb.append(Escape.xml(value));
+ }
sb.append("</");
sb.append(elementName);
sb.append(">\n");
}
}
- private static void appendElement(StringBuilder sb, String indent, String
elementName, Object value) {
+ private void appendElement(StringBuilder sb, String indent, String
elementName, Object value) {
if (value == null) {
return;
}
diff --git a/test/org/apache/tomcat/util/descriptor/web/TestWebXml.java
b/test/org/apache/tomcat/util/descriptor/web/TestWebXml.java
index 874de4b6bf..19583f369b 100644
--- a/test/org/apache/tomcat/util/descriptor/web/TestWebXml.java
+++ b/test/org/apache/tomcat/util/descriptor/web/TestWebXml.java
@@ -630,4 +630,176 @@ public class TestWebXml {
Assert.assertFalse(main.merge(fragments));
}
+
+
+ @Test
+ public void testToXml01() throws Exception {
+ // Empty web.xml
+ doTestToXml("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
+ "<web-app xmlns=\"https://jakarta.ee/xml/ns/jakartaee\"\n" +
+ "
xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n" +
+ "
xsi:schemaLocation=\"https://jakarta.ee/xml/ns/jakartaee" +
+ " https://jakarta.ee/xml/ns/jakartaee/web-app_6_2.xsd\"\n" +
+ " version=\"6.2\"\n" +
+ " metadata-complete=\"true\">\n" +
+ "\n" +
+ "</web-app>");
+ }
+
+
+ @Test
+ public void testToXml02() throws Exception {
+ // Deny all
+ doTestToXml("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
+ "<web-app xmlns=\"https://jakarta.ee/xml/ns/jakartaee\"\n" +
+ "
xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n" +
+ "
xsi:schemaLocation=\"https://jakarta.ee/xml/ns/jakartaee" +
+ " https://jakarta.ee/xml/ns/jakartaee/web-app_6_2.xsd\"\n" +
+ " version=\"6.2\"\n" +
+ " metadata-complete=\"true\">\n" +
+ "\n" +
+ " <security-constraint>\n" +
+ " <web-resource-collection>\n" +
+ " <web-resource-name>Test</web-resource-name>\n" +
+ " <url-pattern>/deny-all</url-pattern>\n" +
+ " </web-resource-collection>\n" +
+ " <auth-constraint/>\n" +
+ " <user-data-constraint>\n" +
+ " <transport-guarantee>NONE</transport-guarantee>\n" +
+ " </user-data-constraint>\n" +
+ " </security-constraint>\n" +
+ "\n" +
+ "</web-app>");
+ }
+
+
+ @Test
+ public void testToXml03() throws Exception {
+ // other role plus all roles
+ doTestToXml("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
+ "<web-app xmlns=\"https://jakarta.ee/xml/ns/jakartaee\"\n" +
+ "
xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n" +
+ "
xsi:schemaLocation=\"https://jakarta.ee/xml/ns/jakartaee" +
+ " https://jakarta.ee/xml/ns/jakartaee/web-app_6_2.xsd\"\n" +
+ " version=\"6.2\"\n" +
+ " metadata-complete=\"true\">\n" +
+ "\n" +
+ " <security-constraint>\n" +
+ " <web-resource-collection>\n" +
+ " <web-resource-name>Test</web-resource-name>\n" +
+ " <url-pattern>/deny-all</url-pattern>\n" +
+ " </web-resource-collection>\n" +
+ " <auth-constraint>\n" +
+ " <role-name>other</role-name>\n" +
+ " <role-name>*</role-name>\n" +
+ " </auth-constraint>\n" +
+ " <user-data-constraint>\n" +
+ " <transport-guarantee>NONE</transport-guarantee>\n" +
+ " </user-data-constraint>\n" +
+ " </security-constraint>\n" +
+ "\n" +
+ "</web-app>");
+ }
+
+
+ @Test
+ public void testToXml04() throws Exception {
+ // all roles
+ doTestToXml("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
+ "<web-app xmlns=\"https://jakarta.ee/xml/ns/jakartaee\"\n" +
+ "
xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n" +
+ "
xsi:schemaLocation=\"https://jakarta.ee/xml/ns/jakartaee" +
+ " https://jakarta.ee/xml/ns/jakartaee/web-app_6_2.xsd\"\n" +
+ " version=\"6.2\"\n" +
+ " metadata-complete=\"true\">\n" +
+ "\n" +
+ " <security-constraint>\n" +
+ " <web-resource-collection>\n" +
+ " <web-resource-name>Test</web-resource-name>\n" +
+ " <url-pattern>/deny-all</url-pattern>\n" +
+ " </web-resource-collection>\n" +
+ " <auth-constraint>\n" +
+ " <role-name>*</role-name>\n" +
+ " </auth-constraint>\n" +
+ " <user-data-constraint>\n" +
+ " <transport-guarantee>NONE</transport-guarantee>\n" +
+ " </user-data-constraint>\n" +
+ " </security-constraint>\n" +
+ "\n" +
+ "</web-app>");
+ }
+
+
+ @Test
+ public void testToXml05() throws Exception {
+ // other role plus authenticated users
+ doTestToXml("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
+ "<web-app xmlns=\"https://jakarta.ee/xml/ns/jakartaee\"\n" +
+ "
xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n" +
+ "
xsi:schemaLocation=\"https://jakarta.ee/xml/ns/jakartaee" +
+ " https://jakarta.ee/xml/ns/jakartaee/web-app_6_2.xsd\"\n" +
+ " version=\"6.2\"\n" +
+ " metadata-complete=\"true\">\n" +
+ "\n" +
+ " <security-constraint>\n" +
+ " <web-resource-collection>\n" +
+ " <web-resource-name>Test</web-resource-name>\n" +
+ " <url-pattern>/deny-all</url-pattern>\n" +
+ " </web-resource-collection>\n" +
+ " <auth-constraint>\n" +
+ " <role-name>other</role-name>\n" +
+ " <role-name>**</role-name>\n" +
+ " </auth-constraint>\n" +
+ " <user-data-constraint>\n" +
+ " <transport-guarantee>NONE</transport-guarantee>\n" +
+ " </user-data-constraint>\n" +
+ " </security-constraint>\n" +
+ "\n" +
+ "</web-app>");
+ }
+
+
+ @Test
+ public void testToXml06() throws Exception {
+ // authenticated users
+ doTestToXml("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
+ "<web-app xmlns=\"https://jakarta.ee/xml/ns/jakartaee\"\n" +
+ "
xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n" +
+ "
xsi:schemaLocation=\"https://jakarta.ee/xml/ns/jakartaee" +
+ " https://jakarta.ee/xml/ns/jakartaee/web-app_6_2.xsd\"\n" +
+ " version=\"6.2\"\n" +
+ " metadata-complete=\"true\">\n" +
+ "\n" +
+ " <security-constraint>\n" +
+ " <web-resource-collection>\n" +
+ " <web-resource-name>Test</web-resource-name>\n" +
+ " <url-pattern>/deny-all</url-pattern>\n" +
+ " </web-resource-collection>\n" +
+ " <auth-constraint>\n" +
+ " <role-name>**</role-name>\n" +
+ " </auth-constraint>\n" +
+ " <user-data-constraint>\n" +
+ " <transport-guarantee>NONE</transport-guarantee>\n" +
+ " </user-data-constraint>\n" +
+ " </security-constraint>\n" +
+ "\n" +
+ "</web-app>");
+ }
+
+
+ private void doTestToXml(String input) throws Exception {
+ Digester digester = DigesterFactory.newDigester(true, true, new
WebRuleSet(), true);
+
+ XmlErrorHandler handler = new XmlErrorHandler();
+ digester.setErrorHandler(handler);
+
+ InputSource is = new InputSource(new StringReader(input));
+ WebXml webxml = new WebXml();
+ digester.push(webxml);
+ digester.parse(is);
+
+ String output = webxml.toXml();
+
+ Assert.assertEquals(input, output);
+ }
}
diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml
index dd98994bdf..511282503c 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -285,6 +285,12 @@
(according to the examples in the RFC). Use the first acceptable value.
(remm)
</fix>
+ <fix>
+ Fix various issues when logging the effective web.xml for a web
+ application. Empty sections are no longer logged. Special roles and
+ empty authorisation constraints are included. All session cookie
+ attributes are included. (markt)
+ </fix>
</changelog>
</subsection>
<subsection name="Coyote">
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]