今天在开发中遇到一个问题。
公司用的前端框架是AngularJS,得益于其双向绑定机制,新增和修改使用的是同一个页面,但这也变相的造成了一个问题:并非是使用表单提交的方式将对象传到后台,而是自己在js中将属性封装成一个对象,传往后台。
每一个页面都有一个controller.js,多个controller.js之中可能会有共用的方法,那么这些方法将会定义在service.js中,controller.js引入这个service.js,使用其中的方法。
在service.js中,使用$apis,调用后台Controller层的接口。
但是,我做的只是一个小功能,因为不用考虑代码复用,根本没有必要再多去写一个service.js,那么就出现了一个问题:前台封装好的对象如何传到后台的Controller层中去,因为后台Controller层中的入参是一个实体类对象。
其实解决的办法也很多,比如既然我不能以实体类传参,那么我可以将后台的入参改为一个Map.
甚至是稍笨一点的方法,后台用的Jersey框架,我甚至可以用@QueryParam("xxx")String xxx
这种方式来入参,只不过这样就太麻烦了。如果前台多一个属性,后台同样也要多增加一个形参。
不过当时我就较上劲了,我就不想使用Map传参,就像直接传前台封装好的对象,想来想去,想到一个办法,我可以先把前台的对象转换为Json啊,后台接收String类型的Json字符串,然后后台再将Json转换为实体对象。
AngularJS将对象转为Json
angular.toJson(obj);
可以将对象转换为Json格式。
后台Controller将String类型的Json串转换为实体类详见:json字符串与java对象互转
遇到的问题
一开始后台是使用@QueryParam(xxx)String xxx
这种方式来接收Json字符串,但是却报了异常:
java.lang.IllegalArgumentException: Invalid character found in the request target. The valid characters are defined in RFC 7230 and RFC 3986
因为使用的是问号传参, URL中带有特殊字符:花括号,例如:http://localhost:8080/api/branch/save?{xxx:xxx}
所以后来使用了Rest风格的url,后台使用@PathParam("xxx")String xxx
,解决了此问题。