Posts Tagged ‘開發日誌’

Java JSP 正規式取出中文字

5 六月, 2009

import java.util.regex.Matcher;import java.util.regex.Pattern;String str="o中文o";String pattern="";Pattern p=null;Matcher m = null;//中文字碼範圍pattern="[\u4e00-\u9fa5]";p=Pattern.compile(pattern);m=p.matcher(str);while(m.find()){	System.out.println(m.group());}

Java JSP 讀取UTF-8檔案

4 六月, 2009

以下程式不考慮UTF-8 BOM的問題
 

import java.io.BufferedReader;import java.io.File;import java.io.FileInputStream;import java.io.IOException;import java.io.InputStreamReader;File fn=new File("utf8.txt");FileInputStream fis = new FileInputStream(fn);//指定utf-8編碼BufferedReader br = new BufferedReader( new InputStreamReader( fis,"utf-8" ) );String file_str_append="";String file_str="";while((file_str_append=br.readLine())!=null){  file_str+=file_str_append;}br.close();fis.close();//將utf-8所有檔案內容輸出System.out.println(file_str);

中央氣象局 RSS 解析正規式 Regex

1 五月, 2009

<%@page contentType="text/html; charset=utf-8" errorPage=""%>&#x10;<%@page import="java.util.regex.Pattern"%>&#x10;<%@page import="java.util.regex.Matcher"%>&#x10;<%&#x10;out.clear();&#x10;%><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">&#x10;<html xmlns="http://www.w3.org/1999/xhtml">&#x10;<head>&#x10;<title>Parse Central Weather Demo</title>&#x10;<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />&#x10;</head>&#x10;<body>&#x10;<%&#x10;String str="";&#x10;String pattern="^([\\D]+)\\d{2}/\\d{2}\\s([\\D]+)\\s([\\D]+)\\s[\\D]+:\\s(\\d{1,3}\\s~\\s\\d{1,3})\\s[\\D]+:\\s(\\d{1,3})%\\((\\d{2}/\\d{2})\\s(\\d{2}:\\d{2})[\\D]+\\)$";&#x10;Pattern p=null;&#x10;Matcher m=null;&#x10;%>&#x10; 台北市05/01 今晚至明晨 晴時多雲 溫度: 22 ~ 24 降雨機率: 0%(05/01 16:30發布)<br />&#x10;<%&#x10;str=" 台北市05/01 今晚至明晨 晴時多雲 溫度: 22 ~ 24 降雨機率: 0%(05/01 16:30發布)";&#x10;pattern="^[\\D]+\\d{2}/\\d{2}\\s([\\D]+)\\s([\\D]+)\\s[\\D]+:\\s*(\\d{1,3}\\s~\\s\\d{1,3})\\s[\\D]+:\\s*(\\d{1,3})%\\((\\d{2}/\\d{2})\\s(\\d{2}:\\d{2})[\\D]+\\)$";&#x10;p = Pattern.compile(pattern);&#x10;m = p.matcher(str.trim());&#x10;if(m.find()){&#x10;	for (int i = 1; i <= m.groupCount(); i++) {&#x10;      out.println("group(" + i + "):" + m.group(i)+"<br />");&#x10;    }&#x10;    m.reset();&#x10;}&#x10;%><hr />明日白天 晴時多雲 溫度: 24 ~ 28 降雨機率: 0% <br />&#x10;<%&#x10;str="明日白天 晴時多雲 溫度: 24 ~ 28 降雨機率: 0% ";&#x10;pattern="^([\\D]+)\\s([\\D]+)\\s[\\D]+:\\s*(\\d{1,3}\\s~\\s\\d{1,3})\\s[\\D]+:\\s*(\\d{1,3})%$";&#x10;p = Pattern.compile(pattern);&#x10;m = p.matcher(str.trim());&#x10;if(m.find()){&#x10;	for (int i = 1; i <= m.groupCount(); i++) {&#x10;      out.println("group(" + i + "):" + m.group(i)+"<br />");&#x10;    }&#x10;    m.reset();&#x10;}&#x10;%><hr />05/02 溫度:22 ~ 28 晴時多雲&#x10;<%&#x10;str="05/02 溫度:22 ~ 28 晴時多雲";&#x10;pattern="^(\\d{2}/\\d{2})\\s[\\D]+:\\s*(\\d{1,3}\\s~\\s\\d{1,3})\\s([\\D]+)$";&#x10;p = Pattern.compile(pattern);&#x10;m = p.matcher(str.trim());&#x10;if(m.find()){&#x10;	for (int i = 1; i <= m.groupCount(); i++) {&#x10;      out.println("group(" + i + "):" + m.group(i)+"<br />");&#x10;    }&#x10;    m.reset();&#x10;}&#x10;%>&#x10;</body>&#x10;</html>

