SpringMVC ภาคแถม JSON View

February 26th, 2009 by roofimon Leave a reply »

ภาคสี่ เราผ่านการ POST ข้อมูลไปจัดเก็บแล้วครับในตอนที่แล้ว ตอนนี้เป็นตอนแถมในภาคของ SpringMVC นั่นคือถ้ามผมต้องการส่ง Response กลับไปให้ Browser เป็นรูปแบบอื่น
เช่น JSON จะทำยังไงเพราะถ้าผมทะลึ่งอยากใช้ ExtJS หรือ Dojo ที่สามารถทำงานกับข้อมูลที่ถูกแปลงเป็น JSON ได้ดีเราจะทำอย่างไรครับ
โชคดีที่มีคนอยากได้แบบนี้แล้วเหมือนกันโดยโปรเจคนี้ชื่อ SpingJSON-View ครับเนื่องจาก SpringMVC เราสามารถปล่อย View ออกมาได้สามล้านแบบครับ XML, PDF … JSON
ดังนั้นอย่ารอช้าครับเริ่มด้วยการเพิ่มไลบรารี่เข้าไปใน pom.xml ก่อนครับตามสูตร

        <dependency>
            <groupId>net.sf.spring-json</groupId>
            <artifactId>spring-json</artifactId>
            <version>1.1</version>
        </dependency>

ต่อไปเราต้องบอกให้ SpringMVC รู้ว่าเรามี View แบบใหม่แล้วนะชื่อ jsonView เพื่อให้มันสามารถจัดการรับมือได้อย่างถูกต้องโดยสิ่งที่เราจะต้องทำคือการเพิ่มไฟล์ชื่อ views.xml เข้าไปที่
WEB-INF ให้มีรายละเอียดตามนี้ครับ

<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
    <bean name="jsonView" class="org.springframework.web.servlet.view.json.JsonView"/>
</beans>

จากนั้นสิ่งที่เราต้องทำคือเพิ่ม mapping เข้าไปใน web.xml เพื่อแยกว่า response ที่เราต้องการเป็น JSON นั้นเราจะแยกไฟล์ออกไปไม่ให้ปะปนกับของเดิมครับ โดยผมจะสร้างไฟล์ชื่อ
springjson66-servlet.xml ขึ้นมาเพื่อใช้เก็บ Controller ทุกตัวที่ทำงานเกี่ยวกับ JSON ไว้ในนี้ หลังจากสร้างไฟล์เรียบร้อยก็จัดการไปเพิ่มข้อมูลเข้าไปใน web.xml ดังนี้ครับ

    <servlet>
        <servlet-name>springjson66</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <load-on-startup>2</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>springjson66</servlet-name>
        <url-pattern>*.json</url-pattern>
    </servlet-mapping>

โดยที่ request อะไรก็ตามที่ลงท้ายด้วย *.json จะถูกส่งต่อไปให้ springjson66 จัดการต่อครับจากนั้นให้เราไปสร้าง Controller หนึ่งตัวครับที่มีหน้าที่ดึงข้อมูลออกมาจากตารางที่เราต้องการ
และทำการเปลี่ยนผลที่ได้ออกมาเป็น JSON ดังนี้ครับ

/**
 *
 * @author TwinP
 */
public class SimpleJsonGetController implements Controller {

    private AppUserService appUserService;

    @Override
    public ModelAndView handleRequest(HttpServletRequest arg0, HttpServletResponse arg1) throws Exception {
        Map model = new HashMap();
        model.put("model", this.appUserService.getUsers(null));
        return new ModelAndView("jsonView", model);
    }

    /**
     * @return the appUserService
     */
    public AppUserService getAppUserService() {
        return appUserService;
    }

    /**
     * @param appUserService the appUserService to set
     */
    public void setAppUserService(AppUserService appUserService) {
        this.appUserService = appUserService;
    }
}

