Muszę otrzymać dostęp do session scoped CDI bean z poziomu request scoped CDI bean.
- Session scoped CDI bean (
LoginController
) utrzymuje zalogowanego w serwisie użytkownika; - Request scoped CDI bean (
DataServiceImpl
) przetwarza pewne dane i potrzebuje do tego celu obiektu zalogowanego użytkownika.
Obecnie kiedy próbuje otrzymać dostęp do session bean z poziomu request bean - otrzymuję wyjątek NullPointerException
w tej linijce:
String surname=loginController.getCurrentUser().getSurname();
Dla jasności, wyjątek nie jest spowodowany metodą getCurrentUser()
, a już samym obiektem loginController
, który został wstrzyknięty do request bean'a. Oczywiście z poziomu każdego widoku mogę odwołać się do tego obiektu poprzez #{loginController.currentUser.surname}
i wszystko działa bez problemu, ale potrzebuje dostęp z poziomu bean'a, a nie widoku.
Ma ktoś jakiś pomysł na rozwiązanie problemu?
Część strony logowania:
<h:form class="form">
<p:growl id="growl" showDetail="false" />
<pm:field>
<h:inputText id="username" value="#{userLogin.username}" label="Username" required="true" requiredMessage="Username: This field is required." title="Enter your username." pt:placeholder="Username" />
</pm:field>
<pm:field>
<h:inputSecret id="password" value="#{userLogin.password}" label="Password" required="true" requiredMessage="Password: This field is required." title="Enter your password." pt:placeholder="Password" />
</pm:field>
<p:commandButton value="Login" action="#{loginController.login}" update="growl" styleClass="buttonStyle"/>
</h:form>
Session scoped CDI bean:
@Named
@SessionScoped
public class LoginController implements Serializable {
private static final long serialVersionUID = -6322113716363932422L;
public String login(){
if(userService.login(userLogin)){
currentUser=userService.getCurrnetUser(userLogin.getUsername());
return "home?faces-redirect=true";
}
else{
facesContext.addMessage(null, new FacesMessage("Data entered are incorrect"));
return null;
}
}
public String logout(){
currentUser=null;
return "login?faces-redirect=true";
}
public boolean isLoggedIn() {
return currentUser!=null;
}
@Produces
@LoggedIn
public UserAccount getCurrentUser(){
return currentUser;
}
@Inject
private FacesContext facesContext;
@Inject
private UserServiceImpl userService;
@Named
@Produces
@RequestScoped
private UserAccount userLogin=new UserAccount();
private UserAccount currentUser;
}
Request scoped CDI bean:
@Named
@RequestScoped
public class DataServiceImpl implements DataService {
@Override
public void addData(String[] data) {
//Proccess some data
String surname=loginController.getCurrentUser().getSurname();
//Proccess some data
}
@Inject
private LoginController loginController;
@Inject
private DataDao dataDao;
}
Aktualizacja:
- Dodanie bean'a
DataController
, który podobnie jakLoginController
jest kontrolerem dla pewnego widoku. Posiada wstrzyknięty beanDataServiceImpl
, który wykorzystuje wsend()
.
View scoped CDI bean:
@Named
@ViewScoped
public class DataController implements Serializable {
private static final long serialVersionUID = 1383572529241805730L;
//some methods
public void send(){
if(uploadFile==null){
FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "The file isn't uploaded", "You should upload the file"));
}
else{
list=new ArrayList<String>();
//Here should be the uploaded file but for now I added it manually.
try(Stream<String> stream=Files.lines(Paths.get("F:/VirtualBox/Share/capture20110815.binetflow"))) {
list=stream.collect(Collectors.toList());
int start=0;
Pattern pattern=Pattern.compile(",");
dataService=new DataServiceImpl();
for (String s : list) {
if(start!=0){
String[] data=pattern.split(s);
dataService.addData(data);
}
else start++;
}
} catch (IOException e) {
e.printStackTrace();
}
FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "The data has been added.", ""));
}
}
@Inject
private DataService dataService;
@Inject
private Logger log;
private UploadedFile uploadFile;
private List<String> list;
}