&#x10;

 

&#x10;

執行結結果:

&#x10;

台北市05/01 今晚至明晨 晴時多雲 溫度: 22 ~ 24 降雨機率: 0%(05/01 16:30發布)
&#x10;group(1):今晚至明晨
&#x10;group(2):晴時多雲
&#x10;group(3):22 ~ 24
&#x10;group(4):0
&#x10;group(5):05/01
&#x10;group(6):16:30

&#x10;


&#x10;

明日白天 晴時多雲 溫度: 24 ~ 28 降雨機率: 0%
&#x10;group(1):明日白天
&#x10;group(2):晴時多雲
&#x10;group(3):24 ~ 28
&#x10;group(4):0

&#x10;


&#x10;

05/02 溫度:22 ~ 28 晴時多雲&#x10;group(1):05/02
&#x10;group(2):22 ~ 28
&#x10;group(3):晴時多雲

&#x10;

 

&#x10;

 

&#x10;

 

&#x10;

備註:中央氣象局的RSS2.0並不是完全符合W3C的標準,且資料呈現不夠有條理,不易被解析

開發有中文內容的專案要考慮的事情

30 四月, 2009

跟一個美工人員說目前的專案要有中文,

&#x10;

美工會考慮有沒有適合的中文字型

&#x10;

 

&#x10;

跟一個程式人員說目前的專案要有中文,

&#x10;

程式人員會考慮會不會有中文衝碼

&#x10;

 

&#x10;

跟一個資料庫管理人員說目前的專案要有中文,

&#x10;

資料庫管理人員會考慮資料儲存是否要用Unicode儲存中文

&#x10;

 

&#x10;

跟一個企劃人員說目前的專案要有中文,

&#x10;

企劃人員會考慮內容是否能夠因為中文而引人注目

&#x10;

 

&#x10;

跟老闆說目前的專案要有中文,

&#x10;


老闆會考慮什麼時候開始專案會開始賺錢,有沒有中文都沒關係

JSP 強制下載檔案

10 四月, 2009

<%@page import="java.util.ArrayList"%>&#x10;<%@page import="java.io.OutputStream"%>&#x10;<%@page import="java.io.FileInputStream"%>&#x10;<%@page import="java.util.Date"%>&#x10;<%@page import="java.net.URLEncoder"%>&#x10;<%@page import="com.pcyi.walkone.DAO.Verify"%>&#x10;<%@page import="org.hibernate.Session"%>&#x10;<%&#x10;out.clear();&#x10;//要給clinet下載時顯示的名字&#x10;String fileName = "clinet.txt";&#x10;fileName=URLEncoder.encode(fileName, "utf-8");&#x10;response.setHeader("Content-Disposition","attachment; filename=" + fileName );&#x10;String f_path="server_file.txt";&#x10;FileInputStream fis = new FileInputStream( application.getRealPath(f_path));&#x10;OutputStream os=response.getOutputStream();&#x10;byte byteRead;&#x10;while(-1 != (byteRead = (byte)fis.read())) {&#x10;  //文字檔UNIX換行轉PC換行&#x10;  if(byteRead=='\n'){&#x10;    os.write('\r');&#x10;  }&#x10;  os.write(byteRead);&#x10;}&#x10;os.close();&#x10;if (fis != null) {&#x10;  response.setStatus(200);&#x10;  response.flushBuffer();&#x10;  fis.close();&#x10;}&#x10;%>&#x10;

偶遇walkOne元老 – ellis – 張家榮

30 三月, 2009

我們walkOne難產了一年多,那時我還沒進公司,

&#x10;

我的前輩ellis張家榮先生留下了一個未完成的walkOne,讓我繼續把它發揚光大,

