2015-01-07 3 views
0

У меня есть файл свойств, который, как это -Как безопасно прочитать файл свойств в Java?

[email protected] 
[email protected] 

# can be separated by comma 
whichServer=UserServer,GuestServer 

maxTestInSec=120 
numberOfUsers=1000 

Сейчас я читаю это свойство файла, как это в Java, который работает, если все настроено правильно -

private static final Properties prop = new Properties(); 

private static String emailFrom; 
private static String emailTo; 
private static List<String> whichServer; 
private static String maxTestInSec; 
private static String numberOfUsers; 

public static void main(String[] args) { 
    readConfig(args); 
} 

private void readConfig(String[] args) throws FileNotFoundException, IOException { 
    if (!TestUtils.isEmpty(args) && args.length != 0) { 
     prop.load(new FileInputStream(args[0])); 
    } else { 
     prop.load(TestTask.class.getClassLoader().getResourceAsStream("config.properties")); 
    } 

    emailFrom = prop.getProperty("emailFrom").trim(); 
    emailTo = prop.getProperty("emailTo").trim(); 
    whichServer = Arrays.asList(prop.getProperty("whichServer").trim().split(",")); 
    maxTestInSec = prop.getProperty("maxTestInSec").trim(); 
    numberOfUsers = prop.getProperty("numberOfUsers").trim(); 
} 

Постановка задачи: -

Мне нужно убедиться, что если какое-либо значение свойства отсутствует, то я хочу использовать значение по умолчанию для этого, и если по какой-либо причине это свойство закомментировано, Я хочу использовать значение по умолчанию, но я бы записал предупреждающее сообщение о том, что свойство отсутствует или пустое, поэтому используйте значения по умолчанию. Я пытаюсь охватить все случаи угла для чтения файла -

  • Теперь, скажем, если я не уточняя значение любого из моего имущества в указанном файле, то я хочу, чтобы использовать значения по умолчанию для свойства который я не предоставил и не зарегистрировал в качестве предупреждения, указав, что для этого свойства не были указаны значения, поэтому используйте значения по умолчанию. Например: допустим, если я не дал никакого значения для поля emailFrom, тогда я хотел бы использовать значение по умолчанию как [email protected] для этого и аналогичного для других. Значения по умолчанию для всего имущества будет:

[email protected]

[email protected]

whichServer = UserServer

maxTestInSec = 30

NUMBEROFUSERS = 500

  • Кроме того, если какое-либо свойство закомментировано, то приведенный выше код будет проходить через исключение NPE. Как я могу использовать значения по умолчанию в этом сценарии?

Должен ли я использовать синтаксический анализатор командной строки для этого? Каков наилучший и чистый способ обработки этих продуктов?

Я не хочу иметь много блоков if, чтобы добавить чек, а затем установить значения по умолчанию.

ответ

0

В случае, если свойство закомментировано, возврат будет пустым, поэтому просто выполните нулевую проверку.

if (prop.getProperty("name")==null) 

В случае, если значение не заполнено, проверьте, равно ли оно равным пустому пространству после операции отделки.

if (prop.getProperty("name").trim().equals("")) 
+0

Спасибо за предложение. При таком подходе, если у меня есть 20 свойств в моем файле конфигурации, значит, мне нужно иметь 40 блоков if? Есть ли другой чистый способ сделать это? – john

+0

вы можете получить все имена свойств, используя перечисление, как показано ниже. Enumeration en = prop.propertyNames(); while (ru.hasMoreElements()) { System.out.println (ru.nextElement()); } и убедитесь, что все ваши объекты присутствуют. – robin

0

Вы можете попробовать обналичить свойства в статической карте и обработать на этой карте до ее фактического использования.

private Map<String, String> rawProps = new HashMap<String, String>; 
public static Map<String, String> actualProps = new HashMap<String, String>; 

static { 
    checkMapForNullAndReport(); 
} 

private static void checkMapForNullAndReport() { 
    // Null logic and Reporting logic 
    // Empty rawProps and populate the actualProps 
} 

Что-то вроде этого будет работать для вас, я верю.

1

С точки зрения Java 8 проще всего использовать getOrDefault(), который позволяет указать значение по умолчанию на сайте get-site. Например:

String email = properties.getOrDefault("emailFrom", "[email protected]"); 

Это чистое и краткое описание, но это означает, что вам необходимо указать значение по умолчанию во всем мире, доступ к которому вы хотите.

Если это не будет работать для вас (то есть вы будете читать значения из свойств объекта более одного раза), вы можете использовать встроенную поддержку для значений по умолчанию -notice в constructor, который принимает defaultProperties объекта. Это позволяет создать объект Properties, содержащий ваши значения по умолчанию, а затем, когда вы загружаете файл свойств пользователя, он будет отбрасываться по умолчанию, если пользователь не укажет значение.

private static final Properties DEFAULTS = new Properties(); 
static { 
    DEFAULTS.setProperty("emailFrom", "[email protected]"); 
} 

public Properties getProperties() { 
    Properties props = new Properties(DEFAULTS); 
    props.load(...); 
    return props; 
} 

Просто обратите внимание, что это не идентично тому, как работает Map «s конструктор - по умолчанию остаются в виде отдельной карты, и только .getProperty() также запрашивает значения по умолчанию; методы, определенные в Map, как .get(), нет. Одна из многих причин, это было ужасное решение для Properties продлить Hashtable, но се ля ви ...


Эти опции работают, но они оба подвержены ошибкам, так как а) Properties изменчиво и б) только некоторые из его общедоступных методов возвращают экземпляр default. Я предпочитаю никогда не подвергать объектам Properties напрямую, а вместо этого создавать класс-оболочку с помощью методов типа-типа, которые отображают значения, которые будут учитывать мои приложения. Это немного больше печатается, но с ним гораздо безопаснее работать. Это будет выглядеть примерно так:

public class ApplicationSettings { 
    private final Properties properties = new Properties(); 
    public ApplicationSettings() { 
    properties.load(...); 
    } 

    public String emailFrom() { 
    // simple methods are concise, and encode the default right inline 
    return properties.getOrDefault("emailFrom", "[email protected]"); 
    } 

    public int getMaxTestSeconds() { 
    // You can do more complex validation if you want, too 
    String value = properties.get("maxTestInSec"); 
    if (value == null) { 
     return 30; 
    } 
    int maxTestSeconds = Integer.parseInt(value); 
    if (maxTestSeconds <= 0) { 
     // could instead log a warning and return the default if you want 
     throw new IllegalStateException(
      "maxTestInSec must be positive - was " + maxTestSeconds); 
    } 
    return maxTestSeconds; 
    } 
} 

Если вам нужно, чтобы вы также можете выставить сеттеры, что аналогичным образом проверьте значения, прежде чем добавить их к Properties объекта, хотя по умолчанию делает все только для чтения, как правило, является хорошей практикой.

Смежные вопросы