自定義ResponseResult在controller響應信息主體和自定義全局及局部異常中的實現

前言:

在controller及hanlder的消息返回給客戶端的json對象信息,一般是自定義的,輸出格式是json格式!

自定義詳細編號HttpEnum

/**
 * <b><code>HttpEnum</code></b>
 * <p>
 * Description
 * </p>
 * <b>Creation Time:</b> 2019/11/26 16:21.
 *
 */
public enum HttpEnum {
    /**
     * 請求處理正常
     */
    OK_200(200, "請求成功"),

    /**
     * 請求處理正常
     */
    CREATED_201(201, "創建成功"),


    /**
     * 請求處理異常,請稍後再試
     */
    ERROR_400(400, "非法請求"),

    /**
     * 訪問內容不存在
     */
    NotFound_400(404, "訪問內容不存在"),

    /**
     * 系統內部錯誤
     */
    ERROR_500(500, "系統內部錯誤"),

    /**
     * 參數校驗失敗
     */
    ERROR_600(600, "參數校驗失敗");

    private String desc;

    private int code;

    private HttpEnum(int code, String desc) {
        this.desc = desc;
        this.code = code;
    }

    public String desc() {
        return desc;
    }

    public int code() {
        return code;
    }

}

自定義響應的信息主體ResponseResult

import java.io.Serializable;

import com.a.b.c.commons.enums.HttpEnum;

import lombok.Getter;
import lombok.Setter;

/**
 * <b><code>ResponseResult</code></b>
 * <p>
 * Description響應信息主體
 * </p>
 * <b>Creation Time:</b> 2019/11/26 17:55.
 *
 * @author chensen
 * @since gempile-boiler-code 0.1.0
 */
public class ResponseResult<T> implements Serializable {
    private static final long serialVersionUID = 1L;

    @Getter
    @Setter
    private int code;

    @Getter
    @Setter
    private String msg;

    @Getter
    @Setter
    private T data;

    public static <T> ResponseResult<T> ok() {
        return restResult(null, HttpEnum.OK_200.code(), HttpEnum.OK_200.desc());
    }

    public static <T> ResponseResult<T> ok(T data) {
        return restResult(data, HttpEnum.OK_200.code(), HttpEnum.OK_200.desc());
    }

    public static <T> ResponseResult<T> ok(T data, String msg) {
        return restResult(data, HttpEnum.OK_200.code(), msg);
    }

    public static <T> ResponseResult<T> failed() {
        return restResult(null, HttpEnum.ERROR_500.code(),
                HttpEnum.ERROR_500.desc());
    }

    public static <T> ResponseResult<T> failed(String msg) {
        return restResult(null, HttpEnum.ERROR_500.code(), msg);
    }

    public static <T> ResponseResult<T> failed(int code, String msg) {
        return restResult(null, code, msg);
    }

    public static <T> ResponseResult<T> failed(T data) {
        return restResult(data, HttpEnum.ERROR_500.code(),
                HttpEnum.ERROR_500.desc());
    }

    public static <T> ResponseResult<T> failed(T data, String msg) {
        return restResult(data, HttpEnum.ERROR_500.code(), msg);
    }

    private static <T> ResponseResult<T> restResult(T data, int code,
                                                    String msg) {
        ResponseResult<T> apiResult = new ResponseResult<>();
        apiResult.setCode(code);
        apiResult.setData(data);
        apiResult.setMsg(msg);
        return apiResult;
    }
}

ResponseResult在Handler中的應用

處理異常

在應用開發過程中,除系統自身的異常外,不同業務場景中用到的異常也不一樣,爲了與標題 輕鬆搞定全局異常 更加的貼切,定義個自己的異常,看看如何捕獲…

  • @ControllerAdvice 捕獲 Controller 層拋出的異常,如果添加 @ResponseBody 返回信息則爲JSON格式。
  • @RestControllerAdvice 相當於 @ControllerAdvice 與 @ResponseBody 的結合體。
  • @ExceptionHandler 統一處理一種類的異常,減少代碼重複率,降低複雜度。

創建全局異常

創建一個 GlobalExceptionHandler 類,並添加上 @RestControllerAdvice 註解就可以定義出異常通知類了,然後在定義的方法中添加上 @ExceptionHandler 即可實現異常的捕捉…

GlobalExceptionHandler 類

import java.util.List;

import org.springframework.http.HttpStatus;
import org.springframework.validation.BindException;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import com.alibaba.fastjson.JSONObject;
import com.a.b.c.commons.enums.HttpEnum;
import com.a.b.c.commons.util.ResponseResult;

import lombok.extern.slf4j.Slf4j;

/**
 * <b><code>GlobalExceptionHandler</code></b>
 * <p>
 * Description
 * </p>
 * <b>Creation Time:</b> 2019/11/26 16:17.
 *
 */
