Wednesday, March 18, 2009

How to get client Request object in IBM java web service

เมื่อเราเขียน web application ไม่ว่าจะด้วย servlet หรือ jsp
หรืออื่นๆ เราก็สามารถ get client request ออกมาเพื่อหาค่า
information ของ client ได้ แต่ web service ล่ะทำยังไง

สำหรับ java web service นั้น ปกติ ก็ต้องมีการ implement
interface ที่ inherit มาจาก rmi.Remote แล้วนำมา Generate
ออกมาเป็น web serice

อาว ไม่เห็นมี Request แบบใน Servlet เลยที่มี Request
อยู่ใน doPost, doGet

วิธีเพื่อให้ได้มาซึ่ง Request มาสองทางครับคือ
1. ในกรณีใช้ RAD ก็ง่าย หรือถ้าไม่ใช้ RAD ก็ต้องแก้ไข
ค่าของ web.xml เพื่อทำการ create Filter class ขึ้นมาครับ
โดยถ้าเป็น RAD ก็ไปที่ web.xml แล้ว click ขวา
หลังจากนั้นเลือกให้เป็นด้วยตัว Editor ของมันครับ
แล้วมองหา Tab ที่เขียนว่า Filters ครับ แล้วเลือก Add เพื่อสร้าง
Filter ขึ้นมาครับแล้วตั้งชื่อ Filter class ตามใจชอบครับ
หลังจากนั้นกด Next แล้วระบุว่าจะให้ Filter class ที่ได้นี้
generate ลงไปใน folder อะไร มี package ชื่ออะไร
และหรือ inherit มาจาก class ไหนด้วย จากนั้นก็ Finish ครับ
สุดท้ายเมื่อมาถึง Add Filter Mapping To Servlet
ก็ให้เลย Dispatcher Type เป็น Request ครับ เพื่อให้
เราสามารถ Filter Request message ออกมาได้

package filters;

import javax.servlet.Filter;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.FilterChain;
import java.io.IOException;

public class MyFilter implements Filter {

public MyFilter() {
super();
}

public void init(FilterConfig arg0) throws ServletException {}

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
System.out.println("Remote Address: "+request.getRemoteAddr());
chain.doFilter(request, response);
}

public void destroy() {}

}


Filter class ที่ได้ก็จะออกมาประมาณนี้ครับ เราสามารถเอาค่า Request มาใช้งานได้
ใน doFilter ครับ

2. คือเราไม่ต้องใช้ตัวช่วยครับ โดยให้เรา implement javax.xml.rpc.server.ServiceLifecycle
ให้กับ class ที่เราใช้ทำเป็น web service ครับ โดย interface ServiceLifecycle นี้
จะบังคับให้เรา override 2 method คือ init และ destroy ครับ และเราสามารถ get Request ได้ผ่าน
ทาง ServletEndpointContext ดังนี้ครับ

public class MyService implements javax.xml.rpc.server.ServiceLifecycle {

private javax.xml.rpc.server.ServletEndpointContext ctx;
public MyService(){
}

public void init(Object arg0) throws ServiceException {
ctx=(javax.xml.rpc.server.ServletEndpointContext)arg0;
}

public void destroy(){

}

public java.lang.String getRemoteAddr() throws java.rmi.RemoteException {
javax.servlet.http.HttpServletRequest request = (javax.servlet.http.HttpServletRequest)ctx.getMessageContext().getProperty(
com.ibm.ws.webservices.engine.transport.http.HTTPConstants.MC_HTTP_SERVLETREQUEST);
return = request.getRemoteAddr();
}

}


จาก code ข้างบน method getRemoteAddr() คือตัวอย่างการเอา Request มาใช้งานเพื่อหาค่า ip address ของ client ครับ

No comments: