日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

java web 自定义异常_Java web, service 层应该通过异常(自定义Exception)来中断业务吗?...

發布時間:2024/8/23 java 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java web 自定义异常_Java web, service 层应该通过异常(自定义Exception)来中断业务吗?... 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

同意!但是不是最佳實踐還有待商榷,我這里給出自己一直使用的用異常控制流程的方案,分享討論一下吧。

由于JAVA只能有一個返回值,但有時候一個service方法除了返回結果外還真的需要有一些附加信息,比如用戶非法操作時要中斷流程并給出錯誤信息。如果你不想在service方法中充滿著各種大多時候都無用的ResultBean或者讓人看見就頭大的Map,異常的確值得去嘗試一下。

異常最大的優勢就是可以中斷方法并返回附加信息,方便統一管理,使你的代碼更簡潔。

缺點就是性能,至于差多少還沒測試過,希望有人可以去測一下。

下面開始主題內容:

1.定義異常;

我理解的業務異常是指用戶非法操作(如注冊用戶名重復)需要中斷操作并給用戶返回合理信息的異常。定義如下:

先定義一個繼承自RuntimeException的異常,主要在最后一個構造方法,后面兩個值為false,false。意思就是不調用fillIStackTrace()方法和不添加suppressException;因為我們主要關注錯誤信息,并不在意棧軌跡,所以禁用他們用來提高性能。當然也可以通過復寫特定方法來實現,我只是覺得用構造方法更簡單。

public class UnFillStackTraceException extends RuntimeException {

private static final long serialVersionUID = -3181827538683088424L;

public UnFillStackTraceException() {

this(null, null);

}

public UnFillStackTraceException(String message) {

this(message, null);

}

public UnFillStackTraceException(Throwable cause) {

this(null, cause);

}

public UnFillStackTraceException(String message, Throwable cause) {

super(message, cause, false, false);

}

}

接下來定義業務異常:

public class APIException extends UnFillStackTraceException {

private static final long serialVersionUID = -1043498038361659805L;

private final StatusCode statusCode;

public APIException(StatusCode statusCode) {

this.statusCode = statusCode;

}

public APIException(StatusCode statusCode, String message) {

super(message);

this.statusCode = statusCode;

}

public StatusCode getStatusCode() {

return this.statusCode;

}

@Override

public String getMessage() {

return StringUtils.defaultIfBlank(super.getMessage(), statusCode.defaultMessage);

}

}

很簡單,上面的看一下就明白。因為我們說了業務異常必須是明確,可以給用戶提示的錯誤,所以要構造APIException必須設置相應的StatusCode。

2. StatusCode的設計

業務異常之中肯定要包含相應的錯誤信息,一般用代碼來表示,代碼設計的方式有好多種,這里我采用的方案是:基于HttpStatusCode的基礎上擴展三位。好處就是可以和HTTP狀態碼相互轉換,因為我們前臺返回的時候都是基于http狀態碼的。

代碼如下:

public enum StatusCode {

/**

* 服務器未知異常

*/

ERROR(500000, "服務器異常"),

//授權異常

DISABLE_ACCOUNT(401001, "賬戶已被凍結"),

INVALID_TOKEN(401002, "無效的身份憑證"),

EXPIRED_TOKEN(401003, "身份憑證已過期"),

NO_PERMISSION(401004, "無權限進行該操作"),

BAD_CREDENTIALS(401005, "密碼錯誤"),

ILLEGAL_OPERATION(400001, "非法操作"),

NOT_FOUND(404000,"訪問的資源不存在"),

INVALID_PARAM(422001, "參數無效");

public final int code;

public final String defaultMessage;

StatusCode(int code, String defaultMessage) {

this.code = code;

this.defaultMessage = defaultMessage;

}

public int getHttpStatusCode(){

return convertToHttpStatus(this);

}

public static StatusCode valueOf(int code) {

for (StatusCode value : StatusCode.values()) {

if (value.code == code) {

return value;

}

}

throw new IllegalArgumentException("沒有符合'" + code + "'的StatusCode");

}

public static int convertToHttpStatus(StatusCode statusCode) {

return statusCode.code / 1000;

}

public static int convertToHttpStatus(int code) {

return convertToHttpStatus(valueOf(code));

}

}

3. 捕獲異常

這一步基本上沒啥說的,統一用ControllerAdvice捕獲就行了。

@RestControllerAdvice

public class ControllerExceptionHandler {

public static final Logger log = LoggerFactory.getLogger(ControllerExceptionHandler.class);

@ExceptionHandler(APIException.class)

public ResponseEntity handleBusinessException(APIException apiException){

return ResponseEntity.status(apiException.getStatusCode().getHttpStatusCode())

.body(new ErrorBody(apiException));

}

@ExceptionHandler(Exception.class)

@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)

public ErrorBody handleUnknownException(Exception e){

log.error("服務器未知異常",e);

return new ErrorBody(StatusCode.ERROR);

}

}

4. 使用

定義好這些東西后就可愉快的使用了,Service中簡單的代碼如下:

@Override

@Transactional(rollbackFor = Exception.class)

