Thursday, November 17, 2011

Instalação (manual) do Java 7 no Ubuntu 11 64 bits


Roteiro para instalar o Kit de desenvolvimento do Java (JDK) 7 no Ubuntu 11 64 bits, de forma manual, baixando o pacote do jdk7 direto do site da Oracle.

Baixe o tar com o pacote de binários do site da Oracle.

Depois é só colocar o arquivo na pasta /usr/lib/jvm e extrair o tar, por exemplo (meu arquivo é jdk-7u1-linux-x64.tar.gz):

$ sudo mv /home/yaw/Download/jdk-7u1-linux-x64.tar.gz /usr/lib/jvm/jdk-7u1-linux-x64.tar.gz
$ tar -zvxf jdk-7u1-linux-x64.tar.gz

Próxima etapa é configurar o ambiente, isso pode ser feito também de forma manual editando o arquivo bashrc:

$ sudo vim /home/yaw/.bashrc

Outra opção seria realizar a configuração através do comando update-alternatives. A seguir a instrução que abre o menu com opções de atualização do Java.
$ sudo update-alternatives --config java

Provavelmente existem três, começando com a Selection 0, não selecione nenhuma, saia usando enter.

O comando a seguir cria a quarta opção, Selection 3, apontando para a pasta do Java 7:
$ sudo update-alternatives --install /usr/bin/java java /usr/lib/jvm/jdk1.7.0/jre/bin/java 3

Rode novamente o comando para atualizar o Java:

sudo update-alternatives --config java

Escolha a Selection 3 (a mesma que vc criou para o Java 7).


Pronto, fácil.

@edermag
www.yaw.com.br

Thursday, November 03, 2011

O TDC2011 foi tri-sucesso

Não poderia deixar de escrever sobre a tri-participação da YaW no The Developer’s Conference 2011, conhecido como o TDC2011. Copiando uma frase da Yara: “somos 100% TDC2011”, presentes na edição São Paulo, Florianópolis e Goiânia.

Florianópolis

O evento em Florianópolis contou com 12 trilhas em 2 dias, 20 e 21 de Agosto, em sua 4a edição. Muito conteúdo, ótima organização, e uma galera bastante interessada no evento, em trocar idéias e fazer networking. Fiquei impressionado com o número de pessoas presentes no encerramento: um sábado, passando das 19 horas o auditório estava completamente lotado, impressionante!





Lá apresentei a palestra com as mudanças e novidades do Java 7 e junto com o Rafael Nunes a palestra sobre Arquiteturas JavaEE no Google App Engine, ambas na trilha Java. No domingo como congressista, assisti diversas palestras em várias trilhas. O Rafael Nunes foi o coordenador da trilha SOA/Cloud, em parceria com o Felipe Oliveira (SOAExpert).





Goiânia

Eu não conhecia Goiânia, adorei a cidade, muito bonita com um povo muito simpático. Falando sobre o evento, foi um sucesso, mais de 500 pessoas estiveram presentes nos dois dias do TDC2011 Goiânia, 29 e 30 de outubro. Foi a primeira edição do evento na região, que contou com 13 trilhas, e muita gente fera das comunidades presentes.

No mesmo espírito TDC, a galera estava 100% interessada no evento, rolando muita troca de informação e networking. Revi vários amigos, conheci uma galera muito gente boa e bastante prestativa. No primeiro dia, como congressista, assisti palestras nas trilhas: Empreendedorimo, Arduíno e Java.




No domingo fui o coordenador da trilha Mobile, e tenho muito a agradecer aos palestrantes dessa trilha que simplesmente arrebentaram, com palestras excelentes em diversos assuntos:
  • Como tirar proveito de uma plataforma Cloud (Google App Engine) em desenvolvimento Mobile, com o Rafael Nunes;
  • Soluções da Nokia para desenvolvimento mobile: Windows Phone e Symbia, com o Heitor Repolho;
  • As alternativas e o mercado de mobilidade, com Marcelo Quinta;
  • Os desafios no desenvolvimento de sites para mobile, com Marcelo Quinta e André Vilas Boas;
  • Uma visão completa de como funciona o programa de desenvolvedor iOS (iPhone, iPod, iPad), com Edson Luiz;
  • Reuso de código Android com as ferramentas BugSense e PushLink, com Célio Vasconcelos;