จะเห็นได้ว่าไม่มีอะไรแต่กต่างจากเดิมมากนักสิ่งที่ต่างคือจังหวะที่เราคืนค่าออกมาจากเมธอด handleRequest นั้นเราเพียบแต่ระบุเพิ่มเติมว่าเราต้องการให้แปลงเป็น JSON นะแต่ Controller นี้จะใช้
งานไม่ได้ถ้าเราไม่ไป register มันไว้ตามระเบียบของ Spring โดยที่เราจะไปใส่ข้อมูลไว้ที่ springjson66-servlet.xml ครับ

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN"
		  "http://www.springframework.org/dtd/spring-beans-2.0.dtd">

<beans>
    <bean name="simpleJsonGetController"
          class="com.spring66.tutorial.web.controller.SimpleJsonGetController">
        <property name="appUserService" ref="appUserService"/>
    </bean>

    <bean name="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
        <property name="mappings">
            <props>
                <prop key="/hello.json">simpleJsonGetController</prop>
            </props>
        </property>
    </bean>
    <bean  name="viewResolver" class="org.springframework.web.servlet.view.XmlViewResolver" />
</beans>

เป็นอันเรียบร้อยครับต่อไปสุดท้ายคือเราต้องไปสร้าง View ที่สามารถรับ response เป็น JSON แล้วเอาไป process ต่อได้ในทันควันนั่นคือ ExtJS ครับโดยที่ผมจะไม่ลงรายละเอียดนะครับเขียนเลยละกัน

<html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
    <title>Paging Grid Example</title>

    <link rel="stylesheet" type="text/css" href="scripts/ext/resources/css/ext-all.css" />

    <!-- GC -->
    <!-- LIBS -->
    <script type="text/javascript" src="scripts/ext/adapter/ext/ext-base.js"></script>
    <!-- ENDLIBS -->

    <script type="text/javascript" src="scripts/ext/ext-all.js"></script>
    <link rel="stylesheet" type="text/css" href="css/examples.css" />

    <script type="text/javascript" src="scripts/usrJSONService.js"></script>
    </head>
    <body>

        <!?- grid will render to this element -?>
        <div id="db-grid"></div>

    </body>
</html>

จากไฟล์นี้ผมไปเรียก JS พิเศษหนึ่งไฟล์ชื่อ usrJSONService.js ครับโดยไฟล์นี้จะทำหน้าที่ไปเรียก controller ของเราและเอาผลมา process ใส่ grid แบบบ้านๆของ ExtJS ครับ

Ext.onReady(function(){
    // create the data store
    var store = new Ext.data.JsonStore({
        url: 'hello.json',
        root: 'model',
        fields: [
        {
            name: 'usrFirstLogin'//, mapping: 'usrFirstLogin', type: 'date', dateFormat: 'timestamp'
        },

        {
            name: 'usrId'
        },

        {
             name: 'regDate'//, mapping: 'usrFirstLogin', type: 'date', dateFormat: 'timestamp'
        },
        {
            name: 'usrPwd'
        },
        {
            name: 'logDate'//, mapping: 'usrFirstLogin', type: 'date', dateFormat: 'timestamp'
        },
        {
            name: 'usrName'
        }
        ]
    });
    //store.loadData(myData);
    store.load();

    // create the Grid
    var grid = new Ext.grid.GridPanel({
        store: store,
        columns: [
        {
            id:'usrFirstLogin',
            header: "usrFirstLogin",
            width: 160,
            sortable: true,
            dataIndex: 'usrFirstLogin'
        },

        {
            header: "usrId",
            width: 75,
            sortable: true,
            renderer: 'usMoney',
            dataIndex: 'usrId'
        },

        {
            header: "regDate",
            width: 75,
            sortable: true,
            dataIndex: 'regDate'
        },

        {
            header: "% logDate",
            width: 75,
            sortable: true,
            dataIndex: 'logDate'
        }
        ],
        stripeRows: true,
        autoExpandColumn: 'usrFirstLogin',
        height:350,
        width:600,
        title:'Array Grid'
    });

    grid.render('db-grid');
});

เรียบร้อยครับเราก็ได้ View สุดสวยกันแล้วครับภาคต่อไปเราจะลองมา POST ผ่าน ExtJS กันนะครับ

Advertisement

1 comment

Leave a Reply

You must be logged in to post a comment.