Spring Boot Security: добавляем панель администратора и роли пользователей, ограничиваем доступ

Поделиться
HTML-код
  • Опубликовано: 29 апр 2018
  • Spring Boot Web Application (MVC): Добавляем панель администрирования пользователей и управляем правами доступа пользователей с помощью аннотации hasAuthority из Spring Security.
    Код из видео:
    github.com/drucoder/sweater/t...
    В самом начале нам нужно добавить новую роль в список ролей (enum Role) и страницу, отображающую список пользователей нашего приложения. Для этого создадим новый шаблон для списка пользователей. Используем в нем удобный синтаксис для отображения списков через разделитель.
    Синтаксис этой директивы описан тут:
    freemarker.apache.org/docs/re...
    Далее добавим ссылку на эту страницу с главной страницы приложения main.ftl. Следующим этапом добавляем шаблон для редактирования пользователя, где доступными для редактирования сделаны поля username и roles (доступный в виде списка чекбоксов).
    В редакторе пользователя для вывода ролей используем функции seq_contains:
    freemarker.apache.org/docs/re...
    После этого создаем новый контроллер UserController и прописываем в нем эндпойнты для отображения списка пользователей, формы редактирования пользователя и обработки изменённых данных пользователя.
    Теперь для любого авторизованного пользователя доступен список всех пользователей и возможность изменения их имени и списка ролей. Значит следующим логичным шагом будет ограничение прав. После добавления одному из пользователей роли ADMIN добавляем на UserController аннотацию
    @PreAuthorize("hasAuthority('ADMIN')")
    Которая ограничит доступ к панели администратора и оставит его только для пользователей с ролью ADMIN. Но эта аннотация не будет работать до добавления конфигурационной аннотации
    @EnableGlobalMethodSecurity(prePostEnabled = true)
    На класс конфигурации WebSecurityConfig
    Документация по Freemarker:
    freemarker.apache.org/docs/in...
    Документация по языку выражений Spring Security, определяющих доступ
    docs.spring.io/spring-securit...
    ➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖
    ➡ Твиттер: / letscodedru
    ➡ Чат в Discord: / discord
    ➡ Группа Вконтакте: letscodedru
    ➡ Канал в Telegram: t.me/letsCode_dru
    ➡ Чат в Telegram: t.me/joinchat/FeiP9xEhqHajfqh...
    ➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖
    Поддержать проект:
    ➡ Patreon / letscodedru
    ➡ Яндекс.Деньги money.yandex.ru/to/4100145167...
    ➡ PayPal paypal.me/letscodedru
    ➡ Qiwi qiwi.me/letscode
    ➡ WebMoney/BitCoin funding.webmoney.ru/d/drucoder
    ➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖
    Ссылка на плейлист:
    • Spring Boot 2
    Ссылка на канал: / @letscodedru
    Ссылка на Яндекс.Дзен: zen.yandex.ru/media/id/5ac209...
  • НаукаНаука

