Ich hatte das gleiche Problem: Ich musste die Portnummer kennen, um eine URL für eine bestimmte Tomcat-Instanz zu erstellen, die Portnummer kann variieren (weil ich mehrere Instanzen zum Testen ausführe), und seit Tomcat 7 ist ServerFactory weg Weg.
Ich schrieb den folgenden Code zum Suchen und Parsen der Tomcat server.xml-Datei. Es analysiert nicht viel, nur die HTTP "Port" und "RedirectPort" -Werte erhalten. Dies hängt von den Systemeigenschaften "catalina.home" oder "catalina.base" ab, die in jeder laufenden Tomcat-Instanz vorhanden sein sollten. Das Schöne ist, dass es nicht von Tomcat-Klassen abhängig ist und den XML-Parser der JVM verwendet.
Ich hoffe, das hilft.
public final class TomcatConfigUtil {
private static final String CONFIG_FILE_PATH = "conf/server.xml";
private static Map<String, String> properties = null;
// No instances, please.
private TomcatConfigUtil() { }
/**
* Get the configuration as a map of name/value pairs, or throw an exception if it wasn't found.
* All values are returned as Strings.
* <ul>
* <li> httpPort - the HTTP port</li>
* <li> httpRedirectPort - the HTTP redirect port (which seems to be the SSL port) </li>
* </ul>
* @exception FileNotFoundException if the configuration file wasn't found
* @exception IOException if there was a problem reading the configuration file
* @exception SAXException if there was a problem parsing the configuration file
*/
public static synchronized Map<String, String> getConfig() throws FileNotFoundException, IOException, SAXException {
if (properties != null) {
return properties;
}
final File serverConfigFile = findServerConfigFile();
if (serverConfigFile == null) {
throw new FileNotFoundException("Couldn't find the configuration file.");
}
final Map<String, String> tmpProperties = new HashMap<String, String>();
// Content-handler does the actual parsing.
final ServerConfigContentHandler contentHandler = new ServerConfigContentHandler(tmpProperties);
final XMLReader xmlReader = XMLReaderFactory.createXMLReader();
xmlReader.setContentHandler(contentHandler);
// Pass the config file as the input source for parsing.
final FileReader fileReader = new FileReader(serverConfigFile);
xmlReader.parse(new InputSource(fileReader));
fileReader.close();
return (properties = Collections.unmodifiableMap(tmpProperties));
}
private static File findServerConfigFile() {
if (System.getProperty("catalina.home") != null) {
final File file = new File(System.getProperty("catalina.home"), CONFIG_FILE_PATH);
if (file.isFile()) {
return file;
}
}
if (System.getProperty("catalina.base") != null) {
final File file = new File(System.getProperty("catalina.base"), CONFIG_FILE_PATH);
if (file.isFile()) {
return file;
}
}
return null;
}
/**
* ContentHandler implementation for the XML parser.
*/
private static class ServerConfigContentHandler implements ContentHandler {
private final Map<String, String> map;
private boolean inServerElement;
private boolean inCatalinaServiceElement;
private ServerConfigContentHandler(final Map<String, String> map) {
this.map = map;
}
@Override
public void startDocument() throws SAXException {
this.inServerElement = false;
this.inCatalinaServiceElement = false;
}
@Override
public void startElement(final String uri, final String localName, final String qName, final Attributes atts) throws SAXException {
if (!this.inServerElement && "Server".equals(localName)) {
this.inServerElement = true;
}
else if (this.inServerElement && "Service".equals(localName) && "Catalina".equals(atts.getValue("name"))) {
this.inCatalinaServiceElement = true;
}
else if (this.inCatalinaServiceElement && "Connector".equals(localName) && "HTTP/1.1".equals(atts.getValue("protocol"))) {
if ((atts.getValue("SSLEnabled") == null || "false".equals(atts.getValue("SSLEnabled"))) &&
(atts.getValue("secure") == null || "false".equals(atts.getValue("secure"))) &&
(atts.getValue("scheme") == null || "http".equals(atts.getValue("scheme")))) {
final String portStr = atts.getValue("port");
if (portStr != null) {
this.map.put("httpPort", portStr);
}
final String redirectPortStr = atts.getValue("redirectPort");
if (redirectPortStr != null) {
this.map.put("httpRedirectPort", redirectPortStr);
}
}
}
}
@Override
public void endElement(final String uri, final String localName, final String qName) throws SAXException {
if (this.inCatalinaServiceElement && "Service".equals(localName)) {
this.inCatalinaServiceElement = false;
}
else if (this.inServerElement && "Server".equals(localName)) {
this.inServerElement = false;
}
}
@Override
public void endDocument() throws SAXException {
this.inServerElement = false;
this.inCatalinaServiceElement = false;
}
@Override
public void characters(final char[] ch, final int start, final int length) throws SAXException { }
@Override
public void endPrefixMapping(final String prefix) throws SAXException { }
@Override
public void ignorableWhitespace(final char[] ch, final int start, final int length) throws SAXException { }
@Override
public void processingInstruction(final String target, final String data) throws SAXException { }
@Override
public void setDocumentLocator(final Locator locator) { }
@Override
public void skippedEntity(final String name) throws SAXException { }
@Override
public void startPrefixMapping(final String prefix, final String uri) throws SAXException { }
}
}
Es gibt ein ** Plattendateisystem ** basierend 'URL' an die Wurzel des öffentlichen webcontent verweist. Also nein, das tut absolut nicht was der OP will :) – BalusC
Okay. Die API-Dokumente geben nicht an, welche Art von URL zurückgegeben wird, und ich hatte keine Zeit, sie zu testen. Danke, dass du das überprüft hast. –