Tôi gặp phải vấn đề tương tự: Tôi cần biết số cổng để tạo URL cho một cá thể Tomcat cụ thể, số cổng có thể khác nhau (vì tôi chạy nhiều phiên bản để thử nghiệm) và Tomcat 7 ServerFactory đã mất xa.
Tôi đã viết mã sau đây để tìm và phân tích cú pháp tệp tin server.xml Tomcat. Nó không phân tích cú pháp nhiều, chỉ nhận các giá trị HTTP "port" và "redirectPort". Nó phụ thuộc vào thuộc tính hệ thống "catalina.home" hoặc "catalina.base", sẽ tồn tại trong bất kỳ cá thể Tomcat đang chạy nào. Vẻ đẹp là nó không phụ thuộc vào bất kỳ lớp Tomcat nào và sử dụng trình phân tích cú pháp XML của JVM.
Tôi hy vọng điều này sẽ hữu ích.
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 { }
}
}
Nó trả về một hệ thống tập tin trên đĩa ** ** dựa 'URL' trỏ đến thư mục gốc của WebContent công cộng. Vì vậy, không, điều này hoàn toàn không làm những gì OP muốn :) – BalusC
Được rồi. Tài liệu API không chỉ định loại URL mà nó trả về và tôi không có thời gian để kiểm tra. Cảm ơn bạn đã kiểm tra điều đó. –