Destaque para a palestra do Rafael Costa, um GAROTO de 13 anos atualmente com 9 aplicativos publicados no Apple Store! O Rafa falou sobre desenvolvimento iOS com o framework GameKit, e impressionou a galera com seu conhecimento, desenvoltura e habilidade na apresentação da palestra. No fim da palestra ele interagiu com o público, respondendo com muita boa vontade todas as perguntas e curiosidades da galera.

Agradecimento mais do que especial para o Marcelo Quinta, grande profissional, gente finíssima, me ajudou muito na formação de conteúdo da trilha.

O Rafael Nunes, além de apresentar a palestra na trilha Mobile, foi o
coordenador da trilha SOA/Cloud, novamente em parceira com o Felipe Oliveira.



Outro destaque do TDC2011 Goiânia foram os happy’s e as baladinhas, rolou muita diversão, com direito até a uma canja do Saulo Arruda: o cara arrebentou, manda muito bem no violão!

O TDC já foi consolidado com um dos melhores e principais eventos sobre desenvolvimento de software do Brasil, seu formato inovou e agradou as diversas comunidades que apoiaram e seguiram proposta do evento. O TDC2011, no meu caso, foi uma oportunidade para:
  • Compartilhar um pouco do que eu conheço;
  • Aprender mais e renovar minhas inspirações;
  • Conhecer pessoas de diferentes estilos, com foco em conteúdo;
  • Conhecer lugares interessantes;
  • Muita diversão, com happy’s regados a muita cerveja e excelentes conversas;

Uma pena que TDC2011 acabou, mas já na expectativa pois logo logo chega a vez do TDC2012! Parabéns a Globalcode e a empresas que atuaram na organização das 3 edições do TDC2011, foi incrível.

@edermag
www.yaw.com.br

Friday, October 14, 2011

Oracle linguistic sort: desconsiderar letras minúsculas/maiúsculas e acentuação

A partir da versão 10g o Oracle passou a suportar a busca em String utilizando classificação linguística (linguistic sort). O que na prática permite a busca em um campo String desconsiderando diferenças, por exemplo, entre letras minúsculas e maiúsculas ou o uso de acentuação.

Os comandos a seguir habilitam, na sessão do usuário, a comparação por linguística e a classificação binária desconsiderando acentuação e case insensitive:

ALTER SESSION SET NLS_SORT='BINARY_AI';
ALTER SESSION SET NLS_COMP='LINGUISTIC';

CREATE TABLE teste (texto VARCHAR2(10));
INSERT INTO teste VALUES('Macaco');
INSERT INTO teste VALUES('maça');
INSERT INTO teste VALUES('maçarico');
INSERT INTO teste VALUES('MAÇONARIA');

SELECT texto FROM teste WHERE texto like 'mac%';

TEXTO
---------
Macaco
maça
maçarico
MAÇONARIA


O mesmo resultado é processado com a seguinte instrução:

SELECT texto FROM teste WHERE texto like 'MAÇ%';

Mesmo informando o acento, como no segundo comando, registros sem acentuação são Macaco sem acento é retornado.

O Oracle também suporta a busca ordena por um idioma:

SELECT texto FROM teste ORDER BY NLSSORT(texto, 'NLS_LANG = PT');

Outra funcionalidade, apresentar a descrição da data em um determinado idioma:

SELECT to_char(sysdate, 'DD/MON/YYYY', 'nls_date_language = French') 
FROM dual;

Link para a documentação online dessas funcionalidades.



Tuesday, August 23, 2011

Solução em Java 7 para a prova do Google Developer Day 2011

Semana passada me diverti um pouco com a prova para o Google Developer Day 2011. A prova não é obrigatória, na verdade faz parte do processo de inscrição e dever ser utilizada como filtro para identificar as pessoas que se adequema o público alvo do evento: Developers.

A prova era composta por 5 questões, todas em torno de 2 textos do idioma Googlon.


Regras do idioma

Letras e ordem do idioma: t w d c r z p s v h m k l n f x q j b g

Esse idioma estipula grupos de letras:
  - letras tipo foo: g, f, z, t e s
  - letras tipo bar: todas as outras.

As preposições são identificadas com a seguinte regra: palavras com 3 letras que terminam com uma letra do tipo bar, mas que não pode ser m.

A regra para identificar verbos: palavras de 7 ou mais letras que terminam com uma letra do tipo bar. Caso a palavra seja um verbo e começe com uma letra do tipo bar, deve ser considerado um verbo de primeira pessoa.

