需求有点复杂,一开始项目只要支持get和post的x-www-form-urlencode就可以了,但到中期发现还需要application/json方式,前端用的vue,所以后端的接口都是高度集成的(就10个左右接口)。
想了一些办法,但是感觉代码改动最小的方式就是重载Controller,参考以下了帖子:http://www.jfinal.com/feedback/57
但是此贴的一个问题是每次取参数都必须进行比较复杂的判读,我的想法是,每次进入action,就固定先判断一次,以后的取参数,就简单高效一些。
大致代码如下:
public class ExtController extends Controller {
private JSONObject jsonObj = null;
Map<String,Object> map=null;
//注意,必须在读取参数之前先调用此函数,来确保Json数据被读入
public JSONObject readJson(){
jsonObj = null;
map=new HashMap<String,Object>();
if ("application/json".equals(getRequest().getContentType())|| "text/json".equals(getRequest().getContentType())) {
String readData = HttpKit.readData(getRequest());
jsonObj = JSONObject.parseObject(readData);
//为了兼容get和post(www-form-url)方式,把JsonObj转成String,存入Map
Set<String> keySet= jsonObj.keySet();
Object value;
for(String key:keySet){
value = jsonObj.get(key);
if(value instanceof JSONArray || value instanceof JSONObject){
map.put(key, value.toString()); //看源码实际调用的是toJSONString()
}else{
map.put(key, value);
}
}
}
return jsonObj;
}
@Override
public String getPara() {
if(jsonObj!=null){
return map.toString();
}
return super.getPara();
}
@Override
public String getPara(String name) {
if(jsonObj!=null){
return (String)map.get(name);
}
return super.getPara(name);
}
}
现在的最大问题,必须在每个Action函数的入口处马上调用readJson()这个函数,如下代码:
//测试参数传递专用,没有实际作用
public void testJson(){
this.readJson(); //必须先调用
String tmp=getPara("data");
List<Integer> ids=JSON.parseArray(tmp,Integer.class);
tmp=getPara("test");
..........
}
不知道能否有办法,自动做到这一步?