Struts2中使用JSON作数据的get/post,方法有不少种,这里有一篇文章比较详细的列举出了JSON在Struts和Servlet中如何GET:html
http://yshjava.iteye.com/blog/1333104java
Servlet的不写了,也就是how to use HttpRequest和HttpResponse。主要是在Struts2身上。apache
以文章所描述的方法彷佛老是差了那么点东西:能够不使用那么多配置吗?json
因而研究了些时间,能够这么玩:浏览器
1)Eclipse引用Struts2的JSON plug-in和Convertion plug-in。缓存
2)struts.xml这么写:服务器
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN" "http://struts.apache.org/dtds/struts-2.3.dtd"> <struts> <!-- 把它设置为开发模式,发布时要设置为false --> <constant name="struts.devMode" value="true" /> <!-- 设置在class被修改时是否热加载,发布时要设置为false --> <constant name="struts.convention.classes.reload" value="true"/> <!-- 自动动态方法的调用,使用这个设置后能够这样调用:action!method --> <constant name="struts.enable.DynamicMethodInvocation" value="true" /> <!-- 指定jsp文件所在的目录地址 --> <constant name="struts.convention.result.path" value="/WEB-INF/content/" /> <!-- 用于配置包名后缀。默认为action、actions、struts--> <!-- <constant name="struts.convention.package.locators" value="controller" /> --> <constant name="struts.convention.action.packages" value="com.my.controller"></constant> <!-- 用于配置类名后缀,默认为Action,设置后,Struts2只会去找这种后缀名的类作映射 --> <constant name="struts.convention.action.suffix" value="Controller"/> <!-- 设置即便没有@Action注释,依然建立Action映射。默认值是false。由于Convention-Plugin是约定优于配置的风格, 能够不经过注解根据预先的定义就能访问相应Action中的方法 --> <constant name="struts.convention.action.mapAllMatches" value="true"/> <!-- 自定义jsp文件命名的分隔符 --> <constant name="struts.convention.action.name.separator" value="-" /> <!-- 国际化资源文件名称 --> <constant name="struts.custom.i18n.resources" value="i18n" /> <!-- 是否自动加载国际化资源文件 --> <constant name="struts.i18n.reload" value="true" /> <!-- 浏览器是否缓存静态内容 --> <constant name="struts.serve.static.browserCache" value="false" /> <!-- 上传文件大小限制设置 --> <constant name="struts.multipart.maxSize" value="-1" /> <!-- 主题,将值设置为simple,即不使用UI模板。这将不会生成额外的html标签 --> <constant name="struts.ui.theme" value="simple" /> <!-- 编码格式 --> <constant name="struts.i18n.encoding" value="UTF-8" /> <!-- 设置默认package --> <constant name="struts.convention.default.parent.package" value="default"></constant> <package name="default" namespace="/" extends="json-default"> <interceptors> <interceptor name="cacheInterceptor" class="com.my.interceptor.CacheInterceptor" /> <interceptor-stack name="cacheStack"> <interceptor-ref name="defaultStack"></interceptor-ref> <interceptor-ref name="paramsPrepareParamsStack"></interceptor-ref> <interceptor-ref name="cacheInterceptor"></interceptor-ref> </interceptor-stack> </interceptors> <default-interceptor-ref name="cacheStack"></default-interceptor-ref> <default-action-ref name="index" /> <global-results> <!-- <result name="error">/error.jsp</result> --> <result name="json" type="json"> <!-- 是否包括父类的属性输出,默认true. --> <!-- <param name="ignoreHierarchy">false</param> --> <!-- 是否输出null值的属性,默认false --> <!-- <param name="excludeNullProperties">true</param> --> </result> </global-results> <global-exception-mappings> <exception-mapping exception="java.lang.Exception" result="error"/> </global-exception-mappings> </package> </struts>
上面有两个<param/>注释了,使用方法已经有写在里头,若是须要,能够加上或在类中加入@Results。restful
关键点在于把<package />中的 extends设置为json-default,以及在global-results中的这个json result。app
3)加入一个UserControl.javajsp
package com.my.controller; import java.io.IOException; import java.util.ArrayList; import java.util.List; import net.sf.json.JSONObject; import com.my.beans.User; import com.opensymphony.xwork2.ActionSupport; @SuppressWarnings("serial") public class UserController extends ActionSupport { private User user = new User(); public User getUser() { return user; } public void setUser(User user) { this.user = user; } private String json; public String getJson() { return json; } public void setJson(String json) { this.json = json; } private List<User> users = new ArrayList<User>(); public List<User> getUsers() { return users; } public void setUsers(List<User> users) { this.users = users; } @Override public String execute() throws Exception { return SUCCESS; } public String loadModel() throws IOException { System.out.println("json=" + getJson()); System.out.println("user=" + getUser().getUsername()); System.out.println("users=" + getUsers().size()); User userBean = new User(); userBean.setUsername("robin"); users.add(userBean); this.setJson(JSONObject.fromObject(userBean).toString()); return "json"; } }
这里没有什么特别的东西,就是一些getter/setter,以及一个loadModel() action
4)JS对JSON的提交:
var url = "user!loadModel"; var params = { "json": "json string", "user.username" : "zhang", "users[0].username" : "zhang1", "users[0].password" : "1", "users[1].username" : "zhang2", "users[1].password" : "2", }; $.post(url, params, function callback(data) { console.log(data) });
这里是重点。
能够看到这段JS里的params有:json/user.username/users[X].username
其中:
a) json
对应的就是上页java中的getJson/setJson,这个东东列出来是能够用于在页面与服务器之间传递JSON字符串用的。若是你须要在action中输出或提交json的字符串,它有很大做用,直接到位。可是缺点是要本身去将对象转化为json string以及json string转化为对象。
b) user.username
这样的写法能够在后台java中直接转化成了对象。user.username中的user就是java中的user object。
c) users[0].username
这能够直接转化成后台java中的List<user>对象users。
能够看出,Struts2是能够完成将json直接转化成java object的。不过这样的写法,不是好的。由于这个JS的JSON只能称做是一个字符串拼接,不是一个JSON object
还有一种方法,使用ModelDriven:
package com.my.controller; import com.my.beans.User; import com.opensymphony.xwork2.ActionSupport; import com.opensymphony.xwork2.ModelDriven; @SuppressWarnings("serial") public class UserModelController extends ActionSupport implements ModelDriven<Object> { private User user = new User(); @Override public Object getModel() { return user; } @Override public String execute() throws Exception { return SUCCESS; } public String load() { return "json"; } }
使用ModelDriven,能够JS直接提交JSON了:
var url = "user-model!load"; var params = { "username": "zhang1", "password": "123456" }; $.post(url, params, function callback(data) { console.log(data) });
这个params才是真正的JSON object,它会被ModelDriven直接转成user model。
可是:它彷佛不能提交List object。至今写文时也没有找到在ModelDriven中能够提交JSON array to List的方法。
若是须要提交复杂的JSON到服务器,若是你用的是Struts,使用第一种方法的json的getter/setter吧。
我的Struts2研究了些日子对它的总结:
1)若是是使用MVC开发的,它是个很是好的选择。由于它提供了很是丰富的可配置的功能及标签。可是也正是由于这些复杂的配置,会使用得开发及维护上带来不少诟病,好比速度上、发布上、后期清理上的问题。既然MVC的理想是约定优于配置,那为何还须要这么复杂的配置呢?
2)它的Action在URL上的表现上让人看着不舒服,由于太不restful了,同时它的restful plug-in彷佛没太多的可扩展性。说白了,若是要作rest,理应不选择它。
3)struts它合适于使用普通的form提交开发当中(即MVC)。不合适于MVVM模式的开发。若是想使用MVVM,那么建议使用SpringMVC,而不是Struts。
沉思:
若是MVVM是将来的主流设计,那么struts将会有天淡去在这个舞台。