Комментарии • 276

  • @samsonboroda1983
    @samsonboroda1983 5 лет назад +64

    Мне нечего сказать по делу. Сразу подписался, все огонь! Автор, прошу... Нет заклинаю - НЕ ОСТАНАВЛИВАЙСЯ, ВАЛИ ЕЩЕ! Отдача будет, век воли не видать, главное делай и не закидывай! Всем, я думаю, понятно насколько востребован спринг, но материала как твой я больше не видел. Огонь. +100500 тебе в карму ;)

  • @mihailan8711
    @mihailan8711 3 года назад +14

    Я в шоке, не представляю как можно так владеть программированием и понимать, что делаешь. Это круто. Тоже хочу.

  • @DEVKA777
    @DEVKA777 5 лет назад +7

    Ну ооочень круто!!!! Все понятно,без воды! Влюблена в Ваш стиль подачи информации! Спасибо большое! Продолжайте пожалуйста!

  • @yuriifrolkov7717
    @yuriifrolkov7717 6 лет назад +42

    Благодарю за Ваш труд. Очень полезно

  • @user-fl5hk8mg4y
    @user-fl5hk8mg4y 5 лет назад +4

    Андрей, огромное спасибо за Ваши видео! Это огромная помощь в изучении spring!

  • @YuretsUA
    @YuretsUA 5 лет назад +3

    Еще раз большое спасибо за уроки. Все очень доступно.

  • @Name-mm2kx
    @Name-mm2kx 6 лет назад +4

    Круто! Спасибо большое, очень интересно и вы очень хорошо все объясняете. Ещё раз спасибо! Без вас бы сложно было разобраться.

  • @AlexSenichek
    @AlexSenichek 4 года назад +2

    Спасибо за эти уроки. Очень полезно.

  • @user-ih7yr2sj5y
    @user-ih7yr2sj5y 3 года назад +3

    Самые качественные видео на эту тему, /и в рунете, и на англ/ Крутой
    подход, спасибо автору. Следовал видео и получилось сделать интересный
    проект, который любопытно "докручивать" самому. Советы автора помогают
    не утонуть в деталях и не потерять мотивацию. Спасибо ребятам в
    комментах - если вы напоролись на ошибку, решения находил здесь же.
    Успехов! Хватит читать комменты, идите кодить)

  • @farallel6796
    @farallel6796 6 лет назад +21

    Прежде всего я бы хотел выразить Вам свою благодарность за столь полезные видео уроки.) У меня есть к Вам просьба, не могли бы Вы сделать небольшой видео урок, о том как добавить сюда поддержку Cookie, что бы на форме логина была кнопка - "Запомнить меня", и при следующем нашем возвращении на сервер, он нас помнил и не требовал делать логин снова. Я думаю это будет не менее полезный и интересный урок.) Ещё раз спасибо за то, что вы делаете!)

    • @letsCodeDru
      @letsCodeDru  6 лет назад +8

      Это будет в следующем видео. Тут дело не в Cookie (они и так используются на сервере), тут работа с сессиями на стороне сервера

    • @farallel6796
      @farallel6796 6 лет назад +3

      letsCode отлично, с нетерпением ждём Ваших новых уроков.)

  • @D.P._
    @D.P._ 5 лет назад +1

    Спасибо! Отличный и лаконичный материал!

  • @user-pz6ss6qo6y
    @user-pz6ss6qo6y 4 года назад +1

    Отличный курс!

  • @D.P._
    @D.P._ 4 года назад +1

    Спасибо за труды!

  • @alexdavydov3311
    @alexdavydov3311 5 лет назад +1

    Очень круто! Спасибо.

  • @user-pr5jo2ly6y
    @user-pr5jo2ly6y 6 лет назад +12

    Большое спасибо за видео! Было бы интересно узнать о возможностях прикрутить какой-нибудь более объемный функционал. Например, использование капчи при регистрации нового юзера или уведомление о новых сообщениях на почту. Если это, конечно, реально в рамках курса))

    • @letsCodeDru
      @letsCodeDru  6 лет назад +6

      Капчу записал, почта в очереди)

  • @kyrylokadyshev5674
    @kyrylokadyshev5674 4 года назад +1

    Спасибо автору за труд!!!

  • @cocos1337
    @cocos1337 3 года назад +2

    Этот комментарий для тех у кого вылетают ошибки при добавлении нового пользователя и код точно такой же как у Андрея. На следующем видео все исправляется и это не вы рукожоп (и не Андрей :))
    И да, спасибо за уроки!

  • @user-qd4pf8sb3p
    @user-qd4pf8sb3p 5 лет назад +2

    Спасибо за видео!

  • @nikitaantonenko3287
    @nikitaantonenko3287 5 лет назад +3

    Thank you! Very interesting)

  • @user-ti7wk4qt6s
    @user-ti7wk4qt6s 11 месяцев назад

    отличный урок. Хорошо что есть гит со всей этой фримаркер-херней и можно не тратить время на это. Однако в основном все ошибки идут оттуда :( Очень наглядно и доходчиво показан вход в секьюрити. Спасибо!

  • @viktoriatulupova3631
    @viktoriatulupova3631 2 года назад

    Я смотрела ваши видео 3 часа, исправила только одну ошибку. Но видео сделаны хорошо

  • @aleksandrtabolkin868
    @aleksandrtabolkin868 4 года назад +4

    Отличная подача материала! Спасибо! Очень интересует авторизация по токену ( X-AUHT-TOKEN или аналог) для REST приложения, можете рассказать об этом?

  • @alikhansharapat9933
    @alikhansharapat9933 4 года назад +1

    Добрый день, спасибо за видео, как сделать редирект на основную страницу когда мы открываем страницу /login через ссылку в браузере, если пользователь уже залогинелся (authenticated) ?

  • @user-jo9zj4bj8g
    @user-jo9zj4bj8g 5 лет назад +3

    Подскажите пожалуйста, все работает. Но!! После перезапуска программы- необходимо логиниться заново. Ранее, сохраляло пользователя залогиненным.
    Это в ресурсах? Или в классах java проблему искать.

  • @user-ng9ky1tl3x
    @user-ng9ky1tl3x 2 года назад

    Отличный урок. И главное, самый нормальный голос!!!

    • @letsCodeDru
      @letsCodeDru  2 года назад

      да лааааадна. У меня в этом видео еще аппаратуры нет и микро говна кусок)

    • @user-ng9ky1tl3x
      @user-ng9ky1tl3x 2 года назад

      @@letsCodeDru не скромничай)))

  • @user-xp3fw1qr6h
    @user-xp3fw1qr6h 6 лет назад +1

    Как всегда замечательно! Спасибо! Хотелось бы увидеть разграничения прав на страницы с админ панели без хардкода роли в атрибутах, т.е. динамически с админ панели привязывать роли на страницы.

    • @letsCodeDru
      @letsCodeDru  6 лет назад +1

      Можно кейс реальный? Потому как данный способ разделения прав покрывает почти все соответствующие потребности. Далее я планирую сделать видео про разграничения прав на основании настроек пользователей, но это совсем про другое. А так не совсем понимаю, что значит "без хардкода роли в атрибутах"

    • @user-xp3fw1qr6h
      @user-xp3fw1qr6h 6 лет назад

      Есть админ, который с гуи решает какой пользователь(роли) может иметь доступ к той или иной странице или может лишить право доступа к той или иной странице. Также может дать право на редактирование. Главное все происходит с гуи.

    • @letsCodeDru
      @letsCodeDru  6 лет назад +6

      Ну так я это и решаю в данном видео)))
      Процесс: делаем роли, например "просмотр документов" и "редактирование документов" и вешаем на методы аннотации, проверяющие наличие этих ролей у пользователей. На метод "список документов" и "просмотр документов" у нас запрашиваются права на просмотр, а на "редактирование" и "создание" - права на редактирование. В интерфейсе пользователям ставим галочки "может читать" или "может редактировать"

    • @letsCodeDru
      @letsCodeDru  6 лет назад +5

      Более того, далее у нас в пределах одной страницы будут проверяться права на разные действия. Роли будут определять что видит пользователь на странице и у админа и рядового пользователя одна и та же страница будет выглядеть по-разному)

  • @iryna6389
    @iryna6389 5 лет назад +12

    Очень хороший канал. Жаль, но на данный момент оказать материальную помощь каналу не имею возможности, Это правда что если переходить по рекламной ссылке, автору будет капать бонус? Хочется хоть как-то поддержать

  • @andriyvandam5978
    @andriyvandam5978 4 года назад +1

    Подскажите, чем redirect:/user отличается от просто userlist возвращения?

  • @user-hm8wx2us8l
    @user-hm8wx2us8l 10 месяцев назад

    просто бесподобные видео

  • @user-qy7yv1ut4c
    @user-qy7yv1ut4c 3 года назад

    Такой вопрос - у кого получилось полностью(так что бы работали не только методы get но и post) подключить swagger к данному проекту? поделитесь секретом

  • @maks10110
    @maks10110 2 года назад +1

    Подскажите как будет выглядеть userList в thymeleaf уже нервы на переделе. спасибо заранее за ответ!

  • @yelamaan
    @yelamaan 5 лет назад +3

    как сделать тако что бы кнопка список пользователей отображалась только у админа?

  • @hyperborean72
    @hyperborean72 5 лет назад

    Андрей, поясните, пожалуйста, метод #userSave
    В нем параметр (userId) User user передается в случае редактирования существующего метода
    А как будет выглядеть сигнатура метода (будет ли в ней (userId) User user) в случае заведения нового пользователя?
    Спасибо

  • @fedorchernolutsky146
    @fedorchernolutsky146 5 лет назад

    Почему, если у корневого обработчика greeting написать аннотацию @GetMapping("/"), то всё работает, а если @GetMapping, то не открывается ни main page, ни login? Автор же вроде говорил, что это одно и то же, разве нет? Разница только в лишнем слэше в конце пути, но почему при @GetMapping вообще ничего не работает?

  • @TheDavid4c
    @TheDavid4c 4 года назад

    а @Transactional не надо на userSave вешать? или проект однопоточный?

  • @AnnaSmirnova1
    @AnnaSmirnova1 4 года назад +1

    СПАСИБО!!!!

  • @Libra7by
    @Libra7by 3 года назад

    Объясните, как из формы с чекбоксами получается -> @RequestParam Map form
    Возвращаются только пары с значением string("checked")?
    Которые string("") не попадают в мапу?

  • @user-rr8gn3ft5b
    @user-rr8gn3ft5b 4 года назад

    Шикарно

  • @sambarn5635
    @sambarn5635 3 года назад

    Как у тебя получается засетить цельный объект с PathVariable...
    @GetMapping("{user}")
    ...(PathVariable User user, ...)
    вроде в документации написанно что можно только простые типы "A @PathVariable argument can be of any simple type such as int, long, Date, etc. "

  • @juggernaut1680
    @juggernaut1680 6 лет назад

    Андрей, СПАСИБО ВАМ ЗА ТАКОЙ ПОЛЕЗНЫЙ ВИДЕОКУРС!!!!
    У вас самый замечательный канал!! Вы очень хорошо объясняете, чувствую, что по вашим видео я очень быстро росту!! Такой вопрос, а можно сделать как-нибудь, чтобы ссылку перехода для изменения прав пользователей отображалось только для администратора? Возможно я забегаю на перед, но наверно вы уже сделали эту возможность в следующих уроках, так что, пошел смотреть следующий урок)))

    • @letsCodeDru
      @letsCodeDru  6 лет назад +1

      Вроде было где-то, про ограничение видимости.
      Рад, что мои видео помогают :)

  • @javohirabduxakimov8710
    @javohirabduxakimov8710 4 года назад +1

    Thanks a lot.

  • @zhennik263
    @zhennik263 3 года назад

    4.20 как сказал автор спринг должен сам найти пользователя в БД и подставить его. Так вот у меня этого не происходит. Просто Failed to convert value of type 'java.lang.String' to required type 'com.example.sweter.domain.User';

  • @Libra7by
    @Libra7by 3 года назад

    По поводу: user.getRoles().add(Role.valueOf(key));
    Разве безопасно написан геттер, который выдает закрытое поле в контроллер и там его можно изменять через вызов?: public Set getRoles() { return roles; }

  • @muznachasify
    @muznachasify 6 лет назад +4

    При запуске на пустой базе, когда еще нет ни одного пользователя, не возможно будет получить права ADMIN. Ведь если их ни у кого нет, то не возможно попасть на форму регистрации. Напрашивается вариант, когда первый пользователь получает права админа автоматически. Вопрос, как правильно это реализовать? Если проверять при регистрации наличие пользователей в базе, то это лишнее обращение.
    if(userRepo.count()>0) {
    user.setRoles(Collections.singleton(Role.USER));
    }
    else{
    user.setRoles(Collections.singleton(Role.ADMIN));
    }
    Есть ли вариант лучше?

    • @letsCodeDru
      @letsCodeDru  6 лет назад +8

      Есть. Скоро покажу) очень много всего надо показать, просто не успеваю генерировать контент.

  • @user-qy7yv1ut4c
    @user-qy7yv1ut4c 3 года назад

    спасибо огромное

  • @hyperborean72
    @hyperborean72 5 лет назад

    Особое вам спасибо за подробнейшие аннотации к вашим видео.
    Ой... вы не могли бы поправить ссылочку на "Документация по языку выражений Spring Security, определяющих доступ"

    • @letsCodeDru
      @letsCodeDru  5 лет назад

      Спасибо за заметку. Сломали ребята адрессацию. Исправил ссылку

  • @hyperborean72
    @hyperborean72 5 лет назад

    Андрей, буду вам очень признателен, если найдете возможность ответить на последнюю группу моих вопросов к этому видео .. обещаю, последнюю - все же хочется разобраться досконально.
    1. объект Model, который передается из метода в метод - он доступен лишь в случае @Controller? Или, поскольку @RestController = @Controller + @ResponseBody, можно что угодно писать/читать из Model и в случае @RestController, передавая его аргументом методов?
    2. по поводу карты - аргумента #userSave. Эта карта - перечень всех элементов формы? Её ключами являются их (элементов) атрибуты name ?
    3. похоже, что в #userSave мы передаем как все элементы формы (в виде map), так и выборочные из них (кроме чекбоксов) - так проще ?
    4. Если в форме будет несколько наборов чекбоксов (в DO несколько вложенных коллекций), все из них мы распарсим как в вашем примере, проблем не возникнет (если не будет совпадений name)?
    6. В примере форма редактирует. Но что если нужна возможность сохранения нового пользователя (с созданием экземпляра DO в #userSave) - будет ли тогда два метода (один из которых PUT({user}), или как-то можно приспособить единственный POST-метод? Как тогда отличить ситуацию редактирования от создания?... если воспользоваться PUT, то один и тот же DO играет роль и @PathVariable - при поиске, что обновить, и @RequestParam - при обновлении?
    Большое вам спасибо за крайне полезный контент

    • @letsCodeDru
      @letsCodeDru  5 лет назад +1

      1. Модель для рест не нужна
      2. Да
      3. Да
      4. Да
      5. Да
      6. У нас тут не рест, поэтому можно все через пост слать. Для рест приложения мы знаем для каждого экземпляра объекта является ли он новым или нет. Исходя из этого знания мы и используем пост или пут.
      Но, по большому счету это всего лишь рекомендации и отступление от них - не нарушение закона, а, всего лишь, потенциальная путаница, остающаяся на совести разработчика. Если все красиво и понятно оформить, то можно и отступить в отдельных случаях

  • @user-xk3zb9qs9t
    @user-xk3zb9qs9t 2 года назад

    Можно как-то перенаправить пользователя без прав админа на страницу с сообщением о недостаточных правах?

  • @serhiivorobiov5794
    @serhiivorobiov5794 5 лет назад +1

    Спасибо за уроки! И сразу вопрос.
    Зачем в userEdit.ftl выводится скрытое поле user.id?
    И еще. Как все-таки сделать выпадающее меню? У пользователя, по идее должна быть одна роль (имеется ввиду текущий список - или USER или ADMIN)
    Решение от подписчика
    ${role}

    не работает. При выборе одной из ролей из списка и нажатии "Save" просто пропадает запись из таблицы 'user_role' в БД

    • @egorbosolyho3287
      @egorbosolyho3287 5 лет назад +1

      user.id для того чтобы потом понять какого пользователя изменить
      в UserController
      @RequestParam("userId") User user
      по выпадающему меню HTML тебе в помощь:
      www.mobila.name/post/5172c6cbb4ab3/

  • @hyperborean72
    @hyperborean72 5 лет назад

    Подскажите, Андрей,
    если я правильно понимаю, поведение GetMapping / PostMapping варьируется в зависимости от того, объект какого типа возвращает метод:
    Если строка, то она подразумевает имя шаблона, куда осуществляется редирект
    ?
    А если POJO, то он вернется запросом в виде XML/JSON? - Так?
    И почему лишь в методе userSave() возникла потребность воспользоваться инструкцией "redirect/"?
    Значит ли это, что GET-метод должен возвращать просто String, а POST-метод при необходимости редиректа - redirect/?
    Чисто стилистическое отличие?

    • @letsCodeDru
      @letsCodeDru  5 лет назад +2

      Мэппинги ничего не решают. Решает аннотация Controller и RestController
      Первая означает, что методы возвращают строку, указывающую, какой шаблон отображать. Вторая говорит о том, что все методы этого класса возвращают объекты, которые должны быть сериализованны в json. Из класса с аннотацией Controller также можно возвращать json, но тогда на методы, которые возвращают его, надо вешать аннотацию ResposeBody

  • @amalkabulov8916
    @amalkabulov8916 5 лет назад

    Спасибо за качествееный контент! Скажите пожалуйста может есть в планах как сделать авторизацию с REST?

    • @letsCodeDru
      @letsCodeDru  5 лет назад +1

      Так уже на канале гугловая авторизация) последние видео как раз о том

  • @user-ws8cd8js3i
    @user-ws8cd8js3i 4 года назад +1

    Подскажите, только у меня сломалось регистрация и добавление новых сообщений.
    Мы же не ставили лимит ни на сообщения, ни на юзеров.
    Сделал 30 сообщений, выдает теперь ошибку.
    Пытаюсь зарегать нового юзера, тоже выдает ошибку.
    ПыСы код аналогичен как и у Андрей.

    • @belsempai
      @belsempai 4 года назад

      в предыдущем видео есть варианты решения проблемы, у меня получилось исправить

  • @gogogo2022
    @gogogo2022 Год назад

    Так дядька ты крутой 😎 я бы это пол дня делал 😂ты за 15 минут 😂ты мастер джедай в мире джава 😂если не выше 👆

  • @user-df9lg3og6z
    @user-df9lg3og6z 4 года назад

    подскажите как вывести на форму текущего пользователя?

  • @user-vg7hc1ci5p
    @user-vg7hc1ci5p Год назад

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

  • @rus2m
    @rus2m 5 лет назад +1

    Здравствуйте, Андрей, почему-то после перехода на Freemarker с Mustache, отвалилась менюшка logout (стала Forbidden), настрйка viewName через MvcConfig не помогла, подскажите пожалуйста как решить проблему(
    Но вообще огромное спасибо за все ваши видео и правда очень помогают)

    • @letsCodeDru
      @letsCodeDru  5 лет назад +1

      Не подскажу без кода. Попробуй сравнить свой код с моим. На канале есть видео, как сравнивать код, с ним сильно проще

  • @silarion4792
    @silarion4792 5 лет назад

    Все супер, хотелось бы увидеть, а если есть готовый фронт энд, как его правильно надевать на спринг

    • @letsCodeDru
      @letsCodeDru  5 лет назад +1

      С болью и слезами. Это же реверс-инжиниринг, тут нужна особая мотивация. Я сценарий не придумаю для такого видео

  • @Libra7by
    @Libra7by 3 года назад

    И еще вопрос, по логике работы с Hibernate. Для сохранения изменений в объекте User (его листа с ролями) мы используем метод .save Но, по описанию, метод .save выполняет сохранение в БД, как нового объекта с выдачей уникального идентификатора, а мы же просто обновляем старый объект. Куда девался тогда старый объект? Может нужно использовать метод update? В чем ошибка моих наблюдений?

    • @granddfatmiq591
      @granddfatmiq591 Год назад

      Метод save из JpaReposotory делает update если уникальные поля(@id) совпадают.

  • @global_silence2623
    @global_silence2623 5 лет назад

    letsCode, Здравствуйте. Не подскажете, зачем мы в userEdit.ftl добавляем
    ${user.roles?seq_contains(role)?string("checked", "")
    ?
    Просто я удалил эту строчку и у меня также добавляются роли в любых комбинациях: отсутствие ролей, юзер, админ, юзер+админ.
    Это для чего-то вообще нужно?

    • @letsCodeDru
      @letsCodeDru  5 лет назад +1

      Помечаем галочкой в итоговой форме те роли, которые уже установлены пользователю

  • @AlexandeRogov
    @AlexandeRogov 3 года назад +2

    Если у когото возникает подобная ошибка:
    There was an unexpected error (type=Bad Request, status=400).
    Failed to convert value of type 'java.lang.String' to required type 'com.rog.teach.domain.User'; nested exception is org.springframework.core.convert.ConversionFailedException: Failed to convert from type [java.lang.String] to type [java.lang.Long] for value '1 057'; nested exception is java.lang.NumberFormatException: For input string: "1 057"
    org.springframework.web.method.annotation.MethodArgumentTypeMismatchException: Failed to convert value of type 'java.lang.String' to required type 'com.rog.teach.domain.User'; nested exception is org.springframework.core.convert.ConversionFailedException: Failed to convert from type [java.lang.String] to type [java.lang.Long] for value '1 057'; nested exception is java.lang.NumberFormatException: For input string: "1 057"
    то есть ответ тут:
    qna.habr.com/q/696518
    суть в том что в userList.ftlh надо ставить Редактировать
    и в userEdit.ftlh

  • @OtariRu
    @OtariRu 5 лет назад +1

    9:33 никак не получается добавить добавить Role.values() в Arrays.stream(), что за комбинацию клавиш нажимает автор, чтобы аргументы автоматически переносились. Кто знает подскажите.

  • @dispar8503
    @dispar8503 6 лет назад

    Как делать ajax запросы? куда давать csrf токен, и можно ли это как-то автоматизировать? Заголовки ajaxSetup jquery как вариант например сгодятся?. Его (токен) возможно получить только выдергивая из скрытого инпута в самом начале?
    Как примерно работать в спринге с сессией? Куда копать.
    Пробовал на thymeleaf авторизоваться/регаться, работает только через дополнительный открытый в конфиге секюрити мапинг реги только на get.
    Он почему то не подсовывает токен, хотя должен по умолчанию

    • @letsCodeDru
      @letsCodeDru  6 лет назад

      При Ajax запросах надо csrf в заголовки запроса кидать. Чтобы на клиенте их удобно получать, можно его либо в js переменные подложить, либо в какой-нибудь тэг засунуть и потом распарсить. Подробнее - скоро на канале будет серия видео про rest spa приложение на спринг.

  • @user-ix5ok7gl6n
    @user-ix5ok7gl6n 4 года назад

    Отличный курс!
    Вопрос:
    А как можно удалить юзера? Удалять по id не получается, т.к. там связанные таблицы.

  • @l524l8
    @l524l8 3 года назад +2

    Можно ли как-нибудь получить список пользователей с определённой ролью например только с ролью админ или юзер?
    Все ни как не могу понять как это сделать

    • @vitalijuskolinko9011
      @vitalijuskolinko9011 3 года назад

      Попробуй так:
      public List getAdmins() {
      return userRepository.findAll().stream()
      .filter(user -> user.getRoles().contains(Role.ADMIN))
      .collect(Collectors.toList());
      }

  • @azerphoenix
    @azerphoenix 5 лет назад +1

    Благодаю за видео! Исходя из видео напрашивается вопрос - как ограничить доступ к чему либо в шаблоне freemarker в зависимости от роли пользователя или статуса авторизации? Например, показать ссылку выход и профиль, если пользователь авторизован, а также показать ссылку Админка если роль пользователя админ. P.S. столкнулся с проблемой использования taglibs

    • @egorbosolyho3287
      @egorbosolyho3287 5 лет назад +2

      Используй например блок if из frermarket:
      ...
      ...
      и проверяй какой нибудь дополнительно передаваемый параметр например:
      if(user.getRoles().contains(Role.valueOf("ADMIN"))){
      model.addAttribute("admin", true);
      }
      только надо добавить в блок метода get аннотацию в принимаемых параметрах
      @AuthenticationPrincipal User user

    • @azerphoenix
      @azerphoenix 5 лет назад

      @@egorbosolyho3287 благодарю за помощь. Я решил чуть другим способом - перешел на thymeleaf, а там как-то попроще) Уже все подключил и все работает. Еще раз спасибо

  • @LWHikarik
    @LWHikarik 5 лет назад +2

    А можно сделать, чтобы обычному пользователю не отображалась ссылка на user list?

    • @danibani200
      @danibani200 4 года назад

      Может быть вы уже знаете ответ? Если да, скажите если не трудно.

    • @aleksei4604
      @aleksei4604 4 года назад +2

      В main.ftlh добавил

      User list

      В MainController
      model.addAttribute("isAdmin", user.getRoles().contains(Role.ADMIN));

  • @user-mx1st2vy5d
    @user-mx1st2vy5d 5 лет назад +5

    Подскажите пожалуйста следующее. Делаю все как в видео, но у меня почему-то Spring не хочет собирать объект класса User, который я собираюсь отредактировать.
    @GetMapping("{user}")
    public String userEditForm(@PathVariable User user, Model model) {
    // System.out.println(user);
    model.addAttribute("user", user);
    model.addAttribute("roles", Role.values());
    return "userEdit";
    }
    Этот метод мне выбрасывает следующее исключение:
    There was an unexpected error (type=Bad Request, status=400).
    Failed to convert value of type 'java.lang.String' to required type 'me.vrnsky.mimiter.domain.User'; nested exception is org.springframework.core.convert.ConversionFailedException: Failed to convert from type [java.lang.String] to type [@org.springframework.web.bind.annotation.PathVariable me.vrnsky.mimiter.domain.User] for value '1'; nested exception is org.springframework.dao.InvalidDataAccessApiUsageException: Provided id of the wrong type for class me.vrnsky.mimiter.domain.User. Expected: class java.lang.Integer, got class java.lang.Long; nested exception is java.lang.IllegalArgumentException: Provided id of the wrong type for class me.vrnsky.mimiter.domain.User. Expected: class java.lang.Integer, got class java.lang.Long
    В котором как я понял он не может сконвертировать тип. Я гуглил решение проблемы, но ничего толкового не нашел.
    github.com/vrnsky/mimiter - ссылка на репозиторий. Подскажите пожалуйста в чем может быть проблема

    • @user-mx1st2vy5d
      @user-mx1st2vy5d 5 лет назад +11

      Нашел, причину. Я неправильно объявил поле id у класса User, у меня было integer, а надо было long

  • @global_silence2623
    @global_silence2623 5 лет назад

    Такая фишка. Попробовал в userService сделать такую штуку для сохранения пользователя (его ролей)
    user.setRoles(new HashSet(){{
    add(Role.USER);
    add(Role.ADMIN);
    }});
    Это для того, чтобы я смог зарегать админа сначала. Потом уберу строку с добавлением роли Admin. Меня удивляет то, что аннотация @PreAuthorize("hasAuthority('ADMIN')") меня все равно не пропускает. Надо как-то по-другому добавлять роли? Просто в вашем примере, в видео, показано, как можно обновить роли или изменить их. Я просто пишу свой проект и хотел бы узнать, как правильно роль добавить. Я не предполагаю изменение ролей (которые кстати почему-то дико сложно обновляются, судя по вашему примеру).
    Кстати, не пропускает, если я даже добавлю через синглтон, как у вас, только роль ADMIN.

    • @global_silence2623
      @global_silence2623 5 лет назад +1

      implements UserDetails в классе User. Там нужно реализовать метод getAuthorities

  • @_DSchannel_
    @_DSchannel_ 3 года назад

    Приветствую. Когда выводится ошибка 403, то после текста ошибки снизу идет куча всякого текста с ошибками от страницы(наш проект). Я так понимаю, спринг все же дает ссылку на страницу userList, но без прав доступа она не может вывести инфу и получается белидерда. Кто знает в чем дело? Как редиректом вывести заранее заготовленную страницу на ошибку 403?
    Tue Sep 29 14:42:28 MSK 2020
    There was an unexpected error (type=Forbidden, status=403).
    Forbidden
    org.springframework.security.access.AccessDeniedException: ?????? ????????
    at org.springframework.security.access.vote.AffirmativeBased.decide(AffirmativeBased.java:84)
    at org.springframework.security.access.intercept.AbstractSecurityInterceptor.beforeInvocation(AbstractSecurityInterceptor.java:233)
    at org.springframework.security.access.intercept.aopalliance.MethodSecurityInterceptor.invoke(MethodSecurityInterceptor.java:65)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
    at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:688)
    at com.example.sweater.controller.UserController$$EnhancerBySpringCGLIB$$7fb063b5.userList()
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Met

  • @user-vo7hi1py5n
    @user-vo7hi1py5n 3 года назад

    Я правильно понимаю, что мы конфиг для доступа к эндпоинтам настраиваем либо через аннотации к контролерам, либо настройкой configure через antMatchers и hasAuthority в классе, унаследованном от WebSecurityConfigurerAdapter, совмещение двух способов невозможно? И почему так происходит, пробовал совместить, не получается.
    Предпочтительнее я так понимаю разграничение доступа на уровне аннотаций контроллеров? Или есть подводные камни?

    • @SolisOrtum
      @SolisOrtum 3 года назад +1

      developer.okta.com/blog/2019/06/20/spring-preauthorize
      Здесь описаны отличия двух методов.

  • @sergeygasak484
    @sergeygasak484 6 лет назад +4

    Пытаюсь запустить код автора, но при попытке добавить нового пользователя выскакивают ошибки:
    Add new user FreeMarker template error (DEBUG mode; use RETHROW in production!): The following has evaluated to null or missing: ==> message [in template "registration.ftl" at line 6, column 3]
    Из-за чего может такое быть?

    • @sergeygasak484
      @sergeygasak484 6 лет назад +2

      Убрал из registration.ftl строку с ${message}, заработало

    • @SudoSzamar
      @SudoSzamar 5 лет назад +3

      Правильнее будет сделать ${message!}, если месседжа нет, то и ошибки не будет, но и сообщение том, что такой же юзер уже есть в БД, будет выводиться.

    • @niyazkhannanov5790
      @niyazkhannanov5790 5 лет назад

      Та же проблема

  • @imkarabl2
    @imkarabl2 5 лет назад +1

    хочу сказать что по этому коду, если не вводить ни логин ,ни пароль и просто нажать sign in то войдет без пользователя! как решить эту проблему?

    • @egorbosolyho3287
      @egorbosolyho3287 5 лет назад

      у тебя сохранился пользователь со значениями логина и пароля null null - проверь

    • @Imkarabl1
      @Imkarabl1 5 лет назад

      Egor Bosolyho а как запретить ввод null спасибо!

    • @egorbosolyho3287
      @egorbosolyho3287 5 лет назад +1

      @@Imkarabl1 добавить проверку на пустоту при регистрации user.getUsername().isEmpty()

  • @mizantropoff
    @mizantropoff 5 месяцев назад

    У меня при добавлении в enum Role значения ADMIN не обновляется enum в таблице user_role, соответственно после добавления роли и перенаправления на user вылетает 500. Вручную добавил в таблицу значение 'ADMIN" - заработало. С чем это связано? Потому что Role не Entity? Или еще что то?

    • @Runner76rus
      @Runner76rus 5 месяцев назад

      Потому что у таблицы стоит ограничение по значению. Она принимает только USER, так как когда она создавалась автоматически, то других ролей не было. Я сделал как написали в комментах перед тобой. В консоле базы данных ввёл:
      ALTER TABLE user_role DROP CONSTRAINT user_role_roles_check;
      ALTER TABLE user_role ADD CONSTRAINT user_role_roles_check CHECK (roles::text = 'USER'::text OR roles::text = 'ADMIN'::text);

  • @user-km6gd5qq7h
    @user-km6gd5qq7h 5 лет назад +9

    Здравствуйте! Делаю один в один, как у вас. Но при попытке нажать "edit" получаю одну и ту же ошибку There was an unexpected error (type=Internal Server Error, status=500).
    Failed to convert value of type 'java.lang.String' to required type 'com.example.postgresqltest.domain.User'; nested exception is java.lang.IllegalStateException: Cannot convert value of type 'java.lang.String' to required type 'com.example.postgresqltest.domain.User': no matching editors or conversion strategy found.
    Многое перепробовал - не помогает. Что можно сделать? Заранее,спасибо.

    • @DmitryBesan
      @DmitryBesan 4 года назад

      Решили как?

    • @DmitryBesan
      @DmitryBesan 4 года назад

      @Денис Гончаренко ну, я под другим шаблонизатором в итоге сделал, но если я все так понимаю, что-то не так с repo

    • @gleb8238
      @gleb8238 3 года назад

      @Денис Гончаренко , вышло решить?) Если да, то как, тоже заменой шаблонизатора? И я не понимаю в чем суть предупреждения, он имеет ввиду, что в "... @GetMapping("{user}")
      public String userEditForm(@PathVariable User user, Model model) {... " переменная user является строкой и ее нельзя преобразовать в класс User?

    • @gleb8238
      @gleb8238 3 года назад

      @Денис Гончаренко А, окей спасибо, ну я так и думал реализовать, интересно было, почему не выходит как у автора, но может это из-за конфликта версий как-нибудь или еще чего-то

    • @teofilrozaliuk4102
      @teofilrozaliuk4102 3 года назад +5

      @Денис Гончаренко вот так будет менее криво)
      @GetMapping("{userId}")
      public String userEditForm(@PathVariable Long userId, Model model) {
      User user = userDao.findById(userId).orElse(null);
      model.addAttribute("user", user);
      model.addAttribute("roles", Role.values());
      return "userEdit";
      }

  • @MA-wi8qd
    @MA-wi8qd 5 лет назад +3

    Чтобы получить значения чекбоксов Можно было вместо requestParam form, получить массив значений выбранных чекбоксов и тогда работа упрощается.
    В html параметру name для чекбоксов присвоить одинаковое имя "roles[]":


    А в контроллере написать:
    public String userSave(@RequestParam String username, @RequestParam(name="roles[]", required = false) String[] roles, @RequestParam("userId") User user){
    user.setUsername(username);
    user.getRoles().clear();
    if(roles!=null) {
    Arrays.stream(roles).forEach(r -> user.getRoles().add(Role.valueOf(r)));
    }
    userRepository.save(user);
    return "redirect:/user";

    • @MA-wi8qd
      @MA-wi8qd 5 лет назад

      Но спасибо, что показали как получать всю форму как параметр. Пригодится в будущем

    • @user-pq8cn4uh7r
      @user-pq8cn4uh7r 3 года назад

      О Боги, вы даже не представляете насколько я благодарна вашему комментарию))))))

    • @Mareldris
      @Mareldris 3 года назад

      Ты просто царь, я смог додуматься, как сделать, чтобы чекбокс работал, но не смог додуматься, как сделать чтобы пост отправка у чекбоксов работала, так как у меня @RequestParam Map form почему-то не работает

    • @user-qh9ug5gq5p
      @user-qh9ug5gq5p 3 года назад

      славься мил человек, помогла распутать клубок безобразия

    • @user-jn7xc4lw3w
      @user-jn7xc4lw3w Год назад

      Спасибо за такой бесценный коментарий!

  • @MrMarvelS30
    @MrMarvelS30 3 года назад

    У меня возникла проблема - 4:30 автор говорит, что спринг умеет: заменяет Long в User.
    У меня же выскакивает ошибка в преобразовании. Нужны дополнительные библиотеки?

    • @shukhratrakhmonov3699
      @shukhratrakhmonov3699 3 года назад

      Могу только догадываться, какая именно ошибка у вас возникает, но я тоже тут застрял, пока не осознал, что userEdit.ftlh создал в parts, а не в templates. После исправления этого косяка все заработало.

  • @user-qh9ug5gq5p
    @user-qh9ug5gq5p 3 года назад

    У меня в проекте не 3 поля, а 7. Поэтому я передавал параметры с помощью аннотации @ModelAttribute. Так гораздо короче получается, да и правильнее, наверное. Чуть не забыл, так потом удобнее проверку валидности формы проводить. P.S. автор, где видео про "защиту от дурака" при отправке на сервер пустых полей?
    @PostMapping
    public String userSave(@ModelAttribute("user") User user,
    @RequestParam(name="roles[]", required = false) String[] roles) {
    user.getRoles().clear();
    if(roles!=null) {
    Arrays.stream(roles).forEach(r -> user.getRoles().add(Role.valueOf(r)));
    }
    userService.saveUser(user);
    return "redirect:/users";
    }

  • @anu8is930
    @anu8is930 5 лет назад

    А можно попросить видео по веб сокетам на примере чатика с разными валидациями и т.д.?

    • @letsCodeDru
      @letsCodeDru  5 лет назад

      Про Сокеты есть видос, но там не чатик, а нотификации. Но сделать чатик не сильно сложно, на основании моего видоса

  • @alisheruluknazarov5106
    @alisheruluknazarov5106 5 лет назад +1

    Отличное видео! Отличны канал!
    У меня есть один вопрос. Ребята, не могли бы вы объяснить новичку следующее: в классе UserController мы добавили @RequestMapping("/user"). Как я понимаю, "/user" это должен быть шаблон с названием "user". Но, мы же не создавали такую вьюшку? Тогда, куда ссылается @RequestMapping("/user")?
    Заранее спасибо!

    • @user-ot1hf9ov6s
      @user-ot1hf9ov6s 5 лет назад +2

      Нет, представь что Mapping("/user") - это как маркер, например, из goto, если знакома такая команда, в том числе @GetMapping и @PostMapping. Возьмем третий урок. Когда мы обращаемся через пост запрос, например такой из main.mustache(mustache более подходит для примера):
      Список сообщений
      то мы отправляем форму в пост метод(@PostMapping) с маркером "filter" (@PostMapping("/filter")).
      Аннотация же @RequestMapping("/user") применяет маркер "user" к гет и пост методу данного класса. Это просто сокращение, вместо того, чтоб писать в трех местах @PostMapping("/user"), @GetMapping("/user"), @GetMapping("/user/{user}") мы пишем его в одном месте, тем самым сокращая адрес строки.
      "Тогда, куда ссылается @RequestMapping("/user")?" - так что он не ссылается никуда, вообще маппинги никуда не ссылаются. Когда Spring стартует, он сканирует все приложение на аннотации и создает экземпляры нужных классов(они называются бины) и помещает в свой контекст(хранилище) и вот там уже происходит вся работа(иначе как мы запросами из страничек ссылаемся на не статик методы классов?). Я всего лишь джун и могу ошибаться в тонкостях, но примерно это выглядит так.
      Если это вызвало трудности и нет уверенного знания как html общается с сервером, то лучше приостановить Spring и недельку посвятить чистому jpa и jdbc(Ultimate версия позволяет делать такие приложения в пару кликов). После этого будет полное понимание что и как устроено, без основ дальше смотреть смысла нет, я именно так и делал.
      На форуме джавараша есть шикарные статьи, которые помогут подготовиться к изучению спринга.

    • @alisheruluknazarov5106
      @alisheruluknazarov5106 5 лет назад

      @@user-ot1hf9ov6s Благодарю Вас за ответ. Пожалуй, так и сделаю, попробую разобраться перед тем, как идти дальше.

    • @user-qy7yv1ut4c
      @user-qy7yv1ut4c 3 года назад +1

      @@alisheruluknazarov5106 @RequestMapping("/user") - /user это не вьюшка, а путь. по этому пути срабатывает контроллер. Вьюшки из контроллера могут посылаться, и во вьюшках указывается на какой путь будут данные отправлять на обработку когда ты их вводишь во вьюшку

    • @onmatorpretonar8413
      @onmatorpretonar8413 Год назад

      Простым языком - это маппинг по которому работает данный контроллер, т.к. теперь тебе не надо писать в каждом методе на @GetMapping или @PostMapping в скобках урл который ты обрабатываешь данным контроллером

  • @yakovperchik5857
    @yakovperchik5857 4 года назад

    Уроки супер, подача отличная, за высвечивание горячих клавиш - отдельный респект, помогите разобраться с ошибкой 403
    При попытке установить пользователю роль или сменить ник, выводит ошибку 403, свой код сверил с кодом на GITе, самое интересно что @PostMapping userSave() вовсе не запускается...

    • @yakovperchik5857
      @yakovperchik5857 4 года назад

      сам разобрался) ошибка вот в чем, в файле userEdit.ftlh у автора value="_csrf.token" а нужно value="${_csrf.token}"

  • @artemdme5164
    @artemdme5164 4 года назад

    А как удалить объект из БД?

  • @sharky_47
    @sharky_47 3 года назад +1

    не нашел ответа в комментариях, при обработке Пост запроса выдает
    Failed to convert value of type 'java.lang.String' to required type 'com.example.sweater.domain.User'; nested exception is java.lang.IllegalStateException: Cannot convert value of type 'java.lang.String' to required type 'com.example.sweater.domain.User': no matching editors or conversion strategy found
    такое ощущение, что в строке @RequestParam("userId") User user спринг не понимает что нужно достать пользователя из базы, как это можно заменить чтоб работало?
    Такая же проблема была с Гет запросом, но там решил с помощью одного из комментариев указав в параметрах Long userId и достав в теле метода этого пользователя из репозитория по номеру. Тут не пойму как сделать аналогично.
    Помогите пожалуйста, голову сломал.

    • @ihorhryniv160
      @ihorhryniv160 3 года назад

      ...
      @PostMapping
      public String userSave(
      @RequestParam("username") String username,
      @RequestParam Map form,
      @RequestParam ("userId") User user
      ) {
      ...

    • @sharky_47
      @sharky_47 3 года назад

      @@ihorhryniv160 я справился через получение Long id клиента и доставание его из базы по этому id

    • @user-qh9ug5gq5p
      @user-qh9ug5gq5p 3 года назад

      @@sharky_47 поделись кодом, если не сложно

  • @ipg683
    @ipg683 4 года назад +1

    почему важен порядок name и value:
    , но
    т.е. в одном случае сначала передаем value затем name, в другом случае - наоборот?

  • @user-mk3db1qz9x
    @user-mk3db1qz9x 5 лет назад

    Здравствуйте! Почему вы не добавили аннотацию EnableWebMvc к классу WebSecurityConfig?

    • @global_silence2623
      @global_silence2623 5 лет назад

      Потому что EnableWebMvc не имеет отношения к Security и она по дефолту, как я понимаю, включена в SpringBoot.

    • @YuretsUA
      @YuretsUA 5 лет назад

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

  • @user-fn5el2lt4u
    @user-fn5el2lt4u 6 лет назад

    Здравствуйте , тут такая возникла проблема : при добавлении нового сообщения в список выдает ошибку. ( Ваш код)
    FreeMarker template error (DEBUG mode; use RETHROW in production!):The following has evaluated to null or missing:==> filter [in template
    when-presentwhen-missing.

    • @letsCodeDru
      @letsCodeDru  6 лет назад

      это часть ошибки и по этой части непонтно ничего)

    • @vahas8980
      @vahas8980 4 года назад

      попробуй вот это в MainController
      @PostMapping("/main")
      public String addMessage(
      @RequestParam(required = false, defaultValue = "") String filter,
      @AuthenticationPrincipal User user,
      @RequestParam String text,
      @RequestParam String tag,
      Model model) {
      Message message = new Message(text, tag, user);
      repository.save(message);
      Iterable messages = repository.findAll();
      model.addAttribute("messages", messages);
      model.addAttribute("filter", filter);
      return "main";
      }

  • @yauhensaladukha6600
    @yauhensaladukha6600 5 лет назад

    Андрей, подскажите пожалуйста. А как эту строку " ${user.roles?seq_contains(role)?string("checked", "")" написать в thymeleaf?

  • @KurkovBros
    @KurkovBros 5 лет назад +2

    Огромное спасибо за подробные и понятные видео!!!
    Есть один вопрос. Скачал код из репозитория, все запускается и работает, но при нажатии на ссылку User list получается вот такая ошибка:
    Whitelabel Error Page
    This application has no explicit mapping for /error, so you are seeing this as a fallback.
    Thu Nov 22 14:35:29 MSK 2018
    There was an unexpected error (type=Forbidden, status=403).
    Forbidden

    • @viktorlyakhovych9070
      @viktorlyakhovych9070 5 лет назад

      @Mihail Vilms сначала закомментируй @PreAuthorize("hasAuthority('ADMIN')") в UserController, далее под любым юзером логинся, и в userList через edit дай хоть одному юзеру админские права. Далее, из под админа можно на UserList попасть, из простого юзера - нет (не забудь раскомментировать @PreAuthorize)

    • @vladimirchevalier3486
      @vladimirchevalier3486 5 лет назад +2

      @Mihail Vilms имел подобную проблемку, проверьте в Role метод getAuthority...

    • @ilimsarykbaev5084
      @ilimsarykbaev5084 4 года назад

      @@vladimirchevalier3486 у меня аналогичная проблема, подскажите пжл, что именно надо проверить и сделать?

    • @mobiusgroup5045
      @mobiusgroup5045 4 года назад +1

      @@ilimsarykbaev5084 Дополню правильное уточнение Владимира выше.
      Сам столкнулся с этой ошибкой и после проверки кода с Git-ом, выявилась ошибка в Role.java -> Getter изначально выглядел так:
      public String getAuthority() {
      return null;
      }
      И оказывается ничего не возвращал, следовательно и система не могла узнать авторизацию.
      Правильно:
      public String getAuthority() {
      return name();
      }

    • @user-wt1es7em5n
      @user-wt1es7em5n 2 года назад +1

      тоже выскочила такая проблема, у автора не хватало "/" в файле userEdit и также местами поменял name c value. Все четко заработало.

  • @YWNWA-ZXC
    @YWNWA-ZXC 5 лет назад +1

    создал новый проэкт, и все создал по-новой, на новой созданной базе данных, нет ошибок в коде,
    но на localhost:8080 не хочет открываться, открывает сразу localhost:8080/login
    при вводе логин и пасс выводит
    Your login attempt was not successful, try again.
    Reason: UserDetailsService returned null, which is an interface contract violation
    При этом нет ни user list, ничего.
    Только
    Login with Username and Password, поля для ввода и кнопки login

    • @letsCodeDru
      @letsCodeDru  5 лет назад

      Ну так смотреть надо, почему сервис возвращает null.

    • @user-qy7yv1ut4c
      @user-qy7yv1ut4c 5 лет назад

      разобрался в чем дело?

  • @YWNWA-ZXC
    @YWNWA-ZXC 5 лет назад

    как зайти под админом? идентичный код, нет штуки, где я могу сделать какогото пользователя админом

    • @letsCodeDru
      @letsCodeDru  5 лет назад

      Простейший способ - зайти в БД и добавить нужному пользователю роль админ. А вообще мы же миграцией добалювляли админа

  • @YWNWA-ZXC
    @YWNWA-ZXC 5 лет назад +1

    при замене localhost:8080/main на /user выводит
    Whitelabel Error Page
    вместо userlist

    • @letsCodeDru
      @letsCodeDru  5 лет назад

      Это не текст ошибки

    • @artemzubov7640
      @artemzubov7640 5 лет назад +2

      Если все прочее сделано правильно, то предполагаю, что csrf забыли добавить.

  • @user-pu7kb3il2y
    @user-pu7kb3il2y 6 лет назад

    Андрей, спасибо большое за уроки, не могли бы вы объяснить метод userSave класса UserController, а именно эти строчки:
    user.setUsername(username);
    Set roles = Arrays.stream(Role.values())
    .map(Role::name)
    .collect(Collectors.toSet());
    user.getRoles().clear();
    for (String key : form.keySet()) {
    if (roles.contains(key)){
    user.getRoles().add(Role.valueOf(key));
    }
    }
    Спасибо большое за ваш труд!

    • @letsCodeDru
      @letsCodeDru  6 лет назад +5

      user.setUsername(username); - устанавливаем пользователю имя, которое пришло с фронта
      Set roles = Arrays.stream(Role.values())
      .map(Role::name)
      .collect(Collectors.toSet());
      берем все существующие в приложении роли, преобразуем массив этих ролей в стрим (java stream api), где получаем имена ролей и полученый список имён складываем в set
      user.getRoles().clear(); - очищаем персистентную коллекцию от установленных ролей
      for (String key : form.keySet()) {
      if (roles.contains(key)){
      user.getRoles().add(Role.valueOf(key));
      }
      }
      обходим список полей, пришедших от пользователя, проверяем, если имя какого-то поля является именем роли, то ищем такую роль в enum Role и устанавливаем эти роли пользователю.
      Почему так: 1) коллекции у объектов, полученных через JPA не являются обычными коллекциями, их нельзя просто заменить, можно только обновлять. 2) чтобы не городить каких-то сложных проверок, мы просто берем всё поля, полученные от пользователя и проверяем, являются ли они ролями, если да - устанавливаем их пользователю, обновляя таким образом нашу персистентную коллекцию ролей

    • @user-pu7kb3il2y
      @user-pu7kb3il2y 6 лет назад

      спасибо большое за пояснения!

  • @leetcode_over_khinkali
    @leetcode_over_khinkali 4 года назад +5

    Ловлю:
    Resolved exception caused by Handler execution: org.springframework.web.method.annotation.MethodArgumentTypeMismatchException: Failed to convert value of type 'java.lang.String' to required type 'com.example.sweater.domain.User'; nested exception is org.springframework.core.convert.ConversionFailedException: Failed to convert from type [java.lang.String] to type [java.lang.Long] for value 'post'; nested exception is java.lang.NumberFormatException: For input string: "post "

    • @FARENGElT
      @FARENGElT 4 года назад +1

      Проверьте что типы полей в сущности User такие же как и у автора. У меня id был Integer, а не Long к примеру.

    • @Roker1stas
      @Roker1stas 3 года назад +2

      public String userEditForm(@PathVariable Long user, Model model){
      model.addAttribute("user", userRepo.findById(user).get());
      model.addAttribute("roles", Role.values());
      return "userEdit";

    • @Booruvcheek
      @Booruvcheek 3 года назад +1

      я когда не работает и не могу понять в чём дело хоть убейте, качаю проект с гитхаба (по тэгу, соответствующему теме урока) и сравниваю со своим проектом - папка с папкой.
      На Линуксе для этого использую программу Meld, на Windows есть WinMerge.

    • @ihorhryniv160
      @ihorhryniv160 3 года назад +1

      ...
      @PostMapping
      public String userSave(
      @RequestParam("username") String username,
      @RequestParam Map form,
      @RequestParam ("userId") User user
      ) {
      ...

  • @werixia6255
    @werixia6255 5 лет назад +3

    Вот такая ошибка: Add new user FreeMarker template error (DEBUG mode; use RETHROW in production!): The following has evaluated to null or missing: ==> message [in template "registration.ftl" at line 6, column 7] ---- Tip: If the failing expression is known to legally refer to something that's sometimes null or missing, either specify a default value like myOptionalVar!myDefault, or use when-presentwhen-missing
    Как понял пока база путая не хочет добавлять пользователей не подскажете как исправить?)

    • @yelamaan
      @yelamaan 4 года назад

      как решил можешь написать?

    • @sergeigrimanov5971
      @sergeigrimanov5971 4 года назад

      Тот же вопрос. Как решил?

    • @igorsurv2174
      @igorsurv2174 4 года назад +5

      Решается это легко, в контроллере RegistrationController в параметр метода добавьте public String registration(@ModelAttribute ("message") String message ) вместо public String registration(), после чего можно корректно добавлять юзеров без ошибок.

    • @motiversia4714
      @motiversia4714 4 года назад +4

      ​ igor hadarin Хз насколько актуально в 2020 году, но если у вас вдруг вылетает ошибка при запуске на 3:04
      The following has evaluated to null or missing: ==> user.username в строке ${user.username}, то необходимо сделать следующее:
      ${user.username!"null or missing"}
      Такое может произойти, если вдруг у вас есть пустая запись (пользователь без имени) в БД

    • @Rassulkhair
      @Rassulkhair Год назад +1

      @@motiversia4714 Prosto Bozhenka

  • @user-uv9rp5up4p
    @user-uv9rp5up4p 5 лет назад

    У меня почему то:
    1) в userEdit.ftl для первого input'a ingellij idea подписывает missing associated label;
    2) в userEdit.ftl
    не видит откуда взять roles, хотя в model передаю. И по этому не могу напечатать наименования ролей, получаются пустые чекбоксы.
    Может кто сталкивался - отзовитесь)
    "Page editor






    "

    • @mobiusgroup5045
      @mobiusgroup5045 4 года назад

      Если ещё актуально, то вы не в правильном месте закрыли тег input. У вас )}${role}>${role}

  • @artemdme5164
    @artemdme5164 4 года назад

    Куда писать если есть вопросы? (У меня проблема с передачей данных в форму для изменения)

    • @maxrus6173
      @maxrus6173 3 года назад +1

      в милицию!

  • @ilia5194
    @ilia5194 6 лет назад

    Отличное видео.
    Вроде все хорошо, ровно до попытки подключения bootstrap(Неплохо бы было посмотреть, как подключать к нашему шаблону это дело т.к. все с ним выходит довольно странно), так что добавите этот момент?
    И теперь не работает добавление новых пользователей таки :)

    • @letsCodeDru
      @letsCodeDru  6 лет назад

      Да, со стилями что-нибудь придумаю. А про регистрацию уже писали. Вот так лечится:
      Нужно в темплейт registration.ftl заменить
      ${message} на ${message?ifExists}

    • @ilia5194
      @ilia5194 6 лет назад

      А можете на словах сказать как подключить?
      Если подключать bootstrap через porm -> "webjars/..." + править в WevSecurityConfig , то всё работает
      Но как только пытаешься подключить любой внешний css/js(не только bootstrap, но и другое. Даже лежащий рядом), то ничего не работает
      Все дело в пути? как его прописывать тогда вWSC? или где-то еще
      Вот, как подключить в общем css к допустим к common.ftl пусть даже любой рядом лежащий

    • @letsCodeDru
      @letsCodeDru  6 лет назад

      Нужна многоходовка. На эту тему будет видео ближайшую неделю-полторы)
      кратко: добавить мэппинг статических ресурсов в MvcConfig в виде метода
      @Override
      public void addResourceHandlers(ResourceHandlerRegistry registry) {
      registry.addResourceHandler("/static/**")
      .addResourceLocations("classpath:/static/");
      }
      потом добавить разрешение на запрос статики в конфиге web security:
      .antMatchers("/static/**").permitAll()ну и создать в resources директорию static, куда ложить статику. Обращаться к ней из темплейтов например так:
      /static/some_style.css

    • @ilia5194
      @ilia5194 6 лет назад +1

      Большое спасибо, а то столько всего перерыл, но ответы слишком неупорядочены, уж думал через bean лезть.
      Всё прекрасно работает)

  • @user-vc4bd6bv4i
    @user-vc4bd6bv4i 5 лет назад

    Код полностью совпадает с Вашим. Подскажите пожалуйста что может быть При переходе к userEdit выскакивает ошибка:
    There was an unexpected error (type=Bad Request, status=400).
    Failed to convert value of type 'java.lang.String' to required type 'com.dzenlab.sweater.domain.User'; nested exception is org.springframework.core.convert.ConversionFailedException: Failed to convert from type [java.lang.String] to type [@org.springframework.web.bind.annotation.PathVariable com.dzenlab.sweater.domain.User] for value '43'; nested exception is org.springframework.dao.InvalidDataAccessApiUsageException: Provided id of the wrong type for class com.dzenlab.sweater.domain.User. Expected: class java.lang.Long, got class java.lang.Integer; nested exception is java.lang.IllegalArgumentException: Provided id of the wrong type for class com.dzenlab.sweater.domain.User. Expected: class java.lang.Long, got class java.lang.Integer

    • @user-vc4bd6bv4i
      @user-vc4bd6bv4i 5 лет назад

      Если поменять поле Long id в классе User на Integer то все работает. Помогите пожалуйста разобраться. Заранее Благодарен.

  • @jensenackles8998
    @jensenackles8998 2 года назад

    The following has evaluated to null or missing:
    Failed at: ${message} [in template "registration.ftlh" at line 5, column 5] что не так? я уже с гита скопировал все, не помогает

    • @user-ti7wk4qt6s
      @user-ti7wk4qt6s 11 месяцев назад

      ${message!} попробуй с воскл знаком

  • @zagamusic5089
    @zagamusic5089 3 года назад +1

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

  • @user-sd4bw9gh1l
    @user-sd4bw9gh1l 3 года назад

    Подскажите ,почему при переходе на /user может вылетать 404 ошибка ?Spring не видит класс UserController?

    • @nullptrperson168
      @nullptrperson168 3 года назад

      Я только начал смотреть видик но вангую что скорее всего ты либо ошибаешся в название шаблона либо в делаешь запрос на не правельный аддресс. 404 означает "не найдено"

    • @nullptrperson168
      @nullptrperson168 3 года назад

      Если 404 проверь все файл и аддрессы чтоб совпадали!
      Еслт 403 то это хрень с CSRF'ом! Это просто в каждую форму (тэг в html, ) ляпни эту строку!