E os números? As palavras são números. Esses números são formados em base 20, onde cada letra é uma digito ordenado do menos para o mais significativo (contrário do binário). Dessa forma a primeira posição é 1, a segunda é 20, a terceira é 400 e assim por diante. Outro detalhe importante: cada letra tem um valor (posição) conforme a ordem do alfabeto, por exemplo t é 0, w é 1, d é 2, etc. Ainda para os números, existem uma classificação de números bonitos. Em Googlon um número bonito deve ser maior ou igual a 502344 e divisível por 4.


Questões

Todas as questões contavam com uma dica do Google, elas eram respondidas levando em consideração a o texto A, mas o participante deveria responder considerando o texto B.
  1. Qual a quantidade preposições no texto B?
  2. Quantos verbos existem no texto B?
  3. Quantos verbos em 1a pessoa existem no texto B?
  4. Imprimir o texto B colocando as palavras na ordem alfabética do Googlon.
  5. Quantos números bonitos existem no texto B?

A solução

Na semana passada estava focado em terminar demos e a apresentação que fiz no TDC2011 em Floripa, sobre Java 7. Aproveitei o embalo pra implementar a solução da prova do GDD usando Java, mas com um detalhe especial: primeiro programa utilizando Java 7. Coloquei as letras na ordem do Googlon em um List e fiz um split do texto (uma String). Dessa forma iteirei sob as palavras para encontrar as preposições, verbos (1a pessoa tb) e números, além de aplicar a ordenação Googlon.

import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.TreeSet;

import static java.lang.System.out;

public class Googlon {

static List<Character> alf_ordem = 
    Arrays.asList( new Character[] {'t','w','d','c','r','z','p','s','v','h',
      'm','k','l', 'n','f','x','q','j','b','g'} );

  public static void main(String[] args) {
    String textoB = "prm pmqcf flqk mblz fzrr ..."; //um pedaco do texto B

    int preposicoes = 0, verbos = 0, verbos1Pessoa = 0, numerosBonitos = 0;
    //determina as letras do tipo foo
    List<Character> foo = 
      Arrays.asList( new Character[]{'g','f','z','t','s'} );

    //treeset com comparator resolvendo a ordem as palavras (questao 3)
    TreeSet<String> listaEmOrdem = new TreeSet<>(new Comparator<String>(){
      @Override
      public int compare(String s1, String s2) {
        int len1 = s1.length(), len2 = s2.length();
        int lim = Math.min(len1, len2);
        char chars1[] = s1.toCharArray(), chars2[] = s2.toCharArray();

        int i = 0;
        while (i < lim) {
          char c1 = chars1[i];
          char c2 = chars2[i];
          if (c1 != c2) {
            return alf_ordem.indexOf(c1) - alf_ordem.indexOf(c2);
          }
          i++;
        }
        return len1 - len2;
      }
    });

    //aqui percorro todas palavras, para ordernar e validar
    for (String s: textoB.split(" ")) {
      listaEmOrdem.add(s);

      if (isNumeroBonito(converteParaNumero(s))) {
        numerosBonitos++;
      }

      if (s.length() == 3) {
        if (!foo.contains(s.charAt(s.length()-1)) && s.indexOf('m') == -1) {
          preposicoes++;
        }
        continue;
      }

      if (s.length() >= 7) {
        if (!foo.contains(s.charAt(s.length()-1))) {
          verbos++;
          if (!foo.contains(s.charAt(0))) {
            verbos1Pessoa++;
          }
        }
      }
    }

    StringBuilder textoOrdenadoTeste = new StringBuilder();
    for (String s: listaEmOrdem) {
      textoOrdenadoTeste.append(s).append(" ");
    }

    out.println("1a resposta, qtde de preposicoes: "+preposicoes);
    out.println("2a resposta, qtde de verbos: "+verbos);
    out.println("3a resposta, qtde de verbos 1a pessoa: "+verbos1Pessoa);
    out.println("4a resposta, o texto ordenado: "+ textoOrdenadoTeste);
    out.println("5a resposta, qtde de numeros bonitos? "+numerosBonitos);
  }


  private static long converteParaNumero(String palavra) {
    int n = 0;
    long total = 0;
    for (char c: palavra.toCharArray()) {
      int codigo = alf_ordem.indexOf(c);
      total += codigo * (long) Math.pow(20,n++);
    }
    return total;
  }

