自定义responseresult在controller响应信息主体和自定义全局及局部异常中的实现(代码片段)

阿啄debugIT 阿啄debugIT     2022-10-20     212

关键词:

前言:

在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);
    

 

 

 

 

 

自定义 UIView 在 View Controller 中被解包为 nil

】自定义UIView在ViewController中被解包为nil【英文标题】:CustomUIViewisbeingunwrappedasnilinViewController【发布时间】:2020-08-2714:11:33【问题描述】:我正在尝试将自定义UIView添加到视图控制器。我以前做过,没有任何问题,所以我在这里... 查看详情

Safari View Controller 自定义大小,框架添加为子视图

】SafariViewController自定义大小,框架添加为子视图【英文标题】:SafariViewControllercustomizingsize,frameaddasasubview【发布时间】:2016-03-2217:24:40【问题描述】:如何自定义Safari视图控制器以在屏幕上显示我的导航栏和导航栏按钮?这可... 查看详情

如何从自定义 UICollectionViewCell 启动 View Controller

】如何从自定义UICollectionViewCell启动ViewController【英文标题】:HowtolaunchViewControllerfromacustomUICollectionViewCell【发布时间】:2014-07-2208:25:22【问题描述】:我需要从我的自定义UICollectionViewCell启动ViewController,但我无法在那里访问我... 查看详情

rubyonrails如何自定义controller对应的view目录?

比如我有一个users的controller,这个时候view对应view目录的也将会是view/users/,但是我想自定义users的目录为peoples则应该怎么样呢?设置代码如下,classUsersController<ApplicationControllerdefself.controller_path"peoples"endend这样就可以改变User... 查看详情

在 Symfony 4.4 中实现自定义错误控制器

...中实现自定义错误控制器【英文标题】:ImplementacustomerrorcontrollerinSymfony4.4【发布时间】:2021-01-2206:34:01【问题描述】:我做了什么:我创建了这个自定义控制器,因为我想向错误页面传递一些额外的变量。#Controller/CustomErrorContro... 查看详情

MVC:我应该在 View Controller 或 UIView 的自定义子类中添加和实现触摸手势吗

】MVC:我应该在ViewController或UIView的自定义子类中添加和实现触摸手势吗【英文标题】:MVC:shouldiaddandimplementtouchgesturesintheViewControllerormycustomsubclassofUIView【发布时间】:2014-11-0313:48:24【问题描述】:我有一个UIView的自定义子类,... 查看详情

将自定义 UserManager 注入 Controller Net Core 2.1

】将自定义UserManager注入ControllerNetCore2.1【英文标题】:InjectCustomUserManagerToControllerNetCore2.1【发布时间】:2019-01-0817:18:11【问题描述】:我在尝试将我的UserManager注入我的控制器时遇到问题。这是我的自定义UserManager:publicclassAppli... 查看详情

如何在wpf中自定义控件

...并使用DrawingContext从头绘制内容时,才会继承该类。 Control当从头开始创建控件时,这是最常用的起点。该类是所有用户交互小组件的基类。Control类添加了用于设置背景、前景、字体和内容对齐方式的属性。控件类还为自身... 查看详情

iOS 开发 - 如何使用自定义 Table View Controller 显示在 Interface Builder 中创建的静态单元格?

】iOS开发-如何使用自定义TableViewController显示在InterfaceBuilder中创建的静态单元格?【英文标题】:iOSdevelopment-HowtodisplaystaticcellscreatedinInterfaceBuilderwithcustomTableViewController?【发布时间】:2013-12-0813:47:44【问题描述】:我试图用表格... 查看详情

angularjs自定义服务指令

.../wy/js-ajax/90977.htmAngularJS注册服务AngularJS的后台控制可以在Controller里面实现.可是如果所有的逻辑代码都写到Controller会显得该Controller过于臃肿.不方便维护,AngularJS提供了一个可以依赖注入的方法。我们可以将逻辑处理封装到Service... 查看详情

WordPress 自定义表单在管理面板上提交数据视图?

...包含2个字段和一个提交按钮。看看我的表格:<divclass="control-group"><labelclass="control-label"for= 查看详情

k8s自定义controller三部曲之一:创建crd(customresourcedefinition)(代码片段)

欢迎访问我的GitHub本篇概览k8s系统中controller扮演着重要角色,开发自定义controller是深入学习和理解controller的有效途径,《k8s自定义controller三部曲》系列会逐步完成一次完整的自定义controller实战;实战概要整个三部曲的目标如... 查看详情

基于不适用于 System.Web.UI.Control 对象的 CA2000“在失去范围之前处理对象”创建自定义 FXCop 规则

】基于不适用于System.Web.UI.Control对象的CA2000“在失去范围之前处理对象”创建自定义FXCop规则【英文标题】:CreatingaCustomFXCopRulebasedonCA2000"DisposeObjectsBeforeLosingScope"thatdoesn\'tapplytoSystem.Web.UI.Controlobjects【发布时间】:2011-06-0... 查看详情

k8s自定义controller三部曲之二:自动生成代码(代码片段)

欢迎访问我的GitHub本文是《k8s自定义controller三部曲》的第二篇,上一篇我们在k8s环境注册了API对象Student,此时如果创建Student对象就会在etcd保存该对象信息;源码下载接下来详细讲述应用的编码过程,如果您不想自己写代码,... 查看详情

如何在 ASP.NET MVC 中自定义目录结构?

...此最好将它们构造成逻辑目录和各自的命名空间,例如“Controllers/Admin/”、“Controllers/Warehouse/Supplies/”等。ASP.NETMVC是否支持嵌 查看详情

yaf自定义autoload以实现model文件和controller文件命名区分

...于Yaf作者在设计Yaf框架目录时没有直接区分开models文件和controllers文件,所以在IDE看着会很难受,眼睛离开了编辑器就不大好区分这两个文件夹的文件。所以自己写了一个autoload。PS:也许大大们觉德没有必要,之前用Tp的时候觉得... 查看详情

自定义指令

...交互.也就是说,ngModel指令虽然是内置的,但它也有自己的controller属性,其它指令也可以通过require来得到ngModel指令的controller属性的实例来与ngModel指令进行交互.ngModelController用在什么场合呢?我们知道,ngModel提供了数据绑定,验证,样式... 查看详情

为啥 Access-Control-Request-Headers 中包含非自定义标头?

】为啥Access-Control-Request-Headers中包含非自定义标头?【英文标题】:Whyarenon-customheadersincludedinAccess-Control-Request-Headers?为什么Access-Control-Request-Headers中包含非自定义标头?【发布时间】:2013-06-2404:42:28【问题描述】:我正在尝试... 查看详情