Struts2提供了对Ajax的支持,其中JSON是Ajax插件的一种,该插件将Action属性直接序列化为JSON对象后返回给客户端,从而使客户端页面可以直接访问到Action属性。
在Struts2中使用JSON插件,首次将json插件包导入进去,接着实现Action逻辑,在struts.xml中配置该Action,然后实现JSP页面。下面来实现一个小例子,来完成这三个步骤。
1、实现Action逻辑
一个表单,有三个表单域,对应于三个请求参数,因此在Action中用三个相应的属性来封装这三个参数。Action的实现类如下:
package lee;
import java.util.HashMap;
import java.util.Map;
import javax.management.loading.PrivateClassLoader;
import com.opensymphony.xwork2.Action;
import com.opensymphony.xwork2.ActionContext;
import com.sun.org.apache.bcel.internal.generic.NEW;
import org.apache.struts2.json.annotations.JSON;
//import org.apache.struts2.json.*;
public class JSONExample {
private int[] ints={10,20};
private Map<String,String> map = new HashMap<String,String>();
private String customName="顾客";
private String field1;
private transient String field2;
private String field3;
public String execute(){
map.put("name", "wo");
return Action.SUCCESS;
}
@JSON(name="newName")
public Map getMap(){
return this.map;
}
public void setCustomName(String customName) {
this.customName = customName;
}
public String getCustomName() {
return customName;
}
public void setField1(String field1) {
this.field1 = field1;
}
public String getField1() {
return field1;
}
public void setField2(String field2) {
this.field2 = field2;
}
public String getField2() {
return field2;
}
public void setField3(String field3) {
this.field3 = field3;
}
public String getField3() {
return field3;
}
}
上面代码中使用了JSON注释,指定了name属性,作用于下面所以的getter方法,只要属性的getter方法在注释下,则JSon就会返回给客户端。
2、在struts2.xml中配置Action
<package name="example" extends="json-default"> <action name="JSONExample" class="lee.JSONExample"> <result type="json"/> </action> </package>
JSON插件提供一种名为json的ResultType,一旦为某个Action指定了类型为json的result,就不不要再映射到任何的物理视图。因为JSON插件会负责将Action里的状态信息序列化成JSON格式的字符串,并将该字符串返回给客户端页面。
配置时需注意:a 配置strut.i18n.encoding时,编码格式要改为UTF-8编码,因为Ajax的post请求是以UTF-8的方式进 行编码的。
b 配置包时,要继承json-default包,因为只有此包里才定义了json结果类型,可在json插件包里找到 struts-plugin.xml查看里面json-default包的定义,该包实际上继承了default包
3、实现JSP页面
为方面Ajax交互,我们使用javascript的一个框架Prototype.js.同时还要用json2.js库,用于将JSON格式字符串转换成JSON对象。下面是JSP页面:
<%@ page language="java" import="java.util.*" pageEncoding="GBK"%> <% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <base href="<%=basePath%>"> <title>My JSP 'jsonDemo.jsp' starting page</title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> <meta http-equiv="description" content="This is my page"> <!-- <link rel="stylesheet" type="text/css" href="styles.css"> --> <script type="text/javascript" src=json2.js></script> <script type="text/javascript" src=prototype.js></script> <script type=text/javascript> function gotClick(){ var url='JSONExample.action'; var params=Form.serialize('form1'); var myAjax = new Ajax.Request(url,{ method:'post', parameters:params, onComplete:processResponse, asynchronous:true }); } function processResponse(request){ var res = JSON.parse(request.responseText); for(var propName in res){ $("show").innerHTML+=propName+"-->"+res[propName]+"</br>"; } } </script> </head> <body> <form id="form1" name="form1"> field1:<input type="text" name="field1" id="field1"/><br> field2:<input type="text" name="field2" id="field2"/><br> field3:<input type="text" name="field3" id="field3"/><br> <input type="button" value="提交" onclick="gotClick()"/> </form> <div id="show"> </div> </body> </html>
上述页面使用Prototype.js中是Ajax.Request来进行Ajax交互。
完成,测试。
不太顺利,先出现了There is no Action mapped for namespace / and action name JSONExample. 的错误,就是找不到action,将json-default包换成default可以找到action,说明是jar包版本的问题,因为json-default是在json插件jar包里的struts-plugin.xml里定义的。仔细看启动日志,发现找不到json-default的包,于是将struts-plugin.xml重新显式引入了一下,但是此时可以找到了,又出现了新的问题
Result class [org.apache.struts2.json.JSONResult] doesn't exist (ClassNotFoundException) at result-type -
java.lang.ClassNotFoundException:org.apache.struts2.json.JSONResult,即虽然找到了json-default包但是其中定义的result为json的实现类却找不到,下面是struts-plugin.xml:
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE struts (View Source for full doctype...)> - <struts> - <package name="json-default" extends="struts-default"> - <result-types> <result-type name="json" class="org.apache.struts2.json.JSONResult" default="false" /> </result-types> - <interceptors> <interceptor name="json" class="org.apache.struts2.json.JSONInterceptor" /> </interceptors> </package> </struts>
说明jar还是没有发挥作用,于是将插件包jsonplugin-0.34.jar换成struts2-json-plugin-2.1.8.jar包,问题彻底解决,看来就是版本的问题啊!
总结:遇到问题首先要找出原因,仔细分析,并多借助网络。问题解决后要善于总结!