JSON数据的传递在客户端与服务器的通信过程中,有服务器向客户端传送JSON数据,其核心过程中将对象转换成JSON;还有客户端向服务器传送JSON数据,其核心是将JSON转换成对象。JSON数据在传递过程中,其实就是传递一个普通的符合JSON语法格式的字符串而已,而“JSON对象”是指对这个JSON字符串解析和包装后的结果。
Struts2返回JSON数据到客户端:
在Struts2的MVC模型中,对于Struts而言,返回JSON数据到客户端,跟传统的WEB应用一样,存在两种方式,即在Action中输出JSON数据和在视图资源中输出JSON数据。在Action中输出JSON数据又分为两种方式,一是使用传统方式输出自己包装后的JSON数据,二是使用Struts自带的JSON数据封装功能来自动包装并返回JSON数据。
在视图资源中输出JSON数据:
Action处理完用户请求后,将数据存放在某一位置,如request中,并返回视图,然后Struts将跳转至该视图资源,在该视图中,我们需要做的是将数据从存放位置中取出,然后将其转换为JSON字符串,输出在视图中。这跟传统WEB应用中在JSP页面输出JSON数据的做法如出一辙。这里主要讲方法,数据类型不一定非得是JSON类型,所以下面的Demo1的方法即可,使用时把Demo1中的数据类型换成JSON类型即可。
Demo1说明:在login.jsp页面中,如果用户名(admin)和密码(123456)都正确,那么转发到success.jsp页面,在success.jsp页面中取到动作类中存入session和valuestack以及动作类中的值。登录界面如图1所示。
图1 登录界面
Login.jsp代码:
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
<%@ 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=GB18030">
<title>Insert title here</title>
</head>
<body>
<s:form action="loginAction">
<s:textfield name="user.username" label="用户名"></s:textfield>
<s:password name="user.password" label="密 码"></s:password>
<s:submit value="登录"></s:submit>
</s:form>
</body>
</html>
Struts.xml代码:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.1.7//EN"
"http://struts.apache.org/dtds/struts-2.1.7.dtd">
<struts>
<constant name="struts.devMode" value="true"></constant>
<package name="struts2" extends="struts-default" >
<action name="loginAction" class="com.bugs.action.LoginAction" method="log">
<result name="success" type="dispatcher">/success.jsp</result>
<result name="login">/login.jsp</result>
</action>
</package>
</struts>
动作类代码:
package com.bugs.action;
import javax.servlet.http.HttpSession;
import org.apache.struts2.ServletActionContext;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.util.ValueStack;
public class LoginAction extends ActionSupport {
private static final long serialVersionUID = -8306294891174067845L;
private User user;
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public String log() {
if("admin".equals(user.getUsername())&&"123456".equals(user.getPassword())){
System.out.println(user.getUsername()+"&"+user.getPassword());
HttpSession session= ServletActionContext.getRequest().getSession();
session.setAttribute("sessionMap", "在success.jsp页面取到ActonContext中的数据");//向session中存值。取时注意使用#
ActionContext context = ActionContext.getContext();
ValueStack vs = context.getValueStack();
vs.push(user);//向值栈中存值,取出时不用#
return SUCCESS;
}
else{
// System.out.println(user.getUsername()+"&"+user.getPassword());
return LOGIN;
}
}
}
Success.jsp代码:
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
<%@ 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=GB18030">
<title>Insert title here</title>
</head>
<body>
sessionMap:<s:property value="#session.sessionMap"/>!
<br />
欢迎用户(通过动作类):<s:property value="user.username"/>!<br />
欢迎用户(通过前面的栈操作):<s:property value="username"/>!
<s:debug />
</body>
</html>
这个Demo的效果如图2所示。
图二 Demo1的success.jsp结果
在Action中以传统方式输出JSON数据
这种方式的Action没有返回值,通过response.getWriter().print(JSONObject.fromObject(对象).toString())返回json类型的字符串。具体情况见Demo2:在json_demo.jsp页面输入表单内容,在动作类JsonAction.java中获取表单值,并以json类型返回到json_demo.jsp页面,并且加以显示。
json_demo.jsp代码:
<%@ 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>struts+ajax返回json类型数据</title>
<link rel="stylesheet" type="text/css" href="styles/base.css" />
<script type="text/javascript" src="scripts/jquery-1.8.2.js"></script>
</head>
<body>
<div id="div_json">
<h5>录入数据</h5>
<br />
<form action="#" method="post">
<label for="name">姓名:</label><input type="text" name="name" />
<label for="age">年龄:</label><input type="text" name="age" />
<label for="position">职务:</label><input type="text" name="position" />
<input type="button" class="btn" value="提交结果"/>
</form>
<br />
<h5>显示结果</h5>
<br />
<ul>
<li>姓名:<span id="s_name">尚无数据</span></li>
<li class="li_layout">年龄:<span id="s_age">尚无数据</span></li>
<li class="li_layout">职务:<span id="s_position">尚无数据</span></li>
</ul>
</div>
<script type="text/javascript">
/* 提交结果,执行ajax */
function btn(){
var $btn = $("input.btn");//获取按钮元素
//给按钮绑定点击事件
$btn.bind("click",function(){
$.ajax({
type:"post",
url:"excuteAjaxJsonAction",//需要用来处理ajax请求的action,excuteAjax为处理的方法名,JsonAction为action名
data:{//设置数据源
name:$("input[name=name]").val(),
age:$("input[name=age]").val(),
position:$("input[name=position]").val()//这里不要加"," 不然会报错,而且根本不会提示错误地方
},
dataType:"json",//设置需要返回的数据类型 A
success:function(data){
alert(data);
// var d = eval("("+data+")"); //B
//A与B留一句就可以
alert(JSON.stringify(data));
$("#s_name").text(""+data.name+"");
$("#s_age").text(data.age);
$("#s_position").text(data.position);
},
error:function(){
alert("系统异常,请稍后重试!");
}//这里不要加","
});
});
}
/* 页面加载完成,绑定事件 */
$(document).ready(function(){
btn();//点击提交,执行ajax
});
</script>
</body>
</html>
Struts.xml代码:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.1.7//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
<!--解决乱码 -->
<constant name="struts.i18n.encoding" value="UTF-8"></constant>
<constant name="struts.devMode" value="true"></constant>
<package name="simpleton" extends="struts-default,json-default">
<action name="*JsonAction" method="{1}" class="com.simpleton.demo.action.JsonAction">
</action>
</package>
</struts>
JsonAction.java代码:
package com.simpleton.demo.action;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts2.ServletActionContext;
import org.apache.struts2.interceptor.ServletRequestAware;
import com.opensymphony.xwork2.ActionSupport;
import net.sf.json.JSONObject;
public class JsonAction extends ActionSupport implements ServletRequestAware{
private static final long serialVersionUID = 1L;
private HttpServletRequest request;
private String result;
public void setServletRequest(HttpServletRequest arg0) {
this.request = arg0;
}
/**
* 处理ajax请求
* @throws IOException
*/
public void excuteAjax() throws IOException{
HttpServletResponse response = ServletActionContext.getResponse();
try {
//获取数据
String name = request.getParameter("name");
int age = Integer.parseInt(request.getParameter("age"));
String position = request.getParameter("position");
//将数据存储在map里,再转换成json类型数据,也可以自己手动构造json类型数据
Map<String,Object> map = new HashMap<String,Object>();
map.put("name", name);
map.put("age",age);
map.put("position", position);
JSONObject json = JSONObject.fromObject(map);//将map对象转换成json类型数据
result = json.toString();//给result赋值,传递给页面
System.out.println(result);
} catch (Exception e) {
e.printStackTrace();
}
response.getWriter().print(result);
}
}
开始时,json_demo.jsp页面如图3所示。点击了“提交结果”之后如图4所示。
图3 开始时的json_demo.jsp页面
图4 点击了“提交结果”之后的结果
在Action中以Struts2的方式输出JSON数据
struts2提供了一个struts2-json-plugin.jar用于支持JSON的使用。当我们在struts2中使用JSON的时候必须导入struts2-json-plugin.jar。必须要继承struts2-json-plugin.jar中struts-plugin.xml文件中的定义的json-default。只要extends="json-default",json拦截器是默认配置上的,可以不配。result设置成json之后,容器会把action的属性自动封装到一个json对象中(json拦截器来做),然后调用js的回调方法,返回json数据。下面通过Demo3、Demo4、Demo5、Demo6、Demo7几个Demo来详细分析。(Demo在笔记本E:\AAAAAAAAAAAAAAA世界名校公开课\技术总结\Struts2学习的小例子\struts-json文件夹下)。
Demo3:
在json_demo.jsp页面输入表单内容,在动作类JsonAction.java中获取表单值,并以json类型将表单值以及后台的message属性的值都返回到json_demo.jsp页面,并且加以显示。
json_demo.jsp代码:
<%@ 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>struts+ajax返回json类型数据</title>
<script type="text/javascript" src="scripts/jquery-1.8.2.js"></script>
<link rel="shortcut icon" type="image/x-icon" href="images/Icon.png" />
<link rel="stylesheet" type="text/css" href="styles/base.css" />
</head>
<div id="div_json">
<h5>录入数据</h5>
<br />
<form action="#" method="post">
<label for="name">姓名:</label><input type="text" name="name" />
<label for="age">年龄:</label><input type="text" name="age" />
<label for="position">职务:</label><input type="text" name="position" />
<input type="button" class="btn" value="提交结果"/>
</form>
<br />
<h5>显示结果</h5>
<br />
<ul>
<li>姓名:<span id="s_name">尚无数据</span></li>
<li class="li_layout">年龄:<span id="s_age">尚无数据</span></li>
<li class="li_layout">职务:<span id="s_position">尚无数据</span></li>
<li class="li_layout">消息:<span id="s_message">尚无数据</span></li>
</ul>
</div>
<script type="text/javascript">
/* 提交结果,执行ajax */
function btn(){
var $btn = $("input.btn");//获取按钮元素
//给按钮绑定点击事件
$btn.bind("click",function(){
$.ajax({
type:"post",
url:"excuteAjaxJsonAction",//需要用来处理ajax请求的action,excuteAjax为处理的方法名,JsonAction为action名
data:{//设置数据源
name:$("input[name=name]").val(),
age:$("input[name=age]").val(),
position:$("input[name=position]").val()//这里不要加"," 不然会报错,而且根本不会提示错误地方
},
dataType:"json",//设置需要返回的数据类型,因为struts.xml中<result name="success" type="json"></result>配置,且没有root属性,因此有没有这一句,后台都会直接返回json类型对象
success:function(data){
alert(data);//数据过来就是json类型----->[object Object]
alert(JSON.stringify(data));//将data转化为字符串弹框--->{"message":"后台数据","result":"{"position":"学生","age":"22","name":"孙小明"}"}
alert(data.message);//字符串---->"后台数据"
alert(data.result);//字符串---->"{"position":"学生","age":"22","name":"孙小明"}"
var data_result = eval("("+data.result+")");//将result由字符串解析成json数据类型的对象
alert(Object.prototype.toString.call(data.message));//String类型对象------>[object String]
alert(Object.prototype.toString.call(data_result));//json类型对象---->[object Object]
alert(data.message);//String类型对象--->后台数据
alert(data_result);//json类型对象---->[object Object]
$("#s_name").text(""+data_result.name+"");
$("#s_age").text(""+data_result.age+"");
$("#s_position").text(""+data_result.position+"");
$("#s_message").text(""+data.message+"");
},
error:function(){
alert("系统异常,请稍后重试!");
}//这里不要加","
});
});
}
/* 页面加载完成,绑定事件 */
$(document).ready(function(){
btn();//点击提交,执行ajax
});
</script>
</body>
</html>
Struts.xml代码:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.1.7//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
<!--解决乱码 -->
<constant name="struts.i18n.encoding" value="UTF-8"></constant>
<constant name="struts.devMode" value="true"></constant>
<package name="simpleton" extends="json-default">
<action name="*JsonAction" method="{1}" class="com.simpleton.demo.action.JsonAction">
<result name="fail"></result>
<!-- 返回json类型数据 -->
<result name="success" type="json">
</result>
</action>
</package>
</struts>
JsonAction.java代码:
package com.simpleton.demo.action;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import net.sf.json.JSONObject;
import org.apache.struts2.interceptor.ServletRequestAware;
import com.opensymphony.xwork2.ActionSupport;
public class JsonAction extends ActionSupport implements ServletRequestAware{
private static final long serialVersionUID = 1L;
private HttpServletRequest request;
private String result;
private String message;
public void setServletRequest(HttpServletRequest arg0) {
this.request = arg0;
}
public String getResult() {
return result;
}
public void setResult(String result) {
this.result = result;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
/**
* 处理ajax请求
* @return SUCCESS
*/
public String excuteAjax(){
try {
//获取数据
String name = request.getParameter("name");
int age = Integer.parseInt(request.getParameter("age"));
String position = request.getParameter("position");
this.setMessage("后台数据");
//将数据存储在map里,再转换成json类型数据,也可以自己手动构造json类型数据
Map<String,Object> map = new HashMap<String,Object>();
map.put("name", name);
map.put("age",age);
map.put("position", position);
JSONObject json = JSONObject.fromObject(map);//将map对象转换成json类型数据
result = json.toString();//给result赋值,传递给页面
} catch (Exception e) {
e.printStackTrace();
}
return SUCCESS;
}
}
开始时,json_demo.jsp页面如图5所示。点击了“提交结果”之后如图6所示。
图5 开始时的json_demo.jsp页面
图6 点击了“提交结果”之后的结果
Demo4:
在json_demo.jsp页面输入表单内容,在动作类JsonAction.java中获取表单值,并通过在struts.xml中配置<param name="root">result</param>,使得以json类型只将表单值返回到json_demo.jsp页面,并且加以显示。
json_demo.jsp代码:
<%@ 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>struts+ajax返回json类型数据</title>
<script type="text/javascript" src="scripts/jquery-1.8.2.js"></script>
<link rel="shortcut icon" type="image/x-icon" href="images/Icon.png" />
<link rel="stylesheet" type="text/css" href="styles/base.css" />
</head>
<div id="div_json">
<h5>录入数据</h5>
<br />
<form action="#" method="post">
<label for="name">姓名:</label><input type="text" name="name" />
<label for="age">年龄:</label><input type="text" name="age" />
<label for="position">职务:</label><input type="text" name="position" />
<input type="button" class="btn" value="提交结果"/>
</form>
<br />
<h5>显示结果</h5>
<br />
<ul>
<li>姓名:<span id="s_name">尚无数据</span></li>
<li class="li_layout">年龄:<span id="s_age">尚无数据</span></li>
<li class="li_layout">职务:<span id="s_position">尚无数据</span></li>
<!-- <li class="li_layout">消息:<span id="s_message">尚无数据</span></li> -->
</ul>
</div>
<script type="text/javascript">
/* 提交结果,执行ajax */
function btn(){
var $btn = $("input.btn");//获取按钮元素
//给按钮绑定点击事件
$btn.bind("click",function(){
$.ajax({
type:"post",
url:"excuteAjaxJsonAction",//需要用来处理ajax请求的action,excuteAjax为处理的方法名,JsonAction为action名
data:{//设置数据源
name:$("input[name=name]").val(),
age:$("input[name=age]").val(),
position:$("input[name=position]").val()//这里不要加"," 不然会报错,而且根本不会提示错误地方
},
dataType:"json",//设置需要返回的数据类型,因为struts.xml中<result name="success" type="json"><param name="root">result</param></result>配置,只要有root属性,无论有没有设置dataType这一句,后台都会直接返回json类型对象的字符串形式
success:function(data){
alert(data);//数据过来是字符串形式,因为设置了<param name="root">result</param>,所以只返回action动作类中的result属性,message属性不反回。----->"{"position":"学生","age":"22","name":"孙明明"}"
var data_result = eval("("+data+")");//将result由字符串解析成json数据类型的对象
alert(Object.prototype.toString.call(data_result));//json类型对象---->[object Object]
alert(data_result);//json类型对象---->[object Object]
$("#s_name").text(""+data_result.name+"");
$("#s_age").text(""+data_result.age+"");
$("#s_position").text(""+data_result.position+"");
/* $("#s_message").text(""+data_message+""); */
},
error:function(){
alert("系统异常,请稍后重试!");
}//这里不要加","
});
});
}
/* 页面加载完成,绑定事件 */
$(document).ready(function(){
btn();//点击提交,执行ajax
});
</script>
</body>
</html>
struts.xml代码:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.1.7//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
<!--解决乱码 -->
<constant name="struts.i18n.encoding" value="UTF-8"></constant>
<constant name="struts.devMode" value="true"></constant>
<package name="simpleton" extends="json-default">
<action name="*JsonAction" method="{1}" class="com.simpleton.demo.action.JsonAction">
<result name="fail"></result>
<!-- 返回json类型数据 -->
<result name="success" type="json">
<param name="root">result</param> <!-- result是action中设置的变量名,也是页面需要返回的数据,该变量必须有setter和getter方法 -->
</result>
</action>
</package>
</struts>
JsonAction.java代码:
package com.simpleton.demo.action;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import net.sf.json.JSONObject;
import org.apache.struts2.interceptor.ServletRequestAware;
import com.opensymphony.xwork2.ActionSupport;
public class JsonAction extends ActionSupport implements ServletRequestAware{
private static final long serialVersionUID = 1L;
private HttpServletRequest request;
private String result;
private String message;
public void setServletRequest(HttpServletRequest arg0) {
this.request = arg0;
}
public String getResult() {
return result;
}
public void setResult(String result) {
this.result = result;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
/**
* 处理ajax请求
* @return SUCCESS
*/
public String excuteAjax(){
try {
//获取数据
String name = request.getParameter("name");
int age = Integer.parseInt(request.getParameter("age"));
String position = request.getParameter("position");
this.setMessage("message中的消息");
//将数据存储在map里,再转换成json类型数据,也可以自己手动构造json类型数据
Map<String,Object> map = new HashMap<String,Object>();
map.put("name", name);
map.put("age",age);
map.put("position", position);
JSONObject json = JSONObject.fromObject(map);//将map对象转换成json类型数据
result = json.toString();//给result赋值,传递给页面
} catch (Exception e) {
e.printStackTrace();
}
return SUCCESS;
}
}
开始时,json_demo.jsp页面如图7所示。点击了“提交结果”之后如图8所示。
图7 开始时,json_demo.jsp页面
图8 点击了“提交结果”之后的json_demo.jsp页面
Demo5:
在json_demo.jsp页面输入表单内容,在动作类JsonAction.java中获取表单值,并通过在struts.xml中配置<param name="includeProperties">result</param>,使得以json类型只将表单值返回到json_demo.jsp页面,并且加以显示。
json_demo.jsp代码:
<%@ 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>struts+ajax返回json类型数据</title>
<script type="text/javascript" src="scripts/jquery-1.8.2.js"></script>
<link rel="shortcut icon" type="image/x-icon" href="images/Icon.png" />
<link rel="stylesheet" type="text/css" href="styles/base.css" />
</head>
<div id="div_json">
<h5>录入数据</h5>
<br />
<form action="#" method="post">
<label for="name">姓名:</label><input type="text" name="name" />
<label for="age">年龄:</label><input type="text" name="age" />
<label for="position">职务:</label><input type="text" name="position" />
<input type="button" class="btn" value="提交结果"/>
</form>
<br />
<h5>显示结果</h5>
<br />
<ul>
<li>姓名:<span id="s_name">尚无数据</span></li>
<li class="li_layout">年龄:<span id="s_age">尚无数据</span></li>
<li class="li_layout">职务:<span id="s_position">尚无数据</span></li>
<!-- <li class="li_layout">消息:<span id="s_message">尚无数据</span></li> -->
</ul>
</div>
<script type="text/javascript">
/* 提交结果,执行ajax */
function btn(){
var $btn = $("input.btn");//获取按钮元素
//给按钮绑定点击事件
$btn.bind("click",function(){
$.ajax({
type:"post",
url:"excuteAjaxJsonAction",//需要用来处理ajax请求的action,excuteAjax为处理的方法名,JsonAction为action名
data:{//设置数据源
name:$("input[name=name]").val(),
age:$("input[name=age]").val(),
position:$("input[name=position]").val()//这里不要加"," 不然会报错,而且根本不会提示错误地方
},
dataType:"json",//设置需要返回的数据类型,因为struts.xml中<result name="success" type="json"><param name="includeProperties">result</param></result>配置,没有root属性,无论有没有设置dataType这一句(因为struts.xml中配置了type="json"),后台都会直接返回json类型对象[object Object](测试过了)
success:function(data){
alert(data);//json类型对象[object Object],因为设置了<param name="includeProperties">result</param>,所以只返回action动作类中的result属性,message属性不反回。
alert(JSON.stringify(data));//将返回的data的字符串类型----->"{"result":"{"position":"学生","age":"22","name":"孙明明"}"}"
alert(Object.prototype.toString.call(data));//json类型对象---->[object Object]
alert(data);//json类型对象---->[object Object]
alert(data.result);//字符串类型--->"{"position":"学生","age":"22","name":"孙明明"}"
var data_result = eval("("+data.result+")");
alert(data_result);
$("#s_name").text(""+data_result.name+"");
$("#s_age").text(""+data_result.age+"");
$("#s_position").text(""+data_result.position+"");
/* $("#s_message").text(""+data_message+""); */
},
error:function(){
alert("系统异常,请稍后重试!");
}//这里不要加","
});
});
}
/* 页面加载完成,绑定事件 */
$(document).ready(function(){
btn();//点击提交,执行ajax
});
</script>
</body>
</html>
struts.xml代码:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.1.7//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
<!--解决乱码 -->
<constant name="struts.i18n.encoding" value="UTF-8"></constant>
<constant name="struts.devMode" value="true"></constant>
<package name="simpleton" extends="json-default">
<action name="*JsonAction" method="{1}" class="com.simpleton.demo.action.JsonAction">
<result name="fail"></result>
<!-- 返回json类型数据,不设置root就是以action动作类作为root -->
<result name="success" type="json">
<param name="includeProperties">result</param>
</result>
</action>
</package>
</struts>
JsonAction.java代码:
package com.simpleton.demo.action;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import net.sf.json.JSONObject;
import org.apache.struts2.interceptor.ServletRequestAware;
import com.opensymphony.xwork2.ActionSupport;
public class JsonAction extends ActionSupport implements ServletRequestAware{
private static final long serialVersionUID = 1L;
private HttpServletRequest request;
private String result;
private String message;
public void setServletRequest(HttpServletRequest arg0) {
this.request = arg0;
}
public String getResult() {
return result;
}
public void setResult(String result) {
this.result = result;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
/**
* 处理ajax请求
* @return SUCCESS
*/
public String excuteAjax(){
try {
//获取数据
String name = request.getParameter("name");
int age = Integer.parseInt(request.getParameter("age"));
String position = request.getParameter("position");
this.setMessage("message中的消息");
//将数据存储在map里,再转换成json类型数据,也可以自己手动构造json类型数据
Map<String,Object> map = new HashMap<String,Object>();
map.put("name", name);
map.put("age",age);
map.put("position", position);
JSONObject json = JSONObject.fromObject(map);//将map对象转换成json类型数据
result = json.toString();//给result赋值,传递给页面
} catch (Exception e) {
e.printStackTrace();
}
return SUCCESS;
}
}
图9 开始时,json_demo.jsp页面
图10 点击了“提交结果”之后的json_demo.jsp页面
Demo6:
在json_demo.jsp页面输入表单内容,在动作类JsonAction.java中获取表单值,并将表单值封装成Result对象,并将该对象转化为json数据类型的字符串形式,并通过在struts.xml中配置<param name="root">result</param>,使得以json类型只将表单值返回到json_demo.jsp页面,并且加以显示。
json_demo.jsp代码:
<%@ 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>struts+ajax返回json类型数据</title>
<script type="text/javascript" src="scripts/jquery-1.8.2.js"></script>
<link rel="shortcut icon" type="image/x-icon" href="images/Icon.png" />
<link rel="stylesheet" type="text/css" href="styles/base.css" />
</head>
<div id="div_json">
<h5>录入数据</h5>
<br />
<form action="#" method="post">
<label for="name">姓名:</label><input type="text" name="name" />
<label for="age">年龄:</label><input type="text" name="age" />
<label for="position">职务:</label><input type="text" name="position" />
<input type="button" class="btn" value="提交结果"/>
</form>
<br />
<h5>显示结果</h5>
<br />
<ul>
<li>姓名:<span id="s_name">尚无数据</span></li>
<li class="li_layout">年龄:<span id="s_age">尚无数据</span></li>
<li class="li_layout">职务:<span id="s_position">尚无数据</span></li>
<!-- <li class="li_layout">消息:<span id="s_message">尚无数据</span></li> -->
</ul>
</div>
<script type="text/javascript">
/* 提交结果,执行ajax */
function btn(){
var $btn = $("input.btn");//获取按钮元素
//给按钮绑定点击事件
$btn.bind("click",function(){
$.ajax({
type:"post",
url:"excuteAjaxJsonAction",//需要用来处理ajax请求的action,excuteAjax为处理的方法名,JsonAction为action名
data:{//设置数据源
name:$("input[name=name]").val(),
age:$("input[name=age]").val(),
position:$("input[name=position]").val()//这里不要加"," 不然会报错,而且根本不会提示错误地方
},
dataType:"json",//设置需要返回的数据类型
success:function(data){
alert(data);//json类型对象的字符串形式--->"{"position":"学生","age":"22","name":"孙明明"}",因为设置了<param name="root">result</param>,所以只返回action动作类中的result属性,message属性不反回。
alert(Object.prototype.toString.call(data));//String类型---->[object String]
var data_result = eval("("+data+")");
alert(data_result);
$("#s_name").text(""+data_result.name+"");
$("#s_age").text(""+data_result.age+"");
$("#s_position").text(""+data_result.position+"");
/* $("#s_message").text(""+data_message+""); */
},
error:function(){
alert("系统异常,请稍后重试!");
}//这里不要加","
});
});
}
/* 页面加载完成,绑定事件 */
$(document).ready(function(){
btn();//点击提交,执行ajax
});
</script>
</body>
</html>
struts.xml代码:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.1.7//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
<!--解决乱码 -->
<constant name="struts.i18n.encoding" value="UTF-8"></constant>
<constant name="struts.devMode" value="true"></constant>
<package name="simpleton" extends="json-default">
<action name="*JsonAction" method="{1}" class="com.simpleton.demo.action.JsonAction">
<result name="fail"></result>
<result name="success" type="json">
<param name="root">result</param>
</result>
</action>
</package>
</struts>
JsonAction.java代码:
package com.simpleton.demo.action;
import javax.servlet.http.HttpServletRequest;
import org.apache.struts2.interceptor.ServletRequestAware;
import com.opensymphony.xwork2.ActionSupport;
import net.sf.json.JSONObject;
public class JsonAction extends ActionSupport implements ServletRequestAware{
private static final long serialVersionUID = 1L;
private HttpServletRequest request;
private String result;
private String message;
public String getResult() {
return result;
}
public void setResult(String result) {
this.result = result;
}
public void setServletRequest(HttpServletRequest arg0) {
this.request = arg0;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public String excuteAjax(){
try {
//获取数据
String name = request.getParameter("name");
int age = Integer.parseInt(request.getParameter("age"));
String position = request.getParameter("position");
Result result01 = new Result(name,age,position);
result = JSONObject.fromObject(result01).toString();//将result01对象转换为json类型的字符串形式
this.setMessage("message中的消息");
} catch (Exception e) {
e.printStackTrace();
}
return SUCCESS;
}
}
开始时,json_demo.jsp页面如图11所示。点击了“提交结果”之后如图12所示。
图11 开始时,json_demo.jsp页面
图12 点击了“提交结果”之后的json_demo.jsp页面
Demo7:
在json_demo.jsp页面输入表单内容,在动作类JsonAction.java中获取表单值,并将表单值封装成Result对象,并通过在struts.xml中配置<param name="root">result</param><param name="includeProperties">*</param>,使得以json类型将Result对象的所有属性全部返回到json_demo.jsp页面,并且加以显示。
json_demo.jsp代码:
<%@ 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>struts+ajax返回json类型数据</title>
<script type="text/javascript" src="scripts/jquery-1.8.2.js"></script>
<link rel="shortcut icon" type="image/x-icon" href="images/Icon.png" />
<link rel="stylesheet" type="text/css" href="styles/base.css" />
</head>
<div id="div_json">
<h5>录入数据</h5>
<br />
<form action="#" method="post">
<label for="name">姓名:</label><input type="text" name="name" />
<label for="age">年龄:</label><input type="text" name="age" />
<label for="position">职务:</label><input type="text" name="position" />
<input type="button" class="btn" value="提交结果"/>
</form>
<br />
<h5>显示结果</h5>
<br />
<ul>
<li>姓名:<span id="s_name">尚无数据</span></li>
<li class="li_layout">年龄:<span id="s_age">尚无数据</span></li>
<li class="li_layout">职务:<span id="s_position">尚无数据</span></li>
<!-- <li class="li_layout">消息:<span id="s_message">尚无数据</span></li> -->
</ul>
</div>
<script type="text/javascript">
/* 提交结果,执行ajax */
function btn(){
var $btn = $("input.btn");//获取按钮元素
//给按钮绑定点击事件
$btn.bind("click",function(){
$.ajax({
type:"post",
url:"excuteAjaxJsonAction",//需要用来处理ajax请求的action,excuteAjax为处理的方法名,JsonAction为action名
data:{//设置数据源
name:$("input[name=name]").val(),
age:$("input[name=age]").val(),
position:$("input[name=position]").val()//这里不要加"," 不然会报错,而且根本不会提示错误地方
},
dataType:"json",//设置需要返回的数据类型
success:function(data){
alert(data);//json类型对象[object Object],因为设置了<param name="root">result</param>,所以只返回action动作类中的result属性,message属性不反回。
alert(JSON.stringify(data));//将返回的data的字符串形式--->"{"position":"学生","age":"22","name":"孙明明"}"
alert(Object.prototype.toString.call(data));//json类型对象---->[object Object]
$("#s_name").text(""+data.name+"");
$("#s_age").text(""+data.age+"");
$("#s_position").text(""+data.position+"");
/* $("#s_message").text(""+data_message+""); */
},
error:function(){
alert("系统异常,请稍后重试!");
}//这里不要加","
});
});
}
/* 页面加载完成,绑定事件 */
$(document).ready(function(){
btn();//点击提交,执行ajax
});
</script>
</body>
</html>
struts.xml代码:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.1.7//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
<!--解决乱码 -->
<constant name="struts.i18n.encoding" value="UTF-8"></constant>
<constant name="struts.devMode" value="true"></constant>
<package name="simpleton" extends="json-default">
<action name="*JsonAction" method="{1}" class="com.simpleton.demo.action.JsonAction">
<result name="fail"></result>
<!-- 返回json类型数据,不设置root就是以action动作类作为root -->
<result name="success" type="json"><!--对于result对象,不能直接只设置为<param name="includeProperties">result</param> ,但可以写<param name="includeProperties">result.*</param> -->
<param name="root">result</param>
<param name="includeProperties">*</param><!-- 这两句的效果等于只写第一句的效果,这里可以设置<param name="includeProperties">name,age</param>来获取result对象的name和age属性 -->
</result>
</action>
</package>
</struts>
JsonAction.java代码:
package com.simpleton.demo.action;
import javax.servlet.http.HttpServletRequest;
import org.apache.struts2.interceptor.ServletRequestAware;
import com.opensymphony.xwork2.ActionSupport;
public class JsonAction extends ActionSupport implements ServletRequestAware{
private static final long serialVersionUID = 1L;
private HttpServletRequest request;
private Result result;
private String message;
public Result getResult() {
return result;
}
public void setResult(Result result) {
this.result = result;
}
public void setServletRequest(HttpServletRequest arg0) {
this.request = arg0;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
/**
* 处理ajax请求
* @return SUCCESS
*/
public String excuteAjax(){
try {
//获取数据
String name = request.getParameter("name");
int age = Integer.parseInt(request.getParameter("age"));
String position = request.getParameter("position");
this.setMessage("message中的消息");
Result result01 = new Result();
result01.setName(name);//只能使用set方法才能在前台取到值,不能使用带参数的构造方法
result01.setAge(age);
result01.setPosition(position);
this.setResult(result01);//只能使用set方法才能在前台取到值
} catch (Exception e) {
e.printStackTrace();
}
return SUCCESS;
}
}
开始时,json_demo.jsp页面如图13所示。点击了“提交结果”之后如图14所示。
图13 开始时, json_demo.jsp 页面
图14 点击了“提交结果”之后的json_demo.jsp页面
总结:
1、如果不在<result name="success" type="json"></result>里面通过<param>标签设置转化的属性,那么struts2会把action中的所有属性全部转化为json字符串返回给客户端。如果需要根据实际情况返回部分结果,可以通过struts提供的一些参数来解决这个问题:
《1》root参数:从返回结果中根据ognl表达式取出你需要输出的结果,或者说指定要转化传递的属性
《2》excludeNullProperties参数:表示是否去掉空值, 默认值是false,如果设置为true会自动将为空的值过滤,只输出不为空的值。
《3》ignoreHierarchy参数:表示是否忽略等级,也就是继承关系,比如:LogAction类继承于BasicAction类,那么TestAction中返回的json字符串默认是不会包含父类BaseAction的属性值,ignoreHierarchy值默认为true,设置为false后会将父类和子类的属性一起返回。
《4》 includeProperties参数:输出结果中需要包含的属性值,这里正则表达式和属性名匹配,可以用“,”分割填充多个正则表达式。
《5》 excludeProperties参数:输出结果需要剔除的属性值,也支持正则表达式匹配属性名,可以用“,”分割填充多个正则表达式
设置这些参数还有一个原因:主要是为了过滤掉接口,pojo的set、list、其他对象等不需要的数据防止循环取其他对象或找不到。如果不配置,默认是处理action中的所有属性,如果action中有接口注入,json拦截器可能找不到返回不了结果,还有如果action中有一个对象,这个对象与好多对象都有关联,json拦截器会将相关联的所有对象的属性全部转换成json格式,如果其他对象有list、set,其返回结果有可能是死循环,无法返回。因此:action中避免使用get开头的action方法,去掉action中的接口的get方法,或为json类型的result配置includeProperties, excludeProperties等参数.
2、name=”root”,所谓root的含义,是指返回的json数据的根为root中指定的对象。
------->如果不设置root属性,如上面的Demo3所示,返回值的根在Action动作类中,有上面的代码可知返回的是:
{"message":"后台数据","result":"{"position":"学生","age":"22","name":"孙小明"}"},显然只要在Action动作类中有getter方法的属性全部都以json的形式返回。
------->如果设置了root属性,如上面的Demo4所示,设置了<param name="root">result</param> 将返回值的根限制在了result中,因此返回到客户端的值为:
{"position":"学生","age":"22","name":"孙明明"},即只返回了result属性,而message属性没有返回。
3、如果设置了root属性之后,<param includeProperties></param>中就应该直接
使用name,age而非result.name,result.age了。如上面的Demo7,在设置<param name="root">result</param>之后,<param name="includeProperties"></param>中的值可以为:*(result对象的所有属性),age(result对象的age属性),age,name(result对象的age和name属性)等等诸如此类。
4、这里面还有很多可以挖掘的,不一一说了。