Spring MVC 与ExtJS的集成
一、简介
本demon主要是集成了SpringMVC和ExtJS,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.xsd
- http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
- http://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.java(Controller方法)
- 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;
- @Controller
- public 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));
- }
- }
具体效果见下图:
转自:http://blog.csdn.net/q262800095/article/details/12021191
那一汪清眸,那一瞥青涩的目光,那一段青春岁月。我一直在寻找,寻找一个属于我的婆娑世界,寻找那一年的自己,再也回不去了……
浙公网安备 33010602011771号