Могут ли другие сервлеты получить доступ к компонентам cdi в приложении jsf?

У меня есть проблема, которая, вероятно, возникает из-за моего плохого понимания концепции jsf и сталкивается с концепцией сервлета... Наконец-то я заставил свое приложение jsf работать с движком приложений Google. Это заняло много времени и некоторые обходные пути, но оно запущено и работает :) Теперь я хочу использовать данные из приложения для приложения для Android. Нет проблем, подумал я, но, конечно, есть... Я подумал, что могу просто добавить дополнительный сервлет в приложение jsf и получить доступ к тем же компонентам cdi, которые я использую для веб-страницы. Видимо это не так просто. Когда я пытаюсь внедрить bean-компоненты в дополнительный сервлет, они равны нулю. Когда я создал дополнительный контекст Faces для своего сервлета, он действительно сработал! Но только в тестовой среде... Когда я развернулся в движке приложения, этот обходной путь не сработал. Какие-либо предложения?


person Johan Naslund    schedule 25.03.2017    source источник
comment
у вас есть файл EAR с EJB и модулем WAR? И содержит ли путь к классам модуля WAR файл jar модуля EJB?   -  person The Bitman    schedule 27.03.2017


Ответы (1)


Вы можете получить доступ к компонентам CDI через BeanManager. Вы можете ввести его как ресурс. Затем вы можете получить экземпляры компонентов из BeanManager. Эти bean-компоненты очень просты, они просто возвращают значение, чтобы увидеть их типы.

Компонент CDI:

package x;

import java.io.Serializable;
import javax.inject.Named;
import javax.enterprise.context.SessionScoped;

@Named( value = "myCDIBean" )
@SessionScoped
public class MyCDIBean implements Serializable
{
  private String value = "named";

  public MyCDIBean() {}

  public String getValue()
  {
    return value;
  }

  public void setValue( String value_ )
  {
    value = value_;
  }
}

Управляемый компонент JSF:

package x;

import java.io.Serializable;
import javax.annotation.ManagedBean;
import javax.enterprise.context.SessionScoped;

@ManagedBean( value = "myJSFManagedBean" )
@SessionScoped
public class MyJSFManagedBean implements Serializable
{
  private String value = "managed";

  public MyJSFManagedBean() {}

  public String getValue()
  {
    return value;
  }

  public void setValue( String value_ )
  {
    value = value_;
  }
}

Сервлет:

package x;

import java.io.IOException;
import java.io.PrintWriter;
import javax.annotation.Resource;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.enterprise.context.spi.CreationalContext;
import javax.enterprise.inject.spi.Bean;
import javax.enterprise.inject.spi.BeanManager;

@WebServlet( urlPatterns ={"/MyServlet"} )
public class MyServlet extends HttpServlet
{
  @Resource
  BeanManager beanManager;

  public static <T> T getBeanInstance( BeanManager bm_, Class<T> class_ )
  {
    Bean<T> bean = (Bean<T>) bm_.getBeans( class_ ).iterator().next();
    CreationalContext<T> ctx = bm_.createCreationalContext( bean );
    T object = (T) bm_.getReference(bean, class_, ctx);
    return object;
  }

  protected void processRequest( HttpServletRequest request, HttpServletResponse response )
    throws ServletException, IOException
  {  
    response.setContentType( "text/html;charset=UTF-8" );
    try (PrintWriter out = response.getWriter())
    {
      out.println( "<!DOCTYPE html>" );
      out.println( "<html>" );
      out.println( "<head>" );
      out.println( "<title>Servlet NewServlet</title>" );      
      out.println( "</head>" );
      out.println( "<body>" );
      out.println( "<h1>Servlet MyServlet at " + request.getContextPath() + "</h1>" );
      MyCDIBean named = getBeanInstance( beanManager, MyCDIBean.class );
      out.println( "<p>named bean value: <b>" + named.getValue() + "</b></p>" );
      MyJSFManagedBean managed = getBeanInstance( beanManager, MyJSFManagedBean.class );
      out.println( "<p>managed bean value: <b>" + managed.getValue() + "</b></p>" );
      out.println( "</body>" );
      out.println( "</html>" );
    }
  }
person The Bitman    schedule 26.03.2017
comment
Большое спасибо за ваш ответ! Я многому научился, хотя это и не решило мою проблему. Я не мог внедрить или найти диспетчер компонентов каким-либо образом... Однако проблема решена! Когда я понял, что каждый bean-компонент, который мне нужен, имеет область запроса, простого Bean bean = new Bean() было достаточно. Чувствую себя немного смущенным, что я сделал все намного сложнее, чем было... - person Johan Naslund; 27.03.2017
comment
пожалуйста! стоит посетить домашнюю страницу BalusC: jsf.zeef.com/bauke.scholtz#block_24059 Надеюсь, ты не против, что я рекомендую это, дорогой @BalusC :) - person The Bitman; 27.03.2017
comment
Никогда не создавайте экземпляр корпоративного компонента вручную, потому что его ресурсы не будут инициализированы (он создает контейнер). всегда вводите bean-компоненты с аннотациями @EJB/@Inject. в этом случае bean-компонент с жизненным циклом, управляемым контейнером, будет инициализирован до вызова бизнес-метода - person The Bitman; 27.03.2017