Saturday, December 3, 2016

Debug GWT in Eclipse

ช่างเป็นเรื่องยากลำบากจริงในการใช้งาน Eclipse เนื่องจากเดิมใช้ Netbean อยู่ แต่เนื่องจาก GWT ดูๆแล้วจะยังไม่รองรับ Netbean ดีพอ จึงจำเป็นต้องใช้ Eclipse จากที่ได้ลองใช้ก็ถือว่าดี แต่คิดว่า Netbean ดีกว่านะ เอาหละเริ่มเรื่องกันเลย ได้ลองทำตามตัวอย่างในเว็บของ GWT พอมาถึงการดีบัก มันดันไม่หยุดที่ breakpoint ซะงั้น หาข้อมูลจากเน็ตก็เป็นกันหลายคน วิธีแก้คือต้องใช้ตัวช่วย (คิดในใจ  ทำไมต้องใช้ตัวช่วยด้วยวะ ไหงว่า support ไง) คือ SDBG ตามเว็บนี้เลยครับผม https://sdbg.github.io/

Thursday, May 12, 2016

ปัญหาลง window 7 ไม่ผ่าน

วันนี้ได้ลง window 7 ใหม่ แต่เกิดปัญหา

Error message "The Computer Restarted unexpectedly or encountered an unexpected error" after System Startup on Windows 7 Recovery

ลงตั้งหลายครั้ง เลยหาใน อากู๋ ดู แก้โดยเปลี่ยนค่าใน regedit โดย