  private static boolean isNumeroBonito(long numero) {
    //literal int com separador _ e a literal 4 em binario
    return numero >= 502_344 && numero % 0b100 == 0;
  }

}
Para rodar essa classe em versões anteriores do Java é muito simples, na ordem:
  • defina a tipagem de String na instância do objeto TreeSet no lugar do operador diamond.
  • dentro do método isNumeroBonito, na linha 92, remova o "_" entre o número 502304 e utiliza 4 em decimal ao invés de binário (0b100).

@edermag
www.yaw.com.br

Friday, August 05, 2011

Como mudar o encoding de arquivo com conteúdo para UTF-8 no Linux

Alguns dias atrás trabalhei um projeto para customizar um portal para China. Nada muito complicado, afinal era só usar a estrutura do projeto já implementado no Brasil, EUA e outros países para a China.

Mas.... o portal foi projetado com o padrão de charset ISO-8859-1, que não suporta os caracteres do mandarim. A solução então era migrar a estrutura atual, em ISO-8859-1 para UTF-8, mas o buraco era mais embaixo!

São vários detalhes para resolver, por exemplo:
  • Configuração do ambiente servidor e desenvolvimento;
  • Configuração de web-server, application server e database;
  • Outros...

Aqui vou falar apenas de: arquivos texto com algum conteúdo/caractere especial.

O que fazer com os milhares de arquivos Java, JSP, HTML, JS, PHP e outros com algum caractere especial que foram transformados em �?

Lembrando que por se tratar de um projeto já implementado qualquer arquivo com caractere especial em ISO-8859-1 aberto em UTF-8 fica assim: �. Mudar o texto na mão, arquivo a arquivo era completamente fora de cogitação!

Ainda bem que o Linux quebrou nosso galho, e converteu a codificação dos caracteres especiais de um charset para outro, com o mínimo de esforço! Graças ao programa: iconv

Como utilizar o iconv?
$ iconv -f [charset original] -t [charset desejado] < [arquivo original] > [novo arquivo charset desejado]
$ iconv -f ISO-8859-1 -t UTF-8 < htmlEspecial.html > htmlEspecialNovo.html

O iconv considera o conteúdo do arquivo atual (original) no charset indicado e converte o conteúdo, no caso o(s) caractere(s) especial para o novo charset indicado. Portanto, o arquivo htmlEspecialNovo.html não vai conter o símbolo �, e sim o caractere na formatação correta.

Ficou fácil, mas executar o iconv arquivo a arquivo também seria muito trabalhoso, além de que o objetivo era substituir o arquivo para o novo charset sem criar um novo arquivo.

Pra ficar mais fácil ainda meu brother Gimenez, bolou um script bash para executar processar o iconv para todos os arquivos a partir de uma pasta com filtro na extensão do arquivo.

#!/bin/bash

ICONVBIN='/usr/bin/iconv'

