JSF Converter + Injeção de dependência do Spring

Galera,

Estou usando JSF 2 com Spring.
Comecei a usar ontem e já estou batendo cabeça pra caraca. Pesquisei de forum em forum, mas está difícil.
Resolvi algumas coisas, mas outras continuam.
hehehe

Consigo fazer um crud de uma classe sem associação tranquilamente.
Mas numa classe mais “complexa”, já é um pouco diferente.
Usei o selectItems e, com isso, aprendi a usar o tal do Converter.
Pois bem…
Nesse Converter eu preciso injetar uma dependencia dao e ela não está sendo injetada.

Segue o xhtml:

		<h:form>
			<h:inputHidden value="#{cidadeController.cidade.id}"/>

			<h:panelGrid columns="3">
				<h:outputLabel for="nome" value="Nome:"></h:outputLabel>
				<h:inputText value="#{cidadeController.cidade.nome}" id="nome"></h:inputText>
				<h:message for="nome" errorClass="invalid"></h:message>

                <h:outputLabel for = "estado" value ="Estado:"/>
                <h:selectOneMenu value="#{cidadeController.cidade.estado}" id="estado">
                    <f:selectItems value="#{estadoController.all}" var="estado"
                                   itemLabel="#{estado.sigla}" itemValue="#{estado.id}"/>
                    <f:converter converterId="EstadoConverter"/>
                </h:selectOneMenu>
                <h:message for="estado" errorClass="invalid"/>
			</h:panelGrid>
			<h:commandButton action="#{cargoController.save}" value="Enviar"/>
		</h:form>

Converter:

[code]public class EstadoConverter implements Converter {
@Inject
private EstadoDao dao;

public Object getAsObject(FacesContext facesContext, UIComponent uiComponent, String value) {
    if (value.isEmpty()){
        return null;
    }else{
        return dao.findById(Long.parseLong(value));
    }
}

public String getAsString(FacesContext facesContext, UIComponent uiComponent, Object value) {
    return value.toString();
}

}[/code]

Não estou conseguindo injetar esse EstadoDao.
Alguma ideia?

Grade abraço e obrigado.

[quote=Kura]Galera,

Estou usando JSF 2 com Spring.
Comecei a usar ontem e já estou batendo cabeça pra caraca. Pesquisei de forum em forum, mas está difícil.
Resolvi algumas coisas, mas outras continuam.
hehehe

Consigo fazer um crud de uma classe sem associação tranquilamente.
Mas numa classe mais “complexa”, já é um pouco diferente.
Usei o selectItems e, com isso, aprendi a usar o tal do Converter.
Pois bem…
Nesse Converter eu preciso injetar uma dependencia dao e ela não está sendo injetada.

Segue o xhtml:

		<h:form>
			<h:inputHidden value="#{cidadeController.cidade.id}"/>

			<h:panelGrid columns="3">
				<h:outputLabel for="nome" value="Nome:"></h:outputLabel>
				<h:inputText value="#{cidadeController.cidade.nome}" id="nome"></h:inputText>
				<h:message for="nome" errorClass="invalid"></h:message>

                <h:outputLabel for = "estado" value ="Estado:"/>
                <h:selectOneMenu value="#{cidadeController.cidade.estado}" id="estado">
                    <f:selectItems value="#{estadoController.all}" var="estado"
                                   itemLabel="#{estado.sigla}" itemValue="#{estado.id}"/>
                    <f:converter converterId="EstadoConverter"/>
                </h:selectOneMenu>
                <h:message for="estado" errorClass="invalid"/>
			</h:panelGrid>
			<h:commandButton action="#{cargoController.save}" value="Enviar"/>
		</h:form>

Converter:

[code]public class EstadoConverter implements Converter {
@Inject
private EstadoDao dao;

public Object getAsObject(FacesContext facesContext, UIComponent uiComponent, String value) {
    if (value.isEmpty()){
        return null;
    }else{
        return dao.findById(Long.parseLong(value));
    }
}

public String getAsString(FacesContext facesContext, UIComponent uiComponent, Object value) {
    return value.toString();
}

}[/code]

Não estou conseguindo injetar esse EstadoDao.
Alguma ideia?

Grade abraço e obrigado.[/quote]

Nao sei se vc esqueceu de coloca mais seu converter ta sem anotacao de converter, não domino spring mais creio q ele precisa do get /set do seu dao no converter

Rapaz, esse negócio da annotation, eu penei também pra botar pra funcionar.
Eu tinha posto a annotation

@FacesConverter("EstadoConverter")

Mas não funcionou de jeito nenhum.
Então defini no xml.
Ele chega no Converter direito pq eu debuguei, mas não está injetando a dao que quero.

[quote=Kura]Rapaz, esse negócio da annotation, eu penei também pra botar pra funcionar.
Eu tinha posto a annotation

@FacesConverter("EstadoConverter")

Mas não funcionou de jeito nenhum.
Então defini no xml.
Ele chega no Converter direito pq eu debuguei, mas não está injetando a dao que quero.[/quote]não sei como o JSF funciona com o Spring, mas não existe injeção em converter. Apenas na futura versão do JSF (2.2) é que isso vai ser liberado.

