วันพุธที่ 26 กันยายน พ.ศ. 2550

วิธีเรียก Store Procedure จาก Java

วิธีการเรียกเราจะใช้ CallableStatement จากการเรียก Connection.prepareCall(คำสั่ง Store Procedure)
ซึ่งคำสั่งที่ใช้เรียกเป็นตามนี้ครับ
1. ถ้าไม่มี Return ค่า { call PackageName.FunctionName(?,?,?) }
2. ถ้ามี Return ค่า ใช้ {? = call PackageName.FunctionName(?) }

แล้ว Set ค่า Parameter ตามปกติได้เลยครับ
ถ้ามีการ Return เช่น cursor ให้ Set ค่าตัวแรกเป็น
stmt.registerOutParameter(1, OracleTypes.CURSOR);
ครับ ถ้าเป็นตัวเลขอไรก็ลองเซ็ตดูได้เป็นตัว 1,2,3 อ่ะครับ

วันพฤหัสบดีที่ 13 กันยายน พ.ศ. 2550

วิธีการเขียนข้อมูลเรียก LDAP

สำหรับคนที่ไม่รู้ว่า LDAP คืออะไร สามารถอ่านได้ที่นี่
1. ให้ใช้วิธีเรียกจากบน UNIX ด้วยคำสั่ง

ldapsearch -D cn=[username]
-w [password] -h [ip address] -p [port] -s sub -b [service],o=[organization],c=[country]
'objectClass=*'

Username = ชื่อสำหรับทำการเข้า LDAP
Password = Password สำหรับเข้า LDAP
IP Address = IP สำหรับเข้า LDAP
Port = Port ของ LDAP
Service = ที่เราจะเข้าไปดูซึ่งวิธีเข้าไปดูนั้นจะเรียงจากชั้นในสุดไปถึงชั้นนอกสุด
Organization = Config LDAP
Country = Config LDAP

Example
ldapsearch -D cn=sample -w sample1 -h xxx.xxx.xxx.xxx -p xxx -s sub -b taoService=prepaid,serviceName=subProfile,msisdn=xxxxxxxxx, domainName=msisdn, o=xxx,c=TH 'objectClass=*'

ภาพโครงสร้างคร่าวๆ ของ LDAP

2. ถ้าเรียกแล้วข้อมูลขึ้นดังตัวอย่าง โดยที่ไม่มี Error ใดๆ ถือว่าเราสามารถที่จะเรียกได้

dn: msisdn=66xxxxxxxxx,domainName=msisdn,O=xxx,C=TH
msisdn: 66xxxxxxxxx
objectClass: subscriber
dn: serviceName=subProfile,msisdn=66xxxxxxxxx, domainName=msisdn, O=xxx ,C=TH
serviceName: subProfile
objectClass: subProfile
spImsi: 6223904495254321
spIccid: 00000000000000000000
spPricePlan:
spProvDate: 04012002
spAccountType: POS
spSubType:
spAccountCateg:
spSubStatus: A
spLanguage: english
spSKSegment:
spSKMobileType:
spRBTService: FALSE
spSupService: 000000000000000000000000

3. วิธีการเรียกด้วยจาวา จะทำดังนี้


Hashtable env = new Hashtable();
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
env.put(Context.PROVIDER_URL, "ldap://IP:PORT/o=organization,c=country");
env.put(Context.SECURITY_AUTHENTICATION, "simple");
env.put(Context.SECURITY_PRINCIPAL, "cn=username,o=organization,c=country");
env.put(Context.SECURITY_CREDENTIALS, password);
InitialDirContext initNamingContext = new InitialDirContext(env);
Attributes attrs = initNamingContext.getAttributes(service);
attrs.get(ชื่อที่ต้องการจะดึงขึ้นมา).get());
ชื่อที่ต้องการจะดึงขึ้นมานั้นจะเป็นคล้ายๆ แบบที่ 2 เช่น spSubType เป็นต้น


ใช้สำหรับ Config Timeout ให้กับ LDAP โดย put com.sun.jndi.ldap.connect.timeout ลงไปด้วย
เช่น env.put("com.sun.jndi.ldap.connect.timeout", "1000");
และสำหรับ Config Read Timeout โอยเพิ่ม put com.sun.jndi.ldap.read.timeout

