Ответы пользователя по тегу Java
  • Можно ли проект Spring запустить на удаленном сервере?

    @azerphoenix
    Здравствуйте!
    Если кратко, то да, можно))))
    А если подробно, то читайте дальше:
    1) приложение Spring можно запустить на Томкат и т.д. Соответственно, нужен VPS, установите tomcat. А дальше соберите war проект и залейте на сервер.
    https://docs.spring.io/spring-boot/docs/current/re...
    2) можно развернуть приложение без стороннего софта (self-contained app)
    https://docs.oracle.com/javase/8/docs/technotes/gu...

    Список полезных ссылок:
    https://www.baeldung.com/tomcat-deploy-war
    https://forum.vestacp.com/viewtopic.php?t=18378
    https://spring.io/blog/2014/03/07/deploying-spring...
    https://docs.spring.io/spring-boot/docs/current/re...

    Видео -
    https://www.youtube.com/watch?v=kT_xEflmaGE&list=P...

    Если вы используете Intellij IDEA, то там при нажатии ПКМ (при условии, что вы уже настроили параметры деплоя), то можете сразу заливать проект на сервер из программы
    Ответ написан
  • Как разрабатывать графическое приложение на java?

    @azerphoenix
    но создание кнопок, текстовых полей, размеры окна я делал в графическом окружении. Неужели в Java нужно все элементы прописывать вручную?


    Посмотрите в стороны JavaFX. А для визуального проектирования - Scene Builder
    https://gluonhq.com/products/scene-builder/

    Прекрасно интегрируется с Intellij IDEA
    Ответ написан
  • Как отправлять email определяя необходимость отправки в runtime?

    @azerphoenix
    Не уверен, но если я правильно понимаю задачу, то вам по идее должны помочь Spring Email, @Scheduled для запуска по крону например, и @Async для асинхронной отправки. Но возможно, что есть варианты попроще
    Ответ написан
  • Как сделать правильно права доступа всем пользавателям?

    @azerphoenix
    просто у меня сейчас страница авторизации выходит первой

    это происходит по той причине, что урл /allStudents у вас не разрешен скорее всего, потому и у вас открывается страница логина.
    Если вы хотите, чтобы при открытии сайта открывалась страница /allStudents, то вам нужно:
    @GetMapping("/")
    public String homePage() {
    return "redirect:/allStudents";
    }

    простой пример. Ну или можете при обращении к урлу / вернуть шаблон, который возвращаете при /allStudents
    Ответ написан
  • Как обработать значение в контроллере из выпадающего списка?

    @azerphoenix
    Здравствуйте!

    Напишу примерный код, вы уже адаптируйте под себя.
    В контроллере из дропдоун вы можете получить, как сам объект, так и id объекта, а потом в БД найти этот объект по ID.

    Вариант с поиском объекта по ID:
    Plant plant = plantRepository.findById(id);
    Можете использовать Optional, чтобы избежать NPE. Optional<Plant>
    Ответ написан
  • Как правильно сделать аутентификацию в Spring Security?

    @azerphoenix
    @Order(1)
    @Configuration
    @EnableWebSecurity
    @Component

    Я так понимаю, что у вас в файле конфигурации прописано несколько конфигов? Order(1) Order(2) и т.д.?
    Поставьте точку остановки и проведите дебаг. Помню, у меня была задача, когда до второй конфигурации дело не доходило. У меня была задача сделать отдельные конфиги для админки и для фронта.

    antMatchers("/allStudents").hasRole("ADMIN");
    если тут вместо /allStudents указать просто /, то по идее при доступе к любому урлу будет запрошен ввод пароля
    Ответ написан
  • Нужна помощь по парсингу вордпресс сайта?

    @azerphoenix
    Здравствуйте!
    1) нужна ли авторизация на сайте для доступа к контенту? Почитайте, как авторизоваться на сайте используя jsoup.
    2) Не важно, какой CMS вы парсите.. ВП или что-то еще
    3) Jsoup не умеет работать с динамическим контентом (например, ajax пагинация, подгрузка скроллом и т.д.). Обычно, если нет динамического контента, то этого достаточно.
    4) Если все-таки есть динамический контент - смотрите в сторону Selenium + браузер (FF || Chrome и др.)
    5)
    Есть ли ресурсы, где можно найти примерный алгоритм прохождения по статьям и страницам?

    Ресурсов полно, достаточно поискать. А общий принцип прохождения по статьям и страницам - по факту это просто циклы.
    6) Можно спарсить данные и без ЯП. Например, используя программу Visual Web Ripper.

    Примерный план парсинга.
    - определится с типом контента. (см. пункт 3 и 4)
    - определится с авторизацией (и если нужна авторизация, то реализовать авторизацию)
    - определиться с точкой входа. Например, страница категории (рубрики) ВП.
    - определится с типом пагинации. Обычно, в ВП это /page/1,2,3,4 и т.д. Тут зависит от вашей цели. Вы можете просто инкрементировать значение страницы до макс. значения (посмотрите какая самая последняя страница) или же например, можно инкрементировать до того момента, пока на странице не будут характерных записям блоков. (тут все зависит от верстки).
    - Далее циклом - do {} while () или while() {} собираете информацию (ссылки) об имеющихся записях и добавляете в какой-нибудь List.
    - После чего опять-таки циклом пробегаетесь по списку и открываете урлы и парсите контент самой страницы. Вы также можете подключить Apache POI, чтобы после парсинга экспортировать данные в xlsx.
    Обычно, для удобства я создаю объект (тайтл, текст, ссылка на картинку и т.д.). Далее добавляешь все объекты в некий List. А дальше экспортируешь этот лист в xls.
    Вот, тут неплохой сниппет для экспорта List в Excel.
    https://www.jeejava.com/generic-way-of-reading-exc...

    Если вам нужно импортировать информацию на сайт ВП, то используйте плагин WP ALL IMPORT. Созданный вами xlsx файлы отлично подойдет
    Ответ написан
  • Как создать скроллБар на thymeleaf возвращающий строку?

    @azerphoenix
    Скажу честно, не совсем понял, что вы имеете ввиду под "скроллбар"ом, в данном контексте...
    На основании этого текста:
    Но мне надо, допустим ,поднимать данные с базы поддерживаемых растений (только имена допустим), после эти имена надо каким то образом передать на страницу в скролл бар, чтобы пользователь уже из них выбрал растение и при сабмите

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

    Для реализации нужно сделать следующее:
    1) реализовать метод, который возвращает список (List) или массив строк с названиями растений. (в Repository).
    2) В GET запросе при открытии страницы через Model ( model.addAttribute("plants", repo.getPlants()) ) передать эту информацию.
    3) далее остается все это дело красиво завернуть в dropdown список.
    https://getbootstrap.com/docs/4.3/components/dropdowns/

    Возможные растение вы можете хранить, как в БД (если предполагается частое добавления и удаление разновидностей) или хранить в виде Enum.

    .... как обработать выбранное значение в контроллере ...

    зависит от того, что вы выберете. В методе контроллера можно принять объект и сохранить его, можно принять enum и сохранить его, можно принять String и используя String.valueOf(myString) сохранить enum и т.д.
    Ответ написан
  • Failure: Build failed with and exception. Как исправить?

    @azerphoenix
    Первое, что попадается на глаза...
    "Deprecated Gradle features were used in thus build".

    У вас gradle более свежей версии, в то время, как в проекте используется старая версия.
    Например, в build.gradle вам нужно заменить
    compile на implementation
    и т.д. Надо открыть проект в IDE и посмотреть на проект
    Ответ написан
  • Как сделать переход на новую активити при нажатии на определенный текст?

    @azerphoenix
    - Отлавливать клик на область текста
    - Создать Intent и указать на каокй активити нужно перейти
    Ответ написан
  • Проблема в Android Studio. Решите мою проблему?

    @azerphoenix
    Использую эмуляторы Genymotion. С самого начала запускаю VirtualBox. Тогда запускаю эмулятор Android через него. Дальше запускаю Genymotion, и уже через него запускаю эмулятор : Google Nexus5 - 5.1.0 - API22 - 1080x1920.

    Зачем?
    Установили genymotion, открыли и запустили. Он сам запустит virtualbox.

    Например, если использовать программу Nox Player, то помимо запуска программы, вам надо в cli дать доступ к устройству (открыть порт). Genymotion этого не требует. Если устройство запущено, то оно должно работать.

    Ошибка, которая указана на первом скрине "Project XX not found in root project YY" не связана с genymotion.
    Вот, похожая ошибка - https://stackoverflow.com/questions/17662362/gradl...
    Может поможет...
    Ответ написан
  • Как организовать клиентскую часть на thymeleaf?

    @azerphoenix
    Вот, пример метода в контроллере и соответственно шаблонизатор.

    Предположим, что у вас есть страница со списком "коробок".
    Например,

    @GetMapping("/boxes")
    public String getBoxesList(
    	Model model
    ) {
    
    	model.addAttribute("boxes", boxService.getBoxesList());
    	return "/boxes-template";
    }

    <!DOCTYPE html>
    <html>
    <head>
    	<title></title>
    </head>
    <body>
    
    	<!-- тут итерируем по списку -->
    	<div th:each="box : ${boxes}">
    		<span th:inline="text">[[${box.boxTitle}]]</span> <!-- или можно так -->
    		<span th:text="${box.boxTitle}">Название коробки</span>
    		<a th:href="'/boxes/edit/'+${box.boxId}">Изменить</a> <!--обратите внимание на эту ссылку -->
    	</div>
    
    </body>
    </html>


    По клику на кнопку изменить открываем форму с информацией о боксе
    @GetMapping("/boxes/edit/{id}") 
    public String boxEditForm(
    	@Pathvariable("id") Long id,
    	Model model
    ) {
    	Box box = boxRepository.findById(id);
    	model.addAttribute("box", box);
    	return "box-edit-template";
    }

    А все остальное уже делается также....

    Вы можете по-разному реализовать. Например, передавать id бокса не в виде pathVariable, а RequestParam. Можно использовать POST запрос, если вы не хотите передавать id в URL и т.д. Я описал простой вариант.

    Если я правильно понял ваш вопрос, то это то, что вам нужно...
    Ответ написан
  • Почему не получается добавить метод в interface, наследующийся от JpsRepo?

    @azerphoenix
    List<GrowBox> findByUserId(Long userId);
    первое, что попадатся на глаза - вы хотите получить List. Если мне память не изменяет, то надо использовать
    List<GrowBox> findAllByUserUserId(Long userId) если мне память не изменяет, то должно быть как-то так
    а то получается, что вы хотите получаете один объект по userId, но при этом хотите получить List

    либо вы можете сделать следующее:
    List<GrowBox> findAllByUser(User user);
    в таком случае в метод нужно передать пользователя, а не его id.

    Кстати, обычно, IDE подсказывает как должно быть...

    No property userId found for type GrowBox!
    Caused by: org.springframework.data.mapping.PropertyReferenceException: No property userId found for type GrowBox!

    вы как бы получаете доступ к объекту User, а потом userId. А по вашему методу получается, что в таблице growBoxes вы ищете userId
    Ответ написан
  • Как сделать поиск по тексту c сортировкой spring mongodb?

    @azerphoenix
    А почему бы вам не использовать Hibernate Search или ElasticSearch? Если я правильно понял задачу...
    Там есть и сортировка и фильтрация и много чего другого...
    Ответ написан
  • Не работает EntityManager?

    @azerphoenix
    Здравствуйте!
    Начните с правки этого?
    Loading class `com.mysql.jdbc.Driver'. This is deprecated. The new driver class is `com.mysql.cj.jdbc.Driver'. The driver is automatically registered via the SPI and manual loading of the driver class is generally unnecessary.

    Тут написано, что драйвер com.mysql.jdbc.Driver, который вы вставили в application.properties устрарел.
    Используйте вместо него com.mysql.cj.jdbc.Driver
    Это появляется в последних версиях Spring Boot при использовании БД мускула
    Ответ написан
  • Как в thymeleaf дублировать поле для сравнения?

    @azerphoenix
    Здравствуйте!
    Вы сильно заморочились, если честно... тут даже Spring ни причем, а больше базовые знания html + js
    Вот, ваша форма:
    <form th:action="@{/register}"
          th:object="${personForm}" method="POST">
        Login:
        <input type="text" th:field="*{name}" />
        <br/>
        Email:
        <input type="text" th:field="*{email}" />
        <br/>
        Password:
        <input type="text" th:field="*{password}">
        <br/>
        Confirm password:
        <input type="text" th:field="*{doublePassword}">
        <input type="submit" value="Create" />
    </form>


    1) небольшой совет используйте специфические инпуты. Например, если вам нужно поле майл, то используйте майл и т.д.
    Соответственно:
    <form th:action="@{/register}"
          th:object="${personForm}" method="POST">
        Login:
        <input type="text" th:field="*{name}" />
        <br/>
        Email:
        <input type="email" th:field="*{email}" />
        <br/>
        Password:
        <input type="password" th:field="*{password}">
        <br/>
        Confirm password:
        <input type="password">
        <input type="submit" value="Create" />
    </form>

    2) Определитесь с тем, где именно вы хотите валидировать совпадение пароля на клиенте или на сервере. Как по мне, на клиенте лучше, чтобы лищний раз не нагружать сервер.
    Если на клиенте, то средствами js, если на сервере, то средствами java. Рассмотрим оба варианта:
    - На сервере. Получаете оба пароля из формы, сравниваете через equals() и возвращаете нужный результат. Если пароль неверен, то можете добавить сообщение через model.addAttribute() и вывести в шаблоне
    @RequestMapping(value = {"/register"} , method = RequestMethod.POST)
    public String savePerson(Model model, @ModelAttribute("personForm") UserForm personForm) {
    
    
    	if(!personForm.getPassword.equals(personForm.getPasswordConfirmation)) {
    		model.addAttribute("passwordIncorrect", "Вы ввели некорректный пароль");
    		return "register";
    	}
    
        if(personForm.checkPassword() &&
                userRepository.findByEmail(personForm.getEmail()) == null &&
                userRepository.findByName(personForm.getName()) == null) {
    
            AppUser user = new AppUser(personForm.getName(),
                    personForm.getEmail(),
                    personForm.getPassword());
    
            user.setEnabled(true);
            user.setRoles(Collections.singleton(Role.USER));
            userRepository.save(user);
            return "home";
         }
    
        return "register";
    }


    - Обработка на клиенте средствами js. Идея заключается в том, что вы деактивируете кнопку "Регистрация" и только если пароли совпадают, то активируете кнопку.

    Тут материалов хватает. Наберите в гугл jquery password validation.
    Вот, пример:
    Скрипт - https://www.jqueryscript.net/form/Password-Strengt...
    Демо - https://www.jqueryscript.net/demo/Password-Strengt...
    Ответ написан
  • В чем проблема с аутентификацией через Spring?

    @azerphoenix
    С учетом того, что есть готовое видео, которое один в один совпадает с вашим кодом и методом аутентификации через jdbcAuthentication() , то рекомендую посмотреть:
    https://www.youtube.com/watch?v=WDlifgLS8iQ
    и даже можете один в один воспроизвести у себя.

    Что касается вашего кода, то:
    1) добавьте в application.properties
    logging.level.org.springframework.security=DEBUG
    
    logging.level.org.hibernate.SQL=DEBUG
    logging.level.org.hibernate.type.descriptor.sql.BasicBinder=TRACE
    logging.level.org.hibernate.type=TRACE


    и увидите нужный вам стек ошибок, в частости:
    2019-05-25 20:20:12.446 DEBUG 21154 --- [nio-8080-exec-2] o.s.s.p.JdbcUserDetailsManager           : Query returned no results for user ''
    2019-05-25 20:20:12.450 DEBUG 21154 --- [nio-8080-exec-2] o.s.s.a.dao.DaoAuthenticationProvider    : User '' not found
    org.springframework.security.authentication.BadCredentialsException: Bad credentials


    Причина кроится здесь: WebsecurityConfig
    .formLogin()
                    .loginPage("/login")
                    .usernameParameter("name")
                    .passwordParameter("password")

    Вы просто забыли указать usernameParameter & passwordParameter и соответственно, Spring Security ищет в БД пользователя с именем ' '

    5ce96d384bcd4860471431.png
    Ответ написан
  • Как перенаправить пользователя на его страницу если он снова хочет залогиниться в Spring Boot?

    @azerphoenix
    Здравствуйте!
    Все довольно просто.
    1) можно показывать кнопку login только неавторизованным пользователям.
    В thymeleaf подключите spring security thymeleaf extras, а дальше проверяйте по
    https://www.thymeleaf.org/doc/articles/springsecur... (Глава 4)
    <div sec:authorize="isAnonymous()">
    <!-- login button here for non logged-in users -->
    </div>


    Но если вы все же хотите показывать кнопку и редиректить пользователя в его личный кабиент по нажатию кнопки login, в случае, если он уже авторизован, то:

    В методе, который возвращает /login (в контроллере) сделайте проверку:

    if(
            SecurityContextHolder.getContext().getAuthentication() != null &&
            SecurityContextHolder.getContext().getAuthentication().isAuthenticated() &&
            !(SecurityContextHolder.getContext().getAuthentication() instanceof AnonymousAuthenticationToken)
    
        ) {
    
          return "redirect:/home";
        }
    Ответ написан
  • Почему не работает MvcConfig в Spring?

    @azerphoenix
    Здравствуйте!
    А может проблема не в MVCConfig, а например, в Spring Security (если он у вас подключен?).
    Может быть вы получаете ошибку 403 и далее идет редирект на главную (статус 200) из-за Spring Security.
    Что в логах написано?
    Ответ написан
  • Как корректно считать данные с веб страницы и положить в бд?

    @azerphoenix
    Здравствуйте!

    Первое, что сразу попадается на глаза -
    public interface UserRepo extends CrudRepository<ClientOrder, Integer> {
    }


    public class ClientOrder {
    
        @Id
        @GeneratedValue(strategy=GenerationType.AUTO)
        @Column(name = "id", nullable = false)
        private Long id;


    Обратите внимание, что создали вы тип Long, а используете Integer

    Соответственно, должно быть так
    public interface UserRepo extends CrudRepository<ClientOrder, Long>


    + это интерфейс, необязательно писать public

    + Надеюсь, что для сущности ClientOrder есть конструктор. Просто, в сниппете этого не увидел, решил уточнить. Если нет, то создайте:

    ClientOrder() {}

    По идее тут нужно раскомментировать строку
    public String savePerson(Model model,
                                 @ModelAttribute("personForm") ClientOrder personForm) {


    Проверку на пустоту лучше проводить не так:
    firstName != null && firstName.length() > 0
    а так:
    firstName != null && !firstName.isEmpty()
    так как у вас строка
    Ответ написан