服務端代碼:前端
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