Spring — вызов метода службы в JSTL

Я использую Spring Security для аутентификации пользователей для моего веб-приложения Spring MVC. Я могу получить имя пользователя из объекта аутентификации, но мое имя пользователя — это адрес электронной почты, и я хочу иметь возможность отображать фактическое имя пользователя в своем заголовке.

Итак, у меня есть свой пользовательский класс User:

class Users{

    String name;
    String email;
    String password;

    // getters and setters
}

Я думал об использовании прокси-сервера с областью действия aop для установки пользователя в сеансе, как описано в этом блоге: http://richardchesterwood.blogspot.co.uk/2011/03/using-sessions-in-spring.-mvc-include.html . Проблема, с которой я столкнулся при использовании этого подхода, заключается в том, что AuthenticationSuccessHandler на самом деле является службой и не должен иметь состояния. Таким образом, Spring не автоматически связывает объект Users для меня в Сервисе.

Поэтому я создал метод службы, который будет получать имя пользователя (или адрес электронной почты) из объекта аутентификации и возвращать объект пользователей. Это я могу использовать в своих контроллерах.

@Service
@Transactional
public class UserServiceImpl implements UserService {

@Override
public Users getCurrentUser() {
     Authentication auth = SecurityContextHolder.getContext().getAuthentication();

    User userD = (User)auth.getPrincipal();

    Users currentUser = getUserByEmail(userD.getUsername());

    return currentUser;
}

}

Итак, есть ли способ вызвать этот метод службы из JSTL, чтобы получить полное имя пользователя, которое я могу отобразить в своем заголовке?

Я также открыт для предложений по лучшему способу реализации этого.

РЕДАКТИРОВАТЬ:

В моем более раннем подходе с использованием AuthenticationSuccessHandler мой код выглядит следующим образом:

@Service("userDetailsService")
@Transactional
public class UserAuthenticationServiceImpl implements AuthenticationSuccessHandler {

@Autowired
Users currentUser;

@Override
public void onAuthenticationSuccess(HttpServletRequest hsr, HttpServletResponse hsr1, Authentication a) throws IOException, ServletException {
    User user = (User) a.getPrincipal();

    Users user1 = userDao.getUserByEmail(user.getUsername());

    currentUser.setName(user1.getName());
    currentUser.setUserRoles(user1.getUserRoles());

    //currentUser = user1;

}

}

И в моем файле spring-servlet.xml у меня есть это:

<bean id="currentUser" class="com.foo.bean.Users" scope="session">
    <!-- this next element effects the proxying of the surrounding bean -->
    <aop:scoped-proxy/>
</bean>

Проблема, с которой я сталкиваюсь здесь, заключается в том, что Spring не выполняет автоподключение моего объекта currentUser, потому что Служба не находится в области сеанса.


person Anand Sriraman    schedule 19.05.2015    source источник
comment
Создайте собственный User вместо стандартного из Spring Security, который включает эту информацию, и просто измените выражение. Вы не должны делать это так, как сейчас, вы не хотите, чтобы этот дополнительный запрос и сложность каждый раз отображались на странице.   -  person M. Deinum    schedule 19.05.2015
comment
Спасибо Дейнум. Где я могу сказать Spring Security использовать вместо этого мой пользовательский класс User?   -  person Anand Sriraman    schedule 19.05.2015
comment
Если подумать, если у вас уже есть AuthenticationSuccessHandler, почему бы просто не использовать его для получения необходимой информации и сохранения ее в сеансе. У вас есть все необходимое для этого в этом методе.   -  person M. Deinum    schedule 19.05.2015
comment
Я обновил свой вопрос, подробно описав свой подход с использованием AuthenticationSuccessHandler.   -  person Anand Sriraman    schedule 19.05.2015
comment
Не делай так. Просто подключите сеанс. WebUtils.setSessionAttribute(request, "currentUser", user1);, то на своей странице вы можете просто сделать ${currentUser.username}. Вы мыслите комплексно. Добавление полного пользователя в сеанс может быть чем-то излишним, вы можете просто указать имя, которое, вероятно, будет намного легче, чем весь объект.   -  person M. Deinum    schedule 19.05.2015
comment
Ах! Я не знал о WebUtils. Огромное спасибо! Не могли бы вы добавить это как ответ, чтобы я мог пометить его как таковой?   -  person Anand Sriraman    schedule 19.05.2015
comment
Вот только хороший хелпер request.getSession().setAttribute("currentUser", user1) дает тот же результат.   -  person M. Deinum    schedule 19.05.2015


Ответы (1)


Если вам нужно только полное имя, просто используйте AuthenticationSuccessHandler, чтобы получить пользователя и добавить имя в сеанс (или полное имя пользователя, если вам нужно больше).

@Override
public void onAuthenticationSuccess(HttpServletRequest req, HttpServletResponse res, Authentication auth) throws IOException, ServletException {

    User user = (User) auth.getPrincipal();
    Users user1 = userDao.getUserByEmail(user.getUsername());
    WebUtils.setSessionAttribute(req, "currentUser" user1);
}

Тогда в вашем JSP единственное, что вам нужно, это ${currentUser.username}.

Хотя я бы не советовал заполнять сеанс полным пользователем, я бы предложил просто добавить необходимую информацию.

WebUtils.setSessionAttribute(req, "currentUsername" user1.getUsername());

Затем в вашем JSP ${currentUsername} вы сэкономите много накладных расходов на сериализацию сеанса.

person M. Deinum    schedule 19.05.2015