统一前后台数据交互格式
2016-01-29 15:53
344 查看
公司前后台数据交互的格式是统一的,前台对jquery的ajax方法进行了一些封装,也就是说开发的时候并不是自己去调用$.ajax方法,而是调用统一的方法去处理.
我感觉还是比较方便的..确实可以少写一些代码(因为通用代码被封装了),而且管理起来比较方便,统一..然后观察了一些网上的其他网站...发现很多网站都是这么做的...于是我也想自己动手来试试....我自己是使用springmvc与fastjson来实现的...下面分享一下我的经验.
这个页面的地址是https://www.bugclose.com/login.html 是我随便找的一个例子.
仔细观察上面2张图片,我们可以发现几个特点:
1.前台错误提示的样式是一样的,不同的错误的弹出框是一模一样的,只是里面的文字换了而已.
2.2次请求返回的数据格式基本是一样的.
我的思考:
第一张图片里的输出信息是来自root.email,第二张图片里的输出信息是来自errorMessage.
如果我把2种错误输出信息都写到errorMessage里.那我js是不是可以有个通用的请求方法
大家不要吐槽上面这段JS有什么什么错误(我前端不是很好....我只是表达下大致意思..)
这个网站的所有页面只要有弹框提示错误信息,都可以用这个方法.这样我觉得可以省不少力气,不用每次自己去写ajax,而且做到了统一,下次需求要求输出errorcode,或者换个提示样式的时候都只要修改一个地方就行了.不用每个页面都去改一遍.
另外这种封装我觉得是可行的.一般做个页面肯定会用一个前端框架.提示信息的样式一定是统一的.不会这里用alert那里用框架自带的消息框.
首先我要介绍一些背景(据我所知):
SpringMVC有内置的converter可以解析http请求.但是功能比较简单.json字符串默认是不支持的.
前台一般页面写的都是JS代码,传过来的数据一般都是json格式.而fastjson可以方便的将json字符串转化成java对象.
既然如此.我们要做的就是去实现一个converter,将前台传送过来的字符串解析成java对象.
幸运的是fastjson自带了这个一个converter. 叫做FastJsonHttpMessageConverter. 所以只要配置这个converter就行了.
在Springmvc的配置XML中加入下面这段代码就可以了.
我的class是我自己写的一个converter..继承了FastJsonHttpMessageConverter.feature是FastJsonHttpMessageConverter允许的一些特性.不写也可以.另外mvc:message-converters这个标签貌似对springmvc的版本有些要求.反正我http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd是验证不通过的..我用的是http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd....mvc:message-converters这个标签允许配置多个converter(看有个s就知道肯定允许多个).我这里只写了一个converter.对我来说足够了.因为我的目标就是前后台数据格式统一,所以只需要这么一个converter..哪天要加XML格式的时候我再加一个XML的converter就可以了.
然后要用到2个注解:@ResponseBody和@RequestBody..分别对应AbstractHttpMessageConverter中的writeInternal与readInternal方法...对应向HTTP响应写入数据与从HTTP请求中读取数据返回java对象.
converter可以有多个,所以到底哪个converter来处理呢? 这要看converter支持什么类型的MediaType.
如上图,这次请求的ContentType是blablabla.......(看截图红色区域)
而fastjson允许的MediaType是:
所以我的commonAjax方法里需要指明
这样才能被fastjson的converter解析...当然你也可以自己写一个converter去映射N种MediaType.
这样做了以后前后台json格式的数据都可以被fastjson的converter去处理了.然后我们来定义一个统一的数据格式:
假设我的通用格式是这个..
然后我有个和某些业务相关的DTO(我这里随便找了个entity...只是测试用....举个例子而已..大家无视没用的注解....)
然后我在controller里的测试代码
前台请求:
后台返回给前台的数据
后台获取到的数据
是不是很简单呀....
我感觉还是比较方便的..确实可以少写一些代码(因为通用代码被封装了),而且管理起来比较方便,统一..然后观察了一些网上的其他网站...发现很多网站都是这么做的...于是我也想自己动手来试试....我自己是使用springmvc与fastjson来实现的...下面分享一下我的经验.
网上例子:
首先先来找个网上的例子:这个页面的地址是https://www.bugclose.com/login.html 是我随便找的一个例子.
仔细观察上面2张图片,我们可以发现几个特点:
1.前台错误提示的样式是一样的,不同的错误的弹出框是一模一样的,只是里面的文字换了而已.
2.2次请求返回的数据格式基本是一样的.
我的思考:
第一张图片里的输出信息是来自root.email,第二张图片里的输出信息是来自errorMessage.
如果我把2种错误输出信息都写到errorMessage里.那我js是不是可以有个通用的请求方法
function commonAjax(data, url, callBack){ $.ajax({ contentType : 'application/json', url : url, data : data, type : 'POST', success : function(response){ if(response.success == true){ callBack();//请求成功,就调用后续方法 } else{ alert(response.errorMessage);//请求失败,用前端框架输出错误信息 } } }); }
大家不要吐槽上面这段JS有什么什么错误(我前端不是很好....我只是表达下大致意思..)
这个网站的所有页面只要有弹框提示错误信息,都可以用这个方法.这样我觉得可以省不少力气,不用每次自己去写ajax,而且做到了统一,下次需求要求输出errorcode,或者换个提示样式的时候都只要修改一个地方就行了.不用每个页面都去改一遍.
另外这种封装我觉得是可行的.一般做个页面肯定会用一个前端框架.提示信息的样式一定是统一的.不会这里用alert那里用框架自带的消息框.
利用SpringMVC与fastjson实现前后台数据格式统一
公司是用SpringMVC与jackson来做统一的...我不太喜欢和别人代码一样,另外公司的实现代码比较多...我这里只是写个demo,用不着那么多功能...所以我自己用springmvc与fastjson来做了一次尝试.首先我要介绍一些背景(据我所知):
SpringMVC有内置的converter可以解析http请求.但是功能比较简单.json字符串默认是不支持的.
前台一般页面写的都是JS代码,传过来的数据一般都是json格式.而fastjson可以方便的将json字符串转化成java对象.
既然如此.我们要做的就是去实现一个converter,将前台传送过来的字符串解析成java对象.
幸运的是fastjson自带了这个一个converter. 叫做FastJsonHttpMessageConverter. 所以只要配置这个converter就行了.
在Springmvc的配置XML中加入下面这段代码就可以了.
<mvc:annotation-driven> <mvc:message-converters> <bean class="com.labofjet.web.CustomerFastJsonHttpMessageConverter"> <property name="features"> <list> <value>WriteMapNullValue</value> <value>SortField</value> </list> </property> </bean> </mvc:message-converters> </mvc:annotation-driven>
我的class是我自己写的一个converter..继承了FastJsonHttpMessageConverter.feature是FastJsonHttpMessageConverter允许的一些特性.不写也可以.另外mvc:message-converters这个标签貌似对springmvc的版本有些要求.反正我http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd是验证不通过的..我用的是http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd....mvc:message-converters这个标签允许配置多个converter(看有个s就知道肯定允许多个).我这里只写了一个converter.对我来说足够了.因为我的目标就是前后台数据格式统一,所以只需要这么一个converter..哪天要加XML格式的时候我再加一个XML的converter就可以了.
然后要用到2个注解:@ResponseBody和@RequestBody..分别对应AbstractHttpMessageConverter中的writeInternal与readInternal方法...对应向HTTP响应写入数据与从HTTP请求中读取数据返回java对象.
converter可以有多个,所以到底哪个converter来处理呢? 这要看converter支持什么类型的MediaType.
如上图,这次请求的ContentType是blablabla.......(看截图红色区域)
而fastjson允许的MediaType是:
public FastJsonHttpMessageConverter(){ super(new MediaType("application", "json", UTF8), new MediaType("application", "*+json", UTF8)); }
所以我的commonAjax方法里需要指明
contentType : 'application/json'
这样才能被fastjson的converter解析...当然你也可以自己写一个converter去映射N种MediaType.
这样做了以后前后台json格式的数据都可以被fastjson的converter去处理了.然后我们来定义一个统一的数据格式:
package com.labofjet.web; import java.util.HashMap; import java.util.Map; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.labofjet.exception.BaseException; /** * 用于前后台数据交互时候格式的统一 * * @author jyzjyz12@163.com * */ public class ContextDTO { private boolean success; private Map<String, Object> data; private BaseException exception; public boolean getSuccess() { return success; } public void setSuccess(boolean success) { this.success = success; } public Map<String, Object> getData() { return data; } public void setData(Map<String, Object> data) { this.data = data; } public BaseException getException() { return exception; } public void setException(BaseException exception) { this.exception = exception; } public <T> T getDTOFromData(String name, Class<T> dtoClass){ JSONObject o = (JSONObject) data.get(name); return JSON.parseObject(o.toJSONString(), dtoClass); } public void putData(String name, Object obj){ if(data == null){ data = new HashMap<String, Object>(); } data.put(name, obj); } }
假设我的通用格式是这个..
然后我有个和某些业务相关的DTO(我这里随便找了个entity...只是测试用....举个例子而已..大家无视没用的注解....)
package com.labofjet.entity; import javax.persistence.Embedded; import javax.persistence.EmbeddedId; import javax.persistence.Entity; import javax.persistence.NamedStoredProcedureQueries; import javax.persistence.NamedStoredProcedureQuery; import javax.persistence.ParameterMode; import javax.persistence.StoredProcedureParameter; import org.apache.commons.lang3.builder.ToStringBuilder; @Entity @NamedStoredProcedureQueries({ @NamedStoredProcedureQuery(name = "User.plus1", procedureName = "plus1inout", parameters = { @StoredProcedureParameter(mode = ParameterMode.IN, name = "arg", type = Integer.class), @StoredProcedureParameter(mode = ParameterMode.OUT, name = "res", type = Integer.class) }), @NamedStoredProcedureQuery(name = "User.mytest", procedureName = "mytest") }) public class A { @EmbeddedId APK id; String age; @Embedded AComponent acomponent; int b; public AComponent getAcomponent() { return acomponent; } public void setAcomponent(AComponent acomponent) { this.acomponent = acomponent; } public String getAge() { return age; } public void setAge(String age) { this.age = age; } public APK getId() { return id; } public void setId(APK id) { this.id = id; } /** * @return the b */ public int getB() { return b; } /** * @param b the b to set */ public void setB(int b) { this.b = b; } @Override public int hashCode() { // TODO Auto-generated method stub System.out.println("Ahash"); return super.hashCode(); } @Override public boolean equals(Object obj) { // TODO Auto-generated method stub System.out.println("Aequals"); return super.equals(obj); } @Override public String toString() { return ToStringBuilder.reflectionToString(this); } } package com.labofjet.entity; import java.io.Serializable; public class APK implements Serializable{ String id; String name; public String getId() { return id; } public void setId(String id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public APK() { // TODO Auto-generated constructor stub } public APK(String id, String name){ this.id = id; this.name = name; } @Override public int hashCode() { // TODO Auto-generated method stub System.out.println("APKhash"); return super.hashCode(); } @Override public boolean equals(Object obj) { // TODO Auto-generated method stub System.out.println("APKequals"); return super.equals(obj); } }
然后我在controller里的测试代码
@RequestMapping("/test15") @ResponseBody public Object index15(@RequestBody ContextDTO context) { A a = context.getDTOFromData("aName", A.class); ContextDTO dto = new ContextDTO(); dto.putData("aDataName", a); dto.setSuccess(true); return dto; }
前台请求:
后台返回给前台的数据
后台获取到的数据
是不是很简单呀....
相关文章推荐
- Excel01-不同的单元格输入同一数据
- Intellij_idea-14官方快捷键中文版
- linux命令-mv
- 【高精度算法】A*B 加强版
- 织梦tag标签显示每个标签相应的文章数量的方法
- 单例的理解
- oracle层次化查询
- GTK+构件
- 【高精度算法】A*B
- Android:图片大小缩放drawable
- 用户手势检测类GestureDetector及其用法
- 解决无法修改注册表的情况
- office tab插件
- 随手记SharedSDK
- java -cp 用法介绍
- js禁止输入特殊字符
- 【mongodb】Linux 端的安装与测试
- 淘宝技术发展(Java时代:脱胎换骨)
- vcs 下使用system verilog调用c函数
- 二分查找(折半查找)