การ ฺBasic Config Object Pool Manager สำหรับ Websphere 6.0x

เป็นการ Config ให้เราใช้ Object Pool โดยใช้ความสามารถของ Websphere ในการจัดการ Pool ซึ่งถ้าเราไม่ใช้ของ Websphere สามารถที่จะใช้ Common Pool ได้ มีวิธีใช้ดังนี้ครับ
1. เราจะต้องไป Config Object Pool ใน Admin Console ก่อนโดยจะอยู่ที่ Resources --> Object pool managers
2. New จะขึ้นดีงรูป

Name ตั้งชื่อ Object Pool ของเรา
JNDI Name ตั้งชื่อ JNDI ไว้สำหรับเราเรียกใช้งาน
3. หลังจากเสร็จแล้ว Save ข้อมูล
4. เปิดการใช้งานโดยไป Enable ที่ Application Server โดยจะอยู่ที่
4.1 Servers --> Application Servers --> แล้วก็เลือก Server ของเรา
4.2 ไปดูที่ Container Services (อยู่ตรงส่วน Container Settings) --> Object pool service
4.3 แล้ว ติ็กเลือก Enable service at server startup
4.4 หลังจา้กนั้นกด apply แล้วก็ restart server เป็นอันใช้งานได้
5. วิธีเรียกใช้งาน (ก่อนจะเรียกใช้งานทั้งจาก Web หรือ EJB จะต้องเพิ่ม Reference Resource ก่อนไม่อย่างนั้นจะไม่สามารถเรียกใช้งานได้)

InitialContext ic = new InitialContext();
ObjectPoolManager opm = (ObjectPoolManager)ic.lookup("java:comp/env/pool/test");
arrayListPool = opm.getPool(ArrayList.class); //โยน Object ที่เราต้องการลงไป

arrayListPool.returnObject(obj); // หลังจากใช้เสร็จต้อง Return เสมอไม่งั้นมันจะค้างเป็น Garbage ในระบบ

*ควรจะ Config 1 Pool/1 Object จะได้ไม่มีปัญหา

ปัญหาที่พบบ่อยบน Rad 6.0

อันนี้ผมรวบรวมปัญหาที่ผมพบบ่อยพร้อมวิธีแก้นะครับ (หลังจาก Update Patch หมดแล้ว)

Q : พอสั่ง Run server แล้วดันกลายเป็นสั่งให้ Publish แล้วทำให้ Start Server ไม่ได้
A : ให้ทำการปิดเปิด Rad 6.0 ใหม่ ถ้ายังไม่หายอีกให้ Restart เครื่องซึ่งน่าจะหายหมด

Q : อยู่ดีๆ Config ของ Workspace หายไป เช่น Classpath ของ Ear เรา หรือว่าอยู่ดีๆ Application เราก็ Error ทั้งๆ ทีไม่ได้ทำอะไร
A : ให้ Config ใหม่ครับ ก็จะทำงานได้ หรือ Restart อีกครั้งนึงหลังจากปิดไปแล้ว

Q : ปัญหา Generate Webservice ไม่ได้
A : บางทีเราอาจจะ Generate บ่อยเลยไม่สามารถ Generate ได้ให้ไปสร้าง Project ใหม่พื่อ Generate จะสามารถ Generate ได้ครับ (ถ้าจะให้ดีสร้าง Workspace ใหม่เลย)

Q : ทำไมบางทีเรา Restart Server แล้วมันค้างที่ Starting ตลอดเลย
A : แก้โดยให้ Stop Server แล้วเอา Application ที่อยู่ใน Server ออกให้หมดแล้ว Start อีกทีก็น่าจะได้ แล้วส่ง Publish ก่อนแล้วค่อยเอา Application ไปลงที่ Server อีกทีก็จะใช้งานได้

