Spring MVC 与ExtJS完美集成

来源:互联网 发布:今年淘宝生意不好做 编辑:程序博客网 时间:2024/06/05 11:27

一、简介

demon主要是集成了SpringMVCExtJS,SpringMVC和ExtJS之间的数据交互方式为JSON,同时还支持controller返回string和页面地址对应关系配置、页面消息动态配置(类似于国际化)、intercepter


二、系统集成


1、包文件

包文件的重要性就不多说了,建议用maven管理。

但是,为了加深理解,我是直接从官网上下载的包,然后一个个试的,中间遇到了很多问题,包括少包,包冲突等。


2、配置文件

先看web.xml

<?xml version="1.0" encoding="UTF-8"?><web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee"    xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"    id="WebApp_ID" version="2.5">    <display-name>SpringMVCTest</display-name>    <!-- The definition of the Root Spring Container shared by all Servlets and Filters --><!-- 防止资源文件被spring MVC拦截 -->    <servlet-mapping>        <servlet-name>default</servlet-name>        <url-pattern>*.jpg</url-pattern>    </servlet-mapping>    <servlet-mapping>        <servlet-name>default</servlet-name>        <url-pattern>*.js</url-pattern>    </servlet-mapping>    <servlet-mapping>        <servlet-name>default</servlet-name>        <url-pattern>*.css</url-pattern>    </servlet-mapping>    <context-param>        <param-name>contextConfigLocation</param-name>        <param-value>/WEB-INF/spring/root-context.xml</param-value>    </context-param>    <!-- Creates the Spring Container shared by all Servlets and Filters -->    <listener>        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>    </listener>    <!-- Processes application requests -->    <servlet>        <servlet-name>appServlet</servlet-name>        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>        <init-param>            <param-name>contextConfigLocation</param-name>            <param-value>/WEB-INF/spring/appServlet/servlet-context.xml</param-value>        </init-param>        <load-on-startup>1</load-on-startup>    </servlet>    <servlet-mapping>        <servlet-name>appServlet</servlet-name>        <url-pattern>/</url-pattern>    </servlet-mapping></web-app>

然后是root-context.xml,默认的没有加内容。


<?xml version="1.0" encoding="UTF-8"?><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.xsd"><!-- Root Context: defines shared resources visible to all other web components --></beans>

最后是servlet-context.xml



<?xml version="1.0" encoding="UTF-8"?><beans:beans xmlns="http://www.springframework.org/schema/mvc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"    xmlns:beans="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context"    xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsdhttp://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">    <annotation-driven />    <!--防止css js img 文件被拦截     <resources mapping="/images/**" location="/images/" cache-period="31556926" />    <resources mapping="/js/**" location="/js/" cache-period="31556926" />    <resources mapping="/css/**" location="/css/" cache-period="31556926" /> -->        <!-- 加入集中消息文件的配置 //也可以用来支持进行国际化-->    <beans:bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">        <beans:property name="basenames" value="/WEB-INF/message/static_message , /WEB-INF/message/dynamic_message" />        <beans:property name="cacheSeconds" value="2"></beans:property>    </beans:bean>    <!-- 能够让controller返回json格式的配置   //当然也可以自己手动拼json或者用工具类生成json 将拼好的json串写到页面上  然后再返回页面-->    <beans:bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">        <beans:property name="messageConverters">            <beans:list>                <beans:ref bean="mappingJacksonHttpMessageConverter" />            </beans:list>        </beans:property>    </beans:bean>    <beans:bean id="mappingJacksonHttpMessageConverter" class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">        <beans:property name="supportedMediaTypes">            <beans:list>                <beans:value>application/json;charset=UTF-8</beans:value>            </beans:list>        </beans:property>    </beans:bean>    <!-- 加入能够进行前端文件访问的配置  不适用默认的视图解释类-->    <beans:bean id="tilesViewResolver" class="org.springframework.web.servlet.view.UrlBasedViewResolver">        <beans:property name="viewClass" value="org.springframework.web.servlet.view.tiles2.TilesView" />    </beans:bean>    <beans:bean id="tilesConfigurer" class="org.springframework.web.servlet.view.tiles2.TilesConfigurer">        <beans:property name="definitions">            <beans:list>                <beans:value>/WEB-INF/tiles-defs/templates.xml</beans:value>            </beans:list>        </beans:property>    </beans:bean>    <!-- 加入interceptor -->    <interceptors>        <interceptor>            <mapping path="/extjspie" />            <beans:bean id="MeasurementInterceptor" class="com.util.MeasurementInterceptor">                <!-- <beans:property name="paramName" value="theme" /> -->            </beans:bean>        </interceptor>    </interceptors>    <context:component-scan base-package="com.controller" /></beans:beans>