1)      On the same error screen press SHIFT+F10 and it will open up a black Window. (a command prompt window)
2)       In  the black windows type the word "regedit"(without the inverted commas and hit enter. That will open the registry editor.
        In the Registry Editor..
                Browse to....
        HKLocal machine/SYSTEM/SETUP/STATUS/ChildCompletion, and after highliting childcompletion,on the right hand side check for setup.exe. if the value is 1 change it to 3.(by double clicking on setup.exe and changing the value shown in the box).
Then close the registry editor and then also close the black window.
      Then click on OK for the error and the computer will restart and the installation may complete.  just try it and let me know if it worked.

วิธีการนี้เป็นของคุณ J0seph Red  ครับซึ่งก็ได้ผลนะ ที่ต้องกด SHIFT+F10 เพราะยังเข้าวินโดวไม่ได้ครับ จะอยู่ได้แค่หน้า start service ครับผม

Monday, April 11, 2016

ใช้งาน reCaptcha

เนื่องจาก jCaptcha เมื่อส่งไปยังโฮสตอนแรกก็ไม่มีปัญหา แต่พอใกล้จะหมดระยะเช่าซื้อโฮสดันใช้ไม่ได้ซะงั้น และโฮสก็ล่มบ่อยมาก ทำให้ผมต้องมานั่งหาวิธีทำ captcha ใหม่ที่ไม่น่าจะมีปัญหาต่อไปในอนาคต ตัวเก่ามีปัญหาดังนี้

ปัญหานี้น่าจะเกิดจากโฮสเองเพราะในเครื่องผมก็ไม่มีปัญหาอะไร แต่ก็ไม่ทราบว่าทางโฮสมีปัญหาอะไรเหมือนกัน แต่ก็นั่นแหละไม่มีเวลารอแล้ว จึงตัดสินใจไม่ใช้ jCaptcha จึงไปลองใช้ reCaptcha ของ google แทนซึ่งง่ายกว่า jCaptcha ที่ผมใช้อยู่เยอะเลย(ดีแล้วที่เปลี่ยน) โดยมีขั้นตอนดังต่อไปนี้

1. ต้องสมัครก่อน ที่ https://www.google.com/recaptcha/intro/index.html ดังรูป

  • คลิกที่ ปุ่ม Get reCAPTCHA แล้วไปสมัครใช้งานซะดังรูปแรก
  • รูปที่สองจะเห็นว่าเราสามารถที่จะเพิ่ม web เขาไปได้อีกนะครับ กี่เว็บก็ได้ และโดย default แล้วเราสามารถที่จะใช้ reCaptcha บน localhost ได้เลยนะ สำหรับของผมสมัครไว้เว็บเดียวเท่านั้น และก็สามารถใช้บน localhost ได้เลยไม่จำเป็นต้องเพิ่ม localhost ใน reCaptcha แต่อย่างใด
    แต่ต่อมาก็มีปัญหาครับ คือว่าทาง reCaptcha จะให้ใช้แบบ localhost ได้ระยะเวลาหนึ่งเท่านั้น ฉนั้นให้ทำการลงทะเบียน localhost ไปด้วยครับเพื่อต่อไปจะได้ไม่มีปัญหาครับผม แต่ก็จะแยก key กันนะ ระหว่าง localhost กับ site จริงๆที่เราใช้งาน
  • จากนั้นก็คลิกที่ชื่อ web ที่เราสมัครไว้นะครับเพื่อที่จะนำ key มาใช้ reCaptcha ต่อไป
  • รูปที่สาม เป็นการนำ key ที่ reCaptcha ให้มาใช้งานนะ คลิกที่ปุ่ม Keys ในรูปที่สามได้เลย จะให้มา 2 key ด้วยกันคือ Site key และ Secret key โดยผมจะใช้แค่ Site key เท่านั้นครับ

2. จากนั้นก็มาเริ่มเขียน Code ต่อไป สำหรับการสอนการใช้งานแบบละเอียดสามารถดูได้จาก เว็บ https://developers.google.com/recaptcha/intro ได้เลยครับ ซึ่งที่ผมเขียนอยู่นี้เป็นเวอร์ชั่น 2.0 นะ ส่วน code ที่ผมเขียนจะเป็นดังนี้
  • จั่วหัวกันก่อน เพื่อระบุไปที่เว็บ google ส่วน onload=onloadCallback หมายถึงจะมีการเรียน function onloadCallback เมื่อตอนเริ่มต้นของ reCaptcha ส่วน render=explicit เป็นการจัดการการแสดงผล reCapcha เอง จริงๆแล้วการ render มีสองแบบนะ 1. auto 2. explicit
  • render function เป็นฟังก์ชั่นในการ render captcha ขึ้นมา โดยจะต้องระบุ id ของ tag div และ site key และ ฟังก์ชั่น callback (เมื่อผ่าน captcha แล้ว) และสามารถปรับ theme ได้ในที่นี้คือสีดำ dark
var onloadCallback = function() {
        //render captcha
        grecaptcha.render('recaptcha', {
          'sitekey' : '334sToVybVqmBUwsRTXg3jP',
          'callback' : verifyCallback,
          'theme' : 'dark'
        });
      };
                • callback function เป็นฟังก์ชั่นที่จะทำงานก็ต่อเมื่อผ่าน captcha แล้ว ต้องให้ตรงกับที่กำหนดไว้ที่ render function นะ
                      var verify = null;//เอาไว้ตรวจสอบว่ามีการเลือก captcha ถูกต้องแล้วหรือไม่
                      var verifyCallback = function(response) {
                        verify = response;
                        if(response !== null){
                            document.getElementById("btnBooking").src = "images2/booking-now.png";
                        }
                      };
                     ์Note ทั้งสาม code ด้านบนจะอยู่ในส่วนของ javascript นะครับ

                • สุดท้ายก็เพิ่มในส่วนแสดงภาพ render captcha ว่าจะให้อยู่ที่ไหนก็ได้ใน tag body โดยวาง tag div ไว้ในที่ๆต้องการได้เลย สังเกตว่าชื่อ id="recaptcha" จะต้องเหมือนกับชื่อที่ใช้ในการ render ของ render function นะ



                  เป็นอันเสร็จครับผม ง่ายจริงๆ ส่วน jCaptcha ผมยังไม่ได้เอาออกทั้งหมด(ขี้เกียจเอาออกหมด) เพียงแต่แก้ไขในส่วนที่จะเปลี่ยนแค่นั้น(หน้าที่ต้องใช้ captcha) ไปดูได้ที่เว็บ http://www.budsatravel.com/webBudsa/booking/index.jsp













                Tuesday, October 6, 2015

                สาเหตุที่ผู้ประกอบการเจ๊งตั้งแต่เริ่มต้น

                1.เกิดจากการมองโลกในแง่ดีเกินไป
                2.เจ้าของประเมินความสามารถตัวเองสูงเกินไป
                3.โดนสกัดดาวรุ่ง จากคู่แข่ง ที่มีอยู่ก่อน
                4.โดนโกงจนขาดทุน
                5.ขาดเงินทุนสำรอง ไม่มีก๊อก 2

                เพิ่มการ์ดแลนใหม่ให้ clearos 5.2 แต่ดันไม่เห็นซะงั้น


                ผมได้ทำการเพิ่มการ์ดแลนอีกตัว เดิมมีอยู่แล้ว 2 ตัว และ ออนบอร์ดอีก 1 ตัว เพิ่มอีกตัวก็เป็น 4 นะครับ
                ผมจะต่อเน็ต 3 เส้น
                แต่ว่า clearos ไม่เจอการ์ดแลนที่เพิ่มไป ผมได้นำวิธีจากเว็บนี้นะครับ http://talk.ict.in.th/44467 แต่ได้ลดขั้นตอนลงเนื่องจากว่า ใน ect/sysconfig/network-scripts  กับ ect/sysconfig/network-scripts นั้น Mac Address ไม่ตรงกันก็เลยไม่ได้ไปยุ่งกับ ect/sysconfig/network-scripts เลยนะครับ แต่ผมจะยุ่งกับ
                1. putty
                2. ect/sysconfig/network-scripts

                คือผมจะหา mac address ใน putty ดังรูปจะเห็นว่าบรรทัดแรกคือ mac address ของตัวใหม่นะ ของเดิมจะเป็น eth0-eth2

                แล้วมาดูใน ect/sysconfig/network-scripts ที่เป็น eth ต่างๆนะครับ ของผมมี eth0-eth2 ผมก็เลยเพิ่ม eth3 ชื่อว่า ifcfg-eth3 เข้าไปโดย copy ข้อมูลจาก ifcfg-eth0 ซึ่งเป็น lan onboard โดยไฟล์มีข้อมูลดังนี้

                DEVICE=eth3
                TYPE="Ethernet"
                ONBOOT="yes"
                USERCTL="no"
                HWADDR="14:cc:20:03:62:08"
                BOOTPROTO="static"
                IPADDR="192.168.1.5"
                NETMASK="255.255.255.0"

                GATEWAY="192.168.1.2"
                หรือดังรูปแล้วครับ เดิมไม่มีไฟล์ ifcfg-eth3 นะครับผม

                 จากนั้นก็ save ไฟล์ครับผม ต่อไป...
                เข้าไปใน putty พิมพ์คำสั่ง service network restart ครับ

                ก็เป็นอันเสร็จเรียบร้อยครับ เพิ่มมาแล้ว eth3

                และไปเปิดที่หน้า webcofig ดูจะเห็นว่ามี eth3 เพิ่มมาแล้วครับผม

                Wednesday, October 15, 2014

                แสดง captcha ด้วย jcaptcha v.1.0 และปัญหาไม่แสดงภาพ

                เนื่องจากผมต้องการ captcha มาไว้ในเว็บเพื่อป้องกัน bot ต่างเข้ามาพิมพ์โน่นพิมพ์นี่เอง ทำให้ต้องหาๆๆๆ และก็หา เลยไปเจอ jcaptcha v 1.0 ตามลิ้งค์นี้เลย http://jcaptcha.sourceforge.net/ ดาวน์โหลดมาเลย
                ผมโหลด v 1.0 พอดีมีอยู่เวอร์ชั่นเดียวสงสัยไม่พัฒนาต่อแล้วแหละ และตามด้วย  commons-logging และ commons-collection เอาไฟล์ .jar ทั้งสามไป add ใน Library ใน Netbean (ผมพัฒนาด้วย Netbean ครับ) เสร็จแล้วก็ขั้นตอนต่อไป

                กำหนด servlet mapping ในไฟล์ dwr ดังนี้

                เสร็จแล้วก็ไปขั้นตอนสร้าง servlet ต่อไปครับ โดยผมสร้าง java package JCaptchaService ขั้นมาข้างในประกอบไปด้วย 3 Class ด้วยกันคือ
                1. CaptchaServiceSingleton
                2. ImageCaptchaServlet ซึ่งเป็น Servlet
                3. validateJCaptcha สร้างขึ้นมาเองเอาไว้ตรวจสอบเวลาใช้งานกับ DWR
                โดย 2 Class แรก copy มาจากเขาเลยดังนี้
                1.CaptchaServiceSingleton
                package JCaptchaService;

                import com.octo.captcha.service.image.DefaultManageableImageCaptchaService;
                import com.octo.captcha.service.image.ImageCaptchaService;

                /**
                 *
                 * @author Nonpatan
                 */
                public class CaptchaServiceSingleton {
                    private static ImageCaptchaService instance = new DefaultManageableImageCaptchaService();

                    public static ImageCaptchaService getInstance(){
                        return instance;
                    }
                }
                2. ImageCaptchaServlet
                public class ImageCaptchaServlet extends HttpServlet {

                    /**
                     * Processes requests for both HTTP
                     * GET and
                     * POST methods.
                     *
                     * @param request servlet request
                     * @param response servlet response
                     * @throws ServletException if a servlet-specific error occurs
                     * @throws IOException if an I/O error occurs
                     */
                    protected void processRequest(HttpServletRequest request, HttpServletResponse response)
                            throws ServletException, IOException {
                        byte[] captchaChallengeAsJpeg = null;
                       // the output stream to render the captcha image as jpeg into
                        ByteArrayOutputStream jpegOutputStream = new ByteArrayOutputStream();
                        try {
                        // get the session id that will identify the generated captcha.
                        //the same id must be used to validate the response, the session id is a good candidate!
                        String captchaId = request.getSession().getId();
                        // call the ImageCaptchaService getChallenge method
                            BufferedImage challenge =
                                    CaptchaServiceSingleton.getInstance().getImageChallengeForID(captchaId,
                                            request.getLocale());
                            //ImageIO.write(challenge, "jpeg", jpegOutputStream);
                            // a jpeg encoder
                            JPEGImageEncoder jpegEncoder =
                                    JPEGCodec.createJPEGEncoder(jpegOutputStream);
                            jpegEncoder.encode(challenge);
                        } catch (IllegalArgumentException e) {
                            response.sendError(HttpServletResponse.SC_NOT_FOUND);
                            return;
                        } catch (CaptchaServiceException e) {
                            response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
                            return;
                        }

                        captchaChallengeAsJpeg = jpegOutputStream.toByteArray();

                        // flush it in the response
                        response.setHeader("Cache-Control", "no-store");
                        response.setHeader("Pragma", "no-cache");
                        response.setDateHeader("Expires", 0);
                        response.setContentType("image/jpeg");
                        ServletOutputStream responseOutputStream =
                                response.getOutputStream();
                        responseOutputStream.write(captchaChallengeAsJpeg);
                        responseOutputStream.flush();
                        responseOutputStream.close();
                    }
                3. validateJCaptcha
                public class validateJCaptcha {
                    public boolean validate(String captchaId,String value){
                        Boolean isResponseCorrect =Boolean.FALSE;
                        try {
                                isResponseCorrect = CaptchaServiceSingleton.getInstance().validateResponseForID(captchaId,
                                        value);
                            } catch (CaptchaServiceException e) {
                            }
                        
                        return isResponseCorrect;
                    }
                    
                }
                ก็เป็นอันเสร็จนะครับ ในการเพิ่ม คลาส ต่อไปจะเป็นส่วนแสดงภาพ captcha กัน

                ผมทำจะทำร่วมด้วยกับ javascript + dwr นะครับฉนั้นจะต้องแสดงประกอบไปด้วย ส่วน dwr จะไม่อธิบายในนี้นะครับ
                นี่คือส่วนแสดงภาพนะครับ
                ต่อไปส่วนใส่ตัวอักษรที่เห็นนะ


                ต่อไปคือส่วนเปลี่ยนภาพในกรณีที่ดูภาพไ่ม่ออกอยากจะเอาภาพใหม่


                จะเห็นว่าในส่วนเปลี่ยนภาพใหม่นั้นจะมีการเรียก javascript ด้วยคือ reloadImg(); ดังนั้นก็ต้องไปสร้าง javascript เพื่อเปลี่ยนภาพด้วยดังนี้
                function reloadImg() {
                            var d = new Date();
                            document.getElementById("jcap").src = "/webPackage ของคุณ/jcaptcha?a=" + d.getTime();
                        }
                จะเห็นว่าจะต้องใช้ date(); เพื่อหลอกให้มันเปลียนภาพ
                เสร็จแล้วต่อไปก็จะเป็นส่วนของการตรวจสอบว่าสิ่งที่พิมพ์ไปใน textbox นั้นตรงกับภาพหรือไม่ครับดังนี้
                แต่ส่วนนี้จะเป็นหน้าที่ของ DWR ด้วยคือผมจะนำมาไม่หมดทั้ง function นะหลักๆก็ตามไฮไลน์สี่เขียวนะ
                นอกนั้นจะเป็นในส่วนของ callback function ซึ่งเป็นเนื่อหาของ DWR
                function validateForm(){
                        //ทำการตรวจสอบ captcha
                        var sid = "<%=(String)request.getSession().getId() %>";
                        var valueCap = dwr.util.getValue("japtcha");
                        if(valueCap===''){
                            alert("Please fill charactor");
                            var japtcha = dwr.util.byId("japtcha");
                            japtcha.focus();
                        }
                        else{
                            //ทำการตรวจสอบ captcha ก่อนเลยว่าถูกหรือไม่
                            validateJCaptcha.validate(sid,valueCap,{
                                callback:function(ok){
                จะเห็นไว้ว่าในส่วนสีเขียว จะดึง sessionid มาเก็บไว้ที่ sid และดึงค่าที่ผู้ใช้เว็บป้อนมาทาง textbox มาเก็บไว้ที่ valueCap จากนั้นนำค่าทั้งสองไปให้ฟังก็ชั้นที่สร้างเองชื่อว่า validateJCaptcha.validate() ตามที่ได้สร้างไว้ก่อนหน้านี้ในข้อ 3 ถ้าตรงก็จะ return true ถ้าไม่ตรงก็จะ return false ครับผม จบยังเนี่ย เกือบจบแต่ไม่จบ
                คือว่าเมื่อเสร็จแล้วผมก็นำขึ้นโฮสต์แต่ว่าไม่แสดงภาพเหมือนที่ทำกับ Notebook ที่บ้านเลย จึงถามโฮสต์ว่าใช้ jvm เวอร์ชั่นไหนก็ตอบมาว่า version 7 ผมใช้ version 6 และตอนที่ built ใน netbean มันก็บอกว่า JPEGCodec จะยกเลิกใช้แล้วก็เลยสงสัยว่าจะเป็นที่คลาสเนี่ยแหละที่ทำให้ไม่เห็นภาพมันอาจจะยกเลิกไปแล้วใน java 7 ผมก็เลยถ้างั้นหาตัวอื่นก็ได้เลยไปหามาคือ simple captcha ก็ง่ายดีแต่ก็มีปัญหากับ DWR อีกคือจะต้องส่ง session object ของ captcha ไปตรวจสอบที่ validate function ซึ่งส่งยากมากทำๆไปก็ไม่ได้ซักกะทีใครรู้บอกผมด้วยละกันส่งยังไง ก็เลยงั้นกลับมาแก้โค๊ดของ jcaptcha ก็ได้ซึ่งพอทำจริงๆก็ไม่ยากครับ ลองดูใน code ของ 2 นะที่ผมทำสีแดงและ comment เอาไว้หนะ เอา comment ออก และในส่วนของสีชมพูในข้อ 2 ก็ลบออกเลยครับ เสร็จจริงๆแล้วคราวนี้ครับผม สรุปว่าที่ไม่ขึ้นภาพเพราะ JPEGCodec ถูกยกเลิกไปแล้วครับผม

                Monday, October 13, 2014

                ส่งเมลส์ด้วย javaMail ผ่าน gmail

                วันนี้ได้ทดลองส่งเมลส์ด้วย javaMail ดู แต่ก่อนหน้านี้ก็ได้ลองทำแล้วแต่ใช้ mail ที่ localhost
                เริ่มเลยละกัน ออ ผมใช้ netbean นะครับ ฉนั้นพวก import เนี่ยผมไม่พูดละกันมันหาให้เองแหละ

                -การจะติดต่อได้ก็ต้องมี API ก่อนนะ ผมใช้ javaMail คือมีทั้ง javax.mail และ activation หาโหลดเองนะครับ ผมลืมแล้วว่าเว็บไหน ปรึกษา google ได้เลย จากนั้นก็เอาไปไว้ที่ WEB-INF\lib

                -จากนั้นก็เขียน code กัน อันนี้เป็นที่ผมทำไว้ใน web นะครับ ใช้ได้เลย(ลองในเครื่องตัวเองนะ)
                การใช้ javaMail นั้นมีอยู่ด้วยกัน 3 แบบนะ ปกติ smtp จะเป็น port 25 นะ แต่ gmail.com จะใ้ห้เราใช้ port อื่น เพราะต้องใช้ Authen ด้วย
                1. ใช้ smtp ไม่ใช้ Authen
                2. ใช้ smtp ใช้ TLS Authen
                3. ใช้ smtp ใช้ SSL Authen

                สำหรับ gmail.com จะใช้ได้ทั้ง TLS และ SSL นะครับ สำหรับผมใช้แบบ TLS Authen

                        String auth_host = "smtp.gmail.com";//กำหนด host
                        String auth_port = "587";//กำหนด port
                        final String auth_email = "satravel@gmail.com";//กำหนด email
                        final String auth_password = "password";//กำหนด password

                       // Get system properties object
                        Properties properties = System.getProperties();

                       // Setup mail server โดยใช้ TLS Authentication
                        properties.put("mail.smtp.host", auth_host);
                        properties.put("mail.smtp.port", auth_port);
                        properties.put("mail.smtp.auth", "true");
                        properties.put("mail.smtp.starttls.enable", "true");

                        try {
                         
                            Authenticator auth = new Authenticator(){
                                @Override
                                public PasswordAuthentication getPasswordAuthentication(){
                                    return new PasswordAuthentication(auth_email,auth_password);
                                }
                            };
                         
                            Session mailSession = Session.getInstance( properties , auth);//สร้าง session
                            // Create a default MimeMessage object.
                            MimeMessage message = new MimeMessage(mailSession);
                            // Set From: header field of the header.
                            message.setFrom(new InternetAddress(from,"Budsatravel"));//กำหนดชื่อผู้ส่งนะ
                            //Set Reply To
                            message.setReplyTo(InternetAddress.parse("satravel@gmail.com",false));//กำหนด reply
                            // Set To: header field of the header.
                            message.addRecipient(Message.RecipientType.TO,new InternetAddress(to,false));//ผู้รับ
                            // Set Subject: header field
                            message.setSubject("Booking From Budsatravel.com");//หัวข้ออีเมลส์
                            // Now set the actual message
                            message.setContent(content,"text/html");//ส่งเป็น html โดย content จะต้องมีลักษณะเป็น html
                         
                            // Send message
                            Transport.send(message);
                            return true;
                        } catch (Exception mex) {
                            return false;
                        }

                       เรียบร้อยครับผม
                       ออในส่วนของ conten ตัวอย่างเช่น content = หัวข้อ ประมาณนี้ครับผม

                      ข้อควรระวังอีกอย่าง ปิดการทำงานของ antivirus ด้วย ไม่งั้นอาจจะมีปัญหาเกี่ยวกับ Authen ได้ครับ

                Tuesday, April 29, 2014

                web.xml มีปัญหา Application at context path /webbudsa could not be started

                วันนี้ได้ทำการ upload web app ไปที่โฮส ปรากฏว่าไม่ได้ น่าจะเกิดจาก time out
                จากนั้นก็ส่งเมลส์ไปหา host พร้อมกับ war file ทาง host ก็แจ้งมาว่ามีปัญหา "Application at context path /webbudsa could not be started" ทำให้ผมต้องหาสาเหตุ ก็ปรากฏว่า สาเหตุมาจาก การเรียง กับ สะเปะสะปะ อาจจะเนื่องจากผมได้ทำการเขียนบน tomcat 7 ซึ่งน่าจะฉลาดกว่า tomcat 6(บน host) ทำให้สามารถทำงานได้ปกติในระหว่างการเขียนโปรแกรม แต่เมื่อ upload บน host จริงๆกลับมีปัญหาดังกล่าวก็เป็นได้ จึงต้องทำการเรียงซะให้ โดยเรียง ก่อน แล้วตามด้วย ทีหลัง ก็เป็นอันเรียบร้อย

                Wednesday, January 22, 2014

                ไดรเวอร์ printer เครื่องลูก

                วันนี้ผมได้ลง window 7 64 bit ที่เครื่องแม่ เมื่อลงเสร็จแล้ว เครื่องลูกจะทำการ print แต่ไม่ได้เนื่องจากว่าในเครื่องแม่นั้น ไม่มี driver 32 bit ทำให้เครื่องลูกไม่สามารถปริ้นได้
                ทางแก้
                ที่ปริ้นเตอร์เราสามารถเลือก driver 32 เพิ่มเข้าไปได้(เครื่องแม่)  window ก็จะถาม driver 32 bit จากนั้นก็หา driver ของ printer มาลง และ window ก็จะถาม ntprint.inf อันนี้ไปหามาจากเครื่องที่ลง window 32 bit มา เท่านี้ก็เสร็จ

                Monday, December 16, 2013

                ดึง Session ID จาก java มาไว้ที่ javascript

                เนื่องจากผมจะต้องใช้ jsessionid ของ java มาใช้ในการแสดงผลภาพ captcha แต่ในตัวอย่างนั้นผมจะต้องใช้เป็น servlet แต่ผมไม่ต้องการใช้ อยากใช้แบบ Ajax DWR แทน เลยต้องหาค่า 2 ค่าก่อนส่งไปที่ class ของ jcaptcha นั่นคือ sessionid กับ ค่าที่ผู้ใช้เว็บป้อนเข้ามา ปัญหาคือจะหา sessionid ได้ยังไงส่วนค่าที่ผู้ใช้เว็บป้อนมานั้นง่ายเลยติดแค่ sessionid อย่างเดียว
                หาอยู่ตั้งนานว่าจะทำไงโดยใช้ javascript แต่ก็ไม่ได้และยุ่งยากเกินไป ก็มาได้ง่ายๆด้วย java นี่แหละ(มัวแต่คิดถึง Ajax อย่างเดียวเลยลืมเพื่อนเก่าที่เป็น scriptlet ไปเลยนะเนี่ย) ง่่ายๆครับ คือ



                ง่ายๆแค่นี้เลยโดยใช้ expression ใน jsp แค่เนี่ย หาอยู่ตั้งนาน แต่ไม่ได้เป็น object เป็น String อย่างเดียวแค่นั้น

                Tuesday, April 9, 2013

                mySQL error 121

                วันนี้สร้างตารางขึ้นมาชื่อว่า booking โดยเป็น weak entity แบบ M:N ทีนี้สร้างในฐานข้อมูลจริงไม่ได้ เกิด error 121 เลยไปหาในเน็ตทางแก้คือเปลี่ยนชื่อ attribute ของ table booking ที่ fk ไป table อื่นซะ ลองดูในเว็บที่ฝรั่งถามไว้นะครับ
                http://stackoverflow.com/questions/3316410/sql-error-errno-121

                Thursday, March 28, 2013

                การใช้ Transactions ใน Java


                Disabling Auto-Commit Mode

                เมื่อทำการสร้าง connection นั้น จะอยู่ในโหมด Auto Commit โดยอัตโนมัติ นั่นหมายถึงว่าแต่ละคำสั่ง SQL ที่กระทำ transaction นั้นจะ Commit(ยืนยัน) หมด(ถ้าจะให้ละเอียดคือ ในคำสั่ง SQL นั้นจะ Commit เมื่อมันเสร็จสิ้นแล้ว ไม่ใช่ในขณะทำงาน(excuted) )

                ในการ disable commit คือ con.setAutoCommit(false);

                หลังจากที่เราได้ทำการ disable commit ไปแล้วจะไม่มีคำสั่ง SQL Statement ไหน commit จนกว่าเราจะใช้คำสั่ง commit เอง คำสั่ง SQL ทั้งหมดจะถูก excute หลังจากเรียกคำสั่ง commit คือเพิ่มเข้าไปใน transection ปัจจุบันและ commit รวมกันเป็นกลุ่ม ดังตัวอย่าง

                public void updateCoffeeSales(HashMap salesForWeek)
                    throws SQLException {
                
                    PreparedStatement updateSales = null;
                    PreparedStatement updateTotal = null;
                
                    String updateString =
                        "update " + dbName + ".COFFEES " +
                        "set SALES = ? where COF_NAME = ?";
                
                    String updateStatement =
                        "update " + dbName + ".COFFEES " +
                        "set TOTAL = TOTAL + ? " +
                        "where COF_NAME = ?";
                
                    try {
                        con.setAutoCommit(false);
                        updateSales = con.prepareStatement(updateString);
                        updateTotal = con.prepareStatement(updateStatement);
                
                        for (Map.Entry e : salesForWeek.entrySet()) {
                            updateSales.setInt(1, e.getValue().intValue());
                            updateSales.setString(2, e.getKey());
                            updateSales.executeUpdate();
                            updateTotal.setInt(1, e.getValue().intValue());
                            updateTotal.setString(2, e.getKey());
                            updateTotal.executeUpdate();
                            con.commit();
                        }
                    } catch (SQLException e ) {
                        JDBCTutorialUtilities.printSQLException(e);
                        if (con != null) {
                            try {
                                System.err.print("Transaction is being rolled back");
                                con.rollback();
                            } catch(SQLException excep) {
                                JDBCTutorialUtilities.printSQLException(excep);
                            }
                        }
                    } finally {
                        if (updateSales != null) {
                            updateSales.close();
                        }
                        if (updateTotal != null) {
                            updateTotal.close();
                        }
                        con.setAutoCommit(true);
                    }
                }
                
                
                ใน method นี้จะ auto-commit mode เป็น disable ซึ่งหมายถึง 2 prepared statements จะ commit รวมกัน เมื่อ commit มีการเรียก
                ในคำสั่ง con.setAutoCommit(true); จะหมายถึงการกลับไปยัง สถานะ default เมื่อคำสั่งต่างๆเสร็จสิ้้น
                
                

                Using Transactions to Preserve Data Integrity

                ตัวอย่างของ transaction isolation level คือ TRANSACTION_READ_COMMITTED จะไม่ยอมรับการเข้าถึงข้อมูลจนกว่า transaction เสร็จสิ้น พูดอย่างอย่างคือ DBMS จะไม่ยอมรับการมี dirty reads เกิดขึ้น
                Transaction Isolation Level แบ่งออกเป็น 5 ระดับ ดังนี้
                Isolation LevelTransactionsDirty ReadsNon-Repeatable ReadsPhantom Reads
                TRANSACTION_NONENot supportedNot applicableNot applicableNot applicable
                TRANSACTION_READ_COMMITTEDSupportedPreventedAllowedAllowed
                TRANSACTION_READ_UNCOMMITTEDSupportedAllowedAllowedAllowed
                TRANSACTION_REPEATABLE_READSupportedPreventedPreventedAllowed
                TRANSACTION_SERIALIZABLESupportedPreventedPreventedPrevented
                 non-repeatable read  เกิดขึ้นเมื่อ transaction A รับค่าแถว,ลำดับต่อมา transaction B update แถว และลำดับต่อมา transaction A รับค่าที่แถวเดิมอีกครั้ง transaction A รับค่าที่แถวเดิม 2 ครั้งแต่ได้ค่าต่างไปจากเดิม
                 phantom read  เกิดขึ้นเมื่อ transaction A รับค่าจะแถวโดยผ่าน condition (where),ลำดับต่อมา transaction B ก็ทำการเพิ่มและ update แถวโดยผ่าน condition เดียวกันกับ transaction A ต่อมา transaction A ก็มารับค่าตาม condition อีกครั้ง แต่ปรากฏว่าเห็นแถวเพิ่มขึ้น แถวที่เพิ่มขึ้นนี้เองเรียกว่า  phantom
                โดยทั่วไปเราไม่ต้องทำอะไรเกี่ยวกับ Transaction Isolation Level สามารถใช้ค่า defalut ของ DBMS ได้เลย ค่า default ของ DBMS จะขึ้นอยู่กับ DBMS ที่ใช้ เช่น  Java DB คือ TRANSACTION_READ_COMMITTED ถ้าต้องการหาว่า DBMS ใช้ Level ไหนใช้คำสั่ง Connection method getTransactionIsolation และถ้าต้องการ set เองใช้ Connection method setTransactionIsolation 
                Note JDBC driver อาจจะไม่ support transaction level ทั้งหมด ถ้าไม่ support level ที่ระบุใน setTransactionIsolation ก็สามารถสลับไปใช้ level ที่สูงกว่า ถ้า driver ไม่สามารถสลับไปที่ level ที่สูงกว่าได้จะเกิด SQLException ใช้ method DatabaseMetaData.supportsTransactionIsolationLevel ในการหาว่า driver support level ไหน

                Setting and Rolling Back to Savepoints

                 method Connection.setSavepoint คือ set Savepoint Object ใน transaction ปัจจุบัน Connection.rollback method คือส่ง Savepoint ไปเป็น agument
                ตัวอย่างถ้าต้องการเพิ่มราคาแล้วราคานั้นเกินกว่าที่กำหนดไว้ก็จะ rollback ไปค่าเริ่มต้นใหม่อีกครั้ง
                public void modifyPricesByPercentage(
                    String coffeeName,
                    float priceModifier,
                    float maximumPrice)
                    throws SQLException {
                    
                    con.setAutoCommit(false);
                
                    Statement getPrice = null;
                    Statement updatePrice = null;
                    ResultSet rs = null;
                    String query =
                        "SELECT COF_NAME, PRICE FROM COFFEES " +
                        "WHERE COF_NAME = '" + coffeeName + "'";
                
                    try {
                        Savepoint save1 = con.setSavepoint();
                        getPrice = con.createStatement(
                                       ResultSet.TYPE_SCROLL_INSENSITIVE,
                                       ResultSet.CONCUR_READ_ONLY);
                        updatePrice = con.createStatement();
                
                        if (!getPrice.execute(query)) {
                            System.out.println(
                                "Could not find entry " +
                                "for coffee named " +
                                coffeeName);
                        } else {
                            rs = getPrice.getResultSet();
                            rs.first();
                            float oldPrice = rs.getFloat("PRICE");
                            float newPrice = oldPrice + (oldPrice * priceModifier);
                            System.out.println(
                                "Old price of " + coffeeName +
                                " is " + oldPrice);
                
                            System.out.println(
                                "New price of " + coffeeName +
                                " is " + newPrice);
                
                            System.out.println(
                                "Performing update...");
                
                            updatePrice.executeUpdate(
                                "UPDATE COFFEES SET PRICE = " +
                                newPrice +
                                " WHERE COF_NAME = '" +
                                coffeeName + "'");
                
                            System.out.println(
                                "\nCOFFEES table after " +
                                "update:");
                
                            CoffeesTable.viewTable(con);
                
                            if (newPrice > maximumPrice) {
                                System.out.println(
                                    "\nThe new price, " +
                                    newPrice +
                                    ", is greater than the " +
                                    "maximum price, " +
                                    maximumPrice +
                                    ". Rolling back the " +
                                    "transaction...");
                
                                con.rollback(save1);
                
                                System.out.println(
                                    "\nCOFFEES table " +
                                    "after rollback:");
                
                                CoffeesTable.viewTable(con);
                            }
                            con.commit();
                        }
                    } catch (SQLException e) {
                        JDBCTutorialUtilities.printSQLException(e);
                    } finally {
                        if (getPrice != null) { getPrice.close(); }
                        if (updatePrice != null) {
                            updatePrice.close();
                        }
                        con.setAutoCommit(true);
                    }
                }
                
                
                method เริ่มต้นโดยสร้าง Savepoint ด้วยคำสั่ง Savepoint save1 = con.setSavepoint();
                
                
                method จะทำการตรวจสอบค่า new price ว่ามากกว่า maximum price หรือไม่ถ้ามากกว่าก็ให้กลับไปค่าปัจจุบัน con.rollback(save1);
                
                
                ดังนั้น เมื่อ method commit transaction โดยเรียก Connection.commit method มันจะไม่ commit แถวใดๆที่มีความสัมพันธ์กับ Savepoint ที่มีการ rolled back มันจะ commit แถวอื่น
                
                

                Releasing Savepoints

                method Connection.releaseSavepoint โดยป้อน Savepoint Object เป็น parameter และจะ remove Savepoint จาก transaction ปัจจุบัน
                Savepoint จะ Release โดยอัตโนมัติ เมื่อมีการ commit หรือเมื่อ transaction rolle back
                การเรียน method rollback จะทำให้ออกจาก transaction และทำการ return ค่าใดที่ทำการเปลียนแปลงก่อนหน้าให้เป็นค่าเริ่มต้น ถ้าคุณทดลอง execute statment ใน transaction จะทำให้เกิด SQLException การเรียก method จะทำให้ transaction จบ และทำการเริ่มต้น transacton ใหม่อีกครั้ง
                 
                
                

                Saturday, December 1, 2012

                deep freeze v.7 ไม่เห็นใน Task bar

                ผมได้ทำการแช่แข็ง Harddisk ไว้ แล้วทีนี้จะทำการแก้ไข window นิดนึงจึงทำการปลดล็อคแต่ปรากฎว่า
                ปลดล็อกไม่ได้ เนื่องจาก ไม่เห็นรูปไอคอน deep freeze "มันหายไปไหนเนี่ย" หาอยู่ตั้งนานว่าจะทำไง เกือบลง window ใหม่แล้วเชียว ไปพบวิธีแก้ซะก่อน คือ
                -ให้ทำการ logout ก่อนนะ
                -จากนั้นก็เข้า window ใหม่ ไม่ต้อง boot เครื่องใหม่นะกดเข้าไปเลย
                ก็จะเห็น deep freeze และก็จัดการได้เลย ง่ายซะไม่มี

                Sunday, April 15, 2012

                JavaScript undefined Properties

                เป็นการระบุว่า ไม่มีการกำหนดค่าให้กับตัวแปร ดังตัวอย่าง



                ได้ผลลัพธ์คือ
                t2 is undefined


                จะเห็นได้ว่า ตัวแปร t2 ยังไม่ได้กำหนดค่าให้ทำให้มีคุณสมบัติเป็น undefined

                Sunday, March 25, 2012

                Callback Function ใน DWR

                หลักการที่สำคัญใน Ajax คือ callback function หรือพูดง่ายคือ ฟังก์ชั่นที่จะรับข้อมูลกลับเพื่อทำงานต่อนั่นเอง ใน DWR callback ใช้ทำงานกับข้อมูลที่ส่งมาจาก method
                ประเภทของ callback function คือ 1.
                1.ถ้าฟังก์ชั่นไม่มี parameter เช่น HorizontalMenu.getMenuItems(setMenuItems) ฟังก์ชั่นนี้จริงๆแล้วไม่มี parameter แต่ในการเรียกใช้โดย javascript เราจึงได้เพิ่ม callback function เข้าไป คือ setMenuItems นั่นเอง 2.
                2.ถ้าฟังก์ชั่นนั้นมี parameter เช่น CountryDB.getContries(selectLetters,setCountryRows) โดย selectLetters คือ input parameter และ setCountryRows คือ callback function
                     สำหรับแบบนี้ ในการใช้ callback function คือ meta-data object ในการที่ javascript จะเรียกใช้งาน เช่น CountryDB.saveCountryNotes(ccode,newNotes,{ callback:function(newNote)
                 { //function body here
                 } });
                 ฟังก์ชั่นนี้ คือ anonymous และมัน implementation โดยการเพิ่ม javascript ที่เรียก เข้าไปยัง remote Java method ประโยชน์ในการทำลักษณะนี้คือ ง่ายในการอ่าน และจะ execute ทันทีหลังจากได้รับค่าที่ return มาจาก Java method
                สำหรับประโยชน์อื่นๆคือเราสามารถเพิ่ม option ในการเรียกได้ คือสามารถเพิ่ม timeout และ error handler เช่น
                 CountryDB.saveCountryNotes(ccode,newNotes,{ callback:function(newNotes)
                 { //function body here }, timeout:10000, errorHandler:function(errorMsg){ alert(errorMsg);} });

                 มีความเป็นไปได้ว่า Java method จะไม่ return ค่ากลับมา ในการเพิ่ม callback ไปยัง method ที่ไม่ return ค่า จะมีประโยชน์ในการรับการแจ้งเตือน เมื่อ remote call ทำงานเสร็จ

                Sunday, December 18, 2011

                Published with Blogger-droid v2.0.2

                Saturday, December 17, 2011

                ลองเล่นของใหม่ Android

                ผมได้ได้มือถือมาเป็น HTC เลยคิดว่าน่าจะเขียนโปรแกรมสำหรับมือถือซะหน่อย เลยโหลดหนังสือมา แล้วก็ Eclipse Indigo กับ sdk ของ google แต่ปัญหามันมีอยู่ว่า run แล้วไม่ผ่านปัญหาเยอะเหมือนกันนะ ที่เจอคือ
                1.เราจะต้องเปลี่ยนไปที่ control panel แล้วเปลี่ยนเครื่องเราเป็น US ซะ ไม่ว่าจะเป็นวันที่ ประเทศ อะไรต่างๆ ไม่งั้นจะทำให้เกิดปัญหาหมดอายุของโปรแกรมเพราะมันนับอายุเป็น ค.ศ.
                2.เวลา ทดสอบ ก็คลิกที่ project และ F11(debug)รอซักครูเหมือนมือถือแหละนะ ไม่งั้นจะมีปัญหา out.xml(เพราะไปคลิดที่ไฟล์ xml) นะ
                ที่เขียนตรงนี้ไม่ขั้นตอนนะครับแต่เป็นปัญหาทีเจอมา หลายวันทีเดียวกว่าจะเป็นได้ ประมาณ 3 วันได้แหละ ผมย้ายไป netbean 7 อยู่พักนึงนะแต่ดูว่าจะไม่เวอร์คเพราะเขาใช้ eclipse ทั้งน้าน ว่าจะเลิกแล้วเชียวดันมาได้ซะก่อนทำง่ายๆไหงปัญหาเยอะจัด แต่ก็นะของใหม่ครับ

                Friday, June 17, 2011

                firefox ไม่แสดง javascript ที่แก้ไข

                วันนี้ได้ทดลอง run โปรเจ็ค gallery และได้ทำการแก้ไข javascript ที่ netbean7 ปรากฏว่า firefox
                ไม่ทำการ update javascript ที่แก้ไขให้เลย จึงทำการ run ใน chrome ก็สามารถใช้ได้เลย แสดงว่า
                firefox สร้างปัญหาให้เราได้เหมือนกันนนะเนี่ย นี่ดีนะที่มี plugin firebug ถ้าไม่งั้นเลิกใช้ไปแล้ว กิน
                แรมก็เยอะ

                Saturday, May 28, 2011

                ปัญหา mysql ไม่รองรับไทย หลังจากห่างหายไปนาน

                ผมติดปัญหา mysql ไม่เป็นภาษาไทยมาหลายวัน เป็นแต่ ????
                งง มากเลย ทั้งๆที่ปัญหานี้เราแก้ได้นานแล้วนี่(พักการเขียนไปนาน)
                ไม่ว่าจะกำหนด mysql ให้เป็น utf-8 หมด กำหนด encoding ของไฟล์เป็น utf-8 หมด
                ก็ไม่ได้ซักทีทำไงดีเนี่ยยยยยย

                เลยมา track ดูผลปรากฏว่า ใน instance ของ Statement เป็น ISO8859-1
                ก็เลยน่าจะมาจาก Driver

                สุดท้ายก็จริงๆด้วย สาเหตุมาจากผมได้นำ Driver ver.3 โดยเป็น Version เก่า
                ทำให้ไม่รองรับไทย และใน Library ของ project สามารถ add library mysql
                มาได้โดยได้ version 5 ก็เลยทำการลบ Driver เก่าและลง Driver ใหม่ซะะเลย
                จบ................. เฮ้อ ห่างหายไปนานลืมซะได้ว่า netbean มี Driver mysql ให้ add อยู่แล้ว