Получить http сессию / запрос в hibernate-перехватчике - PullRequest
2 голосов
/ 30 ноября 2011

Я хочу внедрить модуль ведения журнала аудита в мою существующую систему и сохранить фактическую информацию о зарегистрированном пользователе, а это только httpSession.

Я использую hibernate / spring / struts 2, и для того, чтобы получить актуальную информацию о зарегистрированном пользователе и вызвать службу saveLog, мне нужен ServletContext, чтобы найти этот компонент службы или получить httpServletRequest ...

Я искал и, кажется, связывание сеанса с ThreadLocal usign Filter - единственный способ? что-то вроде этого или это (последний ответ)

Есть ли другое предложение? Это шаблон общения или хорошая практика?

Ответы [ 4 ]

3 голосов
/ 30 ноября 2011

Spring может привязать текущий запрос к потоку из коробки.Если вы используете DispatcherServlet, это делается автоматически, в противном случае вам нужно объявить RequestContextFilter.

Затем вы можете получить доступ к свойствам запроса через RequestContextHolder.

0 голосов
/ 30 июля 2015

Пример для весенней загрузки (spring-boot-starter 1.2.4.RELEASE).

В некоторых контроллерах:

@RequestMapping("login")
public UserBean login(@RequestParam("email") String email,
                      @RequestParam("password") String password,
                      HttpSession session) {
    // getting usser
    session.setAttribute("currentUser", user);
    return user;
}

Регистрация слушателей гибернации

import org.hibernate.event.service.spi.EventListenerRegistry;
import org.hibernate.event.spi.*;
import org.hibernate.internal.SessionFactoryImpl;
import org.hibernate.jpa.HibernateEntityManagerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;

import javax.annotation.PostConstruct;
import javax.inject.Inject;
import javax.persistence.EntityManagerFactory;

@Component
public class UiDateListener implements PostLoadEventListener, PreUpdateEventListener {
    @Inject EntityManagerFactory entityManagerFactory;

    @PostConstruct
    private void init() {
        HibernateEntityManagerFactory hibernateEntityManagerFactory = (HibernateEntityManagerFactory) this.entityManagerFactory;
        SessionFactoryImpl sessionFactoryImpl = (SessionFactoryImpl) hibernateEntityManagerFactory.getSessionFactory();
        EventListenerRegistry registry = sessionFactoryImpl.getServiceRegistry().getService(EventListenerRegistry.class);
        registry.appendListeners(EventType.POST_LOAD, this);
        registry.appendListeners(EventType.PRE_UPDATE, this);
    }

    @Override
    public void onPostLoad(PostLoadEvent event) {
        final Object entity = event.getEntity();
        if (entity == null) return;

        final UserBean currentUser = (UserBean) RequestContextHolder.currentRequestAttributes().getAttribute("currentUser", RequestAttributes.SCOPE_SESSION);
        // some logic after entity loaded
    }

    @Override
    public boolean onPreUpdate(PreUpdateEvent event) {
        final Object entity = event.getEntity();
        if (entity == null) return false;

        // some logic before entity persist

        return false;
    }
}
0 голосов
/ 30 ноября 2011

Была эта статья , как реализовать Hibernate Listener как Spring bean , чтобы иметь полный доступ к Spring Context.

Это может открыть совершенно новые способы в вашем сценарии (в зависимости от вашегоприложение).

0 голосов
/ 30 ноября 2011

В зависимости от вашей версии Hibernate, вы можете использовать Envers для обеспечения детального ведения журнала аудита.Это включает в себя возможность добавления «текущего пользователя» из переменной сеанса в данную ревизию:

@Entity
@RevisionEntity(ExampleListener.class)
public class ExampleRevEntity extends DefaultRevisionEntity {
    private String username;

    public String getUsername() { return username; }
    public void setUsername(String username) { this.username = username; }
}

. Это прекрасно интегрируется с Hibernate через серию eventListener, которые вы можете вызвать в Spring следующим образом:

<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
...
    <property name="eventListeners">
        <map>
            <entry key="post-insert" value-ref="enversEventListener"/>
            <entry key="post-update" value-ref="enversEventListener"/>
            <entry key="post-delete" value-ref="enversEventListener"/>
            <entry key="pre-collection-update" value-ref="enversEventListener"/>
            <entry key="pre-collection-remove" value-ref="enversEventListener"/>
            <entry key="post-collection-recreate" value-ref="enversEventListener"/>
        </map>
    </property>
</bean>

Затем вы можете запросить ревизии аудита через API запросов Envers.

После использования этого в нескольких недавних проектах, я предпочитаю технику аудита при использовании Hibernate.

Чтобы ответить на ваш вопрос, вы можете настроить Hibernate Interceptor или Envers RevisionListener для доступа к «текущему пользователю», посмотрев его из текущего контекста Spring:

applicationContext.getBean("currentUser", User.class);

, пока ваш пользовательнастроен как боб области видимости весной.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...