2012年11月7日 星期三

透過spring直接讀取hibernate session

現在大部分的spring撰寫都很愛用@Autowired

但是當某些特例時不能用...

所以找了一陣子~
總算找到一個可以手動method呼叫取得spring的物件~~



    Session session;
    SessionFactory sessionFactory = null;



        ApplicationContext ctx = new FileSystemXmlApplicationContext(xmlPath);
        sessionFactory = (SessionFactory)ctx.getBean("sessionFactory");      
        session = sessionFactory.openSession();

spring @RequestParam 亂碼

說到spring每次都有一肚子火=__=...
(抱怨結束...)

這次碰到parameter中文拿出來一直都是亂碼...
而且一拿出來就是????...
(一看就知道是被轉了兩次...)
連想要補救的機會都沒有...

後來終於找到是tomcat要再加設定

server.xml
(加上URIEncoding="UTF-8")

<Connector port="80" protocol="HTTP/1.1" 
               connectionTimeout="20000" 
               redirectPort="8443"
               URIEncoding="UTF-8" />

2012年8月14日 星期二

MySQL 亂碼

其實這個問題應該是很common的~
多到~ 只要在google search bar打兩個字就自己幫你帶出一堆了...

不過因為很久沒有看到MySQL..總之~ 太久沒用就是會碰到鬼~
整理一下~ 解法大概就這幾個~

1. jdbc url加參數, 這個可以解掉九成的問題...
jdbc:mysql://{IP}:3306/epagedb?useUnicode=true&characterEncoding=utf8

2. JDBC換個版本的jar試試看
說瞎也不能說很瞎的XD...幾點幾版的jar是對到那一版的MySQL DB..是也有點道理...

3. 下SQL轉換...這是一切無解又無奈的時候...唉...Orz..這次就碰到這個了...
select convert(unhex(hex(convert(pt_name using latin1))) using utf8) as name from xxxtable

因為撈回來的資料是一半中文一半亂碼...
DB table的編碼用default:latin-1, 但是資料用utf-8的碼寫進去的天才...
狠著心用MySQL轉換就可以出來了...只是這個SQL好長長長....

不過發現一樣很慘的是~ 他的來源好像本來就有些是亂碼了~
應該是硬寫了一堆編碼內沒有的字~ 不過這~ 這我也沒辦法了...
系統是別人建的一_一"...

2012年8月10日 星期五

[Hadoop] 基本環境建立-3


Hadoop不能走IPv6...之後新版會不會支援偶就不知啦XD
ubuntu現在新版的default就是IPv6..記得要先關掉

[Cancel IPv6 on Ubuntu]
1. vim /etc/sysctl.conf
2. add code
  net.ipv6.conf.all.disable_ipv6 = 1
  net.ipv6.conf.default.disable_ipv6 = 1
  net.ipv6.conf.lo.disable_ipv6 = 1
3. execute setting
  sudo sysctl -p
4. Test result(It should be empty)
   ip a | grep inet6


//為了方便~ 我把hadoop相關套件一律裝到/etc/hadoop下~ hdfs檔案位置放在HADOOP_HOME/tmp下
//另外也為了操作方便~ 先把那邊的路徑owner改給hadoop user..省著一直問sudo超麻煩
//先做單機測試與安裝

[Hadoop]
1. Download/SFTP tar.gz to /home/hadoop
2. Copy and unzip
   cd /etc
   sudo mkdir hadoop
   sudo chown -R hadoop hadoop
   cd hadoop
   cp /home/hadoop/hadoop-0.20.2.tar.gz .
   tar -zxv -f hadoop-0.20.2.tar.gz
3. setting
   cd hadoop-0.20.2
   vim conf/hadoop-env.sh
     //SUN-JDK路徑
     JAVA_HOME=/etc/jdk/jdk1.6.0_32/
   Test hadoop cmd
     bin/hadoop
4. setting core-site.xml
   vim conf/core-site.xml
  <property>
    <name>fs.default.name</name>
    <value>hdfs://localhost:9000</value>
  </property>
  <property>
    <name>hadoop.tmp.dir</name>
    <value>/etc/hadoop/hadoop-0.20.2/tmp</value>
  </property>
    mkdir tmp
5. setting hdfs-site.xml
   vim conf/hdfs-site.xml
  <property>
    <name>dfs.replication</name>
    <value>1</value>
  </property>
6.setting mapred-site.xml
  vim conf/mapred-site.xml
  <property>
    <name>mapred.job.tracker</name>
    <value>localhost:9001</value>
  </property>
7. ssh localhost without accept key
   #test
   ssh localhost
   #set
   ssh-keygen -t dsa -P '' -f ~/.ssh/id_dsa
   cat ~/.ssh/id_dsa.pub >> ~/.ssh/authorized_keys
8. Download Master ssh key to store
9. Run Single Node
   bin/hadoop namenode -format
   bin/start-all.sh

10. Check status //他起來到網頁看到一個會活的node或jobnode..要很久(尤其多個node時)...可以先做別的事再來看
   http://{hadoop ip}:50070/  (DataNode is count of slaves)
   http://{hadoop ip}:50030/

[Hadoop Exception Handle]
//datanode有問題~ 通常rm砍掉後重新format就會過

NOTE: if Incompatible namespaceIDs
      rm -R tmp
      mkdir tmp
      bin/hadoop namenode -format