&#x10;

自從ellis走後,他整個人就像回到火星一樣,MSN沒上,yahoo即時通沒上,手機沒人接,

&#x10;

在地球中消失了,所有我對walkOne的問號都沒有辦法解開,在大家努力了幾多個月之後,終於walkOne上線了…

&#x10;

&#x10;

&#x10;

不過…

&#x10;

在上班捷運途中,經過了士林站,竟然看到了…

&#x10;


DSC04568


DSC04567

&#x10;

&#x10;

頓時間,我悟了,原來他不是從地球上消失,也不是回到了火星,

&#x10;

而是當起了
命理老師
啊~~XD!

張家榮大師

吶!

&#x10;

從程式開發轉戰命理世界是很辛苦的,張家榮大師,加油!luka會去跟你談的!

&#x10;

&#x10;

&#x10;


P.S.以上蠢屬虛構,如有姓名雷同之事,那一定只是意外
而已

jQuery 1.3.2 Selectors Demo

9 三月, 2009

Selectors:Hierarchy

  1. ancestor descendant
    選出所有ancestor之下的descendant元素,不論descendant位於ancestor之下幾層。
    類似xpath語法://ancestor//descendant
  2. parent > child
    選出parent的子元素。
    類似xpath語法://parent/child
  3. prev + next
    選出prev元素接著next元素的所有next元素。
    類似的xpath語法://prev/next
  4. prev ~ siblings
    選出prev的所有siblings
    類似的xpath語法://prev/siblings/following-sibling::*
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>jQuery 測試</title>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js" mce_src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
</head>
<body>
<div id="msg_div">default text</div>
<form name="f1">
<span>
<input type="text" name="text1" value="this is f1 text1 value" /><br />
<input type="text" name="text2" value="this is f1 text2 value" /><br />
</span>
<input type="button" value="Demo parent child" id="btn1" /><br />
<input type="button" value="Demo parent > child" id="btn2" /><br />
<input type="button" value="Demo prev + next" id="btn3" /><br />
<input type="button" value="Demo prev ~ siblings" id="btn4" /><br />
</form>
<script type="text/javascript"><!--
$(document).ready(function(){
	var ck='blue';
	$('#btn1').click(function(){
		$('#msg_div').text($.trim($('form[name=f1] input[name=text1]').val()));
	});
	$('#btn2').click(function(){
		$('#msg_div').text($.trim($('form[name=f1] > span > input[name=text2]').val()));
	});
	$('#btn3').click(function(){
		if(ck=='blue'){
			$('span+input').css("color", "yellow");
			ck='yellow';
		}
		else{
			$('span+input').css("color", "blue");
			ck='blue';

		}
	});
	$('#btn4').click(function(){
		$('span ~ input[id=btn1]').css('color','green');
	});
});
// --></script>
</body>
</html>


XSS 攻擊!?walkOne安全嗎?附 XSS 簡易阻斷方法

2 三月, 2009

平常在看不知名人士的部落格時,

&#x10;

也許會被一些部落格元件給吸引,覺得自己也想用一個,

&#x10;

就隨便把來路不明的部落格元件掛到了自己的部落格,

&#x10;

過沒多久卻發現一些私人文章、上鎖文章、甚至完全沒有公開的相簿,

&#x10;

在別處被人完完整整,臉紅心跳的貼出來(這不是塵灌吸~這不是塵灌吸~)

&#x10;

&#x10;

通常人的第一反應,都是:"我的電腦中毒了",

&#x10;

然後就


正妹

好人
,好人去 黃色鬼屋,辛辛苦苦的把電腦重灌完畢

&#x10;

接著平靜的生活過沒多久,同樣的事情又發生了,陷入無盡的重灌...(鄉民也開心的無盡的抓~~喂)

&#x10;

&#x10;

其實~~這最大的元兇也許就是那個來路不明的部落格元件,元件內可能包含了 XSS 攻擊的程式碼!

&#x10;

而不是自己的電腦中毒所造成的資料外流。

&#x10;

 

 

&#x10;

Q:沒有辦法防範XSS攻擊嗎?

&#x10;