Q : ทำไม Generate Web Service Client แล้วไปเรียกคนอื่นไม่ได้
A : Rad 6.0 มันใช้ Mechanism ในการไปเรียกเป็นของ IBM เองซึ่งมันเก่าอ่ะ ทำให้ไปเรียกไม่ได้ แล้วต้องเรียกผ่าน Server ด้วยเรียกผ่าน Application ไม่ได้ แล้วถ้าให้มันเป็น Axis มันก็เก่าไป เรียกคนอื่นไม่ได้ (Rad 7.0 ก็เป็นครับ) สามารถดูได้ที่ Entry นี้

Q : Config SSL แล้วไม่สามารถที่จะ Start Server ได้
A : ให้ Config เครื่องเป้นปี ค.ศ. ก็จะหายครับ (เกิดจาก Certification หมดอายุนั่นเอง มันมอง พ.ศ. เป็น ค.ศ.)

Q : ปัญหาไม่สามารถเปิด File JSP ได้
A : ปิด RAD 6.0 แล้วเปิดใหม่ก็จะหาย

Q : อยู่ดี ๆ RAD 6.0 ก็ปิดตัวเอง
A : แสดงว่า Ram ของเครื่องน้อยเกินไปให้เพิ่ม ปัญหานี้ก็จะหายครับ

Q : พอ Start Server แล้วมองไม่เห็น Class ใน Java Application
A : ให้ทำการ Set Java Dependencies ที่ Properties ของ Project นั้นๆ (จำเป็นจะต้อง Add ลงใน application.xml ใน Ear Project ก่อนด้วย)

Q : เวลาสร้าง Server ใหม่แล้วเรียก Datasource จะมองไม่เห็น Table
A : ปัญหานี้เกิดจากว่าเราสร้าง Server ใหม่แล้ว ตัวที่เรา Config (รวมทั้ง Datasource) ยังจำที่เรา Config ไว้ที่ Server เก่าอยู่ให้ลบทิ้งแล้ว Config ใหม่ก็จะหายครับ

Q : ทำไมเวลเราเรียก Application แล้วมองไม่เห็น Class จากทางฝั่ง Web (เรียกจาก EJB)
A : ปัญหาเกิดจากเอาไม่ได้กำหนดที่ Deployment Description บน Ear Project ให้เป็น Application น่ะครับ โดยทำตามนี้
  1. ไปที่ Tab Deployment (application.xml ใน Ear Project)
  2. แล้วดูที่ Application (อยู่ล่างสุด) ให้ดูที่ WAR classloader policy ว่าเป็น APPLICATION หรือยัง ถ้ายังทำให้เป็นแล้ว Restart Application ใหม่ก็จะเห็นครับ
Q : ทำไมตอนแรกเรียก EJB ได้ แล้วพอแก้ไขอะไรใหม่ กลับเรียกไม่ได้
A : วิธีแก้มีดังนี้ครับ
  1. ดู Error Log ก่อนว่ามันขึ้นมาเป็น JNDI Name Not Found หรือเปล่า ถ้าใช่แก้โดยได้ตรวจสอบ Reference ใน Web.xml ว่าไปเรียก EJB ถูกอันหรือเปล่า (ตรวจสอบทั้ง Web.xml และ ejb-jar.xml ว่าไปถูกตัวกันจริงหรือเปล่า) อ่านเพิ่มเติม ลิงค์นี้
  2. ถ้าไม่ได้ขึ้นแบบข้างบนให้แก้โดย Deploy EJB ใหม่โดยการคลิกขวาที่ EJB Project แล้วเลือก Deploy ครับ มันจะ Generate ตัว Stub ใหม่ แล้วจะใช้งานได้ กรณี่ที่ Deploy EJB ไม่ได้ให้ทำตาม ลิงค์นี้ ครับ
  3. ถ้ายังไม่ได้อีกลอง Clean Project ทั้งหมดที่ใช้แล้ว Build ใหม่ดูน่าจะหายครับ
Q : File Config (.xml เช่น web.xml) พอแก้ไขแล้วทำไมยังเป็น Config แบบเดิมอยู่
A : พวก File เหล่านี้ ถ้าเราแก้ไขแล้ว เราจะต้องทำการ Restart Application เสมอ เพราะ Rad 6.0 จะไม่ Restart ให้ครับ ต้องมา Restart เอง (ในบางครั้ง อาจจะต้องสั่ง Publish Server ใหม่ด้วยถึงจะเป็น Config แบบใหม่)

