Struts2+JQuery+JSON的集成
因为看到项目中用了Struts2+JQuery+JSON的集成 所以自己就网上找资料并自己做了一个实例
1.准备工作:
下面是我导入的jar包:commons-fileupload-1.2.1.jar,commons-io-1.3.2.jar, commons-logging-1.1.jar,
freemarker-2.3.13.jar, json-lib-2.4-jdk15,jar ,ognl-2.6.11.jar,struts2-core-2.1.6.jar ,
struts2-json-plugin-2.3.1.2.jar, xwork-2.1.2.jar
jquery用的是jquery-1.7.1.js
2.过程
1 引入json依赖包和struts2的jar包
2 编写action类
3 配置struts.xml
4 编写页面
5.其它配置
3 实例
1 action类,UserActionTest
package com.test.action;
import java.util.ArrayList;
import java.util.List;
import com.test.entity.UserInfo;
publicclass UserActionTest {
private Stringusername;
private Stringpassword;
private Stringacount;
private UserInfouserInfo;
private List<UserInfo>userList;
public String testJson(){
userInfo=new UserInfo();
userInfo.setId(1);
userInfo.setEmail("123456@qq.com");
userInfo.setName("张三");
userInfo.setPhone("1357473990");
acount="10000";
userList=new ArrayList<UserInfo>();
for(int i=2;i<=4;i++){
UserInfo userInfo=new UserInfo();
userInfo.setId(i);
userInfo.setEmail("123456@qq.com-"+i);
userInfo.setName("张三-"+i);
userInfo.setPhone("1357473990-"+i);
userList.add(userInfo);
}
return"success";
}
public String getUsername() {
returnusername; }
publicvoid setUsername(String username) {
this.username = username; }
public String getPassword() {
returnpassword; }
publicvoid setPassword(String password) {
this.password = password; }
public String getAcount() {
returnacount; }
publicvoid setAcount(String acount) {
this.acount = acount; }
public UserInfo getUserInfo() {
returnuserInfo; }
publicvoid setUserInfo(UserInfo userInfo) {
this.userInfo = userInfo; }
public List<UserInfo> getUserList() {
returnuserList; }
publicvoid setUserList(List<UserInfo> userList) {
this.userList = userList; }
}
2.struts2的配置
<?xmlversion="1.0"encoding="UTF-8"?>
<!DOCTYPEstruts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
"http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
<constantname="struts.enable.DynamicMethodInvocation"value="false"/>
<constantname="struts.devMode"value="ture"/>
<packagename="testJson"namespace="/myjson"extends="json-default">
<actionname="jsonTest"class="com.test.action.UserActionTest"method="testJson">
<result type="json"></result>
</action>
</package>
</struts>
3.页面ajax写法
<%@ page language="java"import="java.util.*"pageEncoding="UTF-8"%>
<%@pageimport="org.apache.struts2.json.annotations.JSON"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPEHTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<basehref="<%=basePath%>">
<title>My JSP 'password.jsp' starting page</title>
<metahttp-equiv="pragma"content="no-cache">
<metahttp-equiv="cache-control"content="no-cache">
<metahttp-equiv="expires"content="0">
<metahttp-equiv="keywords"content="keyword1,keyword2,keyword3">
<metahttp-equiv="description"content="This is my page">
<scripttype="text/javascript"src="js/jquery-1.7.1.js"></script>
<scripttype="text/javascript">
var path ="<%=path%>";
alert(path);
$(function(){
$('#submit').bind('click',function() {
alert('User clicked on "foo."');
var params = {
username : $("#username").val(),
password : $("#password").val()
};
$.ajax({
type:"POST",
url: path+"/myjson/jsonTest.action",
data: params,//传递username,password参数的值给Action
dataType:"json",//返回数据类型设置为json
success:function(msg){
// var obj = eval(msg); //使用这个方法解析json
// alert(obj);
// username是和action中定义的result变量的get方法对应的
var state_username = msg.username;
// password是和action中定义的result变量的get方法对应的
var state_password = msg.password;
// acount是和action中定义的result变量的get方法对应的
var state_acount = msg.acount;
// userInfo是和action中定义的result变量的get方法对应的
var state_userInfo = msg.userInfo;
// userList是和action中定义的result变量的get方法对应的
var state_userList = msg.userList; alert(state_username);
alert(state_password);
alert(state_acount);
//将userInfo bean中的内容输出出来
alert(state_userInfo.id+"--"+state_userInfo.name+"--"+state_userInfo.phone+"--"+state_userInfo.email);
//将集合中的内容输出来下面是两种不同方式的输出
for(var i=0;i<state_userList.length;i++){
type = state_userList[i].type;
dys = state_userList[i].dysnum;
lcs = state_userList[i].csnum;
hs = state_userList[i].hsnum;
alert(i+"--"+state_userList[i].id+"--"+state_userList[i].name+"--"+state_userList[i].phone+"--"+state_userList[i].email);
}
$.each(state_userList, function(i, item) {
alert(i+"--"+item.id+"--"+item.name+"--"+item.phone+"--"+item.email);
});
}
});
});
});
</script>
</head>
<body>
用户名:<inputid="username"name="username"type="text">
<br/>
密 码:<inputid="password"name="password"type="text">
<br/>
<inputtype="button"value="提交"id="submit">
</body>
</html>
4.UserInfo类
package com.test.entity;
publicclass UserInfo {
private Integerid;
private Stringname;
private Stringphone;
private Stringemail;
public Integer getId() {
returnid; }
publicvoid setId(Integer id) {
this.id = id; }
public String getName() {
returnname; }
publicvoid setName(String name) {
this.name = name; }
public String getPhone() {
returnphone; }
publicvoid setPhone(String phone) {
this.phone = phone; }
public String getEmail() {
returnemail; }
publicvoid setEmail(String email) {
this.email = email; }
@Override
publicboolean equals(Object obj) {
returnsuper.equals(obj); }
@Override
publicint hashCode() {
returnsuper.hashCode(); }
@Override
public String toString() {
return "id:"+id+" name:"+name+" phone:"+phone+" email"+email; }}
最后说明哈其它的配置
1.
<packagename="testJson"namespace="/myjson"extends="json-default">
<actionname="jsonTest"class="com.test.action.UserActionTest"method="testJson">
<interceptor-ref name="json" />
<!--处理以JSON文本提交的请求 (可要可不要, 只要继承extends="json-default",json拦截器是默认配置上的,可以不配。result设置成json之后,容器会把action的属性自动封装到一个json对象中(json拦截器来做),然后调用js的callback方法. 返回json数据)-->
<result type="json" /><!--将action的bean属性以json字符串返回浏览器-->
</action>
</package>
2.
如果按照上面中的配置。你会发现前台返回的json字符串,是把action中的所有属性全部转化为json字符串返回给浏览器了(甚至有时候返回不了结果,也不报错,后台执行了,但前台执行不到success:function(msg){ },但是我们有时候需要根据实际情况返回部分结果,如何对json的结果进行定制输出呢?result提供了一些参数替你解决这个问题,一般情况下用的最多的就是includeProperties 参数和excludeNullProperties参数。当然还有其他的方法,如给pojo的属性加json注解。
3.
includeProperties 参数:输出结果中需要包含的属性值,这里正则表达式和属性名匹配,可以用“,”分割填充多个正则表达式。这个参数直接返回对象的json数据,前台不需要eval转换,
<param name="root">result</param>则不同,需要前台进行eval转换 如:输出person的所有属性 <result type="json"> <param name="includeProperties">person.*</param> </result>
输出Action中的某一个属性: <action name="loadMaindataTypeItems" class="com.linkage.ctg.config.maindata.controller.LoadMaindataItemAction" method="loadMaindataTypeItems"> <result type="json">
<param name="includeProperties">maindataTypeList</param> </result> </action>
4.
excludeProperties 参数:输出结果需要剔除的属性值,也支持正则表达式匹配属性名,可以用“,”分割填充多个正则表达式,类同includeProperties
5.
输出一个JSON List列表
<action name="list" class="testAction" method="list"> <result name="success" type="json"> <param name="includeProperties"> list\[\d+\]\.Id,list\[\d+\]\.user\.userName </param> </result> </action>
其中list是action中的一个List类型的属性 list\[\d+\]\.Id表示,list中存储的对象0..end的Id属性(list中存储的对象必须有Id属性)。 list\[\d+\]\.user\.userName就表示list中的对象中的user对象的userName属性
6.
为什么要用includeProperties或者excludeProperties 参数:
主要是为了过滤掉接口,pojo的set、list、其他对象等不需要的数据防止循环取其他对象或找不到。如果不配置,默认是处理action中的所有属性,如果action中有接口注入,json拦截器可能找不到返回不了结果,还有如果action中有一个对象,这个对象与好多对象都有关联,json拦截器会将相关联的所有对象的属性全部转换成json格式,如果其他对象有list、set,其返回结果...有可能是死循环,无法返回
7.
需要注意的是,如果用的json插件把返回的结果定位json,而json的原理是在action中的get*()方法只要没指定不序列化,都会执行
如果该方法一定要命名为get*(比如实现了什么接口),那么可以在该方法前面加注解
@jso(serialize=false)
除此之外,json注释还支持如下几个域
Serialize:设置是否序列化该属性
Deserialize:设置是否反序列化该属性
Format:设置用于格式化输出,解析日期表单域的格式
例如“yyyy-MM-dd HH:mm:ss”
Name:使用注解来改变属性序列化后的属性名
需引入import com.googlecode.jsonplugin.annotations.JSON;
总结: action中避免使用get开头的action方法,去掉action中的接口的get方法 为json类型的result配置includeProperties, excludeProperties等参数.