วันศุกร์ที่ 30 กรกฎาคม พ.ศ. 2553

Example Use Java parse xml to Object : ตัวอย่างการ parse xml String ให้เป็น Object

ปัจจุบัน xml เป็นภาษาที่จำเป็น(ณ ตอนนี้)สำหรับการสื่อสารหรือแลกเปลี่ยนข้อมูลระหว่าองค์กร หรือระหว่าง โปรแกรมกับโปรแกรม ตัวอย่างใช่พวก web service เป็นต้น ปัญหาที่ตามคือการที่ต้อง convert ภาษา xml ให้อยุ่ในรูปของภาษานั้นๆ เช่น เป็น php ,c# หรือ java สำหรับตัวอย่างนี้คือการ parse ค่า xml String ให้เป็น Object โดยมีการใช้ xpath มาช่วยมีตัวอย่างดังนี้

1.xml String format
2.bean Object
3.การ parse โดยใช้ xpath ในการเข้าถึง tree node ใน xml

1.xml String format

<request>
<person>
<id>01</id>
<fname>jame</fname>
<lname>closeling</lname>
<email>jame@ai-prosoft.com</email>
<tel>+6684101312x</tel>
<salary>25000</salary>
</person>
</request>

****************************
2. สร้าง bean สำหรับเก็บ object attribute ของ person ดังนี้
package com.ai.zon;
/*TODO:
* author :pradoem 2010-07-31
* */
public class Person {

//attribute
private String id;
private String fname;
private String lname;
private String email;
private String tel;
private String salary;

//method access getting/setting
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getFname() {
return fname;
}
public void setFname(String fname) {
this.fname = fname;
}
public String getLname() {
return lname;
}
public void setLname(String lname) {
this.lname = lname;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getTel() {
return tel;
}
public void setTel(String tel) {
this.tel = tel;
}
public String getSalary() {
return salary;
}
public void setSalary(String salary) {
this.salary = salary;
}

//toString
@Override
public String toString() {
return "Person [email=" + email + ", fname=" + fname + ", id=" + id
+ ", lname=" + lname + ", salary=" + salary + ", tel=" + tel
+ "]";
}
}

************************************

3.การ parse โดยใช้ xpath ในการเข้าถึง tree node ใน xml
package com.ai.zon;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

public class TestXxm2Obj {

/**
* @author pradoem 2010-07-30
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
//การเรียนใช้งาน

String xml = "01jamecloselingjame@ai-prosoft.com+6684101312x25000";
Person obj = xml2Obj(xml);

System.out.println("*************************");
System.out.println("Object to String values is :"+obj.toString());
}

//method get ค่าจาก tag xml โดย parse parameter doc,xpath,tag_name และ จะ return ค่า value กลับไป
private static String getNodeValuesXml(Document doc,XPath xpath, String preFix)
{
String ret="";
try
{
// คำสั่งชุดนี้สำหรับการใช้ xpath ในการเข้าถึง tag name value และ node name value
XPathExpression expr = xpath.compile(preFix);
Object result = expr.evaluate(doc, XPathConstants.NODESET);
NodeList textNameNodesList = (NodeList) result;


for (int i = 0; i < textnode =" textNameNodesList.item(i);" ret="textNode.getNodeValue();">>getNodeValuesXml:", ex.fillInStackTrace());
return ret;
}//try

}//method

//method convert xml 2 object
private static Person xml2Obj(String xml)
{
Person obj = null;

try
{
//ตรวจสอบ String xml ก่อนว่ามีค่าหรือป่าว
if((xml == null) || xml.equals(""))
return null;

//สร้าง instance Document
DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance();

//โดยค่าเริ่มต้นสำหรับ support Namespace เป็น false แต่เรา set เป็น true
// เพื่อให้สนับสนุน XML namespaces
domFactory.setNamespaceAware(true);

// ปรกาศ doc - builder
DocumentBuilder builder;

try
{
//สร้าง doc - builder มีการ ดักจับ try-catch เพื่อสร้างไม่สำเร็จ
builder = domFactory.newDocumentBuilder();
}
catch (ParserConfigurationException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
return obj;
}

//prepared String to byte array for sax
//ตรงไปตรงมาครับ อ่านข้อมูล xml String ให้เป็น byte array
ByteArrayInputStream bArrStream = new java.io.ByteArrayInputStream(xml.getBytes());

//InputSource เป็น object ของ sax สำหรับรับค่า input ที่เป้น byte array เพื่อเตรียมโหลดเข้า Doc sax
InputSource input = new InputSource(bArrStream);

//โหลด xml เข้าใน Doc
Document doc= builder.parse(input);

//ประกาศและสร้าง instance xpath
XPathFactory factory = XPathFactory.newInstance();
XPath xpath = factory.newXPath();

//สร้าง object person
obj = new Person();

//คำสั่ง xpath สำหรับกาเข้าถึง value ใน tag xml /request/person/id/text()
// ใช้คำสั่ง //id/text() ถ้าแบบนี้ไม่ต้องรู้ว่า tag root ก่อนหน้าเป็นอะไร ให้ค้นหา tag id ทั้งหมด
obj.setId(getNodeValuesXml(doc,xpath,"//id/text()"));
obj.setFname(getNodeValuesXml(doc,xpath,"//fname/text()"));
obj.setLname(getNodeValuesXml(doc,xpath,"/request/person/lname/text()"));
obj.setEmail(getNodeValuesXml(doc,xpath,"/request/person/email/text()"));
obj.setTel(getNodeValuesXml(doc,xpath,"/request/person/tel/text()"));
obj.setSalary(getNodeValuesXml(doc,xpath,"/request/person/salary/text()"));

return obj;
}
catch (SAXException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
return obj;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return obj;
}
catch(Exception e)
{
System.out.println(e.fillInStackTrace());
return obj;
}
}
}

************************

//ผลลัพท์ของโปรแกรมที่เป็น object
****************************
Object to String values is :Person [email=jame@ai-prosoft.com, fname=jame, id=01, lname=closeling, salary=25000, tel=+6684101312x]

เราสามารถใช้คำสั่ง . ในการเอาไปใช้งานได้ดังนี้
System.out.println("ID :"+obj.getId());

อันนี้อาจเป็นตัวอย่างง่ายๆสำหรับการ parse xml ให้เป็น object ซึ่งจริงๆแล้วมีหลายวิธี และมี libraries สำหรับการ parse xml สำหรับ ภาษา java เยอะแยะมากมาย
นี่เป็น demo case study สำหรับ การ parse xml เพื่อไปใช้งานจริง

วันพฤหัสบดีที่ 29 กรกฎาคม พ.ศ. 2553

ตัวอย่าง การ Set & Get Properties File ใน java

บางครั้งในการสร้าง application ขึ้นมาไม่ว่าจะเป็น web หรือ win บางครั้ง application ของเราต้องการค่าเริ่มต้นสำหรับการ run application ซึ่งเราสามารถ กำหนดได้หลายรูปแบบใช่ set ค่าไว้ที่ xml ไฟล์ หรือทำเป็นค่า fix ที่เป็น final หรืออ่านค่าจาก INI ไฟล์ สำหรับตัวอย่างนี้คือการค่า Properties มาใช้งาน(เหมือนกับการอ่านค่าจาก INI ไฟล์)
1.ตัวอย่างการอ่านค่า properties
2.ตัวอย่างการเขียนไฟล์ properties
3.ตัวอย่างไฟล์ properties

1.ตัวอย่างการอ่านค่า properties
package com.test.test;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Properties;

public class AppGetProp
{
public static void main( String[] args )
{
Properties prop = new Properties();

try {
//load a properties file
prop.load(new FileInputStream("config.properties"));
//get the property value and print it out
System.out.println(prop.getProperty("database"));
System.out.println(prop.getProperty("dbuser"));
System.out.println(prop.getProperty("dbpassword"));

} catch (IOException ex) {
ex.printStackTrace();
}
}
}
************************************

2.ตัวอย่างการเขียนไฟล์ properties
package com.test.test;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Properties;

public class AppSetProp {
public static void main( String[] args )
{
Properties prop = new Properties();

try {
//set the properties value
prop.setProperty("database", "localhost");
prop.setProperty("dbuser", "mkyong");
prop.setProperty("dbpassword", "password");

//save properties to project root folder
prop.store(new FileOutputStream("config.properties"), null);

} catch (IOException ex) {
ex.printStackTrace();
}
}

}


************************************
สำหรับ path file : /project_name/config.properties
3.ตัวอย่างไฟล์ properties
#Wed Jul 21 00:20:09 ICT 2010
dbpassword=password_xxx
database=localhostx
dbuser=user_xxx



*************************************

ตัวอย่าง code Gen UUID แบบที่สองเป็น number 14 หลัก

ตัวอย่าง output uuid : 30460064698217
*********************************************
ตัวอย่าง code
package com.test.test;

import java.util.Random;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.security.SecureRandom;

/**
* Classname : GenID

* Description : Generate unique id (lengths of number is 16)

*
Example usage:
* GenID hGenid = GenID.getInstance();
* String strUid = hGenid.getId();

* @version 1.0
*/
public class GenID{

private static GenID Myself;
private static Random MyRand;
private static SecureRandom MySecureRand;
private String strGen_id;

static {
MySecureRand = new SecureRandom();
long nSecureInitializer = MySecureRand.nextLong();
MyRand = new Random(nSecureInitializer);
}

/**
* get date and month
*/
private static String getDateMonth(){
Calendar calendar = new GregorianCalendar();
return(Integer.toString(calendar.get(Calendar.DATE))+
Integer.toString(calendar.get(Calendar.MONTH)));
}

/**
* get random long
*/
private static String getRandLong(){
long nRrand = MySecureRand.nextLong();
if (nRrand<0){
nRrand = nRrand * (-1);
}
return(Long.toString(nRrand));
}

/**
* get current time
*/
private static String getCurrentTime(){
long nTime = System.currentTimeMillis();
return(Long.toString(nTime));
}

/**
* scamble
* 1. random long (2 to 7) and reverse
* 2. current time (4 to 9) and reverse
* 3. date time (0 to 1)
*/
private static String JScamble(){
StringBuffer strScam_rand = new StringBuffer(getRandLong().substring(2,8));
StringBuffer strScam_ctime = new StringBuffer(getCurrentTime().substring(4,10));
StringBuffer strScam_dmy = new StringBuffer(getDateMonth().substring(0,2));
return(strScam_dmy.toString()+strScam_ctime.reverse().toString()+strScam_rand.reverse().toString());
}

private GenID(){
strGen_id = null;
}

/**
* Generate unique id
* @return String (lengths=14)
* @see java.lang.String
*/
public String getId(){
strGen_id = JScamble();
return strGen_id;
}

/**
* The default method used to retrieve an instance of GenID,
*/
public static GenID getInstance() {
if (Myself == null) {
synchronized (GenID.class) {
Myself = new GenID();
}
}
return Myself;
}
}

ตัวอย่าง code Gen UUID แบบที่1

บางครั้งเราต้องการใช้ค่าจาก system ที่ gen auto id ไม่ซ้ำกัน หรือเรียกกันว่า unique identifier (uuid)
ตัวอย่าง code ที่สามารถใช้งานได้ตามข้างล่าง
**************************************************

//output :6f5c9761-4728-4cf6-aace-0321f0027bcf ก็จะประมาณนี้
package com.test.test;

import java.util.Locale;
import java.util.Random;

/**
* A simple UUID.
*/
public final class UUID
{
public static void main(String args[])
{

System.out.println(nextUUID());
}
/**
* The characters to generate this UUID with.
*/
private static final char[] HEX = new char[] {
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'a', 'b', 'c', 'd', 'e', 'f'
};

/**
* Index into the UUID to set its type.
*/
private static final byte INDEX_TYPE = 6;

/**
* Index into the UUID to set its variation.
*/
private static final byte INDEX_VARIATION = 8;

/**
* The specific type of the UUID.
*/
private static final byte TYPE_RANDOM_BASED = 4;
/**
* The rnd generator.
*/
private static final Random RANDOM = new Random();

/**
* The string representing this UUID.
*/
private final String uuid;

/**
* Constructs a new UUID with the specified bytes.
*/
private UUID(byte[] bytes) {
this.uuid = genString(bytes);
}

/**
* Constructs a new UUID with the specified string.
*
* The size of the string must be 32, but no other characters
* are checked.
*/
public UUID(String uuid) {
this.uuid = uuid.toLowerCase(Locale.US);
if(uuid.length() != 36)
throw new IllegalArgumentException();
}

/**
* Returns the next UUID.
*/
public static UUID nextUUID() {
byte[] bytes = new byte[16];
RANDOM.nextBytes(bytes);
bytes[INDEX_TYPE] &= (byte) 0x0F;
bytes[INDEX_TYPE] |= (byte) (TYPE_RANDOM_BASED << sb =" new" i =" 0;" i="="4" i="="6" i="="8" i="="10)" hex =" info[i]">> 4]);
sb.append(HEX[hex & 0x0F]);
}
return sb.toString();
}

/**
* Generates the string of this UUID.
*/
public String toString() {
return uuid;
}

/**
* Determines if this UUID is the same as another.
*/
public boolean equals(Object o) {
if(o == this)
return true;
else if (o instanceof UUID) {
UUID other = (UUID)o;
return uuid.equals(other.uuid);
}
return false;
}

/**
* The hashCode of this UUID.
*/
public int hashCode() {
return uuid.hashCode();
}
}

ปัญหา java call Function return type boolean ใน oracle

สำหรับคนที่เคยใช้ ฐานข้อมูล oracle คงหนีไม่พ้นเรื่องการเขียน pl/sql ซึ่งก็เป็นจุ่นเด่นของ oracle เค้าว่าอย่างนั้น แต่มีนักพัฒนาไม่น้อยที่
ไม่จำเป็นต้องรู้จักหรือต้องเรียนรู้การเขียน pl/sql รู้แต่เพียงว่าเรียกใช้ procedure/function pl/sql เท่านั้น
ปัญหาอย่างหนึ่งระหว่าง java กับ oracle คือการเรียกใช้ function ใน oracle ที่มี Return type เป็น boolean ซึ่งเค้าว่ากันว่า java ยังไม่ support
การเรียกใช้ Return type ที่เป็น boolean นี่อาจเป็นวิธีทางแก้อีก หนึ่งทางเลือกสำหรับนักพัฒนาคือการเขียน pl/sql ครอบระหว่างการเรียนใช้ function ของ orcle
ซึ่งในตัวอย่างประกอบไปด้วย
1. pl/sql function ที่ return ค่าเป็น boolean
2. การเรียกใช้โดยใช้ java

--สร้าง ประกาศ function และสร้าง package
create or replace
PACKAGE PKG_TEST AS
FUNCTION F_GET_TEST_BOOL(P_SALARY1 IN NUMBER, P_SALARY2 OUT VARCHAR2) RETURN BOOLEAN;
END PKG_TEST;

