下面逐一解答上面文章提出的问题。我们使用struts2官网给的demo工程struts2-blank 。struts-2.3.16.1-all.zip解压后,进入struts-2.3.16.1-all\struts-2.3.16.1\apps\文件夹,将struts2-blank.war解压。eclipse里新建一个Dynamic Web Project工程,工程名叫struts2-blank。然后将相应的文件拷贝到新建的工程的相应路径下。源码见文章最后。
如何把form表单序列化成一个json对象? 序列化表单时,会遇到哪些问题?
先来看看jquery的serialize和serializeArray两个方法。
<form id="form1" action="" method="post"> <label>姓名:</label><input type="text" name="name" /><br/> <label>年龄:</label><input type="text" name="age" /><br/> <label>男</label><input type="radio" name="gender" /> <label>女</label><input type="radio" name="gender" /><br/> <label>是否有经验:</label><input type="checkbox" name="experienceFlag" /><br/> <input id="sbmt" type="button" value="提交" /> </form>
$(function(){ $("#sbmt").click(function(){ var serializeData = $("#form1").serialize(); var serializeArrayData = $("#form1").serializeArray(); console.log(serializeData); console.log(serializeArrayData); }); });
I.可以看到radio和checkbox的值都是“on",checkbox是on还可以区分开来,但是radio怎么办?
如果我们把form改成这样会序列化成什么样子?
<form id="form1" action="" method="post"> <label>姓名:</label><input type="text" name="name" /><br/> <label>年龄:</label><input type="text" name="age" value="23" disabled="disabled"/><br/> <label>男</label><input type="radio" name="gender" value="0" /> <label>女</label><input type="radio" name="gender" value="1" /><br/> <label>是否有经验:</label><input type="checkbox" name="experienceFlag" /><br/> <input id="sbmt" type="button" value="提交" /> </form>
II.可以看到disabled的input框和没有选中的checkbox不会被序列化。这里还有一个问题,checkbox的value不是0和1。这个要么在提交表单前将所有选中的checkbox值设置为1,要么在后台进行处理,将experienceFlag的值为"on"变为1。为null就置为0。
可以看到serialize和serializeArray都没有达到我们的要求。serialize的结果是一个字符串,我们不能以"&"和"="进行切割,假如值里就有"&"和"="怎么办? 我们要将整个表单的值都放在一个js对象里。 这里啰嗦一下,js对象就是json对象。json的全称是JavaScript Object Notation。
III.将表单序列化成一个js对象还有一个问题,假如form里有多个text框的name是一样的怎么办?这里介绍一个网友的给出的方法,我仔细的看过,写的非常好。
这里做成了插件的形式,非常好用。
如果对jquery.fn.extend和jquery.extend两种写法不熟悉的同学可以看看这篇文章: jquery.fn.extend与jquery.extend
var formData = $("#form1").serializeJson(); console.log(formData);
以上就是form表单序列化经常遇到的问题,就说到这儿。解决了第一个问题,就算是入门了。
如何传一个对象数组到后台? 有几种实现方式?
据我所知有两种方式:
I.用struts2自带的json拦截器,自动将json填充到List<Bean>里。
这个方法亲测好用 可以看看这篇文章,文章的最后有源码可以下载: Send JSON to Struts2 action
demo也可以从这里下载: jquery的ajax传json对象数组到struts2的action
文章里已经说的很详细了,这里不再赘述。注意这种方式除了 II里提到的jar包,还需要 struts2-json-plugin-2.3.16.1.jar 这个Jar包。
II.将json转成json字符串,在后台用jar包里的方法手动解析。
使用json-lib-2.3-jdk15.jar这个jar包。这个jar包需要依赖其他几个jar包。官网这里有介绍:json-lib
需要用到下面几个Jar包。
json-lib-2.3-jdk15.jar
commons-lang-2.4.jar
commons-beanutils-1.8.0.jar
commons-collections-3.1.jar
commons-logging-1.1.3.jar
ezmorph-1.0.6.jar
import java.util.List; import net.sf.json.JSONObject; public class JsonMapObject { public static void main(String[] args) { String jsonStr = "{\"users\":[{\"name\":\"aaa\",\"age\":23,\"gender\":\"0\",\"experienceFlag\":\"0\"},{\"name\":\"bbb\",\"age\":25,\"gender\":\"1\",\"experienceFlag\":\"1\"},{\"name\":\"ccc\",\"age\":26,\"gender\":\"1\",\"experienceFlag\":\"1\"}]}"; JSONObject json = JSONObject.fromObject(jsonStr); List<User> users = (List<User>) json.get("users"); System.out.println(users.size()); } }
假设jsonStr是前台传过来的字符串。我们可以手动解析,手动解析比较灵活。解析完了还可以做些处理,比如用element()方法给json添加元素,或者remove()方法删除某个元素等。 输出结果: 3
后台如何传json到前台
jquery用ajax请求后台。
$.ajax({ url: "aaa/getSomething.action", type: "post", dataType: "json", // 服务端返回的数据类型 data: {"id":123}, success:function(data){ console.log(data.msg); } });
后台定义一个map,注意map不能为Null,要有setter和getter。
private Map<String, Object> resultData = new HashMap<String, Object>(); public Map<String, Object> getResultData() { return resultData; } public void setResultData(Map<String, Object> resultData) { this.resultData = resultData; } public String getSomething(){ resultData.put("msg", "success"); return SUCCESS; }
<action name="getSomething" class="someAction" method="getSomething"> <result type="json"> <param name="root">resultData</param> </result> </action>
前端如何将json字符串转成js对象? 如何将js对象转成json字符串?
var str = '{"name":"张三", "age":22}'; var obj = JSON.parse(str); // 转成js对象 console.log(obj); var str2 = JSON.stringify(obj); // 转成json字符串 console.log(str2);
注意json的key必须是双引号。
可以用input框存储json字符串吗? 如果不能可以用5的方式解决问题吗?
有些时候我们从一个action跳转到一个页面的时候希望将json数据保存下来供插件使用。我们首先想到的就是用隐藏的input框保存。
但是input框不能存储json字符串,因为json字符串里有冒号!
可以在js中取出EL表达式的值吗
不能。这个问题搞不清基本上可以肯定你不合格。JavaScript王者归来那本书里已经提到,js是运行在客户端的,EL表达式是运行在服务端的。怎么可能取到!
那为什么我确实取到了呢?我这样写不就取到了吗?<script>var aa = "${aa}"</scirpt>。这是一个投机的办法。有一个弊端就是你的js代码不能放在一个单独的js文件里,切记!这样写之所以可以取到,是因为 服务端的jsp编译成servlet之后,通过out.print()将所有html标签以字符串的形式发给浏览器,浏览器会把<script>标签里所有的东西都当作js代码来解析。<script>var aa = "${aa}"</scirpt>在servlet里就是
out.print("<script>var aa = {name:ccc,age:23}</scirpt>");
所以这个时候我们应该怎么做? 用ajax。 我们在使用各种插件的时候基本上都是这种方式。先到达页面,等页面加载完了之后再发一个ajax请求然后拿到数据。虽然有两次请求感觉上很慢,但是真正运行的时候基本上是感觉不到的。所以别犹豫,就用ajax吧。
如何将Java对象转成json?
User user = new User("李四", 26, "1", "1"); JSONObject jsonUser = JSONObject.fromObject(user); System.out.println(jsonUser);
如何将json字符串转成Java对象?
String strUser = "{\"name\":\"aaa\",\"age\":23,\"gender\":\"0\",\"experienceFlag\":\"0\"}"; JSONObject jsonUser2 = JSONObject.fromObject(strUser); System.out.println(jsonUser2);
json对象,map,Java对象三者之间如何互相转换?
Java对象-----> map
try { User user = new User("李四", 26, "1", "1"); Map<String, Object> map = BeanUtils.describe(user); System.out.println(map); } catch (Exception e) { e.printStackTrace(); }
Java对象-----> json对象
JSONObject jsonUser = JSONObject.fromObject(user);
json对象------> map
User user = new User("李四", 26, "1", "1"); Map userMap = JSONObject.fromObject(user); // net.sf.json.JSONObject实现了Map接口,可以直接用map接收Json对象
json对象------> Java对象
JSONObject jsonObj = new JSONObject(); jsonObj.element("name", "王五"); jsonObj.element("age", 23); User user2 = (User) JSONObject.toBean(jsonObj, User.class);
map ------> Java对象
Map<String, Object> map = new HashMap<String, Object>(); map.put("name", "王五"); map.put("age", 23); User user3 = new User(); try { BeanUtils.populate(user3, map); } catch (Exception e) { e.printStackTrace(); }
map ------> json对象
JSONObject mapToJson = JSONObject.fromObject(map); // map也是一个Java对象
json中如何处理Null值? *重要*
JSONObject valueNullJson = new JSONObject(); valueNullJson.element("aa", (Object)null); // 注意element有许多重载的方法,直接传null会报错,element方法不知道具体的类型 System.out.println(valueNullJson); // {} JSONNull jsonNull = JSONNull.getInstance(); // JSONNull 没有构造函数,只能通过getInstance实例化。这是json里正宗的null valueNullJson.element("bb", jsonNull); System.out.println(valueNullJson); // {"bb":null} Map<String, Object> valueNullMap = new HashMap<String, Object>(); valueNullMap.put("cc", null); valueNullMap.put("dd", JSONNull.getInstance()); JSONObject jobj = JSONObject.fromObject(valueNullMap); System.out.println(jobj); // {"cc":null,"dd":null} String valueNullStr = "{\"ee\":\"null\"}"; JSONObject strJson = JSONObject.fromObject(valueNullStr); System.out.println(strJson); // {"ee":null} String valueNullStr2 = "{\"ff\":null}"; JSONObject strJson2 = JSONObject.fromObject(valueNullStr2); System.out.println(strJson2); // {"ff":null}
<global-results> <result type="redirect" name="error">/error.jsp</result> <result name="exp">/exp.jsp</result> </global-results>
因为这里有一个重定向的处理。所以struts2在转json的时候出现异常就会返回一个302的错误。 debug调试代码的时候没有任何问题,return SUCCESS;后就会报错,切记。
有什么工具可以格式化和测试json字符串?
使用在线工具,比如: json.cn 。可以格式化json字符串,也可以压缩json字符串,将json转成xml等。
json是有序的吗?
json对象由许多个element构成。element就是一个key-value的键值对。 就键值对来说它是无序的。
对于一个json对象,我们几乎完全可以把它当作一个map来用。说它是无序的,原则上是没错的。但是有人可能会因此而忽悠你说因为json是无序的,所以我从db里查出东西后不能排序,这个你得自己重新排个序。
想想如果value是一个List<Object>。因为list里的元素是有序的。所以json里的数据可以是“已排好序的”。不要被忽悠了。
// todo
源码链接