@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {
    /**
     * 全局異常.
     *
     * @param e the e
     * @return ResponseResult
     */
    @ExceptionHandler(Exception.class)
    public ResponseResult exception(Exception e) {
        log.error("全局異常信息 ex={}", e.getMessage(), e);
        JSONObject errorObject = new JSONObject();
        errorObject.put("errorInfo", e.toString());
        // 如果錯誤堆棧信息存在
        if (e.getStackTrace().length > 0) {
            StackTraceElement element = e.getStackTrace()[0];
            int lineNumber = element.getLineNumber();
            errorObject.put("errorPosition", element + ":" + lineNumber);
        }
        return ResponseResult.failed(errorObject);
    }

    /**
     * 自定義異常處理
     * @param e
     * @return ResponseResult
     */
    @ExceptionHandler({CustomException.class})
    public ResponseResult customExceptionHandLer(CustomException e) {
        return ResponseResult.failed(e.getCode(), e.getDesc());
    }

    /**
     * 校驗異常 Exception
     *
     * @param exception
     * @return ResponseResult
     */
    @ExceptionHandler({MethodArgumentNotValidException.class, BindException.class})
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public ResponseResult bodyValidExceptionHandler(MethodArgumentNotValidException exception) {
        List<FieldError> fieldErrors = exception.getBindingResult().getFieldErrors();
        String errorMessage="";
        if(fieldErrors!=null&&fieldErrors.size()>0){
            log.warn(fieldErrors.get(0).getDefaultMessage());
            errorMessage=fieldErrors.get(0).getDefaultMessage();
        }
        return ResponseResult.failed(HttpEnum.ERROR_600.code(), errorMessage);
    }

}

出現404或者405等錯誤信息

ErrorController當系統出現404或者405等錯誤信息時,springboot默認的訪問路徑爲/error,所以實現ErrorController並重寫

import javax.servlet.http.HttpServletRequest;

import org.springframework.boot.web.servlet.error.ErrorController;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.a.b.c.commons.enums.HttpEnum;
import com.a.b.c.commons.util.ResponseResult;

/**
 * <b><code>NotFoundException</code></b>
 * <p>
 * Description
 * </p>
 * <b>Creation Time:</b> 2019/12/4 14:15.
 *
 */
@RestController
public class NotFoundException implements ErrorController {

    @Override
    public String getErrorPath() {
        return "/error";
    }

    @RequestMapping(value = {"/error"})
    public ResponseResult error(HttpServletRequest request) {
        return ResponseResult.failed(HttpEnum.NotFound_400.code(), HttpEnum.NotFound_400.desc());
    }
}

在controller中的應用

import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletResponse;

import com.a.b.c.entity.common.GAppDetailInfo;
import com.a.b.c.entity.indicator.GAppIndicator;
import com.a.b.c.mapper.common.GIndicatorQueryMapper;
import com.a.b.c.service.common.GComonConfigService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.a.b.c.commons.util.DateUtils;
import com.a.b.c.commons.util.ResponseResult;
import com.a.b.c.service.alarm.GAlarmQueryService;

import io.swagger.annotations.*;

/**
 * <b><code>GCommonConfigController</code></b>
 * <p/>
 * Description
 * <p/>
 * <b>Creation Time:</b> 2019/12/7 11:22.
 *
 */
@SuppressWarnings("MagicConstant")
@RestController
@RequestMapping("/v1.0")
@Api(value = "[Gpile-voiler 1.0]通用配置查詢")
public class GCommonConfigController {

    /**
     * logger.
     */
    private static Logger logger = LoggerFactory.getLogger(GCommonConfigController.class);

    /**
     * The gmp alarm query statistics service.
     */
    @Autowired
    private GAlarmQueryService GAlarmQueryService;

    @Autowired
    private GComonConfigService GComonConfigService;

    /**
     * get app indicator.
     */
    @RequestMapping(value = "/config/indicators", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    @ApiOperation(value = "[Gpile-boiler]指標查詢", notes = "get indicators")
    @ApiResponses(value = {
            @ApiResponse(code = 200, message = "successful query", response = Integer.class, responseContainer = "int"),
            @ApiResponse(code = 500, message = "internal server error") })
    public ResponseResult getAlertResult(
            @ApiParam(value = "應用code") @RequestParam(value = "appCode") String appCode,
            @ApiParam(value = "模塊id") @RequestParam(value = "module",required = false) String module,
            @ApiParam(value = "維度id") @RequestParam(value = "dimension",  required = false) String dimension
            ) {

        List<GAppIndicator> results= GComonConfigService.selectIndicatorByParm(appCode,module,dimension);
        return ResponseResult.ok(results);
    }

    /**
     * get app detail info.
     */
    @RequestMapping(value = "/config/appDetailInfo", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    @ApiOperation(value = "[Gpile-boiler]設備信息查詢", notes = "get app detail info")
    @ApiResponses(value = {
            @ApiResponse(code = 200, message = "successful query", response = Integer.class, responseContainer = "int"),
            @ApiResponse(code = 500, message = "internal server error") })
    public ResponseResult getAlertResult(
            @ApiParam(value = "應用code") @RequestParam(value = "appCode") String appCode,
            @ApiParam(value = "設備code") @RequestParam(value = "deviceCode",required = false) Long deviceCode
            ) {

        List<GAppDetailInfo> results= GComonConfigService.selectDeviceInfoByAppCode(appCode,deviceCode,null);
        return ResponseResult.ok(results);
    }
}

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章