/***********************************************/
--สร้าง body และสร้าง function F_GET_TEST_BOOL โดย return type ที่เป็น boolean
create or replace
PACKAGE BODY PKG_TEST AS
FUNCTION F_GET_TEST_BOOL(P_SALARY1 IN NUMBER, P_SALARY2 OUT VARCHAR2)
RETURN BOOLEAN AS
B_RESULT BOOLEAN := TRUE;
BEGIN
IF P_SALARY1>1500 THEN
P_SALARY2 := 'salary1 > 1500 bath';
ELSE
P_SALARY2 := 'salary1 < 1500 bath';
B_RESULT := FALSE;
END IF;
RETURN B_RESULT;
END F_GET_TEST_BOOL;

END PKG_TEST;

//เรียกใช้ จากโดย java set parameter in,out,และ return type

package com.test;

import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import oracle.jdbc.OracleTypes;

public class TEST_CALL_FBOOL {
//สร้าง connection method เพื่อ connec oracle
private static Connection conn()
{
String conStr;
Connection conn;
try
{
//สร้าง url connection
conStr = "jdbc:oracle:thin:@localhost:1521:orcl";
//register class dirver
Class.forName("oracle.jdbc.driver.OracleDriver").newInstance();
//connection & return
return conn = DriverManager.getConnection(conStr, "system", "root");
}
catch(Exception e)
{
// TODO Auto-generated catch block
e.printStackTrace();
return null;
}
}
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
//การเรียนใช้
P_CALL_FUNCTION_BOOL();
}