วันอังคารที่ 11 กันยายน พ.ศ. 2550

ปัญหาการรับค่าจาก HttpURLConnection

การรับค่าจาก HttpURLConnection โดยปกติผมจะใช้วิธีดูจาก .available

ตัวอย่างที่ผมเขียนเรียกปกติ

String vXMLStr = request.getParameter("data");
OutputStream vOs = null;
OutputStreamWriter vOsw = null;
URL vUrl = new URL(request.getParameter("url"));
HttpURLConnection vHttpConn = (HttpURLConnection) vUrl.openConnection();

vHttpConn.setUseCaches(false);
vHttpConn.setRequestMethod("POST");
vHttpConn.setRequestProperty("Content-Type", "application/x-www-urlencoded");
vHttpConn.setRequestProperty("Content-Length", Integer.toString(vXMLStr.length()));
vHttpConn.setDoInput(true);
vHttpConn.setDoOutput(true);
vHttpConn.connect();

vOs = vHttpConn.getOutputStream();
vOsw = new OutputStreamWriter(vOs);
vOsw.write(vXMLStr);
vOsw.flush();
vOsw.close();
vOsw = null;
vOs = null;

// get response
InputStream vIs = null;
vIs = vHttpConn.getInputStream();
DataInputStream din = new DataInputStream(vIs);
StringBuffer buffer = new StringBuffer();
String b = "";
while(din.available() > 0) {
buffer.append(b);
}
vIs.close();

System.out.println("Result : " + buffer.toString());

ซึ่งดูจากตัวอย่างจะเห็นว่าผมใช้ din.available() > 0 ซึ่งบางทีไปเรียกแล้วจะรับค่าไม่ได้ จำเป็นต้องเปลี่ยนเป็นวิธีอื่น เช่น ที่ผมรับไม่ได้ผมแก้เป็น (b = din.readLine()) != null ตัวนี้แทนก็จะทำงานได้ครับ สามารถรับค่าได้ครับ

วันพุธที่ 5 กันยายน พ.ศ. 2550

Config Rad6.0 ให้สามารใช้ JDK มากกว่า 1.5 ได้

คำเตือน
1. เมื่อทำแล้วอาจจะทำให้ Java บางไฟลล์ ต้องทำการแก้ไข หรืออาจจะทำให้เรา Generate EJB ไม่ได้ (อันนี้ผมเป็นเลยไม่แน่ใจว่าเครื่องอื่นเป็นหรือเปล่าน่ะครับ)
2. เราไม่สามารถที่จะเปลี่ยนที่ Preference --> Java --> Compiler ในส่วนของ Compliance and Classfiles ให้เป็น Java เวอร์ชันมากกว่า 1.4 ได้ครับ อาจจะทำให้มีปัญหาอย่างอื่นตามมาแนะนำให้ไปใช้ Rad7.0 เลยครับ

วิธีทำดังนี้
1. ให้ทำการเลือก Window --> Preference
2. ไปที่ Java แล้วคลิกที่ Installed JRE
3. ทำการ Add JRE เวอร์ชันที่เราต้องการลงไป เช่น C:\Program Files\Java\jre1.5.0_06 เป็นต้น
4. แล้วเราก็ทำการแก้ทีละ Project ให้ใช้ JRE ตัวที่เราตั้งใหม่นี้
5. โดยการคลิกขวาที่ Project แล้วเลือก Properties ที่ Java Build Path
ุ6. เลือกที่ Tab Libraries
7. เลือก JRE System Library แล้วคลิด Edit
8. ให้เลือก Alternate JRE แล้วก็เลือก JRE ที่เราทำการ Add ไปใหม่ ก็จะใช้งานได้แล้วครับ

Set Connection Timeout ใน HTTPURLConnection

สำหรับ JDK เวอร์ชั่นต่ำกว่า 1.4 จะไม่ให้ Config ค่านี้ครับ เราจำเป็นจะต้องไปใช้อย่างอื่นแทน เช่น HTTPClient
แต่สำหรับ เวอร์ชั่น 1.5 ขึ้นไปจะมีให้ใช้แล้วครับ เป็น .setConnecionTimeOut น่ะครับ