WEBCODELOG

free codes, enjoy

Categoria: ‘Programação’

Maven2 com Oracle JDBC

without comments

Se você é um dos milhares que sofre com o erro abaixo, fique calmo, o seu problema está resolvido!

[INFO] Unable to find resource 'com.oracle:ojdbc14:jar:10.2.0.3.0' in repository central
(http://repo1.maven.org/maven2)

[INFO] ------------------------------------------------------------------------
[ERROR] BUILD ERROR
[INFO] ------------------------------------------------------------------------
[INFO] Failed to resolve artifact.

Missing:
----------
1) com.oracle:ojdbc14:jar:10.2.0.3.0

 Try downloading the file manually from the project website.

 Then, install it using the command:
 mvn install:install-file -DgroupId=com.oracle -DartifactId=ojdbc14
-Dversion=10.2.0.3.0 -Dpackaging=jar -Dfile=/path/to/file

 Alternatively, if you host your own repository you can deploy the file there:
 mvn deploy:deploy-file -DgroupId=com.oracle -DartifactId=ojdbc14
-Dversion=10.2.0.3.0 -Dpackaging=jar -Dfile=/path/to/file -
Durl=[url] -DrepositoryId=[id]

 Path to dependency:
 1) br.com.ninecon.core:isupport:war:0.0.1-SNAPSHOT
 2) com.oracle:ojdbc14:jar:10.2.0.3.0

É possível configurar o repositório do Maven, utilizando a biblioteca localmente, ou seja, se você já tem o arquivo .jar em seu computador, pode corrigir o problema adicionando este arquivo ao repositório.

No meu caso foi simples, pois eu já tinha o banco de dados Oracle instalado localmente, mas caso você não tenha, faça o download library OJDBC.

Acesse o diretório onde esta o arquivo jar.

C:\Users\luciano>cd %ORACLE_HOME%/jdbc/lib

Execute o comando de instalação da library conforme abaixo passando os parametros necessários. No exemplo o banco utilizado é o 10.2.0.3.0.

c:\oracle\product\10.2.0\db_1\jdbc\lib>mvn install:install-file -Dfile=ojdbc14.jar -DgroupId=com.oracle -DartifactId=oracle -Dversion=10.2.0.3.0 -Dpackaging=jar -DgeneratePom=true
[INFO] Scanning for projects...
[INFO] Searching repository for plugin with prefix: 'install'.
[INFO] org.apache.maven.plugins: checking for updates from central
[INFO] org.codehaus.mojo: checking for updates from central
[INFO] ------------------------------------------------------------------------
[INFO] Building Maven Default Project
[INFO]    task-segment: [install:install-file] (aggregator-style)
[INFO] ------------------------------------------------------------------------
[INFO] [install:install-file {execution: default-cli}]
[INFO] Installing c:\oracle\product\10.2.0\db_1\jdbc\lib\ojdbc14.jar to C:\Users\luciano\.m2\repository\com\oracle\oracle\10.2.0.3
.0\oracle-10.2.0.3.0.jar
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 3 seconds
[INFO] Finished at: Wed Jun 09 20:32:02 BRT 2010
[INFO] Final Memory: 3M/15M
[INFO] ------------------------------------------------------------------------
'cmd' is not recognized as an internal or external command,
operable program or batch file.
c:\oracle\product\10.2.0\db_1\jdbc\lib>

Perceba que o artifactId esta como oracle, portanto o seu pom.xml deve ser modificado também.

Com este simples comando você resolverá um problemão chato! ;)

Written by Luciano

junho 9th, 2010 at 9:01 pm

Posted in Programação

Tagged with , , ,

Autenticação e Autorização com a API do Twitter

without comments

O Twitter veio para ficar e isto eu não discuto e, este blog quando empolgado com o micro-blog público um exemplo simples de como utilizar o Twitter4j. Agora estou tentando mostrar uma forma mais avançada de comunicação com o Twitter, utilizando o modo de autenticação/autorização.