As soluções atualmente são:

  1. Anotar o converter como ManagedBean
  2. Fazer lookup
  3. Pegar o managed bean pelo JSF Context e ali fazer a consulta no DB: context.getELContext().getELResolver().getValue(context.getELContext(), null, “MEEEEEEEEEEEEEEEU_MB”)

Boa Tarde,
Para conseguir injetar no converter eu faço assim.

@FacesConverter(forClass = Entidade.class, value = "entidadeConverter")
public class EntidadeConverter implements Converter {

	private EntidadeDao entidadeDao;

	public EntidadeConverter() {
		FacesContext context = FacesContext.getCurrentInstance();
		entidadeDao = (EntidadeDao) context.getELContext().getELResolver()
				.getValue(context.getELContext(), null, "entidadeDao");
	}

	public Object getAsObject(FacesContext context, UIComponent component,
			String value) {
		if (value == null || value.trim().equals("")
				|| value.trim().replaceAll("[^0-9]*", "").equals("")) {
			return null;
		} else {
			try {
				Entidade entidade = entidadeDao.find((long) Integer
						.parseInt(value));
				return entidade;
			} catch (Exception e) {
				return null;
			}
		}
	}

	public String getAsString(FacesContext context, UIComponent component,
			Object value) {
		Entidade entidade = (Entidade) value;
		if (entidade == null || entidade.getId() == null) {
			return null;
		}
		return String.valueOf(entidade.getId());
	}

}

Espero que ajude.

[quote=Edson Donizete]Boa Tarde,
Para conseguir injetar no converter eu faço assim.

@FacesConverter(forClass = Entidade.class, value = "entidadeConverter")
public class EntidadeConverter implements Converter {

	private EntidadeDao entidadeDao;

	public EntidadeConverter() {
		FacesContext context = FacesContext.getCurrentInstance();
		entidadeDao = (EntidadeDao) context.getELContext().getELResolver()
				.getValue(context.getELContext(), null, "entidadeDao");
	}

	public Object getAsObject(FacesContext context, UIComponent component,
			String value) {
		if (value == null || value.trim().equals("")
				|| value.trim().replaceAll("[^0-9]*", "").equals("")) {
			return null;
		} else {
			try {
				Entidade entidade = entidadeDao.find((long) Integer
						.parseInt(value));
				return entidade;
			} catch (Exception e) {
				return null;
			}
		}
	}

	public String getAsString(FacesContext context, UIComponent component,
			Object value) {
		Entidade entidade = (Entidade) value;
		if (entidade == null || entidade.getId() == null) {
			return null;
		}
		return String.valueOf(entidade.getId());
	}

}

Espero que ajude.
[/quote]Onde está a injeção? O.o

Somente pego o bean conforme vc colocou acima.
-> Pegar o managed bean pelo JSF Context e ali fazer a consulta no DB: context.getELContext().getELResolver().getValue(context.getELContext(), null, “MEEEEEEEEEEEEEEEU_MB”)
O bean entidadeDao esta mapeado no arquivo de configuração do spring.

[quote=Edson Donizete]Somente pego o bean conforme vc colocou acima.
-> Pegar o managed bean pelo JSF Context e ali fazer a consulta no DB: context.getELContext().getELResolver().getValue(context.getELContext(), null, “MEEEEEEEEEEEEEEEU_MB”)
O bean entidadeDao esta mapeado no arquivo de configuração do spring.[/quote]É que você falou injeção, eu achei que vc poderia ter falado de injeção mas postou outro código.
blz então.

Pessoal, valeu mesmo pela ajuda.
Tentei o context.getELContext().getELResolver().getValue(context.getELContext(), null, “estadoDao”), mas não funcionou pq, o getELContext() não está achando o getELResolver().
ou seja, não estou conseguindo fazer getELContext().getELResolver()! o.O

mas tudo bem.
ao menos eu já tive uma explicação, então acho que agora da pra eu me achar.

obrigado mesmo! =)

[quote=Kura]Pessoal, valeu mesmo pela ajuda.
Tentei o context.getELContext().getELResolver().getValue(context.getELContext(), null, “estadoDao”), mas não funcionou pq, o getELContext() não está achando o getELResolver().
ou seja, não estou conseguindo fazer getELContext().getELResolver()! o.O

mas tudo bem.
ao menos eu já tive uma explicação, então acho que agora da pra eu me achar.

obrigado mesmo! =)[/quote]Tente fazer pegando o MB e deixe que o MB faça a consulta. Não é boa prática injetar um DAO em um Converter.

Vou tentar sim.
Antes vou dar uma lida pra ver se eu entendo esses conceitos do JSF (managed bean, backing bean, etc) pq, como eu disse, peguei ha pouco tempo, então tô meio cheio de coisa pra aprender. hauahua

Muito obrigado a vocês.
Foram de grande ajuda! =)

Alias, alguma sugestão de leitura rápida e prática?