Passando Objeto Java para uma Applet

10 respostas
luisbizzan

Pessoal estou tentando passar um objeto java para uma applet. Eu preciso disso pois quero enviar um relatorio direto para uma impressora (padrão) do usuário. Através de algumas pesquisas achei que tenho que serializar o objeto que quero (transformalo) em String passar por parametros e recebe-lo na Applet. Então olha como eu fiz.

1°- Classe que gera o Objeto Java e Serializa:

public String executar() throws Exception{
        String a = "";
        if (layout == null) throw new Exception("Relatório vazio.");
        String nameRel = getRandom(20);
        parameters.put("REPORT_LOCALE", new Locale("pt", "BR"));
        JasperPrint jasperPrint = JasperFillManager.fillReport(layout, parameters, conexao);

        try {
            FileOutputStream fileStream = new FileOutputStream(nameRel);
            ObjectOutputStream os = new ObjectOutputStream(fileStream);
            os.writeObject(jasperPrint);
            a = os.toString();
            os.close();
        } catch (Exception ex) {
            ex.printStackTrace();
        }
         return a;
    }
Nesse ponto eu ja tenho dúvida, está certo eu serializar o Objeto "JasperPrint" ? Agora na Applet eu recebo ela como parametro em uma variavel chamada sJasperPrint através do metodo getParameter("") e executo assim:
public void init() {
        try {
            getParameters();
            
            FileInputStream fIn = new FileInputStream(sJasperPrint);
            ObjectInputStream in = new ObjectInputStream(fIn);
            JasperPrint jasperPrint = (JasperPrint) in.readObject();

            JasperPrintManager.printPage(jasperPrint, 0, propPrint);

        } catch (FileNotFoundException ex) {
            Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException ex) {
            Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
        } catch (ClassNotFoundException ex) {
            Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
        } catch (JRException ex) {
            Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
        } catch (SQLException ex) {
            Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
        } catch (Exception ex) {
            Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
So que ele não consegue ler a string e converter em objeto novamente. Da essa mensagem de erro:
18/07/2012 14:37:00 com.smarapd.impdireto.applet.Main init
SEVERE: null
java.io.FileNotFoundException: java.io.ObjectOutputStream@c3d062 (O sistema não pode encontrar o arquivo especificado)
        at java.io.FileInputStream.open(Native Method)
        at java.io.FileInputStream.<init>(FileInputStream.java:106)
        at java.io.FileInputStream.<init>(FileInputStream.java:66)
        at com.smarapd.impdireto.applet.Main.init(Main.java:37)
        at sun.applet.AppletPanel.run(AppletPanel.java:417)
        at java.lang.Thread.run(Thread.java:619)

Será que alguem sabe como fazer isso ?

10 Respostas

A

Não entendi muito como tu vai fazer mais serialização de objetos é possível mas como vc tá se comunicando entre os dois programas ? acho que seria através de Socket.

Para vc serializar tem que ter a mesma classe nos dois arquivos (no caso biblioteca jasper) e claro que essa classe tem que implementar java.io.Serializable;.

luisbizzan

Então a classe do Jasper tem sim nas 2 pontas. e minha classe tem o implements Serializable. Olha como ela esta:

package com.smarapd.teste.applet;

import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Hashtable;
import java.util.LinkedList;
import java.util.Locale;
import java.util.Random;
import net.sf.jasperreports.engine.*;

/**
 *
 * @author LGBIZZAN
 */
public class Relatorio implements Serializable {

    public static Connection conexao;
    public static String driver = "net.sourceforge.jtds.jdbc.Driver";
    public static String servidor = "192.168.0.7:1433";
    public static String base = "smarapdweb";
    public static String login = "usrddw";
    public static String senha = "@#smar#@";
    public static String url = "jdbc:jtds:sqlserver://"+servidor+"/"+base;

    String name = "";
    String xml = "";
    java.io.InputStream layout = null;
    LinkedList lRequeridos = new LinkedList();
    Hashtable hshTipos = new Hashtable();
    java.util.Map parameters = new java.util.HashMap();

    public Relatorio() throws SQLException{
        try {
            Class.forName(driver);
            conexao = DriverManager.getConnection(url,login,senha);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (SQLException s) {
            s.printStackTrace();
        }

        StringBuffer sql = new StringBuffer("SELECT layout,xml,titulo FROM RelatoriosJava WHERE idrelatorio = 354");
        PreparedStatement pSt = conexao.prepareStatement(sql.toString());
        ResultSet rs = pSt.executeQuery();
        if(rs != null){
            rs.next();
            layout = rs.getBinaryStream(1);
            xml = rs.getString(2);
            name = rs.getString(3);
        }
        buildParams(xml);

    }

    public String executar() throws Exception{
        String a = "";
        if (layout == null) throw new Exception("Relatório vazio.");
        String nameRel = getRandom(20);
        parameters.put("REPORT_LOCALE", new Locale("pt", "BR"));
        JasperPrint jasperPrint = JasperFillManager.fillReport(layout, parameters, conexao);


        try {
            FileOutputStream fileStream = new FileOutputStream(nameRel);
            ObjectOutputStream os = new ObjectOutputStream(fileStream);
            os.writeObject(jasperPrint);
            a = os.toString();
            os.close();
        } catch (Exception ex) {
            ex.printStackTrace();
        }
         return a;


    }
}
Agora quando vc instancina o FileOutputStream oque vc passa ali é somente o nome do objeto ? E quando vai ler novamente é assim mesmo ?
FileInputStream fIn = new FileInputStream(sJasperPrint);
            ObjectInputStream in = new ObjectInputStream(fIn);
            JasperPrint jasperPrint = (JasperPrint) in.readObject();

            JasperPrintManager.printPage(jasperPrint, 0, propPrint);

Essa variavel sJasperPrint é a variavel que recebo do metodo que serializa e retorna na variavel a. é uma string entao eu consigo passar isso na applet so q nao funciono !!! Tem alguma ideia ?

E

Uma applet consegue receber parâmetros em strings (tag PARAM) mas cuidado, você tem de passar parâmetros não muito grandes, e tome o cuidado de não fazer isto aqui:

a = os.toString();

Pelo simples motivo que isso não transforma seu objeto em uma String, e sim faz uma outra coisa muito bizarra.

Se realmente você insiste em transformar um objeto em uma String, tente o seguinte:

A

Da uma olhada nos exemplos que achei quando precisei utilizar a serializacao de objetos

http://www.ibm.com/developerworks/br/library/j-5things1/index.html

public class AppSerializacao {

    public static void main(String[] args) {

        ArrayList<Tenis> listaTenis = new ArrayList<Tenis>();
        listaTenis.add(new Tenis(44, "Nike", "Shoks TL 2"));
        listaTenis.add(new Tenis(42, "Adidas", "Microbounce"));
        serializaListaTenis(listaTenis, "D:\\serializados.dat");
        ArrayList<Tenis> listaRecuperada = deserializaListaTenis("D:\\serializados.dat");

        for (Tenis t : listaRecuperada) {
            System.out.println(t);
        }
    }

    private static void serializaListaTenis(ArrayList<Tenis> listaTenis, String arquivo) {
        FileOutputStream arq = null;
        ObjectOutputStream out = null;
        try {
            //arquivo no qual os dados vao ser gravados
            arq = new FileOutputStream(arquivo);
            //objeto que vai escrever os dados
            out = new ObjectOutputStream(arq);
            //escreve todos os dados
            out.writeObject(listaTenis);
        } catch (IOException ex) {
            ex.printStackTrace();
        } finally {
            try {
                arq.close();
                out.close();
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
    }

    private static ArrayList<Tenis> deserializaListaTenis(String arquivo) {
        FileInputStream arqLeitura = null;
        ObjectInputStream in = null;
        ArrayList<Tenis> lista = null;
        try {
            //arquivo onde estao os dados serializados
            arqLeitura = new FileInputStream(arquivo);
            //objeto que vai ler os dados do arquivo
            in = new ObjectInputStream(arqLeitura);
            //recupera os dados
            lista = (ArrayList<Tenis>) in.readObject();
        } catch (ClassNotFoundException ex) {
            ex.printStackTrace();
        } catch (IOException ex) {
            ex.printStackTrace();
        } finally {
            try {
                arqLeitura.close();
                in.close();
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
        return lista;
    }
}
public class Tenis implements java.io.Serializable {

    private int tamanho;
    private String marca;
    private String modelo;

    public Tenis() {
    }

    public Tenis(int tamanho, String marca, String modelo) {
        this.tamanho = tamanho;
        this.marca = marca;
        this.modelo = modelo;
    }

    public String getMarca() {
        return marca;
    }

    public void setMarca(String marca) {
        this.marca = marca;
    }

    public String getModelo() {
        return modelo;
    }

    public void setModelo(String modelo) {
        this.modelo = modelo;
    }

    public int getTamanho() {
        return tamanho;
    }

    public void setTamanho(int tamanho) {
        this.tamanho = tamanho;
    }

    @Override
    public String toString() {
        return "Tenis{" + "tamanho=" + tamanho + ", marca=" + marca + ", modelo=" + modelo + '}';
    }
}
luisbizzan

AndreBonatti bom dia, so pra esclarecer uma coisa que não esta clara, quando vc serializa um objeto, vc transforma o objeto java em um objeto fisico ? É isso mesmo, e depois faz o caminho inverso ?
Eu quero transformar um objeto java, em um conjunto de string. para passar por parametro em uma applet, será q é isso mesmo que devo fazer serializar o objeto JasperPrint ?

A

Seguinte serializando um objeto, vc transforma objeto virtual como esta estrutrado em memoria para onde vc utilizar seja enviar no (HD, Steam,etc.), a classe contem um ID Serial dentro dela que fica marcado no objeto e passado, por isso se vc tiver a mesma classe em outro projeto vc apenas faz um cast (classe) e ela consegue se identificar. Nao sei que ide vc utiliza mas antigamente, nao sei hj o eclipse pedia que identificasse o ID serial Exemplo:. static final long serialVersionUID = -6618469841127325812L;

Deixa ve se entendi o seu problema e o que vc ta tentando fazer:
vc quer pegar seu objeto (jasper) transformar ele literalmente numa String … passar (String[] args) do applet depois … recuperar esse String transformando em objeto novamente … e finalmente gerando o relatório.

Se e realmente isso não acho que vai da certo … e sinceramente não sei como te ajudar.

luisbizzan

Realmente era isso mesmo, cara q foda, mas vc ja precisou fazer alguma applet para impressão? Como que vc fez? so passa uma string com os valores e monta o relatorio no client ?

A

No meu caso não foi pra essa utilização, implementei um sistema de comunicação Socket, como cliente-Servidor só que com umas funções invertidas a lógica cliente-Servidor. Também já implementei comunicação RMI para entregar apenas o JasperPrint, para o client fazendo, fazendo todo o processamento no server e entregando apenas a resultado ao client . Não sei qual a melhor maneira de tu fazer, por não entender como vai funcionar a infraestrutura de comunicação entre eles … se vc fez web, desktop (cliente-Servidor), a base vai estar num lugar especifico tudo pode variar dependendo do que tu planejou, penso que melhor solução seja Socket, mas tem RMI, ou até uma solução escrever num determinado arquivo como feito no exemplo depois o applet apenas lê o arquivo (mas suscetivo a problema, mas possível), passando por parâmetro o caminho do arquivo a ser lido. Mas como falei depende de como foi estruturado e pensado para funcionar…

bom ai vai de vc estudar qual melhor solução que te atenda. Blz …

luisbizzan

Então André mudei a ideia cara, minha aplicação web sempre gera os relatórios partindo do binario do relatorio que eu salvo em uma coluna de tabela, isso me otimiza no tempo, mas como eu nao consigo enviar o JasperPrint para a applet, oq eu pensei vou enviar entao o XML. Até ai blz a applet compila ele e boa, mas e as informações que a aplicação web busca no banco para processar o relatorio. Entao aqui na empresa fizesmos uma classe que converte CachedRowSet para XML, e tivemos que fazer o inverso tambem. Ai matou o problema envio os 2 XML e processo tudo na applet. Fiz um teste em um prototipo funcionou, agora vou montar a applet mesmo dentro da minha aplicação e ver os resultados. Eu posto a conclusão depois. Abraço e valeu pela ajuda !!!

luisbizzan

Cara deu certo a ideia de gerar um CachedRowSet em xml e envia-lo como parametro para applet. assim consigo todas as informações la e ela q me processa o relatorio.

So que agora estou com uma duvida/problema. Como a applet não tem nenhum botão, ela só serve para impressão direta, tem como apos a impressão ela fechar o navegador ? Não tenho nem ideia de como fazer isso ? Alguem ja fez?

Criado 18 de julho de 2012
Ultima resposta 24 de jul. de 2012
Respostas 10
Participantes 3