Springboot 實作api介面(一)
1、序言
網路程式正朝著移動設備的方向發展,前后端分離、APP,最好的互動互動方式莫過于通過API介面實作,
本專案加密方式采用引數排序+key驗簽方式,后期可按需求更換
本次我們先了解一下Spring對API介面開發的支持,然后我們采用Spring Boot搭建專案,本專案暫未使用權限管理系統,后期主鍵完善,可按需求對key進行配置或者使用安全框架進行管理,借用Swagger列出API介面,便于查閱,
2、回傳格式
根據當前趨勢,API介面要求回傳的格式一般為 application/json,有特殊行業如銀行等回傳格式為xml報文,本次統一使用json,Spring Boot回傳json,提供了兩種實作方式:類注解 和 方法注解,
類注解 @RestController
@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介面,會顯得我們的編碼風格十分統一,代碼更加緊湊,不至于看起來零散,
注:Mapping根據業務自行選擇,推薦@GetMapping、@PostMapping格式,
3、接收引數/引數驗證
- 舉例說明
@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例外,后期統一例外處理回應,
@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;
}
4、例外統一處理
每個程序都單獨處理例外,系統的代碼耦合度高,作業量大且不好統一,維護的作業量也很大, 為了將所有型別的例外處理從各處理程序解耦出來,保證相關處理程序的功能較單一,實作例外資訊的統一處理和維護,
Spring MVC處理例外有3種方式:
-
使用Spring MVC提供的簡單例外處理器SimpleMappingExceptionResolver;
-
實作Spring的例外處理介面HandlerExceptionResolver 自定義自己的例外處理器;
-
使用@ExceptionHandler注解實作例外處理;
今天主要說springboot基于@ExceptionHandler注解實作例外處理
@ExceptionHandler注解:定義控制器發生例外后的操作,可以攔截所有控制器發生的例外,統一例外處理 ,通過@ExceptionHandler(value = Exception.class) 來指定捕獲的例外,“@ControllerAdvice + @ExceptionHandle" 可以處理除“404”以外的運行例外,
- 創建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;
}
}
- 創建統一回應類
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;
}
- 創建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;
}
}
注:下一篇請求加密驗簽和介面檔案使用,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/193483.html
標籤:其他
上一篇:ArrayList原始碼(new(),add(),get())
下一篇:java尋找迷宮路徑的簡單實作
