前言:
在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);
}
}