No puedo @Inject a @ManagedBean en otro @ManagedBean
-
24-10-2019 - |
Pregunta
Ok, aquí está mi bean de sesión. Siempre puedo recuperar el UCTURUSER de cualquier servlet o filtro. Ese no es el problema que el problema es el Filelista y CurrentFile. He probado con INT y cadenas simples y su mismo efecto. Si establecí un valor de mi visión, el frijol alcanzado, puedo obtener los datos de otra clase.
@ManagedBean(name = "userSessionBean")
@SessionScoped
public class UserSessionBean implements Serializable, HttpSessionBindingListener {
final Logger logger = LoggerFactory.getLogger(UserSessionBean.class);
@Inject
private User currentUser;
@EJB
UserService userService;
private List<File> fileList;
private File currentFile;
public UserSessionBean() {
fileList = new ArrayList<File>();
currentFile = new File("");
}
@PostConstruct
public void onLoad() {
Principal principal = FacesContext.getCurrentInstance().getExternalContext().getUserPrincipal();
String email = principal.getName();
if (email != null) {
currentUser = userService.findUserbyEmail(email);
} else {
logger.error("Couldn't find user information from login!");
}
}
Aquí hay un ejemplo.
Mi visión alcanzó el frijol. Así es como está decorado.
@ManagedBean
@ViewScoped
public class ViewLines implements Serializable {
@Inject
private UserSessionBean userSessionBean;
Ahora el código.
userSessionBean.setCurrentFile(file);
System.out.println("UserSessionBean : " + userSessionBean.getCurrentFile().getName());
Puedo ver perfectamente el nombre del archivo actual. En realidad, esto se está imprimiendo desde un método de acción JSF. Así que obviamente se está estableciendo el archivo actual.
Ahora si hago esto.
@WebFilter(value = "/Download")
public class FileFilter implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws ServletException, IOException {
HttpSession session = ((HttpServletRequest) request).getSession(false);
UserSessionBean userSessionBean = (UserSessionBean) session.getAttribute("userSessionBean");
System.out.println(userSessionBean.getCurrentUser().getUserId()); //works
System.out.println("File filter" + userSessionBean.getCurrentFile().getName()); //doesn't work
chain.doFilter(request, response);
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void destroy() {
}
}
CurrentUser aparece bien, pero no puedo ver el archivo. Está en blanco. Lo mismo sucede con las cuerdas, int's, etc.
Gracias por cualquier ayuda que pueda proporcionar en esto.
Información: UsersessionSessionBean: Línea 3B-8531268875812004316.CSV (Valor impreso desde la vista Vista de frijoles)
Información: Filtro de archivo tester.csv (valor impreso cuando se ejecuta el filtro).
**EDITAR**
Esto funcionó.
FacesContext context = FacesContext.getCurrentInstance();
userSessionBean = (UserSessionBean) context.getApplication().evaluateExpressionGet(context, "#{userSessionBean}", UserSessionBean.class);
Puse esto en el constructor del visualización y todo estaba bien. Ahora, ¿por qué el inyección no está haciendo lo que pensé? Al principio pensé que tal vez porque estaba usando frijoles administrados por JSF en lugar de los nuevos frijoles CDI. Pero cambié los frijoles al nuevo estilo (con su nombre) y ese fue el mismo efecto.
¿La inyección solo le permite acceder a los frijoles pero no cambiar sus atributos?
Solución
Estás mezclando JSF y CDI. Su UserSessionBean
es un JSF @ManagedBean
, sin embargo, estás usando CDI @Inject
para inyectarlo en otro frijol. CDI no reutiliza el JSF administrado, en su lugar, crea uno nuevo. Use uno u otro, no ambos. La anotación correcta para inyectar un frijol administrado por JSF es @ManagedProperty
.
Reemplazar
@Inject
private UserSessionBean userSessionBean;
por
@ManagedProperty(value="#{userSessionBean}")
private UserSessionBean userSessionBean;
y asegúrese de no tener un import javax.enterprise.context
En cualquier lugar de su código (que es el paquete de anotaciones CDI).
Alternativamente, migre todas las anotaciones de gestión de frijoles JSF a las anotaciones de gestión de bean CDI.
import javax.inject.Named;
import javax.enterprise.context.SessionScoped;
@Named
@SessionScoped
public class UserSessionBean implements Serializable {}
import javax.inject.Named;
import javax.faces.view.ViewScoped;
@Named
@ViewScoped
public class ViewLines implements Serializable {}
Ventaja adicional es que solo puedes @Inject
dentro de un servlet o filtro regular sin la necesidad de tomarlo manualmente como Atributo de solicitud/sesión/aplicación.
Además, las anotaciones de gestión de frijoles JSF están en desuso desde JSF 2.3. Ver también ¿Backing Beans (@ManagedBean) o frijoles CDI (@named)?
Otros consejos
Mi mejor suposición de por qué está sucediendo esto es porque el archivo variable se está configurando en el alcance de la vista y luego se pasa por referencia a la sesión de la sesión. Tal vez esto está sucediendo porque cuando el alcance de la vista se destruye, todavía tiene una referencia a esa variable, pero no se molesta en ver si hay alguna otra referencia en el alcance de la sesión, donde se debe conservar. Por lo tanto, cuando se destruye, se elimina del alcance de la vista y la sesión en este caso.
¿Podría intentar llamar a SetCurrentFile con un objeto instanciado con 'nuevo'? Eso podría probar o refutar esta hipótesis mía.
De lo contrario, mi mejor consejo sería abrir el depurador y ver exactamente dónde se está cambiando GetCurrentFile.