Spring3MVC和jQuery的集成

在本教程.我们将使用Spring MVC建立一个简单的基于jQuery的计算器AJAX应用.
为了便于对比.
我们将创建两个页面.
一个传统的页面.
一个是基于AJAX的页面.

[size=large][b]什么是jQuery?[/b][/size]

[quote]Jquery是继prototype之后又一个优秀的Javascrīpt框架。它是轻量级的js库(压缩后只有21k) ,它兼容CSS3,还兼容各种浏览器 (IE 6.0+, FF 1.5+, Safari 2.0+, Opera 9.0+)。jQuery使用户能更方便地处理HTML documents、events、实现动画效果,并且方便地为网站提供AJAX交互。jQuery还有一个比较大的优势是,它的文档说明很全,而且各种应用也说得很详细,同时还有许多成熟的插件可供选择。jQuery能够使用户的html页保持代码和html内容分离,也就是说,不用再在html里面插入一堆js来调用命令了,只需定义id即可[/quote]

[url=http://jquery.com/]JQuery官网[/url]

jQuery最新版本是1.5.1
在此教程我们使用1.4.4

[url=http://docs.jquery.com/Downloading_jQuery]jQuery下载地址[/url]


[size=large][b]什么是AJAX?[/b][/size]

[quote]AJAX全称为“Asynchronous JavaScript and XML”(异步JavaScript和XML),是一种创建交互式网页应用的网页开发技术。根据Ajax提出者Jesse James Garrett建议[1],AJAX:

* 使用XHTML+CSS来表示信息;
* 使用JavaScript操作DOM(Document Object Model)进行动态显示及交互;
* 使用XML和XSLT进行数据交换及相关操作;
* 使用XMLHttpRequest对象与Web服务器进行异步数据交换;
* 使用JavaScript将所有的东西绑定在一起。

类似于DHTML或LAMP,AJAX不是指一种单一的技术,而是有机地利用了一系列相关的技术。事实上,一些基于AJAX的“派生/合成”式(derivative/composite)的技术正在出现,如AFLAX。[/quote]


我们的应用程序是一个能进行简单的算术运算:增加两个数字并显示他们的和.
这里有两张截图:
一张是非AJAX版本.

[img]http://dl.iteye.com/upload/attachment/446482/12ffe624-3531-3d88-91a8-adfc3c5cc13f.png[/img]


一张是AJAX版本.

[img]http://dl.iteye.com/upload/attachment/446480/77102807-6530-336e-bea6-e58ae15f6a96.png[/img]


两者没有什么不同.但是非AJAX版本的将会在另外一个页面显示结果.
我们会看到明显的页面刷新过程

而AJAX版本将在同一个页面上显示结果.
我们几乎感觉不到页面刷新.

在此之前我们添加Spring MVC所必须的配置.

[b]web.xml[/b]

<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="2.4"
xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">

<servlet>
<servlet-name>spring</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
<servlet-name>spring</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>

<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

</web-app>



在web.xml中我们定义servlet:spring.
按照惯例,我们必须声明一个spring-servle.xml

[b]
spring-servle.xml [/b]


<?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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

<!-- 定义一个视图解析器 -->
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver"
p:prefix="/WEB-INF/jsp/" p:suffix=".jsp" />

</beans>

这个XML配置声明一个视图解析器.在控制器中会根据JSP名映射到/ WEB-INF/jsp中相应的位置.

然后创建一个applicationContext.xml.

[b]applicationContext.xml [/b]

<?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:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">

<!-- 激活spring的注解. -->
<context:annotation-config />

<!-- 扫描注解组件并且自动的注入spring beans中.
例如,他会扫描@Controller 和@Service下的文件.所以确保此base-package设置正确. -->
<context:component-scan base-package="org.liukai.tutorial" />

<!-- 配置注解驱动的Spring MVC Controller 的编程模型.注:次标签只在 Servlet MVC工作! -->
<mvc:annotation-driven />

</beans>




在webapp下创建一个resources的文件夹用于放置JS和CSS等静态文件.
如下图

[img]http://dl.iteye.com/upload/attachment/446604/0f931e12-104a-3a54-a474-d6476f2c559a.png[/img]


然后就是在pom.xml添加必须的jar包

[img]http://dl.iteye.com/upload/attachment/446478/98d3af4c-4223-3c93-bfc3-c7a270845b41.png[/img]


实现一个简单的 POJO service层

[b]ArithmeticService.java[/b]


package org.liukai.tutorial.service;

import org.apache.log4j.Logger;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service("arithmeticService")
@Transactional
public class ArithmeticService {

protected static Logger logger = Logger.getLogger("service");

/**
* 实现一个加法运算
*/
public Integer add(Integer operand1,Integer operand2){
logger.debug("Adding two numbers");
return operand1 + operand2;
}

}



这是一个非常简单的POJO service,其中包含了一个实现加法运算的方法:add().



[size=large][b]非AJAX版本[/b][/size]

首先我们编写一个非AJAX版本的SpringMVC应用程序.

写一个处理用户请求的controller类:NonAjaxController.java

[b]NonAjaxController.java[/b]


package org.liukai.tutorial.controller;

import javax.annotation.Resource;

import org.apache.log4j.Logger;
import org.liukai.tutorial.service.ArithmeticService;
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.RequestParam;

/**
* 用于处理非AJAX运算.
*/
@Controller
@RequestMapping("/main/nonajax")
public class NonAjaxController {

protected static Logger logger = Logger.getLogger("controller");

@Resource(name = "arithmeticService")
private ArithmeticService arithmeticService;

/**
* 根据请求映射跳转到nonajax-add-page.jsp
*/
@RequestMapping(value = "/add", method = RequestMethod.GET)
public String getNonAjaxAddPage() {
logger.debug("Received request to show non-AJAX, ordinary add page");

// 他将会解析 /WEB-INF/jsp/nonajax-add-page.jsp
return "nonajax-add-page";
}

/**
* 提交表单并进行运算.
* @RequestParam表示从JSP页面接收值.
* 是springMVC重要的传递参数手段之一.
*/
@RequestMapping(value = "/add", method = RequestMethod.POST)
public String add(
@RequestParam(value = "inputNumber1", required = true) Integer inputNumber1,
@RequestParam(value = "inputNumber2", required = true) Integer inputNumber2,
Model model) {
logger.debug("Received request to add two numbers");

// 实现运算
Integer sum = arithmeticService.add(inputNumber1, inputNumber2);

// 添加到model返回到页面
model.addAttribute("sum", sum);

// 他将会解析 /WEB-INF/jsp/nonajax-add-result-page.jsp
//并把model传递到该JSP页面.
return "nonajax-add-result-page";
}
}


这个controller声明了2个映射:
/main/nonajax/add (GET) - 用于跳转到add页面
/main/nonajax/add (POST) -计算值并将结果返回到指定的页面

下面是JSP页面

[b]nonajax-add-page.jsp[/b]


<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!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=UTF-8">

<title>Spring MVC - jQuery 整合教程</title>
</head>
<body>

<h3>Spring MVC - jQuery 整合教程</h3>
<h4>Non-AJAX version</h4>

<c:url var="addUrl" value="/main/nonajax/add" />

<form method="POST" action="${addUrl}">

Demo 1
<div style="border: 1px solid #ccc; width: 250px;">
Add Two Numbers: <br/>
<input id="inputNumber1" name="inputNumber1" type="text" size="5"> +
<input id="inputNumber2" name="inputNumber2" type="text" size="5">
<input type="submit" value="Add" /> <br/>
Sum: (Result will be shown on another page)
</div>

</form>

</body>
</html>



[b]nonajax-add-result-page.jsp[/b]


<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!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=UTF-8">

<title>Spring MVC - jQuery 整合教程</title>
</head>
<body>

<h3>Spring MVC - jQuery 整合教程</h3>
<h4>Non-AJAX version</h4>

Demo 1 Result
<div style="border: 1px solid #ccc; width: 250px;">
Sum: ${sum}
</div>

</body>
</html>



启动web服务器.
我们添加两个数字:12和13.我们预期为25.
输入URL地址
[url]http://localhost:8080/spring-jquery/main/nonajax/add[/url]

[img]http://dl.iteye.com/upload/attachment/446529/92b48b60-58dd-3f32-9fbf-ddf373b1a5dd.png[/img]

得到的结果如下:

[img]http://dl.iteye.com/upload/attachment/446531/1955fa13-a933-3688-9036-6c5fb5167172.png[/img]

注意:结果是在另外一个页面显示的.

[size=large][b]AJAX版本[/b][/size]

现在让我们使用AJAX版本来实现该功能.
首先还是controller

[b]AjaxController.java[/b]

package org.liukai.tutorial.controller;

import javax.annotation.Resource;

import org.apache.log4j.Logger;
import org.liukai.tutorial.service.ArithmeticService;
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.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
@RequestMapping("/main/ajax")
public class AjaxController {

protected static Logger logger = Logger.getLogger("controller");

@Resource(name = "arithmeticService")
private ArithmeticService arithmeticService;

/**
* 根据映射跳转到指定的页面
*/
@RequestMapping(value = "/add", method = RequestMethod.GET)
public String getAjaxAddPage() {
logger.debug("Received request to show AJAX, add page");

// 解析 /WEB-INF/jsp/ajax-add-page.jsp
return "ajax-add-page";
}

/**
* 提交表单并进行运算.
*/
@RequestMapping(value = "/add", method = RequestMethod.POST)
public @ResponseBody
Integer add(
@RequestParam(value = "inputNumber1", required = true) Integer inputNumber1,
@RequestParam(value = "inputNumber2", required = true) Integer inputNumber2,
Model model) {
logger.debug("Received request to add two numbers");

// 实现运算
Integer sum = arithmeticService.add(inputNumber1, inputNumber2);

// @ResponseBody 会自动的将返回值转换成JSON格式
// 但是你必须添加jackson的jar包!!!
return sum;
}
}



该controll还是声明了两个映射:
/main/ajax/add (GET) - 跳转到指定页面.
/main/ajax/add (POST) - 实现加法的过程.


[size=medium][b]注意:
POST方法的映射将返回一个注解了@ResponseBody的Integer类型的整数.
这个注解(@ResponseBody)的意思表示:
Spring将返回的数据自动的转换为Json格式.
要实现@ResponseBody的注解必须导入Jackson的包.[/b][/size]

[b]Jackson是什么?[/b]
[quote]Jackson 是一个 Java 用来处理 JSON 格式数据的类库,性能非常好。[/quote]

我们可以在[url=http://jackson.codehaus.org/]Jackson的官方网站[/url]上了解更多关于jackson的信息.

对于jackson的性能JavaEye已经有同学做了测试.[url=http://hjg1988.iteye.com/blog/561368]json工具性能比较:json-lib和jackson进行Java对象到json字符串序列化[/url]

关于@ResponseBody更多信息可以看Spring官方Blog[url=http://blog.springsource.com/2010/01/25/ajax-simplifications-in-spring-3-0/]Ajax Simplifications in Spring 3.0[/url]


@ResponseBody的用法实在是很简便.

以前我们处理AJAX是用类似下面的代码来进行的.


JSONArray array = JSONArray.fromCollection(list);
PrintWriter out = response.getWriter();
out.write("{datalist:" + array + ",totalPages:" + totalPages
+ ",curPage:" + toPage + ",pageCount:" + pageSize + ",total:"
+ total + "}");
out.flush();
out.close();
return null;


而现在我们只需要在方法返回对象前添加@ResponseBody即可,极大的简化了代码量.


关于JSP页面

[b]ajax-add-page.jsp[/b]


<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!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=UTF-8">

<script type="text/javascript" src="/spring-jquery/resources/js/jquery/jquery-1.4.4.min.js"></script>

<title>Spring MVC - jQuery 整合教程</title>

</head>
<body>

<h3>Spring MVC - jQuery 整合教程</h3>
<h4>AJAX version</h4>

Demo 1
<div style="border: 1px solid #ccc; width: 250px;">
Add Two Numbers: <br/>
<input id="inputNumber1" type="text" size="5"> +
<input id="inputNumber2" type="text" size="5">
<input type="submit" value="Add" onclick="add()" /> <br/>
Sum: <span id="sum">(Result will be shown here)</span>
</div>


<script type="text/javascript">

function add() {
$(function() {
$.post("/spring-jquery/main/ajax/add",
{ inputNumber1: $("#inputNumber1").val(),
inputNumber2: $("#inputNumber2").val() },
function(data){
// data contains the result
// Assign result to the sum id
$("#sum").replaceWith('<span id="sum">'+ data + '</span>');
});
});
}

</script>
</body>
</html>


让我们运行web服务器.
[url]http://localhost:8080/spring-jquery/main/ajax/add[/url]

[img]http://dl.iteye.com/upload/attachment/446590/c7037b66-a127-3ccd-b4d9-00258964ab7c.png[/img]

输入结果后页面将没有任何动静.如果是用firebug.将会得到 $未定义的错误.
实际上就是jquery没有导入.
可是我们导入的路径的确是正确的啊!

出现这个结果的原因在于web.xml中的

<servlet-mapping>
<servlet-name>spring</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>


他能使得我们的URL没有后缀.做到和JavaEye一样的REST风格的URL
而不是类似以前的http://****/**.do

但是这就有个问题了:
他会把所有的资源文件通过DispatcherServlet进行转发.
可是后缀是.js或.css的你转发给谁?
我们以前是用UrlRewriteFilter来进行URL的重定向.
现在我们通过
<mvc:resources location="/resources/" mapping="/resources/**"/>  

来避免DispatcherServlet对静态资源的处理.
但是注意一点.
[b]此功能是在spring3.0.4出现的!所以spring3.0.4之前的版本是没有此注解的[/b]

关于这些方面的信息可以看JavaEye一位同学的Blog:
[url=http://zpball.iteye.com/blog/745440]spring3.0.4 新增加的注解(mvc:resources)[/url]

所以在applicationContext.xml中我们还需要添加
<mvc:resources location="/resources/" mapping="/resources/**"/>  



[b]applicationContext.xml[/b]


<?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:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">

<!-- 激活spring的注解. -->
<context:annotation-config />

<!-- 扫描注解组件并且自动的注入spring beans中.
例如,他会扫描@Controller 和@Service下的文件.所以确保此base-package设置正确. -->
<context:component-scan base-package="org.liukai.tutorial" />

<!-- 配置注解驱动的Spring MVC Controller 的编程模型.注:次标签只在 Servlet MVC工作! -->
<mvc:annotation-driven />

<!-- resources下的静态资源不被DispatcherServlet接收处理 -->
<mvc:resources location="/resources/" mapping="/resources/**"/>

</beans>




重新输入得到的结果:

[img]http://dl.iteye.com/upload/attachment/446592/3c119929-f1ca-3623-b9c7-cf38360d2c53.png[/img]

可以看到结果是显示在同一页上,极大的提高的用户的体验.而不像非AJAX版本那样需要在另外一个页面显示.


[size=x-large][b]总结:[/b][/size]
这样,我们完成了预定的目标:成功的用SpringMVC搭建起了一个简单的基于jQuery的AJAX应用程序.我们还了解了如何利用@ResponseBody和Jackson来进行简便的Json操作.


BTW:附件为本次教程源码.你可以下载后直接在tomcat或其他web服务器启动.也可以自行添加
maven插件启动.
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值