您的位置:首页 > 运维架构 > Apache

Ajax请求数据提示org.apache.struts2.json.JSONException错误

2016-12-28 22:00 561 查看
使用Ajax请求Action中数据,网页提示“org.apache.struts2.json.JSONException”与“java.sql.SQLException: Positioned Update not supported.”错误,如图:



 

笔者发现在程序中确实使用了Ajax与Action交互数据,web页面代码如下所示:

$(function() {	$.post("Inspection_ready.action", null, function(data) {		if (data.Clients.length != 0) {			for ( var i in data.Clients) {				$("<option value='"+data.Clients[i].cid+"'>" +data.Clients[i].cname + "</option>")						.appendTo($("#weituo"));			}		}	});	$("#weituo").change(function() {		$.post("Inspection_selectClientById.action", {			id : $("#weituo").val()		}, function(data) {			$("#simplename").val(data.Client.simplename);			$("#simplename1").val(data.Client.simplename);		});	})}

Action中相应代码如下所示:

public String ready(){	datemap = new HashMap<String,Object>();	List<Client> clients = iinspection.getClientAll();	//集合对象用于封装返回的clients集合数据	datemap.put("Clients", clients);		return SUCCESS;		}
public String selectClientById() { client = iinspection.selectBycid(id); //datemap集合对象,用于封装返回的client数据 datemap.put("Client", client); return SUCCESS;}

Struts2配置文件struts.xml中的设置:

<action name="Inspection_*" class="inspectionAction" method="{1}">	<result  name="success"  type="json" >		<param name="root">datemap</param>	</result></action>

页面加载完毕后首先与服务器交互获取内容,用于为下拉列表初始化数据,当下拉列表切换选项时再与服务器交互根据选中内容检索数据,如图:



但初次交互时并没有出现问题,可以成功返回clients集合,如图所示:



 

说明Struts2的JSON插件可以成功根据集合自动生成JSON数据,但是当列表的change事件触发再次检索数据时,却发生了如题所述错误。

根据提问者描述,如果在Action类型之前添加“@Scope("prototype")”注解,程序出现错误,如果去除此项注解,程序可以正确运行,但返回的结果变为以下效果,如图:



 

这与程序的执行流程不符,因为第二次change检索数据并没有调用ready方法返回clients数据,笔者在调试过程中发现以下关键点:

1. Action注解:

@Controller@Scope("prototype")public class InspectionAction extends ActionSupport 

2. Map注解:

@Resourceprivate Map<String,Object> datemap;

3. Map创建新对象:

datamap = new HashMap<String,Object>();List<Client> clients = iinspection.getClientAll();

我们逐条分析:

1.@Scope注解的作用:表示交由Spring托管对象的作用域,默认情况下作用域为“singleton”,即每次发起请求,都获取Spring容器中相同的对象实例。而Scope取值“prototype”时,表示非单例,即每次发起请求都会创建新的对象。

去掉Action类型之前的“@Scope("prototype")”注解,表示采用Spring的默认设置,即单例模式,此时Action中的所有成员如果没有重新赋值,则保留默认状态,以此可以解释第二次返回结果中为何包含“clients”集合,是由于Action单例,其中的datemap集合常驻容器并未清空。

2.@Resource注解的作用:类中成员属性的自动装配,默认按照属性名称自动装配,如果找不到与名称匹配的bean,则按照类型进行装配。以此可以解释添加“@Scope("prototype")”注解,以非单例方式创建Action并调用selectClientById方法时,可以直接使用datemap对象,而没有抛出NullPointerException异常,是由于Spring自动装配了datemap,而不用手动new此对象。既然datemap可以直接使用,为何还会抛出“JSONException”,经过调试笔者发现,初次访问进入ready()方法时,datemap对象为HashMap<k,v>类型,如图:


 

 

而此二次访问进入selectClientById方法时,datemap为LinkedHashMap类型,如图:



因此可以得出结论了,问题的核心在于datemap = new HashMap<String,Object>();,初次访问时程序员手动构建datemap对象,第二次访问时使用了spring自动装配的datemap对象,默认数值不同,因此JSON无法封装。于是决绝方案也可提出,无论是否对Action添加“@Scope("prototype")”注解,都不是造成本问题的核心原因,手动创建datemap对象才是核心原因,建议datemap之前不要添加注解,其属于此Action专有属性,无需在多个Action间共享,使用时手动开辟空间即可,不需要使用spring自动装配。

本文转自:http://lemmata.blog.163.com/

原文地址:http://lemmata.blog.163.com/blog/static/2686060332016112893556192/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