if [ $# -lt 3 ]
then
    echo "$0 from_charset to_charset extesion"
    exit
fi

for f in `find ./ -name "*.$3" -exec file --mime {} \; | grep $1 | cut -f 1 -d :`
do
    if test -f $f
    then
        echo -e "\nConvertendo $f"
        /bin/mv $f $f.old
        RETMV=$?
        if [ $RETMV -gt 0 ]; then
          echo -e "\n Atencao erro no mv"
          exit 1
        fi

        $ICONVBIN -f $1 -t $2 $f.old > $f
        RETICONV=$?
        if [ $RETICONV -gt 0 ]; then
          echo -e "\n Atencao erro no iconv"
          exit 2
        fi

        /bin/rm $f.old
        RETRM=$?
        if [ $RETRM -gt 0 ]; then
          echo -e "\n Atencao erro no rm"
          exit 3
        fi
    else
        echo -e "\nArquivo $f nao convertido";
    fi
done
 

A execução do script convert seria algo do tipo:
> convert iso-8859-1 utf8 java


@edermag
www.yaw.com.br

Thursday, July 21, 2011

Como foi o #TDC2011, um pequeno resumo

Novamente tenho a satisfação em escrever sobre o The Developer's Conference, um evento criado e realizado pela Globalcode. Vou resumir como foi a participação da YaW a 5a edição do The Developer's Conference, o TDC2011. Essa é a nossa 5a participação, nessa última edição colaborando na organização de 2 trilhas!

O evento seguiu a mesma estratégia do ano, organizado em diversas trilhas, com uma diferença: esse ano foram 25 trilhas dividas em 5 dias de evento, rolando muito conteúdo, networking, trabalho e diversão. O mix entre as 25 comunidades foi sensacional, com certeza esse é um dos principais diferenciais da conferência.


Primeiro dia do TDC2011: Coordenação

Trabalhei junto com o Neto Marin na coordenação/organização da trilha Android. Foram 8 palestras nos mais variados níveis, falando sobre arquitetura do Android; boas práticas e dicas de performance no desenvolvimento para Android; como devemos pensar em relação as interface gráfica tanto para smartphones quanto para os tablets; um pouco sobre desenvolvimento de Games em Android e até a integração de APIs para Android com redes sociais. Essa trilha contou com a presença de alguns palestrantes do Google, como o ilustre Tim Bray.



Ainda no primeiro dia do TDC2011 o Rafael Nunes atuou, também, na coordenação/organização na trilha Cloud, junto com o Bruno Souza (JavaMan). Nessa trilha além de uma boa visão sobre as tecnologias para desenvolvimento em Cloud, muito se falou sobre oportunidades de negócios para soluções em Cloud Computing.



Segundo dia do TDC2011: Palestra


Quinta-feira foi um dia mais que especial para nós da comunidade Java, nesse dia rolou o lançamento oficial do Java 7. O lançamento foi mundial, ocorreu simultaneamente em São Francisco,  Londres e em São Paulo durante o TDC2011.

Nesse dia participamos na trilha Java com a palestra do Wellington Pinheiro e o Marcelo Castro (instrutor da Globalcode Alphaville) sobre as novidades do Java 7, com vários exemplos das novidades que tornam o Java uma linguagem mais simples e relativamente menos verbosa. Estive nessa trilha como congressista.




Terceiro dia do TDC2011: Congressista


Na sexta-feira participei da trilha Mobile como congressista, assisti palestras com Roger Brinkley falando um pouco sobre o que a Oracle tem feito com o Java ME (Mobile & Embedded), assisti  palestras com o pessoal da Nokia, e Daniel Galpin do Google apresentando licenciamento e como fazer negócio no Android Marketing.

Tive a oportunidade de conhecer um pouco sobre o desenvolvimento da plataforma mobile da Microsoft, o Windows Phone, gostei do conceito de interface gráficas com metro, mas acho que eles tem muito a fazer pra chegar perto do Android e OS. No final do dia ainda assisti a ótima palestra do Felipe Rodrigues na trilha Ruby, falando sobre "Starting up", com foco empreendedor em fazer acontecer. Depois só diversão, happy hour com os amigos!


Quarto dia do TDC2011: Palestra

No sábado participei da trilha Java EE, que contou com a presença ilustre do Arun Gupta da Oracle. Apresentei a palestra "RichFaces 4: Desenvolvimento Web com JSF2 mais rico", demonstrando alguns componentes da suíte de componentes JSF da JBoss.


Último dia do TDC2011: Diversão

Domingão e eu ja estava bem cansado, nem por isso deixei de ir no dia mais "relax" do TDC2011, era a vez da trilha Arduíno e a trilha Games. Fiquei como congressista no auditório, participando da trilha Stadium, com um resumo das principais palestras do dia.


Pensa que acabou, não...

As manifestações no twitter foram constantes e bem interessantes, hashtag #TDC2011 bombou! A conta TheDevConf mantinha o timeline sempre atualizado com informações das palestras e feedback do evento. Outra característica genial do evento foi a transmissão GRATUITA via web, para quem não pode vir para Sampa. A Globalcode fez uma parceria com o Subway, em todos os dias os participantes podiam comer sem nenhum custo adicional dentro da Faculdade Anhembi Morumbi.

Muitas palestras foram filmadas, logo logo a Globalcode deve disponibilizar o acessos a esses vídeos.


Tem mais?

E agora é a vez do TDC2011 em Floripa que acontece nos dias 20 e 21 de Agosto. As trilhas foram definidas e já é possível submeter propostas de palestras. Nós da YaW estamos super motivados em participar!

Parabéns a Yara e Vinicius, a toda equipe da Globalcode, as empresas parceiras na organização do evento, os palestrantes e congressistas. Veja mais fotos do TDC2011 aqui.

@edermag
www.yaw.com.br

Thursday, July 14, 2011

Emissão de relatórios no Spring Roo e MVC com Jasper Reports

O Spring MVC é uma das tecnologias que mais gostamos e usamos na YaW. Quando uso o termo "gostar" na verdade me refiro a uma tecnologia que atendeu as nossas espectativas do ponto de vista de implementação e mais importante, supriu as necessidades e objetivos do nosso cliente. A nossa experiência com Spring MVC tem sido bem interessante, por isso faz parte de nosso portfólio de soluções.

Nesse post demonstro como intregrar uma aplicação Web desenvolvida pelo Spring MVC com o JasperReports para emissão de relatórios. A integração entre o Spring MVC e JasperReports não tem nenhuma relação com o Spring Roo, mas para facilitar a criação e o desenvolvimento do projeto vou assumir o uso do Spring Roo.

Dependências

Além da biblioteca do JasperReports, dependendo do caso precisamos de outras libs complementares:
  • Spring Support
  • iText (pdf)
  • POI  (xls)


A seguir o trecho do pom.xml (Maven) com configuração dos artefatos. No trecho abaixo também coloco as configurações para o plugin do Maven que automatiza a compilcação dos relatórios jrxml para o formato jasper, utilizado pelo JasperReports:

...
<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-context-support</artifactId>
  <version>${spring.version}</version>
</dependency>
<dependency>
  <groupId>net.sf.jasperreports</groupId>
  <artifactId>jasperreports</artifactId>
  <version>4.0.0</version>
</dependency>
<dependency>
  <groupId>com.lowagie</groupId>
  <artifactId>itext</artifactId>
  <version>2.1.7</version>
  <scope>compile</scope>
</dependency>
<dependency>
  <groupId>org.apache.poi</groupId>
  <artifactId>poi</artifactId>
  <version>3.6</version>
  <scope>compile</scope>
  <optional>true</optional>
</dependency>
...
<plugin>
  <groupId>org.codehaus.mojo</groupId>
  <artifactId>jasperreports-maven-plugin</artifactId>
  <configuration>
    <sourceDirectory>src/main/webapp/WEB-INF/reports</sourceDirectory>
    <outputDirectory>src/main/webapp/WEB-INF/reports</outputDirectory>
  </configuration>
  <executions>
    <execution>
      <goals>
        <goal>compile-reports</goal>
      </goals>
    </execution>
  </executions>
  <dependencies>
    <dependency>
      <groupId>jasperreports</groupId>
      <artifactId>jasperreports</artifactId>
      <version>3.5.3</version>
    </dependency>
    <dependency>
      <groupId>org.apache.log4j</groupId>
      <artifactId>com.springsource.org.apache.log4j</artifactId>
      <version>1.2.15</version>
    </dependency>
  </dependencies>
</plugin>
...

Próxima etapa é configurar no xml do MVC (webmvc-config.xml) o viewResolver do Spring que indica o properties com as configurações de cada relatório.

<bean id="viewResolver" 
  class="org.springframework.web.servlet.view.ResourceBundleViewResolver">
  <property name="basename" value="relatorios"/>
</bean>

O arquivo relatorios.properties (na raiz do diretório de classes) armazena qual a classe que estipula o formato de geração do relatório, a url com o caminho do arquivo do relatório.

No exemplo estou usando o arquivo compilado, o .jasper, mas o Spring aceita a extensão jrxml. A propriedade reportKeyData (opcional) indica o apelido para o DataSource com os dados que o relatório depende. Já o valor relatorioPedidos usado como base das 3 chaves é o identificador do relatório, usamos no retorno do método da Controller que processa o relatório.

relatorioPedidos.(class)=
org.springframework.web.servlet.view.jasperreports.JasperReportsMultiFormatView
relatorioPedidos.url=/WEB-INF/reports/pedidos.jasper
relatorioPedidos.reportDataKey=pedidosDS

A classe JasperReportsMultiFormatView é indicada em relatórios que podem ser emitidos em mais de um formato, ou seja, o mesmo relatório gerado em xls e pdf. Outra alternativa seria utilizar JasperReportsPdfView, nesse caso a emissão ocorre só em pdf.

Pra fechar o método da Controller que processa os dados para emissão do relatório:

...
@RequestMapping("/report")
@Controller
public class ReportController {

  @RequestMapping(value ="/pedido/pdf", method = RequestMethod.GET)
  public String processaRelatorioPedidos(
     @RequestParam String de, @RequestParam String ate,
     ModelMap modelMap) 
  {
    JRBeanCollectionDataSource ds =
      new JRBeanCollectionDataSource(Pedido.findPedidosByDataGeracao(de, ate),false);
    modelMap.put("pedidosDS", ds);
    return "relatorioPedidos";
  }

}

A documentação oficial do Spring disponibiliza um capítulo sobre a integração do Spring MVC com o JasperReports.

@edermag
www.yaw.com.br

Tuesday, February 15, 2011

Spring: Como definir BasicDataSource usando arquivo properties

Definir um BasicDataSource usando as configurações do database definidas em arquivo properties é bem simples, basta definir um PropertyPlaceholderConfigurer.

Arquivo database.properties, com as configurações JDBC:
#usando mysql nesse exemplo
db.driver=com.mysql.jdbc.Driver
db.host=localhost
db.name=yawdb
db.username=yaw
db.password=yaw
db.port=3306
db.url=jdbc:mysql://${db.host}:${db.port}/${db.name}


spring-config.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" ...>
  <bean id="dbProperties"   
   class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <property name="location" value="br/com/yaw/spring/database.properties" />
  </bean>

  <bean id="myDataSource"
   class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
    <property name="driverClassName" value="${db.driver}" />
    <property name="url" value="${db.url}" />
    <property name="username" value="${db.username}" />
    <property name="password" value="${db.password}" />
  </bean>
</beans>

Pronto!

@edermag
www.yaw.com.br

Monday, February 07, 2011

Habilitando conexão Https c/ Java 'ignorando' o certificado

Frequentemente escrevo um código para realizar requisições entre aplicativos, seja para WS/REST ou mesmo um simples HttpClient, usando Https com Java. Como fazer uma requisição SSL sem registrar o certificado na JVM, ou mesmo um 'bypass' em certificado desconhecido?

Aqui deixo um exemplo de como realizar um requisição Https com Java ignorando o certificado. Usando X509TrustManager [mais sobre X509Certificate] e HostnameVerifier de fachada. Na verdade o uso do HostnameVerifier seria pra evitar java.io.IOException: HTTPS hostname wrong: should be ..., já que o nome do certificado não bate com o domínio.

package br.com.yaw.client.ssl.main;

import java.security.cert.X509Certificate;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
//...

public class TestSecureRequest {

  public static void main(String[] args) throws Exception  {
    final X509TrustManager cert = new X509TrustManager() {
      public X509Certificate[] getAcceptedIssuers() {
        return null;
      }
      
      public void checkServerTrusted(X509Certificate[] certs,
        String authType)
      throws java.security.cert.CertificateException {
        return;
      }
      
      public void checkClientTrusted(X509Certificate[] certs,
        String authType)
      throws java.security.cert.CertificateException {
        return;
      }
    };

    //cria socket ssl
    SSLContext sc = SSLContext.getInstance("SSL");
    sc.init(null, new TrustManager[] { cert }, null);

    //ativa o socket para a requisicao
    HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
    
    final HostnameVerifier hv = new HostnameVerifier() {
      public boolean verify(String urlHostName, SSLSession session) {
        return true;
      }
    };

    HttpsURLConnection.setDefaultHostnameVerifier(hv);

    // daqui pra frente o codigo que acionar WS/REST, ou um simples HttpClient
    //...
  }
}

Peace of cake.

@edermag
http://www.yaw.com.br/

Thursday, January 20, 2011

Acessar properties a partir de uma classe no mesmo jar

Mais um post da série: "É melhor anotar! Afinal, vai que, você sabe...."

Como acessar um arquivo properties, ou qualquer tipo de arquivo, a partir de uma classe definida dentro do mesmo jar?


A estrutura do arquivo aplicacao.jar seria algo mais ou menos assim:

| META-INF/
| META-INF/conf.properties
| br/
| br/com/
| br/com/yaw/
| br/com/yaw/LeProperties.class

Simples, através do getResourceAsStream do ClassLoader da classe LeProperties:

public class LeProperties {
  static {
    ... 
    try {
      Properties p = new Properties();
      p.load(LeProperties.class.getClassLoader().getResourceAsStream("META-INF/conf.properties"));
    } catch (Exception e) {
      ...
    } 
  }

  ...

}

@edermag
http://www.yaw.com.br/