2010-09-18 28 views
5

Tôi có một ứng dụng web được viết bằng Tomcat 6 và tôi đang cố gắng làm cho nó hoạt động với Tomcat 7. Trong khi khởi động ứng dụng, bên cạnh những thứ khác, đăng ký thành phần dịch vụ web của nó tại một số thư mục từ xa. Đối với điều này nó cần phải cung cấp URL riêng của mình. Các (một chút ngây thơ) phương pháp sau đây sẽ trả về URL webservice:Nhận đầy đủ servlet URL khi khởi động theo 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(); 
} 

Phần ServerFactory.getServer() được bật ra được vấn đề: không có org.apache.catalina.ServerFactory lớp trong Tomcat 7. Bất kỳ đề xuất về cách viết lại này cho Tomcat 7 ? Tôi cũng sẽ rất vui khi có mã di động cụ thể hơn, không phải tomcat.

Trả lời

0

Tôi chưa bao giờ sử dụng và có thể không trả lại URL có tên máy chủ và địa chỉ, nhưng có cơ hội nào ServletContext.getResource("/") sẽ làm những gì bạn muốn không? Tôi biết nó nhằm mục đích truy cập vào một tài nguyên nội bộ bởi servlet, nhưng bạn không bao giờ biết.

+0

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

+0

Đượ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 đó. –

3

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

}

+0

Cách tiếp cận thú vị, mặc dù quá bẩn đối với mã sản xuất. +1 cho tính độc đáo. –

+0

Nó hoạt động, tuy nhiên nó liên quan đến việc sử dụng với Tomcat 7. Bổ sung, không cho trả lời này nhưng đối với bài gốc, hiệu suất .getLocalhost() rất kém trong một số hệ thống, có khả năng do tra cứu IP6 từ Java 1.4.1. Tôi tự hỏi, nếu chúng ta có thể thực hiện một yêu cầu dump để servlet chính nó sau khi khởi động để có được thông tin cần thiết thông qua HttpRequest. – lent

Các vấn đề liên quan