3、页面配置文件

templates.xml,用来配置前段页面和后台返回的字符串之间的关系。


<?xml version="1.0" encoding="ISO-8859-1" ?><!DOCTYPE tiles-definitions PUBLIC       "-//Apache Software Foundation//DTD Tiles Configuration 2.0//EN"       "http://tiles.apache.org/dtds/tiles-config_2_0.dtd"><tiles-definitions>    <definition name="extjspie" template="/WEB-INF/chart/pie1.jsp"></definition>    <definition name="jquerypie" template="/WEB-INF/chart/pie.jsp"></definition>    </tiles-definitions>


4、消息文件

dynamic_message.properties

title = Title : {0}


static_message.properties


check_download = Would you like to download the chart as an image?

5、页面文件


pie1.jsp(路径/extjspie会跳转到这个文件)

<spring:messagecode='title' arguments='pie'/>

这个会使用message里的消息,可以对消息进行动态修改而不用重启服务器,一般用于用户消息或系统配置。

<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%><!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><html><head><meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"><title>Insert title here</title></head><script src="js/extjs/ext-all.js"></script><link rel="stylesheet" href="js/extjs/resources/css/ext-all.css"><%@ taglib uri="http://www.springframework.org/tags" prefix="spring"%><script>    Ext.Loader.setConfig({        enabled : true    });    Ext.require('Ext.chart.*');    Ext.require([ 'Ext.layout.container.Fit', 'Ext.window.MessageBox', 'Ext.grid.*', 'Ext.util.*' ]);    Ext.onReady(function() {        //effort        var store = Ext.create('Ext.data.JsonStore', {            fields : [ 'id', 'name', 'data1' ],            proxy : {                type : 'ajax',                url : 'pieData',                reader : {                    type : 'json'                }            }        });        store.load({            callback : function(records, operation, success) {                console.log(records);            }        });        var donut = false, chart = Ext.create('Ext.chart.Chart', {            xtype : 'chart',            animate : true,            store : store,            shadow : true,            legend : {                position : 'right'            },            insetPadding : 60,            theme : 'Base:gradients',            series : [ {                type : 'pie',                field : 'data1',                showInLegend : true,                donut : donut,                tips : {                    trackMouse : true,                    width : 140,                    height : 28,                    renderer : function(storeItem, item) {                        //calculate percentage.                        var total = 0;                        store.each(function(rec) {                            total += rec.get('data1');                        });                        this.setTitle(storeItem.get('name') + ': ' + Math.round(storeItem.get('data1') / total * 100)                                + '%');                    }                },                highlight : {                    segment : {                        margin : 20                    }                },                label : {                    field : 'name',                    display : 'rotate',                    contrast : true,                    font : '18px Arial'                }            } ]        });        Ext.create('widget.panel', {            width : 800,            height : 600,            title : "<spring:message code='title' arguments='pie'/>",            renderTo : "chart",            layout : 'fit',            tbar : [                    {                        text : 'Save Chart',                        handler : function() {                            Ext.MessageBox.confirm('Confirm Download', "<spring:message code='check_download' />",                            function(choice) {                                        if (choice == 'yes') {                                            chart.save({                                                type : 'image/png'                                            });                                        }                                    });                        }                    }, {                        text : 'Reload Data',                        handler : function() {                            // Add a short delay to prevent fast sequential clicks                            window.loadTask.delay(100, function() {                                store1.loadData(generateData(6, 20));                            });                        }                    }, {                        enableToggle : true,                        pressed : false,                        text : 'Donut',                        toggleHandler : function(btn, pressed) {                            chart.series.first().donut = pressed ? 35 : false;                            chart.refresh();                        }                    } ],            items : chart        });    });</script><body>    <div id="chart"></div></body></html>

