Java encoding French Language

เดือนก่อน ลูกค้าเจ้านึงในฝรั่งเศสส่ง issue มาว่า Sever ผม encode ภาษาฝรั่งเศสผิด แปลงตัว é กลายเป็น é ทั้งหมดเลย

สิ่งแรกที่ผมทำคือลอง Google ดูเกี่ยวกับปัญหานี้ ส่วนใหญ่เขาก็จะบอกกันว่าเป็นที่ encoding กันหมด

สิ่งที่สองที่ผมทำคือลอง test กับ server ผมเองว่ามันทำผิดจริงรึเปล่า เท่าที่ลองรัน test page หรือเขียน JavaScript มาลองดูมันก็แสดงผลเป็น é ตรงนี่หว่า -*- ถาม Dev ๆ ก็บอกว่าก็ส่งเป็น UTF-8 นะ สุดท้ายก็เลยลองถามลูกค้าไปว่า “เขาดึงข้อมูลจาก server ผมยังไง” ลูกค้าก็ให้โค๊ดประมาณแนวๆ นี้มา

protected void processRequest(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.setContentType("text/html;charset=UTF-8");
        PrintWriter out = response.getWriter();
        //Create JSON POST 
        JSONObject request_msg = new JSONObject();
        request_msg.put("closure", "JAVA_CLIENT"); 
        JSONArray requestArray = new JSONArray();
        requestArray.add("language=France");
        request_msg.put("request", requestArray);

        try {
            PrintStream outt = new PrintStream(System.out, true, "UTF-8");

            HttpURLConnection urlConn = null;
            URL url = new URL("http://server:80/getdata");
            urlConn = (HttpURLConnection) url.openConnection();
            urlConn.setRequestMethod("POST");
            urlConn.setAllowUserInteraction(false);
            urlConn.addRequestProperty("Accept", "application/json,text/javascript, */*; q=0.01");
            urlConn.addRequestProperty("Accept-Charset", "ISO-8859-1,utf-8;q=0.7,*;q=0.3");
            urlConn.addRequestProperty("Accept-Encoding", "gzip,deflate,sdch");
            urlConn.addRequestProperty("Accept-Language", "fr-FR,fr;q=0.8,en-US;q=0.8,en;q=0.4");
            urlConn.addRequestProperty("Content-Type", "application/json");
            urlConn.addRequestProperty("Connection", "keep-alive");
            // envoyer des params
            urlConn.setDoOutput(true);

            // poster les params
            PrintWriter paramWriter = new PrintWriter(urlConn.getOutputStream());

            paramWriter.print(request_msg.toString());
            // fermer le post avant de lire le resultat ... logique
            paramWriter.flush();
            paramWriter.close();
                        
            // Lire la reponse
            InputStream resp = urlConn.getInputStream();
            BufferedReader bufReader = new BufferedReader(new InputStreamReader(resp));
            String sLine;
            StringBuilder sb = new StringBuilder();
            String lineSep = "###";


            while ((sLine = bufReader.readLine()) != null) {
                sb.append(sLine);
                sb.append(lineSep);
            }

            out.println(sb.toString());

            // deconnection
            urlConn.disconnect();
            bufReader.close();
            out.close();
        } catch (Exception e) {
            System.out.println("Error " + e.toString());
            e.printStackTrace();
        }
    }

Code ข้างบนนี่จริงๆ ลูกค้าให้มาแค่ส่วนตัว HTTP ส่วน Sevlet ทั้งหลายนี่ผมเขียนเพิ่มเองเพื่อ Test ส่วน Logic การใช้ HttpURLConnection, PrintWriter, Buffer ทั้งหลายนั่นเอา code เขามา ส่วนการส่ง JSON ผมเลือกใช้ simple – json เพราะตอนนั้นไม่รู้ว่า Java support JSON แบบ native แล้ว
Continue reading “Java encoding French Language”

JavaScript Web Workers #2

ผมเขียนเรื่อง Web Workers ตอนแรกไปแล้ว วันนี้จะมีเขียนต่อในกรณีที่เราอยากจะ include JavaScript Library อื่นๆ เราจะทำยังไง

ก่อนอื่นต้องย้ำว่าตัว Worker นั้นไม่สามารถจะเข้าถึงพวก DOM Element ใดๆ ได้เลย Library ตัวไหนมีเรียกพวก DOM พวกนี้ include เข้ามาจะเจ๊งเลย ดังนั้น Lib อย่าง jQuery ก็เรียกไม่ได้แน่นอน

คำสั่งที่เราใช้ include JavaScript คือ importScripts() ที่เราจะ include ครับ เช่น

importScripts('underscore-min.js');

