Showing posts with label gwt. Show all posts
Showing posts with label gwt. Show all posts

Wednesday, February 27, 2008

แอบดู GWT code

เมื่อวานผมเขียน code GWT ในส่วนที่เกี่ยวกับ java.util.Date
แล้วเกิดสงสัยว่ามัน implement อย่างไร ก็เลยลอง download source code ของ GWT มาดู
เปิดดูแล้วก็ร้อง 'ฮ่อ'

ลองดูบางส่วนที่ผมตัดมาให้ดู

/**
* Represents a date and time.
*/

public class Date implements Cloneable, Comparable<Date>, Serializable {

public Date() {
init();
}

private native void init() /*-{
this.jsdate = new Date();
}-*/
;


public native int getDate() /*-{
return this.jsdate.getDate();
}-*/
;

public native int getDay() /*-{
return this.jsdate.getDay();
}-*/
;

public native int getHours() /*-{
return this.jsdate.getHours();
}-*/
;

public native String toGMTString() /*-{
var d = this.jsdate;
var padTwo = @java.util.Date::padTwo(I);
var month =
@java.util.Date::monthToString(I)(this.jsdate.getUTCMonth());

return d.getUTCDate() + " " +
month + " " +
d.getUTCFullYear() + " " +
padTwo(d.getUTCHours()) + ":" +
padTwo(d.getUTCMinutes()) + ":" +
padTwo(d.getUTCSeconds()) +
" GMT";
}-*/
;

private static String padTwo(int number) {
if (number < 10) {
return "0" + number;
} else {
return String.valueOf(number);
}
}
}

งามดีเหมือนกัน ส่วนที่ cross กันระหว่าง javascript กับ java (ก่อนที่จะแปลงเป็น javascript)

ที่น่าสนใจก็คือ ตอนที่ฝั่ง javascript call มาที่ฝั่ง java
จาก code ข้างบนลองดูวิธีการ call method padTwo

// เริ่มด้วยการอ้างถึง method ที่ต้องการ
// จะเห็นว่ามันใช้ signature ของ method ในการอ้างถึง method ที่ต้องการ
// สิ่งที่ return กลับมาก็น่าจะเป็น javascript function

var padTwo = @java.util.Date::padTwo(I);
...
padTwo(d.getUTCHours()) + ...
...

Related link from Roti

Wednesday, February 20, 2008

GWT กับ Spring

ผม search หาวิธี map GWT เข้ากับ SpringFramework มาพักใหญ่แล้ว
ส่วนใหญ่ที่เห็นก็จะเป็นการเขียน DispatcherServlet ของตัวเองขึ้นมา
เช่น GWT-SL
วิธีการของ GWT-SL จะเป็นดังนี้
  • config servlet ใน web.xml
      <servlet>
    <servlet-name>rpc</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
    <servlet-name>rpc</servlet-name>
    <url-pattern>*.rpc</url-pattern>
    </servlet-mapping>

  • config spring context โดยใช้ GWTHandler เข้ามาเป็นตัว wrapper
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
    "http://www.springframework.org/dtd/spring-beans.dtd">

    <beans>
    <bean id="urlMapping" class="org.gwtwidgets.server.spring.GWTHandler">
    <property name="mappings">
    <map>
    <entry key="/wcfb110_jobService.rpc" value-ref="jobService"/>
    </map>
    </property>
    </bean>

    <bean id="jobService" class="wcf.web.fin.gwt.wcfb110.server.JobServiceImpl"/>
    </beans>
    </pre>


ดูก็ง่ายดีแล้ว แต่มาวันนี้เจอตัวอย่าง source code ของ Interface21(เจ้าพ่อ spring) ซึ่ง config spring กับ GWT
(โปรดระวัง เห็นนามสกุลเป็น .zip แต่จริงๆแล้วมันเป็นพวก .tgz)
เห็นแล้วต้องร้อง Wow, ทำไมมัน simple อย่างนี้

เขาใช้วิธีนี้
เริ่มด้วย web.xml ที่ทำเหมือนกันกับข้างบน
แต่ ตัว spring context เขาเปลี่ยนเป็นแบบนี้
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd"
>

<context:component-scan base-package="gwt.server" />

</beans>

แล้วตัว GWT Servlet ของเราก็ใส่ annotation เข้าไปแบบนี้
@Controller
public class NoteServiceImpl extends RemoteServiceServlet implements NoteService, ServletConfigAware {

public void setServletConfig(ServletConfig servletConfig) {
try {
init(servletConfig);
} catch (ServletException e) {
throw new IllegalStateException("Cannot initialise Controller.", e);
}
}

@RequestMapping("/gwt.Example/NoteService.rpc")
public void doRpc(HttpServletRequest request, HttpServletResponse response)
throws Exception {
doPost(request, response);
}

public Note loadNote(String name) {
return new Note(name, "This Note named " + name + " was constructed on the server");
}
}

ง่ายขึ้นเยอะ ลด dependency ของพวก wrapper ไปได้
แต่ข่าวร้ายสำหรับผมก็คือ annotation พวกนี้เป็น feature ของ spring 2.5.x
โชคร้ายที่โปรเจคผมยังใช้ spring 2.0.x อยู่เลย

Related link from Roti