Springboot 實現api接口(一)

Springboot 實現api接口(一)

一、序言

網絡程序正朝着移動設備的方向發展,先後端分離、APP,最好的交互交互方式莫過於經過API接口實現。前端

本項目加密方式採用參數排序+key驗籤方式,後期可按需求更換java

本次咱們先了解一下Spring對API接口開發的支持,而後咱們採用Spring Boot搭建項目,本項目暫未使用權限管理系統,後期主鍵完善,可按需求對key進行配置或者使用安全框架進行管理。借用Swagger列出API接口,便於查閱。web

二、返回格式

根據當前趨勢,API接口要求返回的格式通常爲 application/json,有特殊行業如銀行等返回格式爲xml報文,本次統一使用json。Spring Boot返回json,提供了兩種實現方式:類註解方法註解spring

類註解 @RestControllerjson

@RestController
@RequestMapping("/user")
public class UserController { 
    @GetMapping("/saveUser")
    public Object saveUser(@Validated User user){ 
        return user;
    }
}

方法註解 @ResponseBody後端

@Controller
@RequestMapping("/demo")
public class Demo { 
    @RequestMapping
    @ResponseBody
    public String getCapitalize(String args){ 
        return args.toUpperCase();
    }
}

值得提醒的是,雖然都是均可以,但我更推薦使用類註解,項目的主要目的是提供和統一api接口,會顯得咱們的編碼風格十分統一,代碼更加緊湊,不至於看起來零散。api

注:Mapping根據業務自行選擇,推薦@GetMapping、@PostMapping格式。安全

三、接收參數/參數驗證

  • 舉例說明
@GetMapping("/saveUser")
public Object saveUser(@Validated User user){ 
    return user;
}
  • 可使用validation進行參數驗證
    maven導包
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-validation</artifactId>
</dependency>

在實體參數上添加註解來達到驗證參數的效果,而後在方法參數前添加@Validated開啓驗證。若是參數錯誤會拋出BindException異常,後期統一異常處理響應。springboot

@Data
@JsonInclude(JsonInclude.Include.NON_NULL)//解決參數爲null不返回前端
public class User implements Serializable { 
    private Long Id;
    @NotNull(message = "用戶名不能爲空")
    private String username;
    @NotNull(message = "年齡不能爲空")
    private Integer age;
    private String email;
}

四、異常統一處理

每一個過程都單獨處理異常,系統的代碼耦合度高,工做量大且很差統一,維護的工做量也很大。 爲了將全部類型的異常處理從各處理過程解耦出來,保證相關處理過程的功能較單一,實現異常信息的統一處理和維護。網絡

Spring MVC處理異常有3種方式:

  • 使用Spring MVC提供的簡單異常處理器SimpleMappingExceptionResolver;

  • 實現Spring的異常處理接口HandlerExceptionResolver 自定義本身的異常處理器;

  • 使用@ExceptionHandler註解實現異常處理;

今天主要說springboot基於@ExceptionHandler註解實現異常處理

@ExceptionHandler註解:定義控制器發生異常後的操做,能夠攔截全部控制器發生的異常。統一異常處理 ,經過@ExceptionHandler(value = Exception.class) 來指定捕獲的異常。「@ControllerAdvice + @ExceptionHandle" 能夠處理除「404」之外的運行異常。

  1. 建立BaseBusinessException類(自定義業務異常),繼承RuntimeException類。
package com.cch.error;

import lombok.Data;
import lombok.NoArgsConstructor;

/** * @Auther: cch * @Date: 2020/9/21 16:03 * @Description: 自定義異常返回結果實體類 */
@Data
@NoArgsConstructor
public class BaseBusinessException extends RuntimeException{ 

    private BaseError error = DefaultError.SYSTEM_INTERNAL_ERROR;
    private String extMessage = null;

