getRealPath между Tomcat6 и Tomcat8

#java #tomcat8 #tomcat6

#java #tomcat8 #tomcat6

Вопрос:

В моем веб-приложении у меня есть следующий код:

     if( context == null )
        throw new WMSException( "Missing session context." );

    String path  = context.getRealPath("");
    if( path == null )
        throw new WMSException( "Missing context real path." );

    WebSocket ws    = new WebSocket();
    String    sep   = "/";
    int       where = path.lastIndexOf( sep );
    if( where < 0 ){
        sep   = "\";
        where = path.lastIndexOf( sep );
    }

    path  = path.substring( 0, where );
    where = path.lastIndexOf( sep );
    path  = path.substring( 0, where )   "/conf/wms";
    if( firstTime ){
        firstTime = false;
        System.out.println( "Getting configuration from "   path );
    }

    File      docFile = new File(path, "socket.xml");
    System.out.println( "Name "   docFile.getName() );
    System.out.println( "Path "   docFile.getPath() );
  

В tomcat 6 из-за того, как работает getRealPath, я получаю следующее:

 /usr/share/tomcat6/conf/wms/socket.xml
  

В tomcat 8 я получаю следующее для того же файла war:

 /opt/tomcat8/webapps/conf/wms/socket.xml
  

В чем разница в том, как работает getRealPath и как мне это исправить?

Комментарии:

1. Предполагается, что getRealPath возвращает путь к чему-либо в вашем веб-приложении. Версия Tomcat6 этого не делала, она возвращала путь к чему-либо в вашей установке Tomcat. Итак, они исправили ошибку в Tomcat 8.

2. getRealPath предназначен для получения пути к файлу внутри файла war, то есть к промежуточной области, откуда Tomcat извлек файл. Это полностью недокументированное местоположение, и вы никогда не должны использовать этот путь для доступа к файлам за пределами содержимого файла war. Вам нужно исправить свой код, чтобы с помощью других средств можно было указать, где искать внешние файлы.

3. Тогда что мне вызвать вместо getRealPath, который выполняет то же самое, что Tomcat6 делал с getRealPath?

Ответ №1:

Хорошо, проблема была решена, отметив, что Tomcat6 не поставил «/» в конце, но Tomcat8 это делает. Итак, мой новый код исправляет это: LOGGER.info ( «Получить сокет для клиента: » client );

     if( context == null )
        throw new WMSException( "Missing session context." );

    String path  = context.getRealPath("");
    if( path == null )
        throw new WMSException( "Missing context real path." );

    LOGGER.info( "Path 1 '"   path   "'");

    WebSocket ws    = new WebSocket();
    String    sep   = "/";
    int       where = path.lastIndexOf( sep );
    if( where < 0 ){
        sep   = "\";
        where = path.lastIndexOf( sep );
    }

    String newPath  = path.substring( 0, where );
    if( newPath.equals(path.substring(0, path.length() - 1 )))
    {
        where = newPath.lastIndexOf( sep );
        path  = newPath.substring( 0, where );
        LOGGER.info( "Path 2a '"   path   "'");
    }
    else
        path = newPath;

    LOGGER.info( "Path 2 '"   path   "'");
    where = path.lastIndexOf( sep );
    path  = path.substring( 0, where )   "/conf/wms";
    LOGGER.info( "Path 3 '"   path   "'");
    if( firstTime ){
        firstTime = false;
        LOGGER.info( "Getting configuration from "   path );
    }

    LOGGER.info( "Path 4 '"   path   "'");
    File      docFile = new File(path, "socket.xml");
    LOGGER.info( "Name '"   docFile.getName()   "';Path '"   docFile.getPath()   "'");
  

Ключом был if( newPath.equals(path.substring(0, path.length() - 1 ))) раздел if. Очевидно, что это можно было бы решить другими способами. Кроме того, эта проблема подразумевается во многих местах в Интернете, я просто пропустил соединение в отношении «/» в конце пути, поэтому оно не смогло правильно отобразить дерево каталогов.

Не было простого способа получить домашний каталог tomcat (где у нас есть каталог «conf»), поэтому мы сделали это вот так. Не желая ничего менять, просто добавил этот раздел кода, чтобы заставить его работать.

Есть другие способы решения этой проблемы, которые я видел онлайн.