Передать значение введенному EJB - PullRequest
0 голосов
/ 28 марта 2019

У меня есть EJB-приложение, которое состоит из двух bean-компонентов: ServiceEJB (веб-уровень) и BusinessEJB (бизнес-уровень), где BusinessEJB вводится в ServiceEJB.

ServiceEJB получает HTTP-запросы от браузера, вызывает метод в BusinessEJB, получает результат и отправляет HTTP-ответ.

Кроме того, ServiceEJB имеет доступ к HttpSession объект, в котором хранится userId пользователя, который вошел в систему.BusinessEJB НЕ имеет доступа к объекту HttpSession.

Приложению необходимо регистрировать сообщения (например, используя sl4j / logback).Он может регистрировать сообщение в методах ServiceEJB или BusinessEJB, а когда он регистрирует сообщение, он должен включать userId сеанса в запись журнала.

, поскольку BusinessEJB не делаетuserId, его нужно получить из ServiceEJB.Вопрос в том, как лучше всего этого добиться.Я не хочу добавлять поле userId к каждому методу в BusinessEJB в качестве параметра, так как в приложении много ServiceEJB s и BusinessEJB (и других bean-компонентов, вызываемых BusinessEJB, которые также генерируют записи журнала), и я не хочу загрязнять приложение полем userId.Вместо этого у меня могло бы быть поле userId на уровне EJB, но как их заполнить?Есть ли способ добиться этого с помощью аннотаций?Любые предложения будут приветствоваться.

@Produces({MediaType.APPLICATION_JSON})
@Consumes({MediaType.APPLICATION_JSON})
@Stateless
public class ServiceEJB {

    @Context
    HttpServletRequest httpRequest;

    @Inject
    private BusinessEJB bean;

    private String userId;

    @Path("someurl")
    public Response someMethod1() {
       final HttpSession session = httpRequest.getSession();
       // get the userId from the session

       String s = bean.someMethod2();

       // return Response
    }
}

@Stateless
public class BusinessEJB {

  private String userId;

  public String someMethod2() {
     // ....  log an entry with userId
     return "something";
  }   
}

Ответы [ 2 ]

3 голосов
/ 28 марта 2019

Несколько указателей / комментариев:

  1. Если вы интегрируетесь с безопасностью сервера приложений, то имя пользователя доступно для любого компонента. EJB могут получить его, вызвав getCallerPrincipal() для введенного варианта EJBContext, здесь javax.ejb.SessionContext:

    @Resource
    private SessionContext sessionCtx;
    

    Сервлеты могут получить принципал из HttpServletRequest.getUserPrincipal(). Компоненты JAX-RS (ServiceEJB) могут получить его из javax.ws.rs.core.SecurityContext.getUserPrincipal().

    Есть ли причина, по которой вы НЕ интегрируетесь с безопасностью сервера приложений?

  2. Если у вас есть веская причина НЕ интегрироваться с безопасностью сервера приложений, я бы предложил вариант решения от предыдущего ответа . Вариант состоит в том, чтобы установить пользовательские данные из фильтра, применяемого ко всем ресурсам (либо фильтр сервлета, либо JAX-RS ContainerRequestFilter), чтобы вам не приходилось беспокоиться об их установке в нескольких местах.

  3. Если вам нужен только идентификатор пользователя для регистрации, я бы посоветовал вам взглянуть на концепцию сопоставленных диагностических контекстов (MDC) в slf4j. С его помощью вы можете установить идентификатор пользователя рано в начале запроса и сделать его доступным для всех операторов ведения журнала в дальнейшем.

2 голосов
/ 28 марта 2019

Создает bean-объект CDI в области запроса, т.е. UserContext.

Введите его в оба EJB.

В ServiceEJB установить идентификатор пользователя и в BusinessEJB прочитать его.

...