springboot統一ajax返回數據格式,而且jquery ajax success函數修改

服務端代碼:前端

package com.zhqn.sc.cfg;


import org.springframework.core.MethodParameter;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.zhqn.sc.entity.dto.ErrorModal;
import com.zhqn.sc.entity.dto.ResponseInfo;
import com.zhqn.sc.entity.dto.ScException;

@ControllerAdvice
public class ScResponseAdvise implements ResponseBodyAdvice<Object>{

	@Override
	public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {
		return true;
	}

	@Override
	public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType,
			Class<? extends HttpMessageConverter<?>> selectedConverterType, ServerHttpRequest request,
			ServerHttpResponse response) {
		ResponseInfo responseInfo = new ResponseInfo();
		if(body instanceof ErrorModal) {
			responseInfo.setSuccess(false);
		}else {
			responseInfo.setSuccess(true);
		}
		responseInfo.setData(body);
		if(selectedConverterType.equals(StringHttpMessageConverter.class)) {
			return handleString(responseInfo, response);
		}
		return responseInfo;
	}

	Object handleString(ResponseInfo responseInfo, ServerHttpResponse response) {
		ObjectMapper mapper = new ObjectMapper();
		response.getHeaders().add(HttpHeaders.CONTENT_TYPE, "application/json;charset=UTF-8");
		try {
			return mapper.writeValueAsString(responseInfo);
		} catch (JsonProcessingException e) {
			e.printStackTrace();
			ScException.error(e.getMessage());
		}
		return  null;
	}

}

  

  

package com.zhqn.sc.entity.dto;

public class ResponseInfo {

    private boolean success;
    
    private Object data;

    public boolean isSuccess() {
        return success;
    }

    public void setSuccess(boolean success) {
        this.success = success;
    }

    public Object getData() {
        return data;
    }

    public void setData(Object data) {
        this.data = data;
    }
    
}
package com.zhqn.sc.entity.dto;

import java.util.Date;

public class ErrorModal {

    private Date date;
    
    private Integer code;
    
    private String errorStr;

    public Integer getCode() {
        return code;
    }

    public void setCode(Integer code) {
        this.code = code;
    }

    public String getErrorStr() {
        return errorStr;
    }

    public void setErrorStr(String errorStr) {
        this.errorStr = errorStr;
    }

    public Date getDate() {
        return date;
    }

    public void setDate(Date date) {
        this.date = date;
    }
    
}

返回的數據格式是java

{success : true , data : ResponseInfo}表明沒有異常時的數據,jquery

{success : false , data : ErrorModal}表明異常時的數據,有全局異常處理器處理返回的,這一步能夠參考網上的教程。web

這一切看似很完美,可是無論發生不發生異常,response的status都是200,前端jquery ajax函數都走的是success方法,這個函數設計初衷就是處理成功時的數據,失敗應該走error方法,所以須要修改jquery ajax方法,能夠用js aop思路處理,代碼以下:ajax

(function(win){
    var ajax = $.ajax;
    $.ajax = function(a) {
        var oldSuccess = a && a.success && (typeof a.success == "function") ? a.success : null;
        var oldError = a && a.error && (typeof a.error == "function") ? a.error : null;
        var success = function(response) {
            if(response && "data" in response && "success" in response) {
                var res = response;
                arguments[0] = response.data;
                if(res.success == true) {
                    oldSuccess && oldSuccess.apply(this, arguments);
                }else if(oldError){
                    oldError.apply(this, arguments);
                }else {
                    alertError(res.data);
                }
                
            }else {
                arguments[0] = {errorStr : "數據格式錯誤!"};
            }
        };
        var error = function(data) {
            alertError(data);
        }
        if(a) {
            a.success = success;
            a.error = error;
        }else {
            arguments[0] = {
                success : success,
                error : error
            };
        }
        ajax.apply(this, arguments);
    }
    function alertError(data) {
        if("status" in data && data.status == 403) {
            return;
        }
        alert(data.errorStr || data.responseJSON && data.responseJSON.errorStr || data.responseText || "服務器鏈接失敗");
    }
    $(document).ajaxError(function(event,xhr,options,exc){
        if(xhr.status == 403 && xhr.getResponseHeader("redirectUrl")) {
            window.top.location.href = xhr.getResponseHeader("redirectUrl");
        }
    });
})(window);

只要引入這段代碼,原先的success,error均可以正常使用,另外$.get,$.post,$.getJSON,$.getScript都不會有問題,由於它們最後都要調用$.ajax。spring

相關文章
相關標籤/搜索