วันพุธที่ 30 มีนาคม พ.ศ. 2554

Convert Object array To JSON List (support JDK 1.4)

-ตัวอย่าง code นี้ทำขึ้นเพื่อ นำไปใส่บน JSP เนื่องจาก การนำ library JSON ที่เป็น file javascript (.js) หรือ java file (.java) ที่มีอยู่ทั่วไป แล้วดีอยู่แล้วไปไว้นั้น เป็นเรื่องยุ่งยาก ณ ตอนนี้ และ อีกอย่างคือ ไม่มีสิทธิในการ restart Server ด้วย จึงจำเป็นต้องเขียนกันตรงนั้นเลย จึงทำขึ้นมาเองวางเอง เ้น้นง่าย เรียก library ต่าง ๆ ให้น้อยที่สุด แต่เขียนให้ดูง่ายที่สุดเช่นกัน

-จุดประสงค์หลัก ในการทำขึ้นมา
เพื่อใช้ return string data จากการ post jsp ในรูปแบบ json โดยข้อมูลเป็น list data ที่ดึงมาจาก Database code ดั้งเดิม(มีคนเขียนไว้ก่อนหน้านี้แล้ว) ไม่มีเวลาไปแก้ เดี๋ยวตายก่อน เป็น JDBC แบบพื้นฐาน (คือ ถ้าเรียน java เบื้องต้น ติดต่อ database ก็อ่าน code ออกกันเลยทีเดียวเลย) ไม่ได้ทำ model รองรับ (เพราะเดี๋ยวจะต้องเขียน library ยาวกว่านี้ยังไม่ว่างพอ) ใส่ Object array ไปเลย โดยให้
obj[0] = id;
obj[1] = name;
ประมาณนี้

แล้วยัดใส่ใน Object array ที่ใช้เป็น list data อีกที
objs[0] = obj;

แล้วค่าที่ได้ ต้องนำไปแสดงบน Browser โดยให้สามารถ render data ใ้ห้อยู่ในรูปปุ่ม หรือ โชว์รูปภาพได้อยู่
และ เนื่องจากนำไป โว
/**
 *    This time only support JDK 1.4
 *    array, string, number
 */
public static class JsonArrayParseUtil {
    public static String START_ARRAY = "[";
    public static String END_ARRAY = "]";
    public static String MEMBER = ",";

    public static String parse(Object obj){
        String result = "";
        if(null == obj){
            return START_ARRAY+END_ARRAY;
        }

        Class type = obj.getClass();
        if(type.isArray()){
            result = arrayJSONStr((Object[])obj);
        }else{
            String data = obj.toString();
            if(null != data){
                data = data.replace("/", "\\/");
                data = data.replace("\"", "\\\"");
                data = data.replace("\n", "\\n");
                data = data.replace("\t", "\\t");
                data = data.replace("\r", "\\r");
            }
            result = "\""+data+"\"";
        }
        return result;
    }

    private static String arrayJSONStr(Object[] datas){
        StringBuffer sb = new StringBuffer();
        sb.append(START_ARRAY);
        for(int i=0; i<datas.length; i++){
            if(i>0){
                sb.append(MEMBER);
            }
            sb.append(parse(datas[i]));
        }
        sb.append(END_ARRAY);
        return sb.toString();
    }
}

เวลานำไปใช้งานจริง ใน JSP file ก็จะได้ประมาณนี้
DBConnection cmd = new DBConnection(); // call self library
    Connection conn = cmd.getConnection(); // call self library
    Object[] results = null;
    Object[] datas = null;
    int maxDataCol = 2;
    stmt = conn.createStatement();
    rs = stmt.executeQuery("SELECT ID, NAME FROM DATATABLE");
    try{
        while(rs.next()){
            datas = new Object[maxDataCol];
            datas[0] = rs.getInt("id");
            datas[1] = rs.getString("name");

            results = ObjArrayUtil.addArray(results, new Object[]{datas});
        }
        cmd.safeClose(rs);
        cmd.safeClose(stmt);     
        cmd.releaseConnection(conn);

        }catch(Exception ex){ 
            ex.printStackTrace();
            cmd.releaseConnection(conn);
        }
        String resultStr = "{ \"aaData\" : " + JsonArrayParseUtil.parse(results) + "}";
        response.setContentType("application/json");
        response.setHeader("Cache-Control", "no-store");
        out.print(resultStr);
        out.flush();

data ที่ได้ ออกมาก็จะหน้าตาประมาณแบบนี้
{"aaData" : [
["1", "kan"],
["2", "iphone"]
]}

ซึ่งในตัวเลยที่มี "-" double quote ครอบนั้น สามารถเอาออกได้ โดยแก้จาก class บรรทัดที่ 20 หลังจาก หลุดจาก isArray แล้วก็ให้เช็คว่าเป็น data เป็นตัวเลขหรือเปล่า แต่ค่อนข้างยุ่งยากเหมือนกัน กรณีที่เราไม่รู้ว่า มันเป็นตัวเลขจริง หรือเป็นตัวเลข String

ต้องแถมอีกตัว นั้นคือ ตัวที่ทำให้เรา add ข้อมูลใน object ไปเรื่อยๆ โดยไม่ต้องกำหนด ความกว้างพื้นที่ใช้งานก่อน

เนื่องจากความเป็นจริง และความสะดวก ของการใช้การดึงข้อมูลแบบ JDBC นี้ มันจะไม่มี list size ออกมาให้เลย เราต้องไป query ครั้งถ้าอยากรู้ว่าเมื่อกี้เราดึงข้อมูลมีเท่าไร หรือใช้วิธีวน loop แบบพิเศษเพื่อนับจำนวน แต่ว่า เราต้องการใส่ข้อมูลแล้วอะ จะรอก็ไม่รู้จะให้เก็บไว้ที่ใหนก่อน เลยเขียน class นี้ขึ้นมาเพื่อความสะดวก สบาย ไม่คำนึง ทั้งหน่วยความจำ หรืออะไรทั้งสิ้น (เอาง่ายว่างั้น)

public static class ObjArrayUtil {
    public static Object[] addArray(Object[] a, Object[] b) {
        if(null == a && null == b){
            return new Object[0];
        }
        Object[] c;
        if(null == b && null != a){
            c = new Object[a.length];
            System.arraycopy(a, 0, c, 0, a.length);
            return c;
        }
        if(null == a && null != b){
            c = new Object[b.length];
            System.arraycopy(b, 0, c, 0, b.length);
            return c;
        }
        return concatArray(a, b);
    }
 
    public static Object[] concatArray(Object[] a, Object[] b) {
        Object[] c = new Object[a.length + b.length];
        System.arraycopy(a, 0, c, 0, a.length);
        System.arraycopy(b, 0, c, a.length, b.length);
        return c;
    }
}

เสร็จแล้ว มีแค่นี้แหละ กากดีจัง เหอ ๆ แค่นี้ก็รอดไปอีก 1 วันแห่งการทำงาน ^^

ไม่มีความคิดเห็น: