2010-09-18 16 views
5

Mam aplikację napisaną przy użyciu Tomcat 6 i staram się, aby działała z Tomcat 7. Podczas uruchamiania aplikacja, oprócz innych rzeczy, rejestruje swój składnik usługi sieciowej pod adresem jakiś zdalny katalog. W tym celu musi podać własny adres URL. Poniższy (trochę naiwny) metoda powinna powrócić webservices URL:Uzyskaj pełny adres URL serwletu podczas uruchamiania pod Tomcat 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() część okazała się problematyczna: nie ma org.apache.catalina.ServerFactory klasa w Tomcat 7. Wszelkie sugestie, w jaki sposób przepisać to dla Tomcat 7 ? Byłbym również szczęśliwy mając więcej przenośnego kodu, nie będącego tomcatcat.

Odpowiedz

0

Nigdy go nie używałem i prawdopodobnie nie zwraca adresu URL z nazwą hosta i adresem, ale czy jest jakaś szansa, że ​​ServletContext.getResource("/") zrobi to, co chcesz? Wiem, że jest przeznaczony do wewnętrznego dostępu do zasobu przez serwlet, ale nigdy nie wiadomo.

+0

Zwraca ** system plików dysku ** oparty 'URL' wskazując korzenia WebContent publicznego. Więc nie, to absolutnie nie robi tego, co chce OP :) – BalusC

+0

Okay. Dokumenty API nie określają, jaki rodzaj adresu URL zwraca, a ja nie miałem czasu go przetestować. Dzięki za sprawdzenie. –

3

Miałem ten sam problem: musiałem znać numer portu, aby utworzyć adres URL dla konkretnej instancji Tomcat, numer portu może się różnić (ponieważ uruchamiam wiele instancji do testowania), a od Tomcat 7 ServerFactory zniknął z dala.

Napisałem poniższy kod, aby znaleźć i przeanalizować plik serwera server.xml Tomcat. Nie parsuje dużo, tylko pobiera wartości HTTP "port" i "redirectPort". Zależy to od właściwości systemowych "catalina.home" lub "catalina.base", które powinny istnieć w każdej działającej instancji Tomcat. Piękno polega na tym, że nie jest zależne od żadnych klas Tomcat i używa parsera XML JVM.

Mam nadzieję, że to pomoże.

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

Interesujące podejście, choć zbyt brudne dla kodu produkcyjnego. +1 za oryginalność. –

+0

Działa, jednak wiąże użycie z Tomcat 7. Dodatkowo, nie dla tej odpowiedzi, ale dla oryginalnego postu, .getLocalhost() wydajność jest bardzo słaba w niektórych systemach, prawdopodobnie z powodu wyszukiwania IP6 z Java 1.4.1. Zastanawiam się, czy moglibyśmy wysłać żądanie zrzutowania do serwletu po uruchomieniu, aby uzyskać potrzebne informacje za pośrednictwem HttpRequest. – lent

Powiązane problemy