В приложении Spring MVC Hibernate, когда я пытаюсь использовать файл свойств, который находится в src/java/resources, он выдает следующую ошибку:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'userController': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private java.lang.String com.mcb.controller.UserController.strDefaultPage; nested exception is java.lang.IllegalArgumentException: Could not resolve placeholder 'mcbPage.name'
Я использую приведенный ниже код для доступа к значению свойства в моем классе контроллера:
@Value("${mcbPage.name}")
private String strDefaultPage;
Я добавил bean-компонент в свой файл ApplicationContext.xml для этого файла свойств:
<bean id="mcbProperties"
class="org.springframework.beans.factory.config.PropertiesFactoryBean">
<property name="ignoreResourceNotFound" value="true" />
<property name="locations">
<list>
<value>classpath*:mcb.properties</value>
<value>file:src/main/resources/mcb.properties</value>
</list>
</property>
</bean>
<bean id="propertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE" />
<property name="ignoreUnresolvablePlaceholders" value="true" />
<property name="properties" ref="mcbProperties" />
</bean>
и мой файл свойств (mcb.properties
) находится в папке src/main/resources. @Autowired
работает нормально. но при попытке использовать файл свойств выдает ошибку при запуске сервера.
Может ли кто-нибудь помочь мне в решении этого?
package com.javarush.test.level20.lesson02.task03;
/* Знакомство с properties
В методе fillInPropertiesMap считайте имя файла с консоли и заполните карту properties данными из файла.
Про .properties почитать тут — http://ru.wikipedia.org/wiki/.properties
Реализуйте логику записи в файл и чтения из файла для карты properties.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.javarush.test.level20.lesson02.task03; | |
import java.io.*; | |
import java.util.HashMap; | |
import java.util.Map; | |
import java.util.Properties; | |
/* Знакомство с properties | |
В методе fillInPropertiesMap считайте имя файла с консоли и заполните карту properties данными из файла. | |
Про .properties почитать тут — http://ru.wikipedia.org/wiki/.properties | |
Реализуйте логику записи в файл и чтения из файла для карты properties. | |
*/ | |
public class Solution { | |
public static Map<String, String> properties = new HashMap<>(); | |
public void fillInPropertiesMap() | |
{ | |
try | |
{ | |
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); | |
load(new FileInputStream(reader.readLine())); | |
} | |
catch (Exception E){E.printStackTrace();} | |
} | |
public void save(OutputStream outputStream) throws Exception | |
{ | |
Properties prop = new Properties(); | |
try | |
{ | |
for (Map.Entry<String,String> map : properties.entrySet()) | |
{ | |
prop.put(map.getKey(),map.getValue()); | |
} | |
prop.store(outputStream, null); | |
outputStream.close(); | |
}catch (IOException io) | |
{ | |
io.printStackTrace(); | |
} | |
} | |
public void load(InputStream inputStream) throws Exception | |
{ | |
Properties prop = new Properties(); | |
try | |
{ | |
prop.load(inputStream); | |
for (String x : prop.stringPropertyNames()) | |
properties.put(x, prop.getProperty(x)); | |
}catch (Exception e){e.printStackTrace();} | |
} | |
} |
Property файлы присутствуют практически в каждом проекте, и сейчас я вам покажу простой пример их использования, а также расскажу, зачем они и где используются.
Шаг 0. Создание проекта
Начнем с того что создадим простой Maven проект, указав название и имя пакета:
Структура, которая получится в конце проекта довольно таки простая.
Как видите у нас только два файла, первый – Main.java, а второй – config.properties.
Шаг 2. Добавляем конфигурационные данные в проперти файл
Проперти файлы либо файлы свойств – предназначены, для того чтобы хранить в них какие-то статические данные необходимые проект, например логин и пароль к БД.
Давайте добавим в наш config.properties логин и пароль (это любые данные, для того чтобы продемонстрировать работу с property файлами).
Содержимое config.properties:
db.host = http://localhost:8888/mydb db.login = root db.password = dbroot
Как видите, данные представлены в виде {ключ} = {значение}, где
{ключ} – это уникальное имя, по которому можно получить доступ к значению, хранимому под этим ключом.
{значение} – это текст, либо число, которое вам необходимо для выполнения определённой логики в вашей программе.
Шаг 3. Получаем Property данные
Как можно видеть в структуре проекта выше, там есть класс Main.java давайте его создадим и напишем в нем следующее:
package com.devcolibir.prop; import java.io.*; import java.util.Properties; public class Main { public static void main(String[] args) { FileInputStream fis; Properties property = new Properties(); try { fis = new FileInputStream("src/main/resources/config.properties"); property.load(fis); String host = property.getProperty("db.host"); String login = property.getProperty("db.login"); String password = property.getProperty("db.password"); System.out.println("HOST: " + host + ", LOGIN: " + login + ", PASSWORD: " + password); } catch (IOException e) { System.err.println("ОШИБКА: Файл свойств отсуствует!"); } } }
Обращаясь к property.getProperty({ключ}) – вы получаете его значение.
Вот такой краткий, но думаю познавательный урок.
- None Found
Вы достигли нового уровня
— Привет, Амиго! Сегодня мы познакомимся с еще одной интересной темой. А именно: сохранением и загрузкой (восстановлением) объектов. Допустим у нас есть класс Cat:
Код |
---|
class Cat { public String name; public int age; public int weight; } |
И мы хотим добавить в него удобный механизм сохранения в файл и загрузки из файла.
Вот как это можно сделать:
Код |
---|
class Cat { public String name; public int age; public int weight; public void save(OutputStream outputStream) throws Exception public void load(InputStream inputStream) throws Exception |
— О! Это же очень просто. Мы просто печатаем значения всех аргументов, по одному в каждой строчке. А при загрузке читаем их в том же порядке. Отличное решение.
— Спасибо, Амиго. А можешь написать, как будут выглядеть методы save и load у такой группы классов:
Код |
---|
class Cat { public String name; public int age; public int weight; } class Dog { public String name; public int age; } class Human { public Cat cat; public Dog dog; } |
У тебя есть объект человек, и он может иметь одну собаку и одного кота.
— У меня есть решение:
Код |
---|
class Cat { public String name; public int age; public int weight; public void save(OutputStream outputStream) throws Exception public void load(InputStream inputStream) throws Exception |
class Dog { public String name; public int age; public void save(OutputStream outputStream) throws Exception public void load(InputStream inputStream) throws Exception |
class Human { public Cat cat; public Dog dog; public void save(OutputStream outputStream) throws Exception public void load(InputStream inputStream) throws Exception |
— Очень хорошее решение. Но что будет, если у человека нет кота, а есть только собака?
Где проверки на null?
— Сейчас исправлю:
Код |
---|
class Human { public Cat cat; public Dog dog; public void save(OutputStream outputStream) throws Exception public void load(InputStream inputStream) throws Exception |
— Все равно не очень верно. У тебя две ошибки:
1) Если у человека нет ни кота, ни собаки, они все равно будут созданы, при вызове метода load
2) Если мы сохраним только собаку, то ее данные будут прочитаны котом при загрузке.
— А что же делать?
— Мы не можем пропускать запись переменных, иначе это вызовет сбой при чтении. Но нужно сделать так, чтобы переменные, чье значение было null при сохранении и после загрузки, получали null. Вот мой вариант:
Код |
---|
class Human { public Cat cat; public Dog dog; public void save(OutputStream outputStream) throws Exception String isCatPresent = cat != null ? «yes» : «no»; if (cat!=null) String isDogPresent = dog != null ? «yes» : «no»; if (dog != null) public void load(InputStream inputStream) throws Exception String isCatPresent = reader.readLine(); String isDogPresent = reader.readLine(); |
— Да, мне нравится такое решение.
— Да, что-то в нем есть.
— Привет, Амиго!
Задачи |
---|
1. Читаем и пишем в файл: Human
Реализуйте логику записи в файл и чтения из файла для класса Human |
2. Читаем и пишем в файл: JavaRush
Реализуйте логику записи в файл и чтения из файла для класса JavaRush |
3. Знакомство с properties
В методе fillInPropertiesMap считайте имя файла с консоли и заполните карту properties данными из файла. |
4. Читаем и пишем в файл статики
Реализуйте логику записи в файл и чтения из файла для класса ClassWithStatic |
5. И еще раз о синхронизации
Разберитесь почему не работает метод main() |
— Помнишь, мы сегодня разбирали сохранение объектов в файл и чтение из файла?
— Да, только мы сохраняли в поток вывода, а читали из потока ввода.
— Молодец, Амиго. Приятно слышать, что ты замечаешь такие мелочи. А ты бы смог дописать код, чтобы было сохранение в файл и чтение из файла?
— А что там писать?! Объявил FileInputStream и FileOutputStream и передавай их в методы save & load. Тут уже ничего не перепутаешь — все просто.
— Рада за тебя. Итак, новая тема – сериализация.
Сериализация – это практически то же самое, что мы с тобой только что делали, только гораздо круче и встроено прямо в Java-машину. Java-машина умеет сохранять и загружать свои объекты. Для этого ей даже не требуются методы save & load: все объекты хранятся внутри Java-машины, и она имеет к ним полный доступ.
Мы просто берем объект и сохраняем его в поток/читаем из потока:
Код |
---|
public static void main(String[] args) throws Exception { Cat cat = new Cat(); //save cat to file //load cat from file Cat newCat = (Cat)object; |
— И все?
— Да. Там очень большой и сложный механизм сериализации, который поддерживает сохранение в поток и чтение из потока почти всех типов данных.
— Почти всех, это значит не всех?
— Да, дело в том, что не все объекты по своей сути можно сохранить. Некоторые объекты не хранят все свои данные в себе, а лишь ссылаются на другие объекты и/или источники данных. Например, консоль (System.in), поток ввода (InputStream), или что-нибудь еще.
Поэтому разработчики Java придумали специальный интерфейс-маркер – Serializable. Его называют маркером, т.к. он не содержит никаких данных и методов. Он используется только для того, чтобы «помечать» (маркировать) классы. Если мы считаем, что наш класс хранит в себе все свои данные, тогда мы можем пометить его этим маркером – написать implements Serializable.
Пример «кота» с поддержкой сериализации:
Код |
---|
class Cat implements Serializable { public String name; public int age; public int weight; } |
Когда мы пытаемся сериализовать (сохранить) какой-нибудь объект, Java-машина проверяет – поддерживает ли он сериализацию: реализует ли он интерфейс Serializable? Если да, то сохраняет объект, если нет – выкидывает исключение о невозможности сериализации.
Тут нужно понимать, что сериализуемый объект должен состоять тоже только из сериализуемых объектов.
— Ну, этого и следовало ожидать. Нельзя же сохранить целое, не сохранив какие-то его части.
— Именно так.
— А как же типы int, String, ArrayList?
— Они все поддерживают сериализацию, на этот счет разработчики Java специально позаботились. Тут проблем быть не должно.
Более того, при сериализации объекта сохраняется его тип. Теперь ты можешь в переменную класса с типом Object сохранить ссылку на объект Cat, и все это отлично сериализуется и десериализуется.
— Десериализуется?
— Десериализация – так называют процесс, обратный сериализации – чтение и восстановление объекта из потока/файла.
— Тогда вопросов больше нет.
— Привет, Амиго!
Задачи |
---|
1. Как сериализовать?
Сделайте так, чтобы сериализация класса Human была возможной |
2. Как сериализовать JavaRush?
Сделайте так, чтобы сериализация класса JavaRush была возможной |
3. Как сериализовать Singleton?
Два десериализованных объекта singleton и singleton1 имеют разные ссылки в памяти, а должны иметь одинаковые. |
4. Как сериализовать static?
Сделайте так, чтобы сериализация класса ClassWithStatic была возможной |
5. Как сериализовать что-то свое?
Сделайте так, чтобы сериализация класса Object была возможной |
— Привет, Амиго! Хотела тебе порассказывать одно маленькое дополнение к сериализации.
Допустим наш класс содержит ссылку на какой-нибудь InputStream, тогда его нельзя сериализовать, ведь так?
— Да. Ты же сама говорила, что потоки сериализовать нельзя. А сериализовать объект, у которого есть несериализуемые данные – тоже нельзя.
— Да. Именно так. Но что, если класс хранит данные, которые не играют значащей роли в его состоянии, но мешают считаться ему сериализуемым классом? Мало ли что класс может у себя хранить ненужного. Возможно, он может выбросить эти данные в любой момент или даже так и делает постоянно.
Для таких случаев разработчики Java придумали специальное слово – transient. Его можно написать перед переменной класса и она будет не учитываться при сериализации. Ее состояние не будет ни сохраняться, ни восстанавливаться. Как будто и нет ее вовсе. Как раз для таких ситуаций, как мы только что рассмотрели.
Помнишь кеширование и модификатор volatile? Нет правил без исключений.
Вот тебе один примерчик такого счастья:
Пример «кота» с невидимой для сериализации переменной — in:
Код |
---|
class Cat implements Serializable { public String name; public int age; public int weight; transient public InputStream in = System.in; |
— Привет, Амиго! Хотел бы немного дополнить то, что рассказала тебе Элли.
Иногда бывает нужно управлять процессом сериализации. Вот одни из причин:
1) Объект не готов к сериализации: его нынешнее внутреннее состояние в процессе изменения.
2) Объект содержит несериализуемые объекты, но может перевести их в удобную для сериализации форму: сохранить в массив байт или что-нибудь еще.
3) Объект хочет десериализовать все свои данные, как одно целое и/или зашифровать их перед сериализацией.
Причин выполнить сериализацию в ручном режиме может быть множество. Но не хотелось бы лишаться всех тех преимуществ, которые дает стандартная сериализация. Ведь наш объект могут использовать другие объекты. И они тоже не смогут сериализоваться, если наш объект откажется от поддержки сериализации.
На этот случай тоже есть решение – интерфейс Externalizable. Спасибо дальновидным разработчикам Java. Достаточно заменить интерфейс Serializable на интерфейс Externalizable, и ваш класс сможет управлять процессом сериализации в ручном режиме.
Дело в том, что интерфейс Externalizable, в отличие от Serializable, содержит два метода, которые вызываются Java-машиной при сериализации объекта. Вот как это выглядит:
Код |
---|
class Cat implements Externalizable { public String name; public int age; public int weight; public void writeExternal(ObjectOutput out) public void readExternal(ObjectInput in) |
Ничего не напоминает?
— Ух ты! Именно так мы пробовали сохранять объекты до «изобретения» сериализации.
— Да, теперь все просто: если устраивает стандартная сериализация – просто наследуем наш класс от интерфейса Serializable. Если не устраивает – наследуем от Externalizable и пишем код для сохранения/загрузки объекта нашего класса.
— А класс, помеченный Externalizable, считается сериализуемым? Мы можем «безопасно» хранить на него ссылки в наших сериализуемых классах?
— Да. Если класс реализует интерфейс Serializable или Externalizable, он считается сериализуемым.
— Отличное решение. Мне нравится.
— Рад это слышать. Но это еще не всё… Спроси лучше профессора Ханса о всяких нюансах. Они тут точно есть. Он хотел тебе дать что-то почитать.
— Привет, Амиго!
Задачи |
---|
1. Externalizable для апартаментов
Реализуйте интерфейс Externalizable для класса Apartment |
2. OutputToConsole
Класс OutputToConsole должен сериализоваться с помощью интерфейса Externalizable. |
3. Externalizable Person
Класс Person должен сериализоваться с помощью интерфейса Externalizable. |
4. Serializable Solution
Сериализуйте класс Solution. |
5. Переопределение сериализации
Сделайте так, чтобы после десериализации нить runner продолжила работать. Hint/Подсказка: Конструктор не вызывается при сериализации, только инициализируются все поля. |
— А если ты хочешь расширить или углубить свои знания по сериализации. Или, не дай бог, что-нибудь не понял, то для тебя у меня есть замечательные лекции.
Ссылка на сериализацию
— Привет, Амиго! Устал? Ничего, тяжело в учении – легко в бою. Давай посмотрим хорошее видео.
Оригинал видео на YouTube
— Привет, Амиго! Что-то ты расслабился! Вот твои задания. Если вдруг возникнут трудности, то обращайся к коллегам, они точно помогут.
Дополнительные задания для выполнения в Intellij Idea |
---|
1. Минимум изменений
Используя минимум изменений кода сделайте так, чтобы сериализация класса C стала возможной. |
2. Десериализация
На вход подается поток, в который записан сериализованный объект класса A либо класса B. |
3. Найти ошибки
Почему-то при сериализации/десериализации объекта класса B возникают ошибки. |
4. Исправить ошибку
После десериализации объекта класса Solution обнаружили, что данных в словаре [m] нет 🙁 |
5. Сериализуйте Person
Сериализуйте класс Person стандартным способом. |
6. Запрет сериализации
Запретите сериализацию класса SubSolution используя NotSerializableException. |
7. Переопределение сериализации в потоке
Сериализация/десериализация Solution не работает. |
8. Правильный вывод
Расставить обращение к методам суперкласса и модификаторы доступа так, чтобы вывод на экран был следующим: C class, method2 Количество изменений модификаторов доступа и вызовов методов должно быть минимально |
9. Знакомство с графами
Прочитать в дополнительных материалах о сериализации графов. |
— Ты уже всё сделал? Вот тебе ещё и бонусные задания повышенной сложности:
1. Алгоритмы-числаЗадача: Число S состоит из M чисел, например, S=370 и M(количество цифр)=3 Реализовать логику метода getNumbers, который должен среди натуральных чисел меньше N (long) находить все числа, удовлетворяющие следующему критерию: число S равно сумме его цифр, возведенных в M степень getNumbers должен возвращать все такие числа в порядке возрастания Пример искомого числа: На выполнение дается 10 секунд и 50 МБ памяти. |
2. Алгоритмы-прямоугольникиЗадача: 1. Дан двумерный массив N*N, который содержит несколько прямоугольников. 2. Различные прямоугольники не соприкасаются и не накладываются. 3. Внутри прямоугольник весь заполнен 1. 4. В массиве: 4.1) a[i, j] = 1, если элемент (i, j) принадлежит какому-либо прямоугольнику 4.2) a[i, j] = 0, в противном случае 5. getRectangleCount должен возвращать количество прямоугольников. 6. Метод main не участвует в тестировании |
3. КроссвордЗадача: 1. Дан двумерный массив, который содержит буквы английского алфавита в нижнем регистре. 2. Метод detectAllWords должен найти все слова из words в массиве crossword. 3. Элемент(startX, startY) должен соответствовать первой букве слова, элемент(endX, endY) — последней. text — это само слово, располагается между начальным и конечным элементами 4. Все слова есть в массиве. 5. Слова могут быть расположены горизонтально, вертикально и по диагонали как в нормальном, так и в обратном порядке. 6. Метод main не участвует в тестировании |
4. Свой списокЗадача: Посмотреть, как реализован LinkedList. Элементы следуют так: 1->2->3->4 и так 4->3->2->1 По образу и подобию создать Solution. Элементы должны следовать так: 1->3->7->15 ->8... ->4->9 ->10 2->5->11 ->12 ->6->13 ->14 Во внутренней реализации элементы должны добавляться по 2 на каждый уровень |
alexjava 0 / 0 / 0 Регистрация: 01.06.2017 Сообщений: 3 |
||||||||
1 |
||||||||
01.06.2017, 09:09. Показов 4748. Ответов 2 Метки нет (Все метки)
Здравствуйте. Я новичок в java и мне нужна помощь. Настройки приложения лежат у меня в src/main/resources/application.properties. Через IDE программа тестируется и все работает как надо.
Когда запуская программу через командную строку с параметрами в log вылезает ошибка Код где я читаю настройки:
__________________
0 |
6044 / 2159 / 753 Регистрация: 10.12.2010 Сообщений: 6,007 Записей в блоге: 3 |
|
01.06.2017, 16:12 |
2 |
Попробуйте подать
0 |
we2seek 84 / 84 / 42 Регистрация: 25.01.2010 Сообщений: 386 |
||||||||||||
01.06.2017, 23:09 |
3 |
|||||||||||
Вот только что попробовал — все работает.
application.properties: Код welcome.message=Hello, cyberforum! pom.xml (<build> из вашего файла): Кликните здесь для просмотра всего текста
Структура проекта Код src/main/ ├── java │** └── com │** └── we2seek │** └── demo │** └── App.java └── resources └── application.properties
Добавлено через 13 минут
1 |
- Р Р‡.МессенРТвЂВВВВВВВВжер
- ВКонтакте
- РћРТвЂВВВВВВВВнокласснРСвЂВВВВВВВВРєРСвЂВВВВВВВВ
- Telegram
- Viber
- РњРѕР№ Р В Р’В Р РЋРЎв„ўР В Р’В Р РЋРІР‚ВВВВВВВВРЎР‚