No exemplo anterior além de obter o Customer Key e Secret, você irá precisar do Usuário e Senha do Twitter, para assim obter a comunicação devida. Bem, nem todo mundo sente-se disposto a oferecer seus dados confidênciais para um software ou site qualquer. Portanto, este novo exemplo mostrará como você deve comunicar com o Twitter deixando a autenticação por parte do micro-blog e autorização por parte do próprio usuário.

Dando sequência ao assunto, inicialmente você precisará registrar uma aplicação no Twitter caso ainda não a tenha, guarde os dados Consumer Key e Secret. Existem dois tipos de aplicações a Client (Desktop) e Browser (Web), sendo que a segunda precisará de uma url que receberá o Token de autenticação.

Infelizmente, este post foi prejudicado pela falta de um web hosting que suporte Java, a Locaweb (atual host deste blog) cobra valores mensais absurdos, que inviabiliza blogs com intuito simplesmente acadêmico, como este, de realizar testes utilizando a linguagem Java.

Consegui descobrir lendo aqui, aqui e aqui que é possível configurar o seu localhost como Callback URL no Twitter, assim não será necessário ter um site publicado na internet para seus testes.

Web Autenticação

Durante o registro você irá informar o tipo de aplicação Browser e uma Callback URL, é para onde o navegador será redirecionado após a autorização do usuário. Já o campo Application Website, é a origem da sua aplicação web, ou seja, serão aceitas as chamadas feitas apenas a partir deste site.

O código abaixo irá fazer iniciar o processo de autenticação, o navegador vai ser redirecionado para a página de login do Twitter.

 final String CALLBACK_URL     = "http://127.0.0.1:8080/BlogTwitt4u/"; // a mesma configurada na aplicação
 final String CUSTOMER_KEY     = "6MWotGxvuNVGfK4lDqAqhg";
 final String CUSTOMER_SEC     = "oRH0YviLum2Rrii25ePj0DEk6VnmNjoTG0ESUpqSY";

 OAuthConsumer consumer         = new DefaultOAuthConsumer(CUSTOMER_KEY, CUSTOMER_SEC);
 OAuthProvider provider         = new DefaultOAuthProvider( "https://twitter.com/oauth/request_token",
 "https://twitter.com/oauth/access_token",
 "https://twitter.com/oauth/authorize" );

 //
 // Solicita a autorização
 //
 String authUrl = provider.retrieveRequestToken(consumer, CALLBACK_URL);
 session.setAttribute("token",         consumer.getToken());
 session.setAttribute("tokenSecret", consumer.getTokenSecret());

 //
 //
 // Redireciona para  o Twitter solicitar o Usuário e Senha, e Autorização para a aplicação
 // Em seguida será redirecionado para a callback url
 response.sendRedirect(authUrl);

Após fazer o login e autorizar a sua aplicação, o navegador será redirecionado novamente para o seu site, com dois parâmetros preenchidos, como esta abaixo:


http://127.0.0.1:8080/BlogTwitt4u/?oauth_token=RQVPENBxDbQuI1bJ1rjELuVSyZhMYqr8Fcs5eqyZw&oauth_verifier=a8FuEeitfdCR2IfgisfsHopMAUevs4cDyRWkbZz4