ที่นี้มาดูตัวอย่าง JavaScript Worker ที่เรียกใช้ underscore.js เพื่อใช้ยัด JSON จาก Worker ต่อท้าย JSON ที่ master ส่งให้ worker

//master_worker.html
<script language="javascript">
	window.onload=function(){
		var wk=new Worker("./slave_worker.js");
		wk.addEventListener("message",function(oEvent){
			document.getElementById('display').textContent = JSON.stringify(oEvent.data);
		},false);

		wk.postMessage({
			master:'This is master Say Hello'
		});
	};
</script>
</head>
<body>
	<div id="display"></div>
</body>

Code master_worker.html ข้างบนเรียก Worker จาก file slave_worker.js แล้วเราก็ส่ง JSON {master:’This is master Say Hello’} ไปให้ทาง function postMessage

//slave_worker.js
importScripts('underscore-min.js');

self.addEventListener('message',function(e){
	var data=e.data;
	self.postMessage(_.extend(data,{worker:'This is worker Say Hello'}));
},false);

Code slave_worker.js ก็รับ JSON {master:’This is master Say Hello’} มาทาง addEventListener ‘message’ แล้วก็ยัด JSON {worker:’This is worker Say Hello’} เข้าไปด้วย function extend ของ underscore.js ก่อนที่จะส่ง JSON ที่เพิ่ม key:value ไปแล้วให้ master_worker.html ทาง postMessage

แล้ว {master:’This is master Say Hello’,worker:’This is worker Say Hello’} จะถูกส่งมาถึง addEventListener ‘message’ ของ master_worker.html แล้วแสดงค่าใน div

ถ้าลองเปลียนเป็น include jQuery ใน slave_worker.js ดูจะเจ๊งทันที

JavaScript Web Workers

วันนี้ได้ mail จากลูกค้าเจ้านึง เขียนประมาณว่า “กูอยากใช้ Shared Web Workers (SWW) มึงช่วยทำไงก็ได้ให้ JavaScript API มึง support SWW ที หรือไม่งั้นมึงบอก design, protocol มา เดี๋ยวกูเขียน API ใหม่เอง (แต่มึงต้อง test, fix bug แล้ว support code ที่กูเขียนนะ – สัด)” ผมก็เลยต้องมานั่งหาว่าไอ้ Web Workers หรือ Shared Web Worker มันคือะไร เพราะไม่เคยได้ยินมาก่อน entry นี้จะเขียนถึง Web Workers ก่อนละกัน

Web Workers (Web Workers @Wikipedia) เป็น feature ของ HTML 5 ที่ทำให้สามารถรัน JavaScript แบบ multithread ได้ครับ

คือปกติ JavaScript มันเป็น single thread มันจะรันคำสั่งตาม queue ของมันเสมอ ไม่ว่าจะเป็นการ display, validate, ต่อ ajax, websocket หรือทำ function ต่างๆ ที่เราเขียน ทุกอย่างอยู่บน thread เดียวกันหมด ดังนั้นเวลามี function อะไรใน queue รันหนักๆ มันจะกระทบให้ทั้ง page ช้าไปหมดจนบางที browser จะขึ้น pop up มาถามว่า page กำลัง script อะไรบางอย่างทำให้มันช้าจน freeze นะ จะ kill page นี้ทิ้งไหม

เขาก็เลยคิด Web Workers ขึ้นมาเพื่อแตกงานอะไรที่หนักๆ ไปอีก thread นึงเลย จากที่ค้นๆ มาเขาจะยกตัวอย่างเป็นคำนวนค่า Pi ที่ต้องวน loop หนักๆ หรืออะไรที่ต้องคุยกับ server เยอะๆ แยกเป็น thread worker ไปแล้วให้ thread หลักรับผลการทำงานจาก thread ลูก (Worker) แบบ asynchronous ไปซะ

Concept หลักๆ ของการเขียน Web Workers คือ

ตัวแม่ (ชื่อ main.html ละกัน)

//new Worker object
var wk=new Worker("worker.js");
//ใช้ addEventListener เพื่อรับ message จาก Woker --> self.postMessage('worker got : '+data);
wk.addEventListener("message",function(oEvent){
	document.getElementById('display').textContent = oEvent.data;
	//จะ print 'worker got : Hello'
},false);

//start Worker และส่ง message ให้ Worker ด้วย postMessage
wk.postMessage('Hello'); 

worker.js

//ใช้ addEventListener เพื่อรับ message จาก Main --> wk.postMessage('Hello'); 
self.addEventListener('message',function(e){
	var data=e.data;
	//ใช้ postMessage เพื่อส่งกลับให้ Main
	self.postMessage('worker got : '+data);
},false); 

Continue reading “JavaScript Web Workers”