• 统一前后台数据交互格式


    公司前后台数据交互的格式是统一的,前台对jquery的ajax方法进行了一些封装,也就是说开发的时候并不是自己去调用$.ajax方法,而是调用统一的方法去处理.

    我感觉还是比较方便的..确实可以少写一些代码(因为通用代码被封装了),而且管理起来比较方便,统一..然后观察了一些网上的其他网站...发现很多网站都是这么做的...于是我也想自己动手来试试....我自己是使用springmvc与fastjson来实现的...下面分享一下我的经验.

    网上例子:

    首先先来找个网上的例子:

    这个页面的地址是https://www.bugclose.com/login.html 是我随便找的一个例子.

    仔细观察上面2张图片,我们可以发现几个特点:

    1.前台错误提示的样式是一样的,不同的错误的弹出框是一模一样的,只是里面的文字换了而已.

    2.2次请求返回的数据格式基本是一样的.

    我的思考:

    第一张图片里的输出信息是来自root.email,第二张图片里的输出信息是来自errorMessage.

    如果我把2种错误输出信息都写到errorMessage里.那我js是不是可以有个通用的请求方法

     1 function commonAjax(data, url, callBack){
     2     $.ajax({
     3         contentType : 'application/json',
     4         url : url,
     5         data : data,
     6         type : 'POST',
     7         success : function(response){
     8             if(response.success == true){
     9                 callBack();//请求成功,就调用后续方法
    10             } else{
    11                 alert(response.errorMessage);//请求失败,用前端框架输出错误信息
    12             }        
    13         }
    14     });
    15 }

    大家不要吐槽上面这段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中加入下面这段代码就可以了.

     1 <mvc:annotation-driven>
     2         <mvc:message-converters>
     3             <bean
     4                 class="com.labofjet.web.CustomerFastJsonHttpMessageConverter">
     5                 <property name="features">
     6                     <list>
     7                         <value>WriteMapNullValue</value>
     8                         <value>SortField</value>
     9                     </list>
    10                 </property>
    11             </bean>
    12         </mvc:message-converters>
    13     </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是:

    1     public FastJsonHttpMessageConverter(){
    2         super(new MediaType("application", "json", UTF8), new MediaType("application", "*+json", UTF8));
    3     }

    所以我的commonAjax方法里需要指明

    contentType : 'application/json'

    这样才能被fastjson的converter解析...当然你也可以自己写一个converter去映射N种MediaType.

    这样做了以后前后台json格式的数据都可以被fastjson的converter去处理了.然后我们来定义一个统一的数据格式:

     1 package com.labofjet.web;
     2 
     3 import java.util.HashMap;
     4 import java.util.Map;
     5 
     6 import com.alibaba.fastjson.JSON;
     7 import com.alibaba.fastjson.JSONObject;
     8 import com.labofjet.exception.BaseException;
     9 
    10 /**
    11  * 用于前后台数据交互时候格式的统一
    12  * 
    13  * @author jyzjyz12@163.com
    14  * 
    15  */
    16 public class ContextDTO {
    17     private boolean success;
    18     private Map<String, Object> data;
    19     private BaseException exception;
    20 
    21     public boolean getSuccess() {
    22         return success;
    23     }
    24 
    25     public void setSuccess(boolean success) {
    26         this.success = success;
    27     }
    28 
    29     public Map<String, Object> getData() {
    30         return data;
    31     }
    32 
    33     public void setData(Map<String, Object> data) {
    34         this.data = data;
    35     }
    36 
    37     public BaseException getException() {
    38         return exception;
    39     }
    40 
    41     public void setException(BaseException exception) {
    42         this.exception = exception;
    43     }
    44 
    45     public <T> T getDTOFromData(String name, Class<T> dtoClass){
    46         JSONObject o = (JSONObject) data.get(name);
    47         return JSON.parseObject(o.toJSONString(), dtoClass);
    48     }
    49     
    50     public void putData(String name, Object obj){
    51         if(data == null){
    52             data = new HashMap<String, Object>();
    53         }
    54         data.put(name, obj);
    55     }   
    56 }

    假设我的通用格式是这个..

    然后我有个和某些业务相关的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里的测试代码

    1     @RequestMapping("/test15")
    2     @ResponseBody
    3     public Object index15(@RequestBody ContextDTO context) {
    4         A a = context.getDTOFromData("aName", A.class);
    5         ContextDTO dto = new ContextDTO();
    6         dto.putData("aDataName", a);
    7         dto.setSuccess(true);
    8         return dto;
    9     }

    前台请求:

    后台返回给前台的数据

    后台获取到的数据

    是不是很简单呀....

  • 相关阅读:
    方法和参数
    【转】priority_queue优先队列
    【转】主席树学习
    【转】树链剖分
    【转】线段树完全版~by NotOnlySuccess
    【转】树状数组
    【转】最大流EK算法
    【转】POJ题目分类推荐 (很好很有层次感)
    【转】原根
    【转】Polya定理
  • 原文地址:https://www.cnblogs.com/abcwt112/p/5169250.html
Copyright © 2020-2023  润新知