    public BaseBusinessException(String message) { 
        super(message);
        this.extMessage = message;
    }
    public BaseBusinessException(String message, Throwable cause) { 
        super(message, cause);
        this.extMessage = message;
    }
    public BaseBusinessException(Throwable cause) { 
        super(cause);
    }
    public BaseBusinessException(BaseError error) { 
        this.error = error;
    }
    public BaseBusinessException(String message, BaseError error) { 
        super(message);
        this.extMessage = message;
        this.error = error;
    }
    public BaseBusinessException(String message, Throwable cause, BaseError error) { 
        super(message, cause);
        this.extMessage = message;
        this.error = error;
    }
    public BaseBusinessException(Throwable cause, BaseError error) { 
        super(cause);
        this.error = error;
    }
}
  1. 建立統一響應類
package com.cch.error;

import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.Data;

/** * @Auther: cch * @Date: 2020/9/21 16:12 * @Description: 相應結果實體類 */
@Data
@JsonInclude(JsonInclude.Include.NON_NULL)
public class Response { 

    private String code;
    private Object data;
    private String message;

}
  1. 建立ExceptionControllerAdvice類(全局異常處理器),使用ResponseEntity返回自定義響應碼 – 508。
package com.cch.exception;

import com.cch.error.BaseBusinessException;
import com.cch.error.DefaultError;
import com.cch.error.Response;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.BindException;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

/** * @Auther: cch * @Date: 2020/9/21 14:07 * @Description: 全局處理異常 */
@RestControllerAdvice
public class ExceptionControllerAdvice { 

    @ExceptionHandler(Exception.class)
    public ResponseEntity<Response> APIExceptionHandler(Exception exception) { 

        Response response = new Response();

        if (exception instanceof BaseBusinessException) { 
            BaseBusinessException bbe = (BaseBusinessException)exception;
            response.setCode(bbe.getError().getErrorCode());
            response.setData(bbe.getError().getErrorMessage());
            if (exception.getMessage() != null) { 
                response.setData(exception.getMessage());
            }
        } else if (exception instanceof BindException) { 
            BindException bindException = (BindException)exception;
            response.setCode(DefaultError.PARAMETER_ERROR.getErrorCode());
            response.setData(DefaultError.PARAMETER_ERROR.getErrorMessage());
            FieldError fieldError = bindException.getBindingResult().getFieldError();
            response.setMessage(fieldError.getDefaultMessage());
        }else{ 
            exception.printStackTrace();
            response.setCode(DefaultError.SYSTEM_INTERNAL_ERROR.getErrorCode());
            response.setData(DefaultError.SYSTEM_INTERNAL_ERROR.getErrorMessage());
        }
        return new ResponseEntity (response, HttpStatus.LOOP_DETECTED);
    }

}

當項目中又異常可直接拋出,示例:

@GetMapping("/saveUser")
    public Object saveUser(@Validated User user){ 
        if(user == null){ 
            throw new BaseBusinessException("用戶不能爲空");
        }
        return user;
    }

附:異常使用枚舉,可根據我的需求靈活使用,這是我我的使用習慣。
BaseError接口

package com.cch.error;

/** * @Auther: cch * @Date: 2020/9/21 16:06 * @Description: 異常枚舉父接口 */
public interface BaseError { 
    String getErrorCode();
    String getErrorMessage();

}

可根據異常類型定義多個枚舉,而後實現BaseError,示例通用異常:

package com.cch.error;

/** * @Auther: cch * @Date: 2020/9/21 16:07 * @Description: 默認異常 */
public enum DefaultError implements BaseError { 

    SYSTEM_INTERNAL_ERROR("0000", "系統內部錯誤"),
    PARAMETER_ERROR("0001","參數錯誤");

    String errorCode;
    String errorMessage;
    private static final String ns = "DFT";

    DefaultError(String errorCode, String errorMessage) { 
        this.errorCode = errorCode;
        this.errorMessage = errorMessage;
    }

    @Override
    public String getErrorCode() { 
        return ns + "." + errorCode;
    }

    @Override
    public String getErrorMessage() { 
        return errorMessage;
    }
}

注:下一篇請求加密驗籤和接口文檔使用。

相關文章
相關標籤/搜索