网 上有许多关于Struts2与JSON的文章,Google加百度,查阅了许多,有各种各样的做法。其中,大部分的文章都说要加进一个叫 jsonplugin的插件,在Google Code可以下载。以前我有做过测试,也是用它,但着实麻烦,要让Struts2的package继承一个叫“json-default”的父 package。网上的文章,大部分都是说从Struts的Action如何把JSON数据发送回浏览器端(Ajax),而我想要一个跟它们相反的过程 (即从Ajax端发送数据到服务器端的Action并解析出来),却找不到合适的答案。摸索了三个晚上,未果。今天终于让我找到了思路。
其中,不管是从浏览器端(JS,Ajax,Jquery等)发送给服务器端,还是从服务器端(Struts的Action,Servlet等)发送回客户端,都要识别一点:发送的都应该是JSON格式的字符串。
下面,我们先来重写登录模块中的loginform.jsp文件,原来的代码,请看Struts 2.1.6 精简实例系列教程(2):用户登录模块的实现 ,现在修改的代码如下:
<%
@ page language = " java " contentType = " text/html; charset=UTF-8 "
pageEncoding = " UTF-8 "
%>
![](https://i-blog.csdnimg.cn/blog_migrate/1fa987a29c6482f53d401256f96355eb.gif)
<%
@ taglib prefix = " s " uri = " /struts-tags "
%>
<!
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
>
登录页
</
title
>
<
script
type
="text/javascript"
src
="js/jquery-1.3.2.min.js"
></
script
>
![](https://i-blog.csdnimg.cn/blog_migrate/1fa987a29c6482f53d401256f96355eb.gif)
<
script
type
="text/javascript"
>
![](https://i-blog.csdnimg.cn/blog_migrate/97e794c86028c5f5b5461ae5ef440a4c.gif)
$( function ()
{
![](https://i-blog.csdnimg.cn/blog_migrate/d18c02628675d0a2c816449d98bda930.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/97e794c86028c5f5b5461ae5ef440a4c.gif)
$( " #submit " ).click( function ()
{
var loginName1 = $( " input[name='loginName'] " ).val(); // 获取账号
var password1 = $( " input[name='password'] " ).val(); // 获取密码
![](https://i-blog.csdnimg.cn/blog_migrate/97e794c86028c5f5b5461ae5ef440a4c.gif)
var jsonUser =
{loginName:loginName1, password:password1} ; // JSON对象
// 注意:jsonUser.toString()这种方法错误,javaScript中的toString是用于布尔型变量的,而应用以下方法
var strUser = JSON.stringify(jsonUser); // 将JSON对象转变成JSON格式的字符串,
![](https://i-blog.csdnimg.cn/blog_migrate/97e794c86028c5f5b5461ae5ef440a4c.gif)
$.post( " login!valid.action " ,
{json: strUser} , callback, " json " );
} );
![](https://i-blog.csdnimg.cn/blog_migrate/d18c02628675d0a2c816449d98bda930.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/97e794c86028c5f5b5461ae5ef440a4c.gif)
function callback(json)
{
alert(json.msg); // 显示反馈信息
![](https://i-blog.csdnimg.cn/blog_migrate/97e794c86028c5f5b5461ae5ef440a4c.gif)
if (json.suc == 1 )
{ // 如果返回"登录成功"
window.location.href = " admin/index.action " ; // 跳转到后台主页
}
}
} );
</
script
>
</
head
>
<
body
>
![](https://i-blog.csdnimg.cn/blog_migrate/4f1150b881333f12a311ae9ef34da474.gif)
<
form
action
="login.action"
method
="post"
>
账号
<
input
type
="text"
name
="loginName"
/><
br
/>
密码
<
input
type
="password"
name
="password"
><
br
/>
<
input
type
="button"
id
="submit"
value
="登录"
/>
</
form
>
![](https://i-blog.csdnimg.cn/blog_migrate/4f1150b881333f12a311ae9ef34da474.gif)
</
body
>
</
html
>
关键的两句是:
var jsonUser = {loginName:loginName1, password:password1}; (1) var strUser = JSON.stringify(jsonUser); (2) |
第(1)句是组装JSON对象,关于JSON对象的格式,建议大家到http://www.json.org/ 网站上学习一下,要验证你写的JSON对象是否正确,可在http://json.bloople.net/ 网站上验证。上面写的JSON对象其实是非常简单的一种,jsonUser对象里有两个属性,分别是loginName和password,而表示这两个属性,用key-value的形式,loginName1和password1分别是接收表单中的账号、密码的值。
第(2)句,相当重要,通过JavaScript内置对象JSON的stringify方法,将JSON对象转换成字符串。因为,我们传送给服务器端的要是JSON格式的字符串。
$.post("login!valid.action", {json: strUser}, callback, "json"); |
这一句,Jquery用POST方法向服务器端发送数据,login!valid.action是我们要发送到的目的URI,也即直达 loginAction的valid方法。而{…}是我们要发送的数据(data),{json:strUser},其实也是一个JSON对 象,Key:value的形式,大家注意,我们把strUser这个json串发过去,在Action那里接收时,要接收“json”这个变量,这个变量 的值就是我们发送的strUser字符串。
回调函数(callback)是指服务器端成功发回时,在JS端执行的函数。最后一个参数“json”是返回数据类型的一种,另外,还有”text”、“xml”等。而function callback函数体的内容,大家看完LoginAction类后,自然会明白。
好,Show一下修改后的LoginAction.java,代码如下:
package
cn.simple.action;
![](https://i-blog.csdnimg.cn/blog_migrate/4f1150b881333f12a311ae9ef34da474.gif)
import
java.io.IOException;
import
javax.servlet.http.HttpServletResponse;
import
org.apache.struts2.ServletActionContext;
import
org.apache.struts2.convention.annotation.Result;
import
org.apache.struts2.convention.annotation.Results;
import
org.json.JSONObject;
import
cn.simple.manager.UserManager;
import
cn.simple.pojo.User;
import
com.opensymphony.xwork2.ActionSupport;
![](https://i-blog.csdnimg.cn/blog_migrate/4f1150b881333f12a311ae9ef34da474.gif)
//
@Results({
//
@Result(name="success", location="admin/index.action", type="redirect"),
//
@Result(name="input", location="loginform.jsp", type="dispatcher")
//
})
![](https://i-blog.csdnimg.cn/blog_migrate/1fa987a29c6482f53d401256f96355eb.gif)
public
class
LoginAction
extends
ActionSupport
{
![](https://i-blog.csdnimg.cn/blog_migrate/d18c02628675d0a2c816449d98bda930.gif)
private String json; // JSON字符串,JS与Action传递数据的载体
![](https://i-blog.csdnimg.cn/blog_migrate/97e794c86028c5f5b5461ae5ef440a4c.gif)
public String getJson()
{
return json;
}
![](https://i-blog.csdnimg.cn/blog_migrate/97e794c86028c5f5b5461ae5ef440a4c.gif)
public void setJson(String json)
{
this .json = json;
}
![](https://i-blog.csdnimg.cn/blog_migrate/d18c02628675d0a2c816449d98bda930.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/97e794c86028c5f5b5461ae5ef440a4c.gif)
/** */ /**
* 登录验证
* @throws Exception
*/
![](https://i-blog.csdnimg.cn/blog_migrate/97e794c86028c5f5b5461ae5ef440a4c.gif)
public void valid() throws Exception
{
JSONObject jsonObj = new JSONObject(json); // 将JSON格式的字符串构造成JSON对象
String loginName = jsonObj.getString( " loginName " ); // 获取JSON对象中的loginName属性的值
String password = jsonObj.getString( " password " ); // 获取JSON对象中的password属性的值
User user = UserManager.selectUserByLoginName(loginName); // 查询是否有用户名存在
![](https://i-blog.csdnimg.cn/blog_migrate/97e794c86028c5f5b5461ae5ef440a4c.gif)
if (user == null )
{
// 此时的JSON对象,有两个属性suc和msg,其中suc表示是否登录成功的状态
json = " {suc:0, msg:'用户名不存在'} " ; // 构造JSON格式的字符串
![](https://i-blog.csdnimg.cn/blog_migrate/97e794c86028c5f5b5461ae5ef440a4c.gif)
} else if ( ! password.equals(user.getPassword()))
{
json = " {suc:0, msg:'密码不正确!'} " ;
![](https://i-blog.csdnimg.cn/blog_migrate/97e794c86028c5f5b5461ae5ef440a4c.gif)
} else
{
json = " {suc:1, msg:'登录成功!'} " ;
}
sendMsg(json); // 发送JSON格式的字符串回JS端
}
![](https://i-blog.csdnimg.cn/blog_migrate/97e794c86028c5f5b5461ae5ef440a4c.gif)
/** */ /**
* 向客户端的JS发送字符串
* @param content 发送的内容
* @throws IOException
*/
![](https://i-blog.csdnimg.cn/blog_migrate/97e794c86028c5f5b5461ae5ef440a4c.gif)
public void sendMsg(String content) throws IOException
{
HttpServletResponse response = ServletActionContext.getResponse();
response.setCharacterEncoding( " UTF-8 " );
response.getWriter().write(content);
}
}
我们说过了,JS与Action互相传送的是JSON格式的字符串,故在LoginAction里,我们定义了private String json这个成员属性及其getter和setter方法。
大家注意,在valid方法体中,引进了org.json.JSONObject,这个类哪里来?请看:http://www.json.org/java/index.html ,这里有几个处理JSON数据常用的类:JSONObject.java
,JSONArray.java
,JSONStringer.java
,JSONWriter.java
,JSONTokener.java
,JSONException.java
,JSONString.java
,将它们下载下来,放到项目中,如下:
或者,打成jar包,放到项目lib目录下。我们就可以使用JSON类库提供给我们的方法了。
网上有另一个JSON的类库:json-lib,大家也可下载使用一下,不过,它要引进几个其他的jar包,详细请见http://json-lib.sourceforge.net/ 。个人使用它的感受,也真有点郁闷,测试它时,想找一个从JSON字符串转换成JSON对象的方法,找了半天也没找到。不过,它对Java的Bean,Map,List等与JSONObject的互转换做得还好。
sendMsg方法,是从Struts的Action中调用回原生Servlet的response来向浏览器端发送数据。
还有一点,大家应该注意到,我们在LoginAction中写的valid方法返回类型是void型的,跟我们以前做的返回“success”、 ”input”之类的String类型不同。当我们通过 “!valid”来方法它时,它不作跳转,而是像我们平时Servlet中那种直接显示HTML类似。这一点达成了Ajax与Struts的成功交互。而 网上许多写jsonplugin插件使用的文章,所调用的方法都是返回String类型,然后,再来个<result type=”json”>,那样感觉挺麻烦的,不如直接让Ajax发来的请求与void类型的方法交互,不直接爽快?
好,让我们运行一下,看看效果吧:
大家看看fireFox的debug的控制台中显示的:
好,我们来输入一个正确的账号和密码,如下:
点确定后,网页就跳到了后台主页。
这样,Ajax(Jquery)与Struts2.1.6的交互,通过JSON格式的字符串传递数据,这一实践就完成了。有一点需要说明一下:本例 中的JSON对象都是相对比较简单,还有一些复杂的JSON对象,如{company:{building:”五角大楼”,employees: [{name:”tom”,age:21},{name:”marry”,age:18} ] } }。至于这些,该怎么处理呢?其实,处理方法也一样的。只是在Action中调用JSON类库的一些对象和方法,就能很好地处理。
关于Struts2,JSON,Jquery的话题,我们会在Struts2.1.6精简实例系列教程之外,继续讨论。
本文原创,转载请注明出处,谢谢!http://www.blogjava.net/rongxh7 (心梦帆影JavaEE技术博客)