#grails #spring-security
#grails #spring-безопасность
Вопрос:
Это довольно странная проблема, и я занимался этим некоторое время, поэтому я схожу с ума.
У меня есть контроллер, расширяющий другой контроллер, поэтому я могу иметь несколько контроллеров, наследующих метод, и они выглядят примерно так:
class EventController extends EventAwareController {
def springSecurityService
def edit = {
// this line prints out principal id
println springSecurityService.principal.id
def eventInstance = getAuthorizedEventById(params.id)
if (!eventInstance) {
flash.message = "${message(code: 'event.not.found.message')}"
redirect(action: "list", controller: "event")
return false
}
}
class EventAwareController {
def eventService
def springSecurityService
def getAuthorizedEventById(def eventId) {
def event
if (eventId) {
// this springSecurityService is null and throws an error
event = eventService.findAuthorizedEvent(eventId, springSecurityService.principal.id)
if (event) {
session.eventId = eventId
}
}
return event
}
}
EventAwareController выдает:
java.lang.Исключение NullPointerException: не удается получить свойство ‘principal’ для нулевого объекта в com.ticketbranch.EventAwareController.getAuthorizedEventById(EventAwareController.groovy:14)
но мой оператор prinln в EventController печатает основной идентификатор без каких-либо проблем ?!? Итак, springSecurityService вводится как null в EventAwareController?
Есть идеи? предложения? Спасибо.
Ответ №1:
У вас есть поле в обоих классах, и это проблема при использовании Groovy. Внедрение зависимостей в Grails обычно выполняется так, как вы делаете, с def <beanname>
помощью . Это общедоступное поле, поэтому Groovy создает для него общедоступный метод получения и установки и делает поле закрытым. Средство получения не используется, но Spring видит средство установки, и поскольку компоненты настроены для подключения по имени (в отличие от типа), компонент вводится, поскольку есть совпадение между именем установщика ( setSpringSecurityService
) и именем компонента.
Поскольку у вас это происходит дважды, у вас есть два сеттера и один выигрыш, поэтому у вас будет нулевое значение для частного поля в одном классе.
Но, как и любое общедоступное (или защищенное) свойство, внедрение зависимостей наследуется, поэтому просто удалите его из всех ваших подклассов и оставьте в базовом классе.
Комментарии:
1. очень классный ответ, я потратил час, пытаясь понять, что происходит… спасибо, что помогли мне понять, что происходит 🙂