Pronto, ai você já pode colher as informações que desejar, veja:

 if( oauthVerifier!=null && !oauthVerifier.trim().equals("") ){

 String token            = (String) session.getAttribute("token");
 String tokenSecret        = (String) session.getAttribute("tokenSecret");

 //
 consumer.setTokenWithSecret(token, tokenSecret);

 //
 //
 provider.setOAuth10a(true);
 provider.retrieveAccessToken(consumer, oauthVerifier);

 out.println("<h1>AUTORIZADO!</h1>");
 out.println("<pre>");
 out.println("token:\t\t" + consumer.getToken());
 out.println("tokenSecret:\t\t" + consumer.getTokenSecret());
 out.println("oauthVerifier:\t\t" + oauthVerifier);
 out.println("oauthToken:\t\t" + oauthToken);

 //
 //
 URL url                         = new URL("http://twitter.com/statuses/mentions.json");
 HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
 consumer.sign( urlConnection );
 urlConnection.connect();

 BufferedReader in    = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()) );
 String inputLine     = "";
 String content       = "";
 while ((inputLine = in.readLine()) != null){
     content += inputLine;
 }// while end
 in.close();

 int statusCode = urlConnection.getResponseCode();
 out.println("statusCode: " + statusCode);
 out.println("</pre>");

 JSONArray json = JSONArray.fromObject( content );

 out.println("<hr>");
 out.println("<h3>Mentions</h3>");
 out.println("<pre>");
 for(int i=0; i<json.size(); i++){

 JSONObject obj = (JSONObject) json.get(i);
 if( obj!=null ){
   // JSONString str = (JSONString) obj.get("text");
   out.println(obj.getString("text"));
 }

 }// for end
 out.println("</pre>");

 }

Desktop Autenticação

Este é um exemplo comum, muito conhecido em qualquer pesquisa no Google, para utiliza-lo você deve ter uma aplicação do tipo Client.

O código pede para que o usuário abra o navegador, acesse uma determinada URL e depois informe o código númerico no programa, nada eficaz né? Muitos programadores utilizam uma maneira nada elegante que é a de “hackear” esta página e pegar o código automáticamente, facilitando a vida de todo mundo. Faça isto por sua conta e risco. Perceba que quando comparado ao código de autenticação Web a única mudança é a utilização do código PIN, que não necessário informar na web.

<pre>
<pre><pre>// Lembre-se de modificar estes valores para os seus
//
final String CUSTOMER_KEY = "6MWotGxvuNVGfK4lDq";
final String CUSTOMER_SEC = "oRH0YviLum2Rrii25ePj0DEk6VnmNjoTG0ESUp";

