Olá a todos, eu gostaria de saber alguma maneira de eu fazer uma inicialização de variáveis do java bean conforme com o que eu tenho no banco de dados,
um exemplo
package teste;
import java.net.MalformedURLException;
import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPMessage;
public class meubean{
//--------Atributos--------
private enviaSoap objSoap = new enviaSoap();
private String Resposta = "" ;
private String frase= "";
......
nota-se que eu faço a inicialização estática da variável
private String frase= "";
ai o que eu gostaria, é que logo que o cara entra-se na minha pagina o valor dessa variável fosse setada com um valor que eu tenho no banco de dados, estou começando agora com JSF e JavaBeans, ajudaria muito se existi-se um medoto init()
[quote=Ygor]Tu pode colocar no construtor e configurar o escopo do ManegedBeam;
Ai no construtor tu faz uma chamada para um método que inicia essas variáveis[/quote]
mas então Ygor, se o cara atualizar a pagina… o método construtor é chamado novamente?
por exemplo, eu tenho uma lista de usuários aparecendo no meu jsp… ai em cima eu faço um cadastro de um usuário, eu gostaria que esse usuário aparece-se na lista, o método construtor seria chamado novamente ?
Inicialização de dados em ManagedBean’s do JSF não deve ser feita no construtor do bean. Para isso
o JEE5 e JEE6 suporta callbacks de ciclo de vida.
...
import javax.annotation.PostConstruct;
...
public class ManagedBean {
@PostConstruct
protected void init() {
// coloque a sua inicialização aqui.
}
}
O método anotado com @PostConstruct é chamado logo após a injeção nos campos do bean (campos @Inject, @EJB, @PersistenceContext, etc…).
Perceba que esse método é chamado toda vez que o objeto é criado. Caso o processo de inicialização seja muito custoso (tipo uma grande
query no banco) procure criar ManagedBean de escopos mais longos como SessionScoped ou ApplicationScoped para fazer cache dessas
informações.
[quote=dev.rafael]Inicialização de dados em ManagedBean’s do JSF não deve ser feita no construtor do bean. Para isso
o JEE5 e JEE6 suporta callbacks de ciclo de vida.
...
import javax.annotation.PostConstruct;
...
public class ManagedBean {
@PostConstruct
protected void init() {
// coloque a sua inicialização aqui.
}
}
O método anotado com @PostConstruct é chamado logo após a injeção nos campos do bean (campos @Inject, @EJB, @PersistenceContext, etc…).
Perceba que esse método é chamado toda vez que o objeto é criado. Caso o processo de inicialização seja muito custoso (tipo uma grande
query no banco) procure criar ManagedBean de escopos mais longos como SessionScoped ou ApplicationScoped para fazer cache dessas
informações.[/quote]
sim dev.rafael, mas assim, o objeto sempre vai ser criado a toda atualização de pagina?
exemplo
eu vou adiciono um cliente, supondo que tenha um submit com refrash na pagina, assim que a pagina carregar de novo, esse init() vai ser chamado ?
Sim, mas isso não é um problema se o objeto for bem leve (criação de objetos de vida curta em Java é um processo bem pouco custoso).
Mas, por outro lado, se a inicialização desse objeto for muito custosa, ou se por algum outro motivo vc precise que esse objeto sobreviva
a mais que uma request então vc pode coloca-lo no escopo de Session (anote com @SessionScoped [JSF2] ou
session do faces-config.xml [JSF1.x]) que esse managedBean vai durar enquanto o seu
usuário permanecer conectado ao seu sistema.
[quote=victormenegusso][quote=dev.rafael]Inicialização de dados em ManagedBean’s do JSF não deve ser feita no construtor do bean. Para isso
o JEE5 e JEE6 suporta callbacks de ciclo de vida.
...
import javax.annotation.PostConstruct;
...
public class ManagedBean {
@PostConstruct
protected void init() {
// coloque a sua inicialização aqui.
}
}
cara a principio isso que você me passou vai resolver o problema, assim que eu fizer o teste aqui e der certo, coloco como resolvido
Obrigado ae galera
O método anotado com @PostConstruct é chamado logo após a injeção nos campos do bean (campos @Inject, @EJB, @PersistenceContext, etc…).
Perceba que esse método é chamado toda vez que o objeto é criado. Caso o processo de inicialização seja muito custoso (tipo uma grande
query no banco) procure criar ManagedBean de escopos mais longos como SessionScoped ou ApplicationScoped para fazer cache dessas
informações.[/quote]
sim dev.rafael, mas assim, o objeto sempre vai ser criado a toda atualização de pagina?
exemplo
eu vou adiciono um cliente, supondo que tenha um submit com refrash na pagina, assim que a pagina carregar de novo, esse init() vai ser chamado ?[/quote]
[quote=dev.rafael]Sim, mas isso não é um problema se o objeto for bem leve (criação de objetos de vida curta em Java é um processo bem pouco custoso).
Mas, por outro lado, se a inicialização desse objeto for muito custosa, ou se por algum outro motivo vc precise que esse objeto sobreviva
a mais que uma request então vc pode coloca-lo no escopo de Session (anote com @SessionScoped [JSF2] ou
session do faces-config.xml [JSF1.x]) que esse managedBean vai durar enquanto o seu
usuário permanecer conectado ao seu sistema.[/quote]
Opa dev.rafael, acho que agora eu aprendi, seria assim
se eu configurar meu faces-config assim
<managed-bean-scope>session</managed-bean-scope>
quer dizer que o objeto vai existir enquanto a session não terminar então ele não vai chamar o init() ( não fica criando o objeto) a cada atualização de pagina,
[quote=dev.rafael]
O método anotado com @PostConstruct é chamado logo após a injeção nos campos do bean (campos @Inject, @EJB, @PersistenceContext, etc…).
Perceba que esse método é chamado toda vez que o objeto é criado. Caso o processo de inicialização seja muito custoso (tipo uma grande
query no banco) procure criar ManagedBean de escopos mais longos como SessionScoped ou ApplicationScoped para fazer cache dessas
informações.[/quote]
Boa tarde dev.rafael;
Não sabia da existência dessa anotação, muito bom saber. Se for possível gostaria de saber qual a diferença prática entre iniciar os dados no construtor e através de anotações? Pois tenho alguns projetos aqui que a inicialização esta justamente no construtor;
import javax.annotation.PostConstruct;
import javax.enterprise.context.RequestScoped;
import javax.inject.Inject;
import javax.inject.Named;
import com.mycompany.project.ABean;
@Named
@RequestScoped
public class ManagedBean {
@Inject ABean abean;
// Construtor...
public ManagedBean() {
// abean é null. Se eu chamar qualquer método de abean eu vou obter NullPointerException.
}
@PostConstruct
protected void myInit() {
abean.doSomethind(); // aqui tudo bem!!!
}
}
A injeção de dependências permite que vc escreva uma classe sem se preocupar em instanciar as dependências dessa classe.
Campos anotados com @Inject (CDI), @EJB, @PersistenceContext, @PersistenceUnit, @Resource e @ManagedProperty (JSF2)
são inicializados pelo próprio servidor JEE logo após o seu ManagedBean ser criado. Isso torna o seu código menor, mais simples,
provê uma maior separação entre as classes e facilita a manutenção do código. Principalmente se vc comparar com o jeito antigo
de se obter objetos gerênciados (EJBs, DataSources, ManagedBean e etc.):
Context ctx = new InitialContext();
ABean abean = (ABean) ctx.lookup("java:comp/env/ABean"); // ou algo assim...
O problema é que o servidor só pode injetar esses campos num objeto após a JVM ter terminado de construir o objeto, ou seja, após
o fim do construtor. Assim, campo injetados não estarão disponíveis ao objeto durante a execução do seu construtor. O callback @PostConstrut te oferece uma funcionalidade similar à de um construtor porém executada após o termino do processo de injeção.
Assim vc pode realizar quaisquer processamentos que dependam desses objetos. De fato não há nada de errado em usar o construtor
de um ManagedBean realizar inicialização, isso apenas não funciona se essa inicialização depender de algum objeto que será injetado pelo
servidor no seu ManagedBean. Para isso vc deve usar os Callbacks.
E da mesma maneira que vc possui o callback @PostConstruct, para inicializar um ManagedBean, existe também o callback @PreDestroy, para
finaliza-lo. O uso de @PreDestroy é deve ser preferível ao método finalize() pois métodos anotados com @PreDestroy são chamados pelo servidor
assim que o escopo de um ManagedBean termina. Use-o para liberar recursos como conexões com o Banco ou Stateful Session Beans.
import javax.inject.Inject
public class AvisosControl {
//Atributos
@Inject AvisosDAO avisosDao;
private HtmlPanel objPanelComunicado;
private HtmlPanel objPanelDestaque;
//Construtor
public AvisosControl(){}
// coloque a sua inicialização aqui.
@PostConstruct
protected void init() {
createPanelAvisos();
createPanelDestaques();
}
...
...
...
Se vc estiver usando um servidor JEE6, o próprio servidor deve criar o AvisosDAO e inicializar o campo avisosDao.
Agora só uma opinião particular, se possível não use referenciar componentes do JSF (HtmlPanel) no seu managedBean.
É perfeitamente possível fazer construções dinâmicas simples usando apenas Facelets. Caso o seu HtmlPanel tenha um
processo de construção muito complexo, o ManagedBean não o local correto de fazer esse tipo de construção.
E, definitivamente, não use DAOs. Isso é totalmente overenginering!
me desculpa pela ignorancia mas vou te perguntar mais uma coisa
"Agora só uma opinião particular, se possível não use referenciar componentes do JSF (HtmlPanel) no seu managedBean.
É perfeitamente possível fazer construções dinâmicas simples usando apenas Facelets. Caso o seu HtmlPanel tenha um
processo de construção muito complexo, o ManagedBean não o local correto de fazer esse tipo de construção. "
Pelo que li os bindings servem para isso mesmo. para poder acessar, modificar os componentes visuais pelo bean? agora fiquei confuso! nesse htmlpanel eu crio a4jcommandlinks dinamicos vindo com mensagens do banco com data mais rescente dái tem outra forma?
“E, definitivamente, não use DAOs. Isso é totalmente overenginering!”
como não usar DAOs? os meus daos possuem apenas metodo de consulta ao banco com hqls e retorna para os managers! desculpe minha ignorancia mas como posso fazer então?
overenginering?
o @Inject não tem opção de import para mim estou usando GFV2 e JSF 1.2 e richfaces 3.3.3 final
No seu caso o @Inject não estará presente pois essa anotação pertence ao CDI, um novo framework JEE6. Estará disponível no GFv3
caso vc queira tentar. Eu realmente nunca tentei desenvolver JSF sem facelets, e na verdade nem aconselho. Facelets combinam muito
mais com JSF que o JSP. Se vc está usando JSP, e não tem outra opção, vc ainda pode tentar um c:forEach para construir esses paineis
dinâmicamente, e caso não funcione, então pode ser que Bind seja o único caminha (na boa, se esse for o seu caso, meus pesames).
Overenginering significa muito trabalho de engenharia para pouco benefício. O seu hibernate suporte JPA? Se sua resposta for SIM, então
procure usar NamedQueries. Elas permitem que os objetos EntityManager atuem como DAOs genéricos evitando, assim, que vc tenha
que confeccionar tantos DAOs. Se vc ainda respondeu NÃO p/ essa ultima pergunta, então vai na fé que vc provavelmente está fazendo o
certo, mas vc não vai ser feliz com isso!!! (estou falando na boa, eu já passei pela mesma situação)
´Reaproveitando este topico, eu queria expor a minha duvida que tem um pouco haver com o topico.
estou usando o jsf2
Se eu tiver um managed Bean no escopo de sessao e tiver um metodo com a anotacao @PreDestroy , sera que quando for perdida a sessao o metodo com anotacao @PreDestroy sera executado (eu quero fechar uma conexao na bd neste metodo via jdbc ). ???
e por outra é possivel em jsf2 eu definir o tempo de inactividade para se fechar uma sessao e ou poder fechar um bean de sessao, apenas com o jsf2 sem usar xml ou codigos dos servlets???
Sim, quando a sessão encerrar o seu método PreDestroy será automaticamente executado. Mas não deixe uma conecção JDBC aberta por tanto tempo, isso não é escala muito bem. Abra uma nova conexão a cada nova requisição ou, ainda melhor, use um pool de conexões do seu servidor.
Com relação ao timeout da sessão. Não, o único modo de vc redefinir o timeout da sessão é através da API de servlets ou através da propriedade session-config do web.xml.
na verdade eu estava a pensar se era boa idea fechar ou nao a conexao a cada uso, mas depois surgiu uma idea meio maluca de fechar apenas no fim da sessao ( por preguiça …).
mas ok, eu sei que uma conexao aberta consome alguns recursos desnecessarios.valeu a dica