A:XSS的攻擊是非常難看出的,因為它完全不會破壞你的系統。只能消極的慎選自己平時逛的網站,不要使用來路不明的部落格元件,一定要養成登出後再關閉瀏覽器的好習慣,最後一個良心的建議:
敢放上網的東西,就不要怕被人看
…XD

&#x10;

 

 

&#x10;

Q:walkOne會有此問題嗎?

&#x10;

A:目前 walkOne 的登入機制採 IP+cookies+多網認證制,且有提供高安全性模登入模式,安全性較高。

&#x10;

&#x10;

以下是寫給網站開發人員看的,不懂的人請把它當是我的碎碎唸吧!

&#x10;

 

 

&#x10;

基於網站開發人員有義務把會員的資料做到最嚴密的
流出
保護,

&#x10;

我們必須設法阻斷XSS攻擊,以下是重點:

&#x10;

&#x10;

訪客未登入的系統 key 值在 front.net 與 back.net 相同,

&#x10;

當訪客從 back.net 登入後,會有一固定的新系統 key 值,

&#x10;

同時存於 front.net 及 back.net ,並在 back.net 建立 cookies,

&#x10;

再將已登入的訪客導至 front.net ,且也於 front.net 建立 cookies,

&#x10;

正常訪客身上將同時帶有 front.net 及 back.net 的認證 cookies,

&#x10;

當 XSS 攻擊者偷取cookies時,僅能偷取到 front.net 的 cookies,

&#x10;

只要 XSS 攻擊者沒有真正於 back.net 上建立過 cookies,

&#x10;

則back.net會一直回傳未登入的系統 key 值,

&#x10;

於是當訪客登入後在 front.net 操作時,

&#x10;

判斷 front.net 的系統 key 值與 back.net 傳回的系統 key 值是否相等,

&#x10;

即可判斷該訪客是否有透過正常管道登入。

&#x10;

至於如何在 front.net 的頁面中取得 back.net 的 cookies,

&#x10;

可以參考 jQuery 1.3.1 Ajax Cross Domain JSP Demo

&#x10;

jQuery 1.3.1 Ajax Cross Domain JSP Demo

23 二月, 2009

一般Ajax 是無法跨網域呼叫的,不過有兩個方法可以逹到跨網域呼叫:

&#x10;

      &#x10;

    1. 使用伺服器端讀取遠端檔案

&#x10;

  • 使用<script src="remote file">的語法

 

&#x10;

&#x10;

第一種方法很簡單,用java.net.URL寫一個取得遠端content的proxy即可。

&#x10;

第二種方法,jQuery已將<script src="remote file">包裝在$.ajax之內,
並在 jQuery 的 API 內就有 demo 了,而使用的限制就是遠端回傳的content必需是jsonp的物件。

&#x10;

jQuery知道jsonp必需回傳一個function name,在本地端也必需有相對應的function name,

&#x10;

寫程式最麻煩的就是命名了,所以jQuery在$.getJSON(url,function(data){})的url參數內幫我們把call back所需的命名做了簡易的處理,
當jQuery在url參數內找到xxx=?這個參數,便會自動幫我們產生一個獨特的function name,
並將function name賦值給xxx傳出,此function name在本地端也會有實體化,
就是function(data){}的這個隱名函式,所以當我們使用$.getJSON這個方法時,
不用再為每個jsonp的call back想一個名字,實在方便很多,請看以下的簡易範例程式碼:

&#x10;

&#x10;

呼叫端(the_url 請改為您自己的server):

&#x10;

 

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">&#x10;<html xmlns="http://www.w3.org/1999/xhtml">&#x10;<head>&#x10;<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />&#x10;<title>jsonp</title>&#x10;<mce:script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.1/jquery.min.js" mce_src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.1/jquery.min.js"></mce:script>&#x10;<mce:script type="text/javascript">&#x10;$(document).ready(function(){&#x10;	var the_url='http://www.yahoo.tw/json.jsp?callback=?';&#x10;	$.getJSON(the_url,function(data){&#x10;		$('#demo_content').html('<a href="'+data.link+'" mce_href="'+data.link+'" target="_blank">'+data.title+'</a><br />\n');&#x10;		for(var i=0;i<data.items.length;i++){&#x10;			$('#demo_content').append('feed:<a href="'+data.items[i].link+'" mce_href="'+data.items[i].link+'" target="_blank">'+data.items[i].title+'</a><br />\n');&#x10;		}&#x10;	});&#x10;});&#x10;</mce:script>&#x10;</head>&#x10;<body>&#x10;<div id="demo_content"></div>&#x10;</body>&#x10;</html>