//สร้าง method สำหรับ เรียกใช้ fuction PL/SQL
public static void P_CALL_FUNCTION_BOOL()
{
//ประกาศ call prepared
CallableStatement cstmt = null;
//ประกาศ connection
Connection conn = null;
try {
//connection
conn =conn();

// -------------------------------------------------------------
// Call PL/SQL Function to retrieve {?= call function(?,?...n)}
// -------------------------------------------------------------
//F_GET_TEST_BOOL(P_SALARY1 IN NUMBER, P_SALARY2 OUT VARCHAR2)
//วิธีแก้ไขสำหรับการเรียน function จาก pl/sql ที่มี return type เป็น boolean เราจะทำการเขียน pl/sql คลอบ function ที่ต้องการเรียกใช้
//และมีการ return type เป็น varchar แทน ในตัวอย่าง ประกาศ ตัวเเปรที่ชื่อ B_VAL เป็น boolean เพื่อรับค่าจาก function ที่ return type เป็น boolean
//โดย function มี argument ที่เป็น IN(P_SALARY1) และ OUT(P_SALARY2) จากนั้น ก็ทำการ check if B_VAL เป็นจริงหรือไม่ ถ้าเป็นจริงให้ ตัวแปร ? มีค่าเป็น "T" String เพื่อ Return
//ค่าให้ java ใช้งาน

// prepared call
cstmt = conn.prepareCall("DECLARE B_VAL BOOLEAN; " +
"BEGIN B_VAL := PKG_TEST.F_GET_TEST_BOOL(?,?);" +
"IF (B_VAL) THEN ? := 'T'; END IF; END;");

//register input parameters
cstmt.setInt(1,1000);

//register output parameters
cstmt.registerOutParameter(2, OracleTypes.VARCHAR);

//register Return type
cstmt.registerOutParameter(3, OracleTypes.VARCHAR);

// Execute and retrieve the returned values
cstmt.execute();

System.out.println("******************************************8");

String result1 = cstmt.getString(2); //OUT parameter
String result2 = cstmt.getString(3); //Return type เื่พื่อทำไป check แล้วใช้งานต่อไป(ที่ได้จากการเรียก function)
//หมายเหตุ ถ้าเป็น True จะได้ String = 'T' แต่ถ้าเป็น False มีค่าเป็น null

System.out.println("Result Output param:"+result1);
System.out.println("Result Return Type:"+result2);

//close
cstmt.close();
conn.close();
}
catch (SQLException e)
{
System.out.println("'ERROR':"+e.toString());
}
}
}

