Passando Objetos Para um Form no Struts

7 respostas
K

Galera Boa Tarde,

To com o seguinte pepino, já tentei de tudo.

Tenho um form que recebe um objeto mensagem.
nesta mensagem tem 2 campos (origem e destino) que é tambem um objeto chamado amigo.
Acontece que quando eu envio os objetos origem e destino para o form ele dá a mensagem: type mismatch.

Algum sabe como resolver isso?

7 Respostas

Jair_Rillo_Junior

pode postar parte do seu código?
acho que fica mais simples para entender o que você está fazendo

K

Galera Segue os Arquivos…

K

acho melhor postar aqui o codigo…

jsp …

<%@ taglib uri="http://struts.apache.org/tags-html" prefix="html" %>
<html:html>
<head><title>Amigo Secreto TESB - 2006</title></head>
<html:form action="/AdicionandoMsg" method="get" focus="mensagem.msg">
	<html:hidden property="mensagem.origem" value="${amigo.id}"/>
	Mensagem: <html:textarea property="mensagem.msg"/> <br/>
	Destino: 
	<html:select property="mensagem.destino">
		<html:option value="${todos}">Todos</html:option>
		<html:option value="${amigo.amigo}">Meu Amigo</html:option>
		<html:option value="${amigo.tirou}">Quem me Tirou</html:option>
	</html:select>
	<br/>
	<html:submit>Enviar!</html:submit><br/>
</html:form>
<html:errors/>
</html:html>

Agora Vai o Form…

package br.com.tesb.amigosecreto.form;

import java.io.Serializable;

import javax.servlet.http.HttpServletRequest;

import org.apache.struts.action.ActionErrors;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.ActionMessage;

import br.com.tesb.amigosecreto.modelo.Mensagem;


public class AdicionaMsgForm extends ActionForm  implements Serializable{

	private static final long serialVersionUID = -594519282863906608L;
	private Mensagem mensagem = new Mensagem();
	
	public Mensagem getMensagem() {
		return this.mensagem;
	}
	
	public boolean stringVazia(String valor) {
		return valor == null || valor.trim().length() == 0;
	}

	@Override
	public ActionErrors validate(ActionMapping map, HttpServletRequest req) {
		System.out.println("Estou Aqui");
		//verifica a Mensagem
		ActionErrors erros = new ActionErrors();
		if (stringVazia(mensagem.getMsg())) {
			erros.add("mensagem", new ActionMessage("erro.campoMensagem"));
		}
		//verifica o Destino
		//if (mensagem.getDestino() == null) {
		//	erros.add("destino", new ActionMessage("erro.campoDestino"));
		//}
		// verifica campo origem
		//if (mensagem.getOrigem() == null) {
		//	erros.add("origem", new ActionMessage("erro.campoOrigem"));
		//}

		return erros;
		
	}
	@Override
	public void reset(ActionMapping map, HttpServletRequest req) {
		this.mensagem = new Mensagem();
	}
}

Agora Vai a Action… .

package br.com.tesb.amigosecreto.action;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.hibernate.Session;


import br.com.tesb.amigosecreto.form.AdicionaMsgForm;
import br.com.tesb.amigosecreto.modelo.Mensagem;
import br.com.tesb.amigosecreto.persistencia.HibernateFactory;
import br.com.tesb.amigosecreto.persistencia.MensagemDAO;

public class AdicionaMsgAction extends Action {
	@Override
	public ActionForward execute(ActionMapping map, ActionForm form, HttpServletRequest req, HttpServletResponse res) throws Exception {
		// formulario de cliente
		AdicionaMsgForm formulario = ((AdicionaMsgForm) form);
		// acessa o bean
		Mensagem msg = formulario.getMensagem();
		
		Session session = new HibernateFactory().getSession();
		MensagemDAO msgdao = new MensagemDAO(session);
		
		msgdao.adiciona(msg);
		session.close();
		//ok...visualização
		return map.findForward("ok");
	}

}

Aqui é a classe Modelo

package br.com.tesb.amigosecreto.modelo;

import java.text.SimpleDateFormat;
import java.util.Date;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.ManyToOne;



@Entity
public class Mensagem {
	
	@Id @GeneratedValue @Column(name="id_msg")
	private int id;
	@ManyToOne
	private Amigo origem;
	@ManyToOne
	private Amigo destino;
	private String msg;
	@Column (length=20)
	private String data;
	

	public Mensagem (){
		String formato = "dd/MM/yyyy - H:m";
		SimpleDateFormat formatter = new SimpleDateFormat(formato);
		this.data =  formatter.format(new Date());
	}

	public Amigo getDestino() {
		return destino;
	}

	public int getId() {
		return id;
	}

	public String getMsg() {
		return msg;
	}

	public Amigo getOrigem() {
		return origem;
	}