public SecurityAccount registerAccount(AccountRegister register) {

accountRepository.findUserByUsername(register.getUsername()).ifPresent(eac->{

throw new InvalidParamException("用戶名:" + register.getUsername() + "已被使用");

});

Account account = BeanUtil.copyBean(register,Account.class);

if (StringUtils.isNotBlank(register.getPassword())){

account.setPassword(passwordEncoder.encode(register.getPassword()));

} else {

throw new InvalidParamException("密碼不能為空");

}

account.setCreateTime(LocalDateTime.now());

accountRepository.save(account);

return convertToSecurity(account);

}

InvalidParamException是繼承自ApiException并在構造函數中設置好狀態碼,方便使用。

Controller層代碼:

Controller層沒有對返回結果再做封裝,因為大多時候根本沒必要。盡量利用http狀態碼即可,對前端使用很舒服。

如果發生錯誤,再統一返回ErrorBody,里面有錯誤碼和詳細信息,供前端展示。對于有復雜業務的操作,如不能簡單的使用成功或者失敗來表示的,就自己再針對業務和前端協商專門定義即可。

@PostMapping

public long registerAccount(@Validated @RequestBody AccountRegister accountRegister,

BindingResult result) {

checkBindingResult(result);

return accountService.registerAccount(accountRegister).getId();

}

使用http狀態碼返回錯誤后,前端使用相當舒服,不用再為業務異常捕獲一次,為http錯誤再捕獲一次,統一進catch即可:

$http.post("system/accounts", this.editInfo).then(res => {

this.$message.success("操作成功");

this.cancelDialog();

this.loadData();

}).catch(reason => {

if (!reason.handled) {

this.$message.error(reason.response.data.message);

}

})

這些只是我個人習慣中總結下來的實踐,并非最佳實踐。放在這里供大家討論一下,希望能多指出不足,一起學習改進。另外說一句,知乎的電腦端編輯器好難用,,好像有不少bug啊。

總結

以上是生活随笔為你收集整理的java web 自定义异常_Java web, service 层应该通过异常(自定义Exception)来中断业务吗?...的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 国产字幕av | 国产性精品 | 欧美大浪妇猛交饥渴大叫 | 少妇人妻互换不带套 | 性欧美xxxx| aise爱色av | 国产成人短视频 | 国产不卡一区二区视频 | 精品免费一区二区三区 | 国产美女无遮挡免费视频 | 99久久精品日本一区二区免费 | 免费看欧美大片 | 日本亚洲欧洲色 | 久草综合在线观看 | 久久久久久久久久久99 | 天堂久久一区 | 日本视频黄 | av大片网 | www四虎精品视频免费网站 | 国产美女三级无套内谢 | 国产高清免费视频 | 精东影业一区二区三区 | av日韩av | 国产精品久久久久久久av | 欧美一级色片 | 丝瓜色版| 玖玖在线观看 | 96视频在线观看 | 多男调教一女折磨高潮高h 国内毛片毛片毛片毛片毛片 | www日本www| 国产成人无码精品久久久电影 | 一区二区三区在线电影 | いいなり北条麻妃av101 | av动漫在线免费观看 | 男女午夜爽爽爽 | 欧美天天干 | 麻豆av剧情| 爱情岛论坛自拍亚洲品质极速最新章 | 豆花在线视频 | 亚洲xx网 | 青青青手机在线视频 | 又粗又猛又爽又黄少妇视频网站 | 操操色 | 丰满人妻综合一区二区三区 | av永久网站 | 天天操天天插 | 亚洲综合五月天婷婷丁香 | 国产伦精品一区二区三区视频黑人 | 中文字幕一区二区三区精华液 | 日本理论片中文字幕 | 国产成人综合一区二区三区 | 亚洲一级av无码毛片精品 | 日韩精品一区二区电影 | 国产伦一区二区 | 天天爽夜夜爽夜夜爽精品视频 | 亚洲激情第一页 | 91嫩草欧美久久久九九九 | 狠狠干在线视频 | 国产精品污www一区二区三区 | a v视频在线播放 | 国产sm网站 | 久久国产精品二区 | 蘑菇av| 伊人青青草原 | 美女脱衣服一干二净 | 无遮挡在线观看 | 日韩一区二区三区电影 | 一级免费a | 不卡网av| 亚洲性图av | 丰满熟妇被猛烈进入高清片 | 国产suv精品一区二区69 | 欧美日韩视频无码一区二区三 | 黑人巨大精品欧美一区二区 | 原创av | 久久亚洲av无码西西人体 | 激情亚洲视频 | av色在线 | 精品无码一区二区三区爱欲 | 免费黄色三级网站 | 亚洲大片在线观看 | 无码人妻精品一区二区三区99不卡 | 国产精品入口久久 | 亚洲在线网站 | 最新中文字幕免费 | 亚洲网站免费观看 | 夜色视频网 | 性生活在线视频 | 欧美日韩国产成人精品 | 国产一区二区在线播放视频 | 欧美日韩在线视频一区二区三区 | 国产在线观看免费av | 先锋影音久久 | 中国一及毛片 | 亚洲欧美精品一区二区 | 求欧美精品网址 | 欧美老少做受xxxx高潮 | 蜜臀av一区二区三区激情综合 | 男女午夜免费视频 |