&#x10;

&#x10;

&#x10;

遠端被呼叫端:

&#x10;

&#x10;

<%@page contentType="application/x-javascript; charset=utf-8" errorPage=""%>&#x10;<%&#x10;out.clear();&#x10;String callback=(request.getParameter("callback")==null)?"":request.getParameter("callback");&#x10;//callback的開頭必須為英文字元,整個callback只允許長度25的英數字元&#x10;if(!callback.matches("^[a-zA-Z]{1}[a-zA-Z0-9]{0,24}$")){&#x10;	//所有不符合規則的callback都設為空字串,以免javascript發生錯誤&#x10;	callback="";&#x10;}&#x10;pageContext.setAttribute("callback",callback);&#x10;%>${callback}({&#x10;  "title": "walkOne - RSS 2.0",&#x10;  "link": "http://www.walkone.tw/",&#x10;  "description": "walkOne - RSS 2.0",&#x10;  "modified": "2009-02-23T09:55:26Z",&#x10;  "generator": "http://www.walkone.tw/",&#x10;  "items": [{&#x10;    "title": "開發者日誌",&#x10;    "link": "http://www.walkone.com.tw/blog/index.jsp?user_id=test"&#x10;  }]&#x10;})

&#x10;

dom4j insert Element

20 二月, 2009

最近 RSS2.0 在 feed validator 做驗證時,

&#x10;

一直出現 Misplaced Item 的警告訊息,雖然這個錯誤不會讓 RSS 無法被 paser,

&#x10;

但是有警告訊息看起來就是不順眼,

&#x10;

Misplaced Item  提供了解決方法,

&#x10;

告知我的 RSS <item> 元素應該要放在 <channel> 元素的最下方,

&#x10;

但是使用 rome 1.0RC1 製出的 RSS feed 會少一些東西

&#x10;

      &#x10;

    1. &#x10;
      xmlns:atom="http://www.w3.org/2005/Atom"

      &#x10;

&#x10;

  • &#x10;
    <atom:link
     href="feed's link" 
    rel="self" 
    type="application/rss+xml"
    />

    &#x10;

 

&#x10;

&#x10;

之前使用懶人寫法,直接用 dom4j 讀入 feeds 重製,

&#x10;

先用 dom4j 的 addNamespace() 加入 atom 的 namespace,

&#x10;

再用 dom4j 的 addElement() 加入atom:link的元素,

&#x10;

可是~addElement() 會將 Element 加到最後一個<item>之後,

&#x10;

大致找了一下dom4j API,都沒有 insert Element 到指定位置的寫法,

&#x10;

其實當使用 dom4j 取得 Node List後,就可以用 java.util.List 的方法操作 Node 了。

&#x10;

import com.sun.syndication.io.WireFeedOutput;&#x10;import org.dom4j.Document;&#x10;import org.dom4j.Element;&#x10;import org.dom4j.DocumentHelper;&#x10;import com.sun.syndication.feed.rss.Channel;&#x10;//以下是部份程式碼&#x10;Channel channel = new Channel();&#x10;WireFeedOutput wf=new WireFeedOutput();&#x10;Document doc=DocumentHelper.parseText(wf.outputString(channel));&#x10;Element root=(Element)doc.selectSingleNode("/rss");&#x10;root.addNamespace("atom","http://www.w3.org/2005/Atom");&#x10;List<Element> node_list=root.element("channel").elements();&#x10;Element el=DocumentHelper.createElement("atom:link").addAttribute("href","your feed link").addAttribute("rel","self").addAttribute("type","application/rss+xml");&#x10;for(int i=0;i<node_list.size();i++){&#x10;	if(node_list.get(i).getName().equalsIgnoreCase("image")){&#x10;		node_list.add(i+1,el);&#x10;	}&#x10;}&#x10;System.out.println(doc.asXML());&#x10;

&#x10;

&#x10;

&#x10;