	public String getData() {
		return data;
	}

	public void setData(String data) {
		this.data = data;
	}

	public void setDestino(Amigo destino) {
		this.destino = destino;
	}

	public void setId(int id) {
		this.id = id;
	}

	public void setMsg(String msg) {
		this.msg = msg;
	}

	public void setOrigem(Amigo origem) {
		this.origem = origem;
	}

}
Fabio_Kung

mensagem.origem (olhando seu FormBean) é um Objeto do tipo Amigo. Porém o valor que você está tentando colocar para esse objeto é um número, um int. Não um amigo.

O que você provavelmente quer fazer é:

Ou seja, preencher o id do seu objeto. Você vai precisar então recarregar esse Amigo na próxima requisição, isso exatamente pelo fato de que o protocolo http não mantém estado entre as requisições.

Dentro do html:select, o mesmo problema. mensagem.destino é um objeto do tipo Amigo. Você provavelmente quer preencher o id do destino:

<html:select property="mensagem.destino.id"> <html:option value="${amigo.amigo.id}">Meu Amigo</html:option> <html:option value="${amigo.tirou.id}">Quem me Tirou</html:option> </html:select>

K

Fabio,

Cara acho que não é isso, pois veja o seguinte:

Resolvi este problema com as seguintes soluções, porem acho que isso que fiz é muito deselegante pra não dizer gambiarra, veja:

Crei uma outra classe igual a Mensagem porem em vez de receber um Amigo na Origem e Destino ela recebe um Int.

public class MensagemAdd {
	
	private int id;
	private int origem;
	private int destino;
	private String msg;
	private String data;
	

	public MensagemAdd (){
		String formato = "dd/MM/yyyy - H:mm";
		SimpleDateFormat formatter = new SimpleDateFormat(formato);
		this.data =  formatter.format(new Date());
	}

Alterei o meu form para usar esta a classe MensagemAdd

public class AdicionaMsgForm extends ActionForm  implements Serializable{

	private static final long serialVersionUID = -594519282863906608L;
	private MensagemAdd mensagem = new MensagemAdd();
	
	public MensagemAdd getMensagem() {
		return this.mensagem;
	}
	
	public boolean stringVazia(String valor) {
		return valor == null || valor.trim().length() == 0;
	}

	@Override
	public ActionErrors validate(ActionMapping map, HttpServletRequest req) {
		System.out.println("Estou Aqui");
		//verifica a Mensagem
		ActionErrors erros = new ActionErrors();
		if (stringVazia(mensagem.getMsg())) {
			erros.add("mensagem", new ActionMessage("erro.campoMensagem"));
		}
		//verifica o Destino
		//if (mensagem.getDestino() == null) {
		//	erros.add("destino", new ActionMessage("erro.campoDestino"));
		//}
		// verifica campo origem
		//if (mensagem.getOrigem() == null) {
		//	erros.add("origem", new ActionMessage("erro.campoOrigem"));
		//}

		return erros;
		
	}
	@Override
	public void reset(ActionMapping map, HttpServletRequest req) {
		this.mensagem = new MensagemAdd();
	}
}

Alterei a Minha action para receber essa MensagemAdd e Converter em Mensagem antes de persistir.

Achei a solução acima meio feia, ter que criar mais uma classe só pq eu num consigo passar um objeto como parametro, só tipos primitivos!!!

Outra solução que encontrei foi criar os campos da classe POJO no Form e realizar os setters manualmente na POJO, veja abaixo como ficou o form abaixo:

Ai Na Action é só chamar o getAmg() que vc consegue o Amigo pra persistir…

Os dois metodos acima funciona, mas acho que isto não é o certo.

Valeu…

Fabio_Kung

Oi Klaus,

Era exatamente isso que eu tinha postado para você fazer, só que ao invés de criar uma classe nova ou colocar todos os atributos de Amigo no seu FormBean, eu tinha dito para você preencher os atributos do próprio objeto Amigo dentro do seu FormBean.

Isso é uma restrição do protocolo http, quando trabalhamos com a web. Http só conhece String. O Struts ainda faz um pequeno trabalho de converter para números quando precisa (outros frameworks fazem um trabalho melhor de conversão de valores).

O Struts não tem a mínima idéia de como converter uma String que vem na requisição para um objeto do tipo Amigo. O máximo que você consegue fazer é preencher alguns campos do seu objeto amigo com Strings e números:

e não:

Denovo: o Struts sabe converter a String id que vem na requisição para o int (ou Long) id do seu objeto amigo, mas não a String que vem na requisição para um objeto completo Amigo.

K

Fabio,

Agora entendi cara. Puxa muito obrigado pela explicação.

Um Abraço,

Klaus

Criado 6 de novembro de 2006
Ultima resposta 27 de nov. de 2006
Respostas 7
Participantes 3