//status 網頁開不起來時~檢查該聽的port有沒有問題
NOTE: if Connection Fail
      Check hosts and ip in the xml
      netstat -l (on Master u can see the port bind vm1)


//HBase只是裝來給sqoop reference用的~沒設定也沒差

[HBase]
0. download version: hbase-0.92.1.tar.gz
   FTP to host

1. cd /etc/hadoop
   cp /home/hadoop/hbase-0.92.1.tar.gz .
   tar -zxv -f hbase-0.92.1.tar.gz

[Sqoop]
0. download version: sqoop-1.4.1-incubating__hadoop-0.20.tar.gz
   FTP to host, chg name to short name-->sqoop-1.4.1.tar.gz
 
1. cd /etc/hadoop
   cp /home/hadoop/sqoop-1.4.1.tar.gz .
   tar -zxv -f sqoop-1.4.1.tar.gz
   #cp -R sqoop-1.4.1-incubating__hadoop-0.20/. hadoop-0.20.2/sqoop-1.4.1/

2. set PATH
   vim bin/configure-sqoop
   #add on top
   #notice hadoop must use sun java jdk!!
   HADOOP_HOME=/etc/hadoop/hadoop-0.20.2/
   HBASE_HOME=/etc/hadoop/hbase-0.92.1/
   JAVA_HOME=/etc/jdk/jdk1.6.0_32/

//等這些單機裝好測好後~ 就可以將目前的VM做樣本~ 接著就是複雜N份~
//是也可以順便先把Hadoop實做出來的先copy過去啦~不過就~嗯=_="總是會改的~之後還是每一台要上
//ssh without key這件事~ 只要master跟其他的sync完就可以了~ 簡單的說只要讓master可以ssh免pwd去下指令就可以了~~
//masters和slaves我記得是~ master那台兩個檔都要改~ slaves只要去改master就可以~ 不過為了統一~一起都改一樣是也沒差一"一a

[Hadoop Multi PC]
0. Save Basic VM Img
{for each VM}
1. Create New VM..Deploy Basic VM Img..start
2. sync time oclock
   sudo ntpdate time.stdtime.gov.tw
3. Modify PC HostName
   sudo vim /etc/hostname
   sudo vim /etc/hosts
   sudo reboot
   #Remember the VM IP
4. hosts add all ip/hostname
   sudo vim /etc/hosts
   (Notice..remove 127.0.1.1, use outer ip with hostname of master)
5. ssh all without key..(ssh localhost and ssh h1~hN) <--do this only on the Master
   ssh-keygen -t dsa -P '' -f ~/.ssh/id_dsa
   cat ~/.ssh/id_dsa.pub >> ~/.ssh/authorized_keys (ssh localhost need it)
   ssh-copy-id -i ~/.ssh/id_dsa.pub hadoop@h2  (@h1~@hN)
6. set conf again (only Master need to reset masters and slaves)
   cd /etc/hadoop/hadoop-1.0.0
   vim conf/masters  (key in hostname of Master)
     h0
   vim conf/slaves  (add all host include self)
     h1
     h2
     h3
   vim conf/core-site.xml  (update hostname)
     <value>http://h0:9000</value>
   vim conf/hdfs-site.xml (update hostname)
     <value>2<value>
   vim conf/mapred-site.xml
     <value>http://h0:9001</value>
7. Start Hadoop on Master
   bin/stop-all.sh
   bin/hadoop namenode -format
   bin/start-all.sh
8. Check status
   http://192.168.22.111:50070/  (DataNode is count of slaves)
   http://192.168.22.111:50030/
9. #test1
   //bin/hadoop jar hadoop-examples-1.0.0.jar pi 10 5000000
   bin/hadoop jar hadoop-0.20.2-examples.jar pi 10 500
   #test2
   bin/hadoop dfs -ls output
   (if output exists)
      bin/hadoop fs -rmr output
   bin/hadoop dfs -put ./wordcount input
   bin/hadoop jar hadoop-examples-1.0.0.jar wordcount input output