ตัวอย่างสำหรับการเรียกใช้ function ของ pl/sql ที่มีการ Return type เป็น boolean โดยใช้ ภาษา java

Get วันทีปัจจุบันโดยใช้ java.util.date ตาม format

ในการเขียนโปรแกรมทุกภาษาสิ่งที่โปรแกรมเมอร์หลีกเหลี่ยงไม่พ้นคือการที่ต้องไปยุ่งเกี่ยวกับ วันเวลา วันที่ เดือน หรือ calendar ซึ่งในตัวอย่างนี้คือการนำค่าวันที่ปัจจุบันมาใช้งานตาม format (ซึ่งจริงๆมีหลายวิธีที่ได้มาซึ่งวันที่ปัจจุบัน)ดูตัวอย่างใน code ด้านล่าง
package com.test;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
public class TestDate2 {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
//กำหนด format
String format = "yyyyMMdd";

//เรียกใช้
System.out.println("Current System Date is :"+getSystemDate(format));
}
//ประกาศ method สำหรับ return ค่าวันที่ปัจจบัน หรือ system date โดยรับ argument เป็น String format เช่น yyyyMMdd,yyyy-MM-dd
public static String getSystemDate(String format) {
try
{
//ประกาศและสร้าง instance dateFormat
DateFormat dateFormat = new SimpleDateFormat(format,Locale.US);
//ประกาศและสร้าง instance Date
Date date = new Date();
//return date String ที่มีการกำหนด format แล้ว
return dateFormat.format(date).toString();
}
catch (Exception e)
{
e.printStackTrace();
return null;
}
}
}

แค่นี้ก็ได้วันที่ในแบบ format ที่ต้องการ