2010-09-18 48 views
5

我使用Tomcat 6編寫的Web應用程序,我想使它和Tomcat 7的工作在其應用程序啓動時,除其他事項外,在註冊其Web服務組件一些遠程目錄。爲此,它需要提供自己的URL。下面的(有點幼稚)方法應該返回webservice的網址:獲取的Tomcat在全服務器URL 7

import org.apache.catalina.ServerFactory; 
import org.apache.catalina.connector.Connector; 
. 
. 
. 
private String getWsUrl(ServletContext context) 
      throws UnknownHostException, MalformedURLException { 
    String host = java.net.InetAddress.getLocalHost().getCanonicalHostName(); 
    int port = -1; 
    for (Connector c : ServerFactory.getServer().findServices()[0].findConnectors()) { 
     if (c.getProtocol().contains("HTTP")) { 
      port = c.getPort(); 
      break; 
     } 
    } 
    URL wsURL = new URL("http", host, port, context.getContextPath() 
       + C.WEB_SERVICE_PATH /* this is just a constant string */); 
    return wsURL.toString(); 
} 

ServerFactory.getServer()部分被證明是有問題的:沒有org.apache.catalina.ServerFactory類的Tomcat 7.如何重寫此爲Tomcat 7的任何建議?我也很樂意擁有更多可移植的,非tomcat特定的代碼。

回答

0

我從來沒有使用過它,它可能不返回與主機名和地址的URL,但是否有任何機會ServletContext.getResource("/")會做你想要什麼?我知道它的目的是通過servlet在內部訪問資源,但你永遠不知道。

+0

它返回一個**磁盤文件系統**基於'URL'指向公共web內容的根。所以不,這絕對不會做OP的要求:) – BalusC 2010-09-19 22:44:12

+0

好吧。 API文檔沒有指定它返回的URL的類型,我沒有時間去測試它。感謝您檢查。 – 2010-09-19 23:05:11

3

我面臨同樣的問題:我需要知道爲特定的Tomcat實例構建URL的端口號,端口號可能會有所不同(因爲我運行多個實例進行測試),並且從Tomcat 7開始ServerFactory已經不存在遠。

我寫了下面的代碼,以查找和分析Tomcat的server.xml文件。它不會解析太多,只需獲取HTTP「端口」和「重定向端口」值即可。它取決於「catalina.home」或「catalina.base」系統屬性,它應該存在於任何正在運行的Tomcat實例中。它的優點在於它不依賴任何Tomcat類,並使用JVM的XML解析器。

我希望這會有所幫助。

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 { } 
} 

}

+0

有趣的方法,雖然對於生產代碼來說太髒了。 +1原創。 – 2011-09-10 17:39:22

+0

它的工作原理,但它關係用法和Tomcat 7的附加,而不是對這個答覆,但對原來的職位,該.getLocalhost()性能在某些系統很差,可能是由於從Java 1.4.1查找IP6。我想知道我們是否可以在啓動後向servlet發出轉儲請求,以通過HttpRequest獲取必要的信息。 – lent 2014-03-07 03:33:44