最後就是測試啦~可以用現成的範例檔測就好了~
多個node有成功時~ 可以在50030那邊去看~也會有進度~
看log可以多利用50070的logs/~ 比cmd上的黑白mode好看好選多了(名字很長又很像=_=")

話說偶最早是用Hadoop 1.0去裝~但是他有個網路問題不知道是怎樣~ 當時不知道是他開發的bug還怎樣(那時候看到1.0剛出很開心的去抓~就當白老鼠了...)...多台的溝通就是跑不起來只能單台...這樣很有問題Orz...
最後降級至穩定版..至少0.20~照著文件跟網路文章做就很順~

看到example程式沒啥問題的跑完後~ 就可以開始開發應用了!!

 




[Hadoop] 基本環境建立-2


[Sun JDK6]
0. download jdk file from sun: jdk-6u32-linux-x64.bin
   FTP to host 
1. #create jdk folder
   cd /etc
   sudo mkdir jdk
   cd jdk
   sudo cp /home/hadoop/jdk-6u32-linux-x64.bin .
2. #install
   chmod 755 jdk-6u32-linux-x64.bin
   sudo -s ./jdk-6u32-linux-x64.bin


[Tomcat7]雖然後來沒用~ 不過都已經試完了就記錄一下Orz...
1. Download/SFTP tar.gz to /home/hadoop
2. #move and unzip files
   cd /etc
   sudo mkdir tomcat
   sudo chown -R hadoop tomcat
   cd tomcat7
   cp /home/hadoop/apache-tomcat-7.0.26.tar.gz .
   tar -zxv -f apache-tomcat-7.0.26.tar.gz
3. #tomcat setting
   change to port80 vim server.xml
   open manager user vim tomcat-users.xml
   envir var sudo vim environment
    //有裝Sun-JDK也可以指過去~
     JAVA_HOME="/usr/lib/jvm/java-6-openjdk"
     JRE_HOME="/usr/lib/jvm/java-6-openjdk/jre"
     PATH="...(other path):$JAVA_HOME:$JRE_HOME"
   #notice port server
   cat /etc/services
4. #test single startup server
   bin/startup.sh
   bin/shupdown.sh
5. #start on boot
   #create file script into init.d/tomcat.sh, notice +x and notice path
   export JAVA_HOME=/usr/lib/jvm/java-6-openjdk
   export JAVA_JRE=/usr/lib/jvm/java-6-openjdk/jre

   cd /etc/tomcat7/apache-tomcat-7.0.26
   bin/startup.sh
   #add shell into init.d
   update-rc.d -f tomcat defaults

//看到這我突然想起來~用apt-get的postgres owner比較不會有問題~ Option install的那個會好像沒辦法su~ 還是沒有postgres那個user..忘了XD..反正是apt-get安裝的比較正常...
不過apt-get都只會找最新版的~看他apt-get怎麼看~ 如果要指定某一版就要找一下指令位置
//另從9開始~ 他預設的語系並不是UTF-8..會"很有問題"~ 所以請在一開始對DB整個砍掉-->2
//預設的super user是沒有密碼的樣子~ 先處理之後才不會有管理問題

[PostgreSQL (DON'T use server disk install..user strange)]
1. #Install postgresql (You will get the newest 9.1)
   #bin locate=/usr/lib/postgresql/9.1/bin/
   #conf locate=/etc/postgresql/9.1/main/
   sudo apt-get install postgresql
2. #create new Server to change encoding!!
   cd /usr/lib/postgresql/9.1/bin/
   sudo pg_dropcluster --stop 9.1 main
   sudo pg_createcluster --start -e UTF-8 9.1 main    
2. #Reset Password
   sudo -u postgres psql postgres
   \password postgres 
   \q
3. #allow ip access
   cd /etc/postgresql/9.1/main/
   sudo vim pg_hba.conf
   #Add
   host    all         all         192.168.{net}.1/24       trust
   #listen for all
   sudo vim postgresql.conf
   #Update
   listen_addresses='*'
4. #reStart Server
   sudo /etc/init.d/postgresql restart
5. Use GUI Access..Check


[PostGIS]
0. #slove locale bug if needed
   sudo locale-gen
   sudo locale-gen --lang zh_TW.UTF-8
1. Install PostgreSQL down..
2. #apt-get install, according version of the postgreSQL
   sudo apt-get install postgresql-9.1-postgis
   # install path=/usr/share/postgresql/9.1/contrib
3. #crate template db
   sudo su postgres
   createdb template_postgis
   createlang plpgsql template_postgis
   psql -U postgres -d template_postgis -f /usr/share/postgresql/9.1/contrib/postgis-1.5/postgis.sql
   psql -U postgres -d template_postgis -f /usr/share/postgresql/9.1/contrib/postgis-1.5/spatial_ref_sys.sql
4. #check database
   select postgis_lib_version();


//要養成好習慣~ 反正先建個其他帳號來ACCESS...如果有GUI可以用gui玩比較順~當時是因為只有黑白畫面Orz...
[DB create]
1. #create a new database(roadinfo) and owner is {user}/{pwd}
   sudo su postgres
   psql postgres
   CREATE USER  {user}  WITH PASSWORD ' {pwd} ' CREATEDB;
   CREATE DATABASE  {db}  OWNER  {user} ;
   #or DB support postGIS
   CREATE DATABASE  {db}  OWNER {user} TEMPLATE template_postgis;
2. dump DB from testing/dev
   #move path into backup path
   cd /etc/hadoop
   #dump
   pg_dump --host {ip} --username {user} {db2} > {db2 name}.backup
3. restore DB to database    
   psql {db} < {db2 name}.backup
4. If owner errors.. change table owner to its
   psql {user}
   ALTER TABLE {table} OWNER TO {user};


[Hadoop] 基本環境建立-1

碎碎念後~ 開始筆記正文...
Hadoop基本上是linux平台的專案~ 除了省錢之外~ WIN上的支援討論也太少了~
所以就先選個os來~ 因為我有聽過的很少~ 就選ubuntu...

一開始想裝ubuntu desktop..結果好樣的HyperV就是裝不起來~ 所以最後是裝server version..這對我來說是沒什麼差就是...

server version有個方便的地方~ 預設就可以選裝ssh...另外DB雖然有我要用的postgreSQL~但是後來發現怪怪的~ 所以後來還是用apt-get的比較穩

內建可安裝裡面有個Tomcat...裝起來發現他Folder亂生~ 建議Tomcat若要用還是zip方式安裝會比較好管理~我專案到最後是沒用~

基本環境選擇...
ubuntu server 11.10
SSH Server(內建Option安裝)
PostgreSQL 9.1(apt-get安裝)+PostGis 1.5(apt-get安裝)
Sun JDK 1.6(sun/oracle官網bin檔安裝)
Hadoop 0.20.2
Sqoop 1.4 for Hadoop 0.20.2(sqoop要求SUN JDK, 不吃OpenJDK..不過我就是需要他QQ)
HBase 0.92(sqoop會要求HBASE_PATH, 沒用不過就配合著裝)

使用工具...
pietty --> ssh連線管理..我記得putty好像不能顯示中文~而且還可以貼上文字..反正pietty比較powerful就是了
FileZille Client --> 選用SFTP就可以上傳下載檔案~

應該要會的基本操作(或者說我只會這幾樣=_="還常常要去鳥哥那邊查範例)...
vim  --> 嗯~超級重要的編輯檔案~ vim比vi簡單一點點點喔~
tail  --> 看檔案尾巴的內容~ 看log檔好用~
cat --> 也是看檔案~ 適合小檔小設定顯示..
ls/mkdir/cp/mv/rm... --> 檔案基本操作很基本吧Orz..
tar --> 壓縮解壓縮檔
netstat --> 網路狀態~ ㄜ~ 有時候要看他有沒有跑起來看PORT
ifconfig --> 看自己的網路狀態..IP是多少很重要QQ..
reboot/halt... --> 重開機/關機指令

底下是相關指令與cmd...就平常台式英文加後來再補充的筆記...

[Ubuntu]

Linex Basic Evir(Use ubuntu 11.10 64bit server)
1. Append ISO in DVD
2. Install ubnutu OS Language: 台灣繁體
    //pc name之後還可以改
    set pc name:
    //sudo user/pwd很重要~錯了就沒人能用了XD
    set default user name/pwd:
    //proxy不設定之後去系統改也一樣~
    proxy setting(intranet): http://{proxy ip}:{proxy port}
    //Option安裝~ 要管理記得開ssh~可pietty..FTP一次搞定
    Install Project: OpenSSH
3. Network Setting: ifconfig to get IP
   #DHCP(intranet) 在hyperV下他是有問題的~ 要自己加自動取得DHCP IP(Vmware沒事QQ)加完後重開機才有用~另hosts在hyperV下有問題記得去check有沒有看到奇怪的東西~
   ls /etc/network
   sudo vim interfaces
   #add
       auto eth0
       iface eth0 inet dhcp
   sudo reboot
   vim /etc/hosts   remove .(null)
     127.0.1.1       h0  
4. SSH Host and Test upload Files
5. sudo apt-get update (Wait for install)
   #proxy setting (if b4 fail?)
   sudo gedit /etc/apt/apt.conf.d/02proxy
   Acquire::http::Proxy "http://{ip}:{port}";
   wq!
6. Install JDK6 (Wait for While) (See [Sun JDK 6])
   which java (/usr/lib/jvm/java-6-openjdk/)
7. Install Hadoop (See [Hadoop])
8. Date Time Sync
    //同步時間有兩個原因~ 一是當VM複製後或停止再重起~ 時間不會動~ 所以要對時~ 另外是我覺得那個時間真的過一段時間超不準的QQ~ 要是懶的話就是把他寫成crontab去對吧
    sudo ntpdate time.stdtime.gov.tw
    //看時間的指令印象中好像是
    date



2012年8月9日 星期四

[Hadoop]碎碎念

講起Hadoop...恩~ 好吧~ 現在好像正紅~ 趁著實驗案剛結束~
比較悠閒又還有點記憶時~ 來碎碎念一下...

首先~ 配合目前正紅的VM技術~

開發用windows server 2008內建的hyperV..是那個誰叫偶要練習做Template+硬碟用固定大小的~ 然後小小的測試機硬碟就爆了(早期的Server~硬碟都很小才80..100G)..

Production也是沒經驗~ 開了個規格出去...業務也隨便買就...每個server 1.2T...但是連storage也是1.2T..就超搞笑...
再做raid0/raid5...就看到一堆人搶著硬碟要用...

另外VmWare要做HA的話~要額外購買vCenter...vCenter原則上是建議獨立機器~ 不過後來因為各式各樣的原因還是裝在VM裡面~另外要被HA的VM一定要裝在storeage上~還得搭配有G以上的Switch做支援~ 這種東西說真的~ 隨便一樣就貴到死=.=a..還有那個要跟那個配~這些硬體商也不管你會不會懂不懂(說不定他們自己也不懂哩~只會報價而已=.=")~還真是見招拆招~一整個很刺激阿~囧rz

這故事說~ 一個Server有多少實力~ 要切幾個VM..配多少效能~放那~ 真的要有計劃~ 不然結果常常超乾尬...不懂的話~ 去上個原廠課程~ ㄜ~有沒有用我沒上是不知道啦~但應該還是有用吧Orz...


Hadoop本來就是linux專案~ 先是被ubuntu狠狠的電一個月...
受win苦毒很深的人進cmd黑白世界真的要多抓點時間...pietty和Google是你最好的朋友...

XX的hyperV和ubuntu是世仇嗎~ ubuntu在上面一堆基本設定有問題~連apt-get的東西都還裝不起來是那來的鬼...
還好Production上用的VMware有付大錢的就是不一樣~ 一路順到底~ 連clone多台時設定轉換他也有做得很好~


接下來是Hadoop特性的問題~ Hadoop是一很穩重的單線程架構...
一起來就是20s..(沒做事也是20s..我猜大概是在溝通跟CHECK可用資源...)
所以原本不用算到20s的用這跟本效能馬上大輸...
(我無聊寫了一個類似流程但不是Hadoop...說實在話~ 不用10秒就做完了...另一原因是真實情況量就不大...上面也原本打算是做實驗性質...但大家沒想到差這麼多~囧")

他很老實的~ 一定要全部分完(Map)..然後等到全部的結果都算回來後才結算(Reduce)..
其實他這樣子是沒什麼問題的~ 但是~很不幸的這案子的目標是要即時運算~ 即時傳回資料...
所以為了反應時間的關係~ 只好把他改成了非正常一般的Hadoop運作模式...

最大的困擾是在實做驗證時~ 不斷的被長官質疑為什麼Hadoop運算比較慢...還慢那麼久...
在報告時~ 每次都要花一半以上的時間~ 做Hadoop原理架構教學...
全部的人~包含PM也都去上課了...還好最後大家也認同~ 嗯~ 解題方向錯誤=_="...不過計劃書都寫白了要Hadoop..只好給他Hadoop下去~ 還好KPI很寬鬆可以過...


另外關於Hadoop的學習資源~ 嗯~ 套句朋友的老話~ 上官網吧~ 囧rz...
一堆中文書很多只是翻譯官方文件內容而已~ 結果那些書最大的用處是老板拿去抄前幾章的序跟介紹到計劃報告書裡用的...

歐來禮的翻譯書還是有保障一點~ 但是我覺得實務上還是很難解答我的問題~
只是他可以提供一些關鍵字給我問Google大神是也不能說他沒有用Orz...


公司有請資策會的人來上幾堂跟這有關的課~ 不過我的心得是~ 目前台灣在這領域的人很少...
真正應用到實做上的很少少少...老師也只能講講理論面的...可以當做補充知識~ 但實做還是靠自己吧~ 囧rz...


另一點是因為~ 這案子真的是解題方式不好~ 所以相關資源也很少...
都用奧步Orz...


不過實驗麻~ 有取得經驗值還是比較重要的~ 至少長官們下次選解題方式時~ 就不會只喊著要雲端運算~ 要Hadoop...
進步最多的~ 大概就是嘴砲功力吧XD|||...

soapui

在做網站介接最麻煩的之一~
就是有一堆莫名其妙的Web Service...

REST的當然最好解決~文字簡單parse就好~
但是SOAP就機車了...

不貼心就算了~ 幾乎每一種都還要找特定的寫法針對...
(誰叫這些說起來好像照規矩又不照規矩~跟那堆Browser一樣一_一")


有時候也搞不清楚到底是我錯還是對方錯~
最近看到了一個Open Source..soapui~ 可以快速建立request..還可以gen code..還可以做service..
就來試了一下~~

講一下我個人覺得OK的點就是~

單純當client測試很方便~ 只要輸入WSDL網址就出來了...

他request會直接顯示出soap request所需要的xml內容(自己去貼一貼值很快)與回傳內容~ 對於我這種實作上不愛肥胖套件喜愛純文字處理的人很友善!!

另外有gen code~目前是還不需要用到~ 但是support的項目包山包海...java主力的axis1,2..cfx...Net..還有很多我沒看過的東西=.="...也許那天可以方便用也很好~

官網
http://www.soapui.org/

download就是在sourceforge下
http://sourceforge.net/projects/soapui/files/

他主要有一個應用程式~SoapUI..11xM左右~ 小肥但還好下載很快~
也有IDE的plugin...不過大家都知道plugin有版本相容問題(這又是一個很無言的事情就是)

所以就直接用應用程式就好了(有趕上時代的64bit版本喔XD)

操作畫面有興趣可以參考我在網路上看到的網路文章~
http://ejvyas.blogspot.tw/2010/05/create-axis-web-service-stubsartifacts.html

2012年6月15日 星期五

FB JS SDK-顯示粉絲團並檢查按讚

我也是現在才知道~原來在粉絲團按讚就等於加入粉絲團了!!

粉絲團內容+按讚使用like_box,
如果要跟網路上一樣精簡只有讚按紐可以用like_button

官網上這些被列入plugin, 還有預覽跟gen code很貼心!!
http://developers.facebook.com/docs/reference/plugins/like-box/

在送出page前check有沒有加入粉絲團一樣用FB.api...
此頁是接在之前登入APP後做的~ 所以能來到這的user是都已經登入過囉!!

---html/jsp include
<script src="http://connect.facebook.net/zh_TW/all.js"></script>

<div id="like_box" style="margin-top:5px;display:none">
       <div class="fb-like-box" data-href="http://www.facebook.com/tyepb" data-width="300" data-show-faces="true" data-stream="false" data-header="false"></div>      
</div>

---script/js file
FB.init({
    appId: '{APP_ID}', // App ID
    //channelURL: '....................', // Channel File
    status: true, // check login status
    cookie: true, // enable cookies to allow the server to access the session
    oauth: false, // enable OAuth 2.0
    xfbml: true  // parse XFBML
});

 function fan2()  {
    var pid = '{PAGE_ID}';          
    var isFan = false;
    FB.api('/me/likes/'+pid,function(response) {
        //console.log(response);
        if( response.data ) {
            if(response.data)  {
                for(var i = 0 ; i < response.data.length ; i++)  {
                    if(pid == response.data[i].id)  {
                        isFan = true;
                        //console.log('??it is fan!!');
                        //return true;
                    }
                }
            }
            if(isFan)  {
                //do something when user like fans page
            }  else  {
                //do something when user unlike fans page
                return false;
            }
        } else {
            //user not login/or not connect FB APP
            return false;
        }
    });
    return false;
}


FB JS SDK-使用者登入FB APP

不知道是不是閏月的關係~ 最近真是太血淚了Orz..

在Java Base, FB沒有特製的SDK, 就只能用JS SDK
主要有Issue要判斷~ facebook的user是不是某某粉絲團的粉絲~
所以要先弄一個FB APP去access使用者資訊..

而如何讓使用者登入FB APP並同意隱私權授權..
不換頁~ 直接在同一頁登入..
在官網的範例有很不錯的範例~ 我只是把另開改成在原本頁面處理...
FB.api + oauth dialogs
http://developers.facebook.com/docs/reference/dialogs/oauth/

---html/jsp include FB js lib
 <script src="http://connect.facebook.net/zh_TW/all.js"></script>

 ---js script/file
FB.init({
    appId: '{APP_ID}', // App ID
    //channelURL: '....................', // Channel File
    status: true, // check login status
    cookie: true, // enable cookies to allow the server to access the session
    oauth: false, // enable OAuth 2.0
    xfbml: true  // parse XFBML
});

function loginUser() {
    FB.getLoginStatus(function(response) {
        if (response.status === 'connected') {
            //login and permit APP access before
            var uid = response.authResponse.userID;
            var accessToken = response.authResponse.accessToken;
            //do something when user login FB APP ok
            $('#like_box').css('display', 'block'); 
        } else if (response.status === 'not_authorized') {
            //login but not access app
            doLoginApp2();
        } else {
            // the user isn't logged in to Facebook.
            doLoginApp2();           
        }
    }, true);
}


function doLoginApp2()  {
    var appID = '{APP_ID}';
   
    var path = 'https://www.facebook.com/dialog/oauth?';
    //on moblie, display=touch
    var queryParams = ['client_id=' + appID, 'redirect_uri=' + window.location, 'response_type=token', 'display=touch'];
    //on PC web
    //var queryParams = ['client_id=' + appID, 'redirect_uri=' + window.location, 'response_type=token'];
    var query = queryParams.join('&');
    var url = path + query;
       
    window.location = url;
}

2012年6月14日 星期四

NetBeans yWork UML

因應有人要求說程式也要出個物件圖..Class Diagram..
痛恨一力噗死的我就只能用NetBeans..
還好還有個方便的解決方式..yWork..

首先先到yWork官網~ 下載(速度有點慢要有耐心~ 還好等待是有價值的!!)
http://www.yworks.com/en/index.html
選擇UML Doclet, 免費的就有物件圖了..

Step 1. 下載zip包
Step 2. 解壓縮~整個copy到喜歡的地方..
Step 3. 打開NetBeans(我用7.1, 其他IDE或版本設定是不一樣的~可以參照zip裡的usersguide.pdf)
Step 4. NetBeans專案右鍵Properties->Build->Documenting
            Addtional Javadoc Options填入
            -docletpath "{yWorks包絕對路徑}\lib\ydoc.jar" -resourcepath "{yWorks包絕對路徑}\resources" -doclet ydoc.doclets.YStandard -umlautogen
            按下OK儲存
Step 5. NetBeans專案右鍵Generate JavaDoc..
            如果沒有出錯~ 完成後跳出瀏覽器直接link..就含有圖的javadoc了
           
之後就可以去NetBeans專案下找javadoc打包帶走^_^b~

2012年6月6日 星期三

Axis client for .Net web service

這次真是太雖小了Orz..居然用到貌似有bug的前期版本~
問題是~~
SimpleDeserializer encountered a child element, which is NOT expected, in something it was trying to deserialize.
發生的原因應該是在client invoke預設axis他去check 參數傳遞時~ 對於不需要傳參數的判斷會有問題..(明明就是不用~ 但他堅持一定要讀一個來用Orz)

不過因為OOXX機車的原因..所以也不能換lib..
網路上大家好像也沒特別講這個問題要怎麼解...
終於試到一個invoke的方式可以繞過那一段了T_T..要是繞不過去~就要硬刻一個http request了Orz..簡單的說就是用Message來發..這樣子他就不會去check參數了~ 還可以刻一個美美的xml不會有ns:前綴..

使用method如下~

            Call client = new Call(url);
            client.setUseSOAPAction(true);
            String uri = namespace;
            if(uri.endsWith("/"))  {
                uri += op;
            }  else  {
                uri += "/"+op;
            }
            client.setSOAPActionURI(uri);
            if(timeout > 0)  {
                client.setTimeout(timeout);
            }
            client.setOperationName(new QName(namespace,op));
            String xml ="";
            xml += "<soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">";
            xml += "<soap:Body>";
            if(params == null || params.size() == 0)  {
                xml += "<"+op+" xmlns=\""+namespace+"\" />";
            }  else  {
                xml += "<"+op+" xmlns=\""+namespace+"\" >";
                for(int i = 0 ; i < params.size() ; i++)  {
                    String[] pair = params.get(i);
                    xml +="<"+pair[0]+">"+pair[1]+"</"+pair[0]+">";
                }
                xml += "</"+op+">";
            }
            xml += "</soap:Body>";
            xml += "</soap:Envelope>";          
          
            Message msg = new Message(xml);
            SOAPEnvelope res = client.invoke(msg);          
           
 
若是使用RPCElement(之前的寫法)~ 則只能處理有帶參數的~節錄如下當參考
在axis裡~好像前綴是拿不掉的(不過至少.net那邊的web service看得懂就好..)~axis2可以偷做手腳拿掉就是..

            Call client = new Call(url);
            client.setUseSOAPAction(true);
            String uri = namespace;
            if(uri.endsWith("/"))  {
                uri += op;
            }  else  {
                uri += "/"+op;
            }
            client.setSOAPActionURI(uri);
            if(timeout > 0)  {
                client.setTimeout(timeout);
            }

            RPCElement req = new RPCElement(op);
            req.setNamespaceURI(namespace);
            req.setAttribute("xmlns", namespace);

            for(int i = 0 ; i < params.size() ; i++)  {
                String[] input = params.get(i);
                if(input.length == 2 && input[0] != null && input[0].length() > 0)  {
                    RPCElement ele = new RPCElement(input[0]);
                    if(input[1] != null)  {
                        ele.addTextNode(input[1]);
                    }
                    req.addChildElement(ele);
                }
            }
            re = (String)client.invoke( req );

2012年6月5日 星期二

unicode to string..\\u

本來看到unicode(\u)字也沒啥好怕的~ 不過突然發現有人做了一件奇怪的事情~ 為了讓網頁json上可以看到unicode的原型..他就把他寫成了\\u的碗糕|||Orz..

想說怎麼讀他的資料一直都是出\uxxxx真是超頭痛的..只好手動做了String parse..
                //str is origin string (\\uXXXX\\uXXXX)
                String str = (String)mpRow.get(converts[a]);
                if(str != null && str.trim().length() > 0 )  {
                    String un = str.trim();
                    StringBuffer sb = new StringBuffer();
                    int idx = un.indexOf("\\u");
                    while(idx >=0 )  {
                        if(idx > 0)  {
                            sb.append(un.substring(0, idx));
                        }
                       
                        String hex = un.substring(idx+2, idx+2+4);                       
                        sb.append( (char)Integer.parseInt(hex, 16) );
                        un = un.substring(idx+2+4);
                        idx = un.indexOf("\\u");
                    }
                    sb.append(un);
                 
                    //convert result of the str
                    String uf8=sb.toString();
                }

2012年2月22日 星期三

pgRouting Java實做

血淚泣訴?!的把pgrouting建起來了~ 不過他只是幫你算一算兩點間路徑..還是要用程式把資訊都接起來才能用~ 囧/..

以下簡述一下導航的作業流程..
1. Input Parameter: 起終點坐標(WGS84)
2. 取得起終點的結點路段, 起點取source, 終點取target
3. 計算起終點路段的連結路徑
4. 整合路段資訊
5. Output: 回傳路線資訊

就不論防呆條件與物件化的撰寫~ 主要記錄有用到的相關sql語法..

2.a 取得起/終點最近的路段
select gid, st_distance('POINT(120.683513 24.142974)'::geography, the_geom) as dis from edges where the_geom && SetSRID(box2d(geomFromText('MULTIPOINT(120.683213 24.142674,120.683813 24.143274)')),4326) order by dis limit 1

利用box2d先縮減範圍再做計算比較快一點點..另外box2d有點蠢~ 要再給定SRID..Orz..

3.a 起點取source, 終點取target..丟進去算演算法

SELECT d.id, e.gid, e.name, e.length, asText(e.the_geom) FROM dijkstra_sp('edges', 77, 35) as d, edges as e where d.gid = e.gid order by d.id

記得要order by result的id..這樣路段的順序才會正確..

其實好像也沒什麼Orz..不過也是花了一兩天才把流程串起來的~ 就當個記錄吧..
另外在preparedStatement裡的?是沒辦法給定function的..所以就直接接成字串丟下去執行吧~~參數在前面做好一點的檢核判斷就好

pgRouting圖資轉換

pgRouting簡單的講是一個幫你算點間導航的open source..架構於PostgreSQL+PostGIS上..

不過要算導航~ pgRouting有演算法~ 但還是要有圖資..所以他本身也有提供一些轉圖資的cmd..把圖資轉成db的資料..

圖資變成db資料~ 主要就是以原圖資的屬性欄位為table內的欄位名(所以圖資欄位改成英文以免出事)..另外加一個key(default為gid), 以及一個地理欄位(default為the_geom)

但主要因為台灣有中文問題~ 所以還是先人眼check一下資料來源~ 欄位中文應改為英文..以及內容編碼(big5/UTF-8)的差異..還有坐標系

1. 先取得.shp File
PS: 欄位名為英文, 內容編碼為Big5, 並確認坐標系為WGS84(經緯度)
SRID
TWD97=3826
TWD67=3821
WGS86=4326

2. 至pg安裝路徑下之 bin\(edges為產出的table name~ 可以自己改)
shp2pgsql -s 4326 -W big5 -i -I "D:\project\圖資\AllRoad\tAllRoad.shp" edges > "D:\project\圖資\AllRoad\edges.sql"

3. Import SQL File to Postgres SQL, 至postgres bin\
(Drop edges if it exist)
psql --host [host ip] --username [user] --dbname [database name] -f D:\project\圖資\AllRoad\edges.sql

另外是有碰到可能是資料內容有亂碼或是難字之類的~ 會造成產生的sql有問題~
後來是用另一個解法解~ 就是去裝一個open source的gis工具: QGIS..朋友介紹使用的..雖然會當機~ 不過聽說情況有比之前的版本好了Orz..沒辦法~ 沒人沒錢沒知識又要上~

Quantum GIS裡面有一個工具..
先開shp檔起來..看一看有沒有什麼不對的地方..
附加元件-->Shape檔匯出至PostGIS
設定連線..設定幾合欄位名稱..接著放著給他跑到天荒地老..

似乎他對於編碼的解讀比較好的樣子Orz..反正就是這樣子可以把中文字正確的寫進去就好~囧rz

pgRouting

自從在上個公司玩起PostgreSQL..免費的~ 又可以外掛PostGIS做地理資訊運算~
對於沒什麼數學概念的偶還真是一大救星...

在現在的公司裡~ 還是碰到導航的問題~ 還好當時有記得幾個關鍵字..有跟幾個做這方面的人套好交情可以問問題XD..就把這open source project給建出來了~~

底下分享一下偶在Windows版本的安裝方式..

1. 先安裝PostgreSQL..因之前專案使用8.4版就一直延用下來

2. 安裝PostGIS 1.5, 可以在安裝PostgreSQL時就選擇plugin一路安裝..或是另外找postgis的安裝檔..裝完後主要就是會多了一個templete_postgis database, 內有780左右的function, 2個table..跟geom相關的形態..之後有需要postgis功能只要在建資料庫時使用這個做樣版建立就有了~ 很方便..

3. 接下來要安裝pgRouting這個project..因為沒有找到win包裝的~ 所以就手動來裝了..先下載檔案..記得要找符合pg版本的~ 我是用1.03_pg_8.4.2..(最後的.2好像沒差~ 只要8.4的都可以裝起來)..

3.a 將lib下的DLL檔(有三個)~ copy到pg安裝路徑下..PostgreSQL/8.4/lib..重起pg DB Server把dll讀進去

3.b create database for pgrouting..使用templet_postgis建立新db..我這邊database name是叫pgrouting2, owner若有需要變更建議在create db前就先建好直接assign~ 以免後面要改一堆owner很麻煩..

3.c 至cmd 模式下依序執行Share/Contrib裡面的三隻sql檔..必須使用管理者權限的user執行~ 不然會有權限問題..另外需指定db
psql --host localhost --username postgres --dbname pgrouting2 -f [dir]\Share\Contrib\routing_core.sql
psql --host localhost --username postgres --dbname pgrouting2 -f [dir]\Share\Contrib\routing_core_wrappers.sql
psql --host localhost --username postgres --dbname pgrouting2 -f [dir]\Share\Contrib\routing_topology.sql

3.d 若上述出現plpgsql未啟用..執行底下這一行(可於pgAdminIII/phppgadmin連線至該database的sql語法欄執行即可)
CREATE LANGUAGE 'plpgsql'

到上面應該就把pgrouting的function裝好了~ 至該database下看應該看到function會增加到800+..不過~ 裝了很多次~ 裝出來是820左右..但是到後面用db用備份回存時又不一樣了~ 不過總之有用到的function能動就好了~ 不管他了Orz..

4. 創建Table 額外演算 資訊
ALTER TABLE edges ADD COLUMN source integer;
ALTER TABLE edges ADD COLUMN target integer;

計算source/target (要等時間)
SELECT assign_vertex_id('edges', 0.0001, 'the_geom', 'gid');

//dijsktra演算法----
5. 設定權重length
ALTER TABLE edges ADD COLUMN length double precision;

計算要等
UPDATE edges SET length = st_length(the_geom::geography);

設定Index
CREATE INDEX source_idx ON edges(source);
CREATE INDEX target_idx ON edges(target);
CREATE INDEX geom_idx ON edges USING GIST(the_geom GIST_GEOMETRY_OPS);

測試Dijsktra演算法
SELECT * FROM dijkstra_sp('edges', 52, 35);

//astar
6. 設定點資料
ALTER TABLE edges ADD COLUMN x1 double precision;
ALTER TABLE edges ADD COLUMN y1 double precision;
ALTER TABLE edges ADD COLUMN x2 double precision;
ALTER TABLE edges ADD COLUMN y2 double precision;

計算要等
UPDATE edges SET x1 = x(startpoint(the_geom));
UPDATE edges SET y1 = y(startpoint(the_geom));
UPDATE edges SET x2 = x(endpoint(the_geom));
UPDATE edges SET y2 = y(endpoint(the_geom));

NOTE:“endpoint()” function fails for some versions of PostgreSQL (ie. 8.2.5, 8.1.9). A workaround for that problem is using the “PointN()” function instead:
UPDATE edges SET x1 = x(PointN(the_geom, 1));
UPDATE edges SET y1 = y(PointN(the_geom, 1));
UPDATE edges SET x2 = x(PointN(the_geom, NumPoints(the_geom)));
UPDATE edges SET y2 = y(PointN(the_geom, NumPoints(the_geom)));

測試astar
select * from astar_sp_delta('edges', 52, 35, 0.1);

以上建置方法是從網路上爬出來的~ 另外有做一些小修改..

the_geom存的是WGS84坐標系..算長度要轉成geography~ 資料才會是正確的路段長..
TWD97/TWD67時就不需要轉換了

道路節點範圍assign_vertex_id, 裡面的第二個參數也是看情況做調整~