pie.jsp(/jquerypie会跳转到这个界面,主要用来集成jquery)


<%@ page language="java" contentType="text/html; charset=ISO-8859-1"    pageEncoding="ISO-8859-1"%><!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><html><head><meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"><title>Insert title here</title></head>    <link rel="stylesheet" href="js/jquery/themes/base/jquery.ui.all.css">    <script src="js/jquery/jquery-1.9.1.js"></script>    <script src="js/jquery/ui/jquery.ui.core.js"></script>    <script src="js/jquery/ui/jquery-ui.js"></script><script>$(document).ready(function(){    $.get("pieData", function(data) {        $.each(data,function(InfoIndex,Info){            alert(InfoIndex);            alert(Info["name"]);        });    });    });</script><body>this is pie.jsp!!</body></html>


6、后台文件

ChartController.javaController方法)

package com.controller;import java.util.ArrayList;import java.util.List;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.stereotype.Controller;import org.springframework.ui.Model;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestMethod;import org.springframework.web.bind.annotation.ResponseBody;import com.model.Employee;@Controllerpublic class ChartController {    private static final Logger logger = LoggerFactory.getLogger(ChartController.class);    /**     * method description goes here     *      * @param args     */    @RequestMapping(value = "/jquerypie", method = RequestMethod.GET)    public String pie(Model model) {        // TODO Auto-generated method stub        return "jquerypie";    }    @RequestMapping(value = "/extjspie", method = RequestMethod.GET)    public String pie1(Model model) {        // TODO Auto-generated method stub        return "extjspie";    }    @RequestMapping(value = "/pieData", method = RequestMethod.GET)    @ResponseBody    public Object pieData(Model model) {        // TODO Auto-generated method stub        List<Employee> empList = new ArrayList<Employee>();        Employee emp1 = new Employee();        emp1.setId(1);        emp1.setName("steven");        emp1.setData1(10);        empList.add(emp1);        Employee emp2 = new Employee();        emp2.setId(2);        emp2.setName("daniel");        emp2.setData1(25);        empList.add(emp2);        Employee emp3 = new Employee();        emp3.setId(3);        emp3.setName("emily");        emp3.setData1(7);        empList.add(emp3);        Employee emp4 = new Employee();        emp4.setId(4);        emp4.setName("heather");        emp4.setData1(4);        empList.add(emp4);        //return json data        return empList;    }}


Employee.java

package com.model;public class Employee {    private int id;    private String name;    private int data1;        /**     * @return the id     */    public int getId() {        return id;    }    /**     * @param id the id to set     */    public void setId(int id) {        this.id = id;    }    /**     * @return the name     */    public String getName() {        return name;    }    /**     * @param name the name to set     */    public void setName(String name) {        this.name = name;    }    /**     * @return the data1     */    public int getData1() {        return data1;    }    /**     * @param data1 the data1 to set     */    public void setData1(int data1) {        this.data1 = data1;    }        }

MeasurementInterceptor.java(inteceptor方法)


package com.util;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import org.springframework.web.servlet.ModelAndView;import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;public class MeasurementInterceptor extends HandlerInterceptorAdapter {    public boolean preHandle(HttpServletRequest request,          HttpServletResponse response,Object handler)throws Exception{          long startTime = System.currentTimeMillis();          request.setAttribute("startTime",startTime);          return true;    }                public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,        ModelAndView modelAndView) throws Exception {        long startTime = (Long) request.getAttribute("startTime");        request.removeAttribute("startTime");        long endTime = System.currentTimeMillis();        //modelAndView.addObject("handlingTime", endTime - startTime);                System.out.println("______________enter interceptor . use time:" + (endTime - startTime));    }}

具体效果见下图:

   


原创粉丝点击