try {
HttpURLConnection request = null;
URL url = null;
OAuthConsumer consumer = new DefaultOAuthConsumer(CUSTOMER_KEY, CUSTOMER_SEC);

OAuthProvider provider = new DefaultOAuthProvider( <a href="https://twitter.com/oauth/request_token">https://twitter.com/oauth/request_token</a>,
"https://twitter.com/oauth/access_token",
"https://twitter.com/oauth/authorize");

String authUrl = provider.retrieveRequestToken(consumer, OAuth.OUT_OF_BAND);
//
// URL Que irá retornar o PIN, necessário para formar o Token
System.out.println(authUrl);

String pinCode = JOptionPane.showInputDialog("Acesse o endereço:\n" + authUrl + "\nE Informe o PIN:");
System.out.println("PIN Code: " + pinCode);

//
provider.retrieveAccessToken(consumer, pinCode);

String tokenKey = consumer.getToken();
String tokenSec = consumer.getTokenSecret();

System.out.println("Token Key : " + tokenKey);
System.out.println("Token Sec : " + tokenSec);

consumer.setTokenWithSecret(tokenKey, tokenSec);

url  = new URL(<a href="http://twitter.com/statuses/mentions.xml">http://twitter.com/statuses/mentions.xml</a>);
 request = (HttpURLConnection) url.openConnection();
// sign the request
consumer.sign(request);

// send the request
request.connect();

// response status should be 200 OK
int statusCode = request.getResponseCode();
System.out.println("Status Code : " + statusCode);

} catch (OAuthMessageSignerException e) {
e.printStackTrace();
} catch (OAuthNotAuthorizedException e) {
e.printStackTrace();
} catch (OAuthExpectationFailedException e) {
e.printStackTrace();
} catch (OAuthCommunicationException e) {
e.printStackTrace();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}

Foram utilizadas as seguintes bibliotecas:
Apache Commons BeansUtil 1.8
Apache Commons Codec 1.4
Apache Http Client 3.1
Apache Commons Lang 2.4
ezmorph 1.0.6
json-lib 2.3

Faça download do projeto, que contêm ambos exemplos de autenticação.

Written by Luciano

fevereiro 13th, 2010 at 9:27 pm

Usando a API LastFm em Java

without comments

A LastFm é a queridinha das rádios online, mesmo com diversos concorrentes de alto nível como iLike, Pandora, Imeem, e outros tantos, aqui no Brasil a LastFm é um grande sucesso, seus milhões de usuários brasileiros ignoraram o bloqueio de alguns recursos e continuam fazendo scrobbling de seus áudios diáriamente.

Além de um database music, o LastFm é uma rede social e grande parte de suas informações são públicas e podem ser acessadas facilmente através de sua API.
Vamos dar inicio a um exemplo de como consumir os dados utilizando a library para Java lastfm-java. Antes de tudo, se você não tiver uma conta no LastFm, crie-a agora e depois obtenha a API Key. Neste mesmo link você encontrará a documentação da API, que detalha claramente a funcionalidade de cada método disponível e como é o seu acesso e se necessita ou não de autenticação.

Em nosso primeiro exemplo vamos fazer uma página web que irá listar as últimas faixas ouvidas e a lista de amigos de um usuário específico, com isto, você perceberá que nenhuma autenticação é necessária pois os dados são públicos.

Criei a classe LastFmClient, para facilitar os casts necessários e centralizar as chamadas da API.

public class LastFmClient {
// altere para a sua api key
 private static final String APIKEY = "XyZaBc001";
 private String uName = null;

/**
 *
 * @param uName
 */
 public LastFmClient(String uName){
 this.uName = uName;
 }

/**
 *
 * @return User/Friends List
 */
 public ArrayList<User> getFriends(){
 return (ArrayList<User>) User.getFriends(uName, APIKEY);
 }

 /**
 *
 * @return Tracks List
 */
 public ArrayList<Track> getTracks(){
 return (ArrayList<Track>) User.getRecentTracks(uName, APIKEY);
 }
}

Isto é o suficiente para você montar a lista como descrito acima, veja:

 String userName = request.getParameter("username");
 if( userName!=null && !userName.trim().equals("") ){
 // instancia a classe de backend
 LastFmClient client = new LastFmClient(userName);

 // seu código aqui
 }

Ouvidas recentemente.

<table border="0" cellpadding="2" cellspacing="1">
<% for(Track t : tracks){ %>
<tr>
 <td valign="top" align="left">
 <br/><strong><%=t.getAlbum() %></strong>
 <br/><em><%=t.getArtist() %></em>
 </td>
</tr>
<% }// for end tracks %>
</table>

Lista de amigos.

<table border="0" cellpadding="2" cellspacing="1">
<tr>
<%
 ArrayList<User> friends = client.getFriends();
 int count = 1;
 for(User f : friends){
%>
 <td valign="top" align="center">
 <% if( f.getImageURL()!=null ){ %><img src="<%= f.getImageURL() %>"><% } %>
 <br><strong><%=f.getName() %></strong>
 <br><a href="<%= f.getUrl() %>"><%= f.getUrl() %></a>
 <br/>
 </td>
<%
 if( count%5==0 ) out.print("</tr><tr>");
 count++;

 }// for end friends

}//
%>

Faça download do código completo.

Pronto, você conseguiu acessar dados do LastFm, usando o caminho correto e fácil, sem autenticação. Mas alguns dados são restritos e necessitam da autorização do usuário, informações básicas como a quantidade de músicas ouvidas, data de cadastro, nome, etc. são de acesso restrito.

Written by Luciano

fevereiro 1st, 2010 at 9:41 pm

Posted in Programação,Redes Sociais

Tagged with , ,

Manipulando BLOB – MySQL vs. Oracle

without comments

A missão de um programador em manipular arquivos e armazená-los no banco de dados já não é uma tarefa desafiadora a tempos, visto que é extremamente fácil encontrar exemplos internet a fora, aqui vou fazer mais um, em que o foco é demonstrar a diferença de se realizar o mesmo procedimento utilizando o MySQL e Oracle.

1. Oracle

Primeiramente vamos fazer o processo para gravar um arquivo qualquer no banco de dados.
Criação da tabela que será utilizada para armazenar os arquivos.


CREATE TABLE ARQUIVOS(
ID     NUMBER(4)      NOT NULL,
TIPO   VARCHAR2(20)   NULL,
ARQ    BLOB           DEFAULT EMPTY_BLOB() NOT NULL,
CONSTRAINT PKARQ PRIMARY KEY(ID)
)

Perceba que o campo ARQ que irá guardar o binário, tem como valor default a propriedade EMPTY_BLOB() – Retorna um LOB vazio, para ser usado como um indicador para INSERT ou UPDATE.

No geral, o processo para inserir um campo LOB (BLOB ou CLOB) no Oracle é um pouco burocrático, feito em duas etapas. Primeiro deve-se inserir o registro setando o campo BLOB como EMPTY_BLOB, no em seguida finalizamos com um SELECT FOR UPDATE no campo “LOB” especifico para que o byte[] seja gravado.


// Inserindo o empty_blob
//
String sql  = "INSERT INTO arquivos(id, tipo, arq) VALUES(1, ?, EMPTY_BLOB())";
conn   = ConnOracle.getInstance().getConn();
pstmt1   = conn.prepareStatement(sql);
pstmt1.setString(1, "TEXT");
pstmt1.execute();

Este passo irá fazer com que um arquivo seja armazenado no banco.


// Faz o select como for update
// Inserir o binário
//
String ins  = "SELECT arq FROM arquivos WHERE id = 1 FOR UPDATE";
pstmt2  = conn.prepareStatement(ins);
rset  = pstmt2.executeQuery(ins);
while( rset.next() ){
Blob blob   = rset.getBlob(1);
// filePath eh a String com o caminho do arquivo a ser gravado

File file    = new File( filePath );
byte[] bbuf   = new byte[1024];
InputStream bin  = new FileInputStream( file );
// Realiza o cast especifico para o driver Oracle
OutputStream bout  = ((BLOB) blob).getBinaryOutputStream();

int bytesRead   = 0;
while( (bytesRead = bin.read(bbuf))!=-1 ){
bout.write(bbuf, 0, bytesRead);
}//

if( bout!=null ) bout.close();

}// end while
conn.commit();

2. MySQL

A estrutura da tabela muda pouco, o mais importante é que o campo para armazenar o arquivo é do tipo LONGBLOB, veja:

CREATE TABLE ARQUIVOS(
ID     INT(4)        NOT NULL,
TIPO   VARCHAR(20)   NULL,
ARQ    LONGBLOB      NOT NULL,
PRIMARY KEY(ID)
);

Gravar um campo LONGBLOB no MySQL, é tão fácil quando gravar um int ou uma String, e eu não estou falando no sentido figurado.

   File file    = new File( filePath );
byte[] bytes  = getBytesFromFile( file );</pre>
// Inserindo o longblob
//
String sql  = "INSERT INTO arquivos(id, tipo, arq) VALUES(1, ?, ?)";
conn   = ConnMysql.getInstance().getConn();
pstmt   = conn.prepareStatement(sql);
pstmt.setString(1, "TEXT");
pstmt.setBytes(2, bytes);
pstmt.execute();

O método getBytesFromFile() é uma função genérica para converter o File em byte[], e somente este último é necessário para gravar, fácil assim.

Não posso deixar de indicar este artigo completo e bem detalhado, escrito por Giovane Kuhn do JavaFree.

Espero que estes simples códigos sejam proveitosos, abaixo estão as duas classes utilizadas para este post.

Faça download das classes.

Written by Luciano

novembro 16th, 2009 at 10:55 pm

Posted in Programação

Tagged with , ,

Enviando e-mail com PL/SQL para múltiplos endereços

without comments

A situação mais comum é o envio de e-mail para diversos destinatários, portanto, complementando o código já postado aqui sobre o envio de e-mails utilizando PLSQL.

Uma lista de destinatários formatada normalmente assim:

 Luciano <luciano@lucianosilva.com>, Grupos <grupos@lucianosilva.com>, Futebol <futebol@cfb.com.br

Este é o nosso problema, o Oracle não irá conseguir trabalhar com a String formatada dessa maneira, e irá lançar o erro:

ORA-29279: SMTP permanent error: 501 Bad address syntax

Enfim, para conseguir solucionar o problema do envio de e-mail para multiplos destinatários, utilize a função abaixo, ela irá devolver apenas o endereço de e-mail.


FUNCTION FORMAT_ADDRESS(ADDR_LIST IN OUT VARCHAR2) RETURN VARCHAR2 IS
    ---
    ADDR VARCHAR2(256);
    I    PLS_INTEGER;
    ---
    FUNCTION LOOKUP_UNQUOTED_CHAR(STR IN VARCHAR2, CHRS IN VARCHAR2)
      RETURN PLS_INTEGER AS
      C            VARCHAR2(5);
      I            PLS_INTEGER;
      LEN          PLS_INTEGER;
      INSIDE_QUOTE BOOLEAN;
      ---
    BEGIN
      INSIDE_QUOTE := FALSE;
      I            := 1;
      LEN          := LENGTH(STR);
      WHILE (I <= LEN) LOOP
        C := SUBSTR(STR, I, 1);
        IF (INSIDE_QUOTE) THEN
          IF (C = '"') THEN
            INSIDE_QUOTE := FALSE;
          ELSIF (C = '\') THEN
            I := I + 1; -- Skip the quote character
          END IF;
          GOTO NEXT_CHAR;
        END IF;
        IF (C = '"') THEN
          INSIDE_QUOTE := TRUE;
          GOTO NEXT_CHAR;
        END IF;
        IF (INSTR(CHRS, C) >= 1) THEN
          RETURN I;
        END IF;
        <<NEXT_CHAR>>
        I := I + 1;
      END LOOP;
      RETURN 0;
    END;
  BEGIN
    ADDR_LIST := LTRIM(ADDR_LIST);
    I         := LOOKUP_UNQUOTED_CHAR(ADDR_LIST, ',;');
    IF (I >= 1) THEN
      ADDR      := SUBSTR(ADDR_LIST, 1, I - 1);
      ADDR_LIST := SUBSTR(ADDR_LIST, I + 1);
    ELSE
      ADDR      := ADDR_LIST;
      ADDR_LIST := '';
    END IF;
    I := LOOKUP_UNQUOTED_CHAR(ADDR, '<');
    IF (I >= 1) THEN
      ADDR := SUBSTR(ADDR, I + 1);
      I    := INSTR(ADDR, '>');
      IF (I >= 1) THEN
        ADDR := SUBSTR(ADDR, 1, I - 1);
      END IF;
    END IF;
    RETURN ADDR;
  END FORMAT_ADDRESS;

A mudança do código anterior não é tão drástica, já que o parâmetro é entrada/saída, você pode fazer um looping na lista de endereços para adicionar um-a-um.

UTL_SMTP.MAIL(MAIL_CONN, V_FROM );
    WHILE( V_LIST_ADDRESS IS NOT NULL )LOOP
           UTL_SMTP.RCPT(MAIL_CONN, FORMAT_ADDRESS(V_LIST_ADDRESS) );   
    END LOOP;

Veja que é uma modificação simples, porém, ganha-se muito quando é necessário deixar o programa o mais abrangente possível
Enjoy!

Written by Luciano

novembro 16th, 2009 at 3:54 pm