Ответы пользователя по тегу Spring
  • Не работает EntityManager?

    azerphoenix
    @azerphoenix Куратор тега Java
    Java Software Engineer
    Здравствуйте!
    Начните с правки этого?
    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 при использовании БД мускула
    Ответ написан
    4 комментария
  • Как в thymeleaf дублировать поле для сравнения?

    azerphoenix
    @azerphoenix Куратор тега Java
    Java Software Engineer
    Здравствуйте!
    Вы сильно заморочились, если честно... тут даже 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...
    Ответ написан
    1 комментарий
  • В чем проблема с аутентификацией через Spring?

    azerphoenix
    @azerphoenix Куратор тега Java
    Java Software Engineer
    С учетом того, что есть готовое видео, которое один в один совпадает с вашим кодом и методом аутентификации через 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
    Ответ написан
    5 комментариев
  • Как перенаправить пользователя на его страницу если он снова хочет залогиниться в Spring Boot?

    azerphoenix
    @azerphoenix Куратор тега Java
    Java Software Engineer
    Здравствуйте!
    Все довольно просто.
    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";
        }
    Ответ написан
    6 комментариев
  • Почему не работает MvcConfig в Spring?

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

    azerphoenix
    @azerphoenix Куратор тега Spring
    Java Software Engineer
    Здравствуйте!
    Начнем с самого простого...
    Предположим, что вы загрузили изображения в папку img, которая лежит в static ( resources/static/img/myImage.jpg )
    Если вы используете шаблонизатор thymeleaf, то в шаблоне нужно задать:
    <img th:src="@{img/myImage.jpg}" alt=""/>
    У вас на скрине ошибка, так как вы просто вставили картинку в атрибут src, а пути некооректные (404 ошибка), так как не учтен context path. У вас наверняка приложение открывается по урлу localhost:8080/contextPath
    Кстати, урлы к внутренним ссылкам, скриптам и стилям задаются точно также ( th:href="@{/url/url}" )

    Также заметил небольшой баг, с чем это связано не знаю, возможно intellij idea, возможно spring boot...
    В общем, если даже перезапустить приложение, даже при корректных путях к файлам может быть 404 или 500 (насколько я понял, это происходит при настроенном spring security). Чтобы избежать этих ошибок, нужно сделать Rebuild project, а потом запустить. Столкнулся с этим только в одном проекте.
    Ответ написан
    6 комментариев
  • Как корректно считать данные с веб страницы и положить в бд?

    azerphoenix
    @azerphoenix Куратор тега Java
    Java Software Engineer
    Здравствуйте!

    Первое, что сразу попадается на глаза -
    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()
    так как у вас строка
    Ответ написан
    8 комментариев
  • Spring ApplicationContext Container является реализацией ioc контейнера?

    azerphoenix
    @azerphoenix Куратор тега Java
    Java Software Engineer
    ApplicationContext представляет собой Spring IoC контейнер и необходим для инициализации, настройки и сборки бинов для построения приложения.


    spring-projects.ru/guides/lessons/lesson-2
    Ответ написан
    Комментировать
  • Форма регистрации на java?

    azerphoenix
    @azerphoenix Куратор тега Java
    Java Software Engineer
    Приветствую!
    1) идете сюда https://start.spring.io/
    и выбираете dev tools, web, mysql (или postgres), jpa, thymeleaf, security
    2) регистрация и авторизация реализуется при помощи spring security
    3) создаете файт конфигурации (@Configuration) и прописываете ваш конфиг для security
    4) создаете шаблон при помощи thymelеaf (по факту вам сперва нужны 2 формы - форма авторизации и форма регистрации). При необходимости можете добавить форму восстановления пароля и механизм подтверждения аккаунта
    5) реализуете метод, кототрый возвращает список всех пользователей со всеми зависимостями и при помощи шаблонизатора выводите на фротн-энд. Смотрите в сторону Model, model.addAttribute() th:each
    6) создаете форму редактирования профиля и метод в контроллере, который это все приниает и обрабатывает.

    А вот, видео - https://www.youtube.com/watch?v=WDlifgLS8iQ
    Кстати, там используется freemarker, можете выбрать любой понравившийся (mustache, thymeleaf, freemarker и др.)


    С бд проблема тк у меня MAC OS ,

    Я не знаток Маков, но насколько я знаю не должно быть проблем с БД. Так что берите mysql || postgres
    https://dev.mysql.com/doc/mysql-osx-excerpt/5.7/en...
    Ответ написан
    Комментировать
  • Spring. Как получить сущность с определённым значением поля?

    azerphoenix
    @azerphoenix Куратор тега Java
    Java Software Engineer
    Здравствуйте!
    Почему бы вам не использовать возможности jpql (jpa)?
    Я не вижу всего вашего кода, в частности @Service & @Repository
    Примерно, вам нужно сделать что-то подобное...
    В репозиторий добавить
    @Query(SELECT House h FROM ... WHERE h.housId = ?1 AND h.housedoc.docType = ?2)
    House findHouseByIdAndHouseDocByDocType(Long houseId, int docType)

    тут конечно надо подправить... но в целом, примерно как-то так
    А в service реализовать метод, который в качестве аргументов принимает Long & int и возвращает сущность House.
    Ответ написан
  • Как применить несколько фильтров в Hibernate?

    azerphoenix
    @azerphoenix Куратор тега Java
    Java Software Engineer
    Здравствуйте!
    Ведь, по сути фильтрация и есть поиск по БД. Соответственно, подключите hibernate search. А там уже есть возможность индексации + возможность задания нужных параметров, фильтров.
    https://docs.jboss.org/hibernate/stable/search/ref...
    Можно также использовать ElasticSearch.
    Ответ написан
    Комментировать
  • Как сохранить текст из полей в базу данных с Thymeleaf и Spring Boot?

    azerphoenix
    @azerphoenix Куратор тега Java
    Java Software Engineer
    Здравствуйте!
    У вас выбрасывает исключение связанное с шаблонизатором thymeleaf
    + вы не указали атрибут name для инпутов
    А теперь, простой пример
    @Entity
    Car {
    	
    	@Id
    	@GeneratedValue(strategy = GenerationType.AUTO)
      	private Long id;
    
      	private String carModel;
    
      	private String carName;
    
    	public Car() {}
    	//getters & setters & no args constructor
    }


    <form method="post" th:action="@{/cars/add}">
    	
    	<input type="text" name="carModel">
    	<input type="text" name="carName">
    	<input type="submit" value="Добавить машину">
    
    </form>

    @Autowired
    private CarRepository carRepository
    
    @PostMapping("/cars/add")
    public String addNewCar(
     @ModelAttribute("carModel") String carModel,
     @ModelAttribute("carName") String carName,
     Car car
    ) {
     // тут конечно можно в carService создать метод и передать ему эти аргументы
    	car.setCarModel(carModel);
    	car.setCarName(carName);
    	carRepository.save(car);
    
    	return "main"; 
    }


    Видео - https://www.youtube.com/watch?v=jH17YkBTpI4&list=P...
    Ответ написан
    2 комментария
  • Как заполнить поле класса (класс = сущности таблицы)?

    azerphoenix
    @azerphoenix Куратор тега Java
    Java Software Engineer
    Здравствуйте!
    Предположим, что 1 пользователь (User) может иметь несколько задач (Task). Получается, что отношения между ними @OneToMany @ManyToOne

    Этот код в Task лишний
    @Column(name = "user_name")
        @Getter
        @Setter
        private String userName;


    Простой пример тут - https://devcolibri.com/%D0%BA%D0%B0%D0%BA-%D1%81%D...

    OneToMany добавьте в User (List<Task> tasks), ManyToOne добавьте в Task (User user) и все.
    Ответ написан
    Комментировать
  • Как внести sql count в Map?

    azerphoenix
    @azerphoenix Куратор тега Java
    Java Software Engineer
    Что-то типа такого? Это на jpql
    @Query("SELECT COUNT(b) FROM Book b WHERE b.genre = ?1")
    Long booksCount(String genre);
    Ответ написан
    Комментировать
  • Не могу задеплоить war на внешний сервер на Tomcat?

    azerphoenix
    @azerphoenix Куратор тега Java
    Java Software Engineer
    Странно, только вчера я ответил на ваш вопрос... И он почему-то был удален и вы заново разместили этот же вопрос...
    1) Уточните пожалуйста вы собираете war или используете exploded war? Корректно ли вы собираете war в Intellij IDEA? Правда, не всегда она корректно собирается автоматически, если выбирать "From modules and dependencies"...
    2) Учли ли вы context path на удаленном tomcate? Например, если вы запускаете ваше приложение на локалке так: localhost:8080/greening то с учетом context path на удаленке будет выглядеть примерно, так localhost:8080/pathfinderPrj_war_exploded/greeting
    В application properties пропишите - server.servlet.context-path=/YoutContextPathHere
    3) Еще вчера я писал про то, что вы используете шаблонизатор thymeleaf. Соответственно, место хардкодинга ссылок типа href="/greeting"используйте его синтаксис th:href="@{/greeting}"
    Также, на будущее... если ошибка на серверной стороне будет, то можете в любое время поднять логи TomCat
    Ответ написан
    Комментировать
  • Как начать работать со Spring?

    azerphoenix
    @azerphoenix Куратор тега Spring
    Java Software Engineer
    Здравствуйте!
    Не поверите, но я сам пару месяцев назад задавался подобным вопросом. Да, материалов много, но не было информации "как начать" .
    В общем, начал я с Spring Boot.
    Здесь, вы можете быстро собрать проект. Если используете Intellij Idea Ultimate, то он уже имеется там.
    https://start.spring.io/
    Чтобы начать работу обычно хватает Web, JPA, Dev Tools, (какая-нибудь БД) h2 или mysql и т.д., можно lombok. Можно Security потом подключить и остальные либы по мере надобности...
    Для удобства работы можете использовать Intellij Idea или Spring IDE.
    Для минимального старта видео - https://www.youtube.com/watch?v=jH17YkBTpI4&list=P...
    Книга "Спринг в действии" очень информативная. Правда, мне еще один набор видеоуроков помог -
    https://www.udemy.com/spring-boot-intro/learn/v4/o...
    Правда, тут все довольно сильно разжевано для того, чтобы хоть что-то начать разрабатывать. Пару глав посвящены тому, как установить sdkman и прочие программы IDE и т.д.
    Но все начинается с чтения документации...
    Ответ написан
    Комментировать
  • Java + Spring: какой способ API аутентификации использовать?

    azerphoenix
    @azerphoenix Куратор тега Java
    Java Software Engineer
    Здравствуйте! Как раз сам сейчас этим занимаюсь))
    https://auth0.com/blog/implementing-jwt-authentica...
    https://medium.com/@hantsy/protect-rest-apis-with-...
    Ответ написан
    Комментировать
  • Как итерировать в операторе WHERE используя данные из второй таблицы?

    azerphoenix
    @azerphoenix Автор вопроса, куратор тега Spring
    Java Software Engineer
    Вроде бы и этот вариант рабочий:
    SELECT * FROM `USER_META` t1
    INNER JOIN `PAYMENT_METHODS` t2 ON t1.META_KEY = t2.PAYMENT_SYSTEM
    WHERE USER_ID = 736;

    Результат:
    5c7e73dbe95d0970971186.png
    Ответ написан
  • Почему Spring Boot не загружает application.yml?

    azerphoenix
    @azerphoenix Куратор тега Java
    Java Software Engineer
    Если вы работаете в Intellij IDEA, то проверьте в настройках проекта правильно ли добавлен этот файл.
    5c713a0cb8798831136890.png

    У меня совсем другая, но похожая ситуация была. Когда я создавал файл в intellij IDEA и выбирал yml || properties, оказывается он автоматически не добавлял нужный формат к названию файла. Так у меня получались файлы с названием application-dev вместо application-dev.properties
    Ответ написан
    Комментировать
  • Как разграничить функционал страницы сайта в зависимости от роли пользователя?

    azerphoenix
    @azerphoenix Куратор тега Spring
    Java Software Engineer
    Вы можете ограничить функционал на разных уровнях.
    Например, можно ограничить функционал на уровне шаблона. Если вы используете шаблонизатор thymeleaf, то скорее вам понадобится добавить в Gradle || Maven -
    implementation group: 'org.thymeleaf.extras', name: 'thymeleaf-extras-springsecurity5', version: '3.0.4.RELEASE'

    А дальше уже в шаблон вставить - sec:authorize="hasAuthority('ADMIN')"
    Например,
    <div class="dashboard_rules" sec:authorize="hasAuthority('ADMIN')">
    <!-- Увидит только админ-->
    </div>


    Также можно на уровне контроллера ограничить доступ:
    @PreAuthorize("hasAuthority('ADMIN')")

    Как в зависимости от роли пользователя, после удачного входа подгружать index.html с разным наполнением?

    Я обычно, делаю следующим образом:
    После авторизации получаю текущего авторизованного юзера
    @AuthenticationPrincipal UserDetails currentUser
    Нахожу юзера и проверяю его права:
    User user = (User) userService.findUserByEmail(currentUser.getUsername());

    Через if() {} else {} отдаю тот или иной контент.
    Например,
    @GetMapping("/dashboard")
    public String dashboard(
            @AuthenticationPrincipal UserDetails currentUser,
            Model model
    ) {
        model.addAttribute("pageTitle","Панель управления");
        User user = (User) userService.findUserByEmail(currentUser.getUsername());
        if(user.isAdmin()) {
            model.addAttribute("posts", posts.getAdminPosts());
        }  else {
            model.addAttribute("posts", posts.getUserPosts());
        }
    
        return "backend/dashboard";
    }
    Ответ написан
    Комментировать