最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

淺析Java如何優(yōu)雅的設計接口狀態(tài)碼和異常

 更新時間:2024年03月14日 09:50:11   作者:趙俠客  
HTTP協議里定義了一系列的狀態(tài)碼用來表明請求的狀態(tài),如常用的200表示請求正常,404表示請求的資源不存在,所以本文就來和大家討論一下如何優(yōu)雅的設計接口狀態(tài)碼和異常,感興趣的可以了解下

一、前言

目前大多互聯網應用后端輸出數據協議都是使用HTTP協議+JSON數據格式,HTTP協議里定義了一系列的狀態(tài)碼用來表明請求的狀態(tài),如常用的200表示請求正常,404表示請求的資源不存在。由于這些狀態(tài)數量是有限的,無法完整的表達我們業(yè)務中的各種狀態(tài),所以一般會在返回的JSON中增加業(yè)務狀態(tài)碼,如請求參數不對、用戶狀態(tài)禁用、用戶名密碼錯誤等。首先要搞清楚HTTP狀態(tài)碼和我們業(yè)務狀態(tài)的關系, 我們看一個簡單的HTTP協議報文:

GET http://localhost/test?id=2

HTTP/1.1 200 
Content-Type: application/json
Transfer-Encoding: chunked
Date: Mon, 11 Mar 2024 06:42:39 GMT
Keep-Alive: timeout=60
Connection: keep-alive

{
  "code": "OK",
  "message": "OK",
  "data": {
    "id": 2,
    "userName": "test3@8531.cn"
  }
}

上面是一個簡單的返回JSON數據的GET請求,其中響應頭中的HTTP/1.1 200表明HTTP狀態(tài)碼是200,響應Body中的"code": "OK",是我們業(yè)務里定義的狀態(tài)碼。

HTTP狀態(tài)碼

HTTP 狀態(tài)碼是由 HTTP 協議定義的,用于表示 Web 服務器對請求的響應狀態(tài),每一個狀態(tài)碼都有特定的含義。雖然開發(fā)者可以自定義 HTTP 狀態(tài)碼,但并不推薦這樣做,因為這可能會引起混淆或者與將來的 HTTP 規(guī)范相沖突。HTTP 狀態(tài)碼的值是三位數字,其中第一位數字表示響應類別,目前有以下五個類別:

  • 1xx:表示請求已被接收,需要繼續(xù)處理;
  • 2xx:表示請求已成功被服務器接收、理解、并接受;
  • 3xx:重定向,需要客戶端采取進一步的操作才能完成請求;
  • 4xx:客戶端錯誤,表示請求包含語法錯誤或者無法完成請求;
  • 5xx:服務器錯誤,服務器在處理請求的過程中發(fā)生了錯誤。

HTTP狀態(tài)碼有非常多的作用:

  • 服務器通知客戶端:狀態(tài)碼用于指示網頁請求的處理結果,幫助客戶端了解發(fā)生了什么事件;
  • 便于程序處理:三位數字的狀態(tài)碼便于自動化程序和腳本解析和處理響應結果;
  • 便于用戶理解:狀態(tài)消息(狀態(tài)碼后面的文本)為用戶提供關于響應的額外信息,幫助用戶理解發(fā)生了什么問題;
  • 指導后續(xù)操作:例如,301狀態(tài)碼表示資源已永久移動到新地址,客戶端應使用新地址重新發(fā)送請求;
  • 便于監(jiān)控報警:通過監(jiān)控分析nginx的接口請求日志,可以監(jiān)控到服務異常從而發(fā)送報警消息。

業(yè)務狀態(tài)碼

業(yè)務狀態(tài)碼是在 HTTP 狀態(tài)碼之上,由應用程序自身定義的,以反映特定業(yè)務邏輯的狀態(tài)。這些狀態(tài)碼可以針對不同的操作不同的條件提供更詳細更具體的信息,以便客戶端能夠更好地理解和處理業(yè)務流程,根據不同的狀態(tài)碼采取相應的處理措施。業(yè)務狀態(tài)碼的主要作用有:

  • 方便與前端開發(fā)對接:前端在請求接口時通過判斷非正常業(yè)務狀態(tài)碼,可以給用戶對應的提示;
  • 方便對業(yè)務更進一步的監(jiān)控:比如用戶名密碼錯誤用USER_PASSWORD_ERROR,可以分析日志,監(jiān)控用戶登錄錯誤的請求,這個監(jiān)控是HTTP狀態(tài)碼無法實現的;
  • 提升用戶操作體驗:良好的錯誤提示可以大大提升用戶體驗,有些系統用戶操作失敗全部提示“系統異常”,如果是“用戶名不存在”、“用戶密碼錯誤”等提示用戶體驗就非常好了。

HTTP狀態(tài)碼和業(yè)務狀態(tài)碼的關系

業(yè)務狀態(tài)碼應該是包含的HTTP狀態(tài)碼,在實際項目開發(fā)中很多開發(fā)者定義了很多業(yè)務狀態(tài)碼,但是所有接口請求都是返回http狀態(tài)碼為200,這是很不好的,應該是當HTTP狀態(tài)碼中能表達業(yè)務請求的狀態(tài)時應該返回對應的HTTP狀態(tài)碼,HTTP狀態(tài)碼無法表達業(yè)務狀態(tài)時才自定義業(yè)務狀態(tài)碼。我們參考《Google API Design Guide (谷歌API設計指南)中文版》看看大廠業(yè)務狀態(tài)碼是如何定義的:下面是一個表格,其中包含google.rpc.Code中定義的所有gRPC錯誤代碼及其原因的簡短說明:

HTTPRPC描述
200OK沒有錯誤
400INVALID_ARGUMENT客戶端指定了無效的參數。 檢查錯誤消息和錯誤詳細信息以獲取更多信息。
400FAILED_PRECONDITION請求不能在當前系統狀態(tài)下執(zhí)行,例如刪除非空目錄。
400OUT_OF_RANGE客戶端指定了無效的范圍。
401UNAUTHENTICATED由于遺失,無效或過期的OAuth令牌而導致請求未通過身份驗證。
403PERMISSION_DENIED客戶端沒有足夠的權限。這可能是因為OAuth令牌沒有正確的范圍,客戶端沒有權限,或者客戶端項目尚未啟用API。
404NOT_FOUND找不到指定的資源,或者該請求被未公開的原因(例如白名單)拒絕。
409ABORTED并發(fā)沖突,例如讀-修改-寫沖突。
409ALREADY_EXISTS客戶端嘗試創(chuàng)建的資源已存在。
429RESOURCE_EXHAUSTED資源配額達到速率限制。 客戶端應該查找google.rpc.QuotaFailure錯誤詳細信息以獲取更多信息。
499CANCELLED客戶端取消請求
500DATA_LOSS不可恢復的數據丟失或數據損壞。 客戶端應該向用戶報告錯誤。
500UNKNOWN未知的服務器錯誤。 通常是服務器錯誤。
500INTERNAL內部服務錯誤。 通常是服務器錯誤。
501NOT_IMPLEMENTED服務器未實現該API方法。
503UNAVAILABLE暫停服務。通常是服務器已經關閉。
504DEADLINE_EXCEEDED已超過請求期限。如果重復發(fā)生,請考慮降低請求的復雜性。

從Google定義的RPC狀態(tài)碼可以看出業(yè)務狀態(tài)碼里很多都使用了HTTP狀態(tài)碼,這樣通過監(jiān)控HTTP狀態(tài)碼也可以反映出業(yè)務的某些狀態(tài)。

如何設計一套優(yōu)雅的狀態(tài)碼

"工欲善其事,必先利其器"、“磨刀不誤砍柴工”,狀態(tài)碼的設計是非?;A的工作,在很多項目開發(fā)過程中剛開始時項目比較急也沒有考慮統一狀態(tài)碼,等項目做好后發(fā)現船已經太大了,沒法掉頭了,很多錯的東西就將錯就錯,這也增加了項目的后期維護成本,后面接手的人不了解代碼歷史也往往會吐槽前人代碼寫的垃圾。在項目開始時就應該將這些基礎的東西規(guī)范好,這對后面的開發(fā)者來說用著也方便,項目也好維護。那么如何設計一套優(yōu)雅的狀態(tài)碼呢?我覺得有以下幾點:

  • 統一:狀態(tài)碼的編碼和命名風格及接口返回參數要統一,不能每個人搞一種風格,每個人定義一套狀態(tài)碼,狀態(tài)碼要全局唯一,特別是微服務模式開發(fā),有可能每個人開發(fā)的代碼都不是一個GIT,做到統一管理就非常重要了;
  • 兼容HTTP狀態(tài)碼:HTTP狀態(tài)碼是全球通用的,你返回個404知道HTTP協議的人都知道是什么意思;
  • 要可讀:你返回一個USERNAME_NOT_EXIST和10002,很明顯USERNAME_NOT_EXIST一眼就看出是用戶不存在的意思了;
  • 要方便維護:狀態(tài)碼越來越多,后面隨著業(yè)務發(fā)展,添加擴展狀態(tài)碼應該要很方便。

二、設計步驟

總體設計思路

業(yè)務狀態(tài)碼統一使用code枚舉返回,可讀性強,返回格式如下:

HTTP/1.1 200 

{
  "code": "OK",
  "message": "OK",
  "data": {
    "id": 2,
    "userName": "test3@8531.cn"
  }
}

其中code 業(yè)務狀態(tài)碼主要分為三類:

  • HTTP狀態(tài)碼:三位數,對應org.springframework.http.HttpStatus中定義的狀態(tài)碼;
  • 公共狀態(tài)碼: 四位數,對應編碼1XXX開頭,枚舉COMM_*,對應公共異常如參數錯誤;
  • 業(yè)務狀態(tài)碼: 五位數,各業(yè)務模塊自定義,如用戶中心10XXX,枚舉USER_XXX,訂單中心20XXX,枚舉ORDER_XXX等等。

異常設計

異常設計UML圖

  • ApiException定義異常接口,有獲取狀態(tài)碼和提示消息兩個方法,其它所有異常實現該接口;
  • HttpException主要用于HTTP狀態(tài)的異常,其中用了Spring自帶的HttpStatus,如果是HTTP狀態(tài)碼能表達業(yè)務代碼可直接 new HttpException(HttpStatus.XXX);
  • CommException公共業(yè)務異常,如參數沒有傳、文件不存在、數據超界等;
  • UserException用戶模塊的狀態(tài)碼,如用戶不存在、用戶密碼錯誤、手機號已被使用等等;
  • OrderException訂單模塊狀態(tài)碼,如訂單超時、訂單已取消等等。
  • 如果還是其它模塊自定義類XXXException和XXXCodeEnum,并分配好狀態(tài)碼段和枚舉開頭,就可以使狀態(tài)碼全局唯一了。

ApiException

public interface ApiException {
    String getCode();
    String getMessage();
}

HttpException

public class HttpException extends RuntimeException  implements ApiException{
    @Getter
    private final HttpStatus httpStatus;
    private final String message;
    public HttpException(HttpStatus apiCode) {
        this(apiCode, apiCode.getReasonPhrase());
    }
    public HttpException(HttpStatus httpStatus, String message) {
        this.httpStatus = httpStatus;
        this.message = message;
    }
    @Override
    public String getCode() {
        return httpStatus.name();
    }
    @Override
    public String getMessage() {
        return message;
    }
}

CommException

public class CommException extends HttpException implements ApiException{
    private CommCodeEnum commCodeEnum;

    public CommException(CommCodeEnum commCodeEnum) {
        super(commCodeEnum.getHttpStatus());
        this.commCodeEnum=commCodeEnum;
    }

    public CommException(CommCodeEnum commCodeEnum, String message) {
        super(commCodeEnum.getHttpStatus(), message);
        this.commCodeEnum=commCodeEnum;
    }

    @Override
    public String getCode() {
        return commCodeEnum.getEnumName();
    }

    @Override
    public String getMessage() {
        return commCodeEnum.getName();
    }
}

UserException

public class UserException extends HttpException implements ApiException {
    private UserCodeEnum userCodeEnum;
    public UserException(UserCodeEnum userCodeEnum) {
        super(userCodeEnum.getHttpStatus());
        this.userCodeEnum=userCodeEnum;
    }
    public UserException(UserCodeEnum userCodeEnum, String message) {
        super(userCodeEnum.getHttpStatus(), message);
        this.userCodeEnum=userCodeEnum;
    }
    @Override
    public String getCode() {
        return userCodeEnum.getEnumName();
    }
    @Override
    public String getMessage() {
        return userCodeEnum.getName();
    }
}

OrderException

public class OrderException extends HttpException implements ApiException {
    private OrderCodeEnum oderCodeEnum;
    public OrderException(OrderCodeEnum oderCodeEnum) {
        super(oderCodeEnum.getHttpStatus());
        this.oderCodeEnum=oderCodeEnum;
    }
    public OrderException(OrderCodeEnum oderCodeEnum, String message) {
        super(oderCodeEnum.getHttpStatus(), message);
        this.oderCodeEnum=oderCodeEnum;
    }
    @Override
    public String getCode() {
        return oderCodeEnum.getEnumName();
    }
    @Override
    public String getMessage() {
        return oderCodeEnum.getName();
    }
}

異常枚舉設計

BaseEnum

如何優(yōu)雅的處理枚舉可以參考我的另一篇文章《項目中如何優(yōu)雅的使用枚舉

public interface BaseEnum {
    int getCode();
    String getName();
    String getEnumName();
}

CommCodeEnum

public enum CommCodeEnum implements BaseEnum {
    INVALID_ARGUMENT(HttpStatus.OK,600, "參數錯誤"),
    ;
    //公共錯誤碼6xx
    private int code;
    @Getter
    private HttpStatus httpStatus;
    private String name;
    CommCodeEnum(HttpStatus httpStatus, Integer code, String name) {
        this.httpStatus = httpStatus;
        this.code = code;
        this.name = name;
    }
    @Override
    public int getCode() {
        return this.code;
    }
    @Override
    public String getName() {
        return name;
    }
    @Override
    public String getEnumName() {
        return this.name();
    }
}

UserCodeEnum

在定義業(yè)務狀態(tài)碼時,需要注意的是有一個HttpStatus參數,如果我們覺得該業(yè)務出錯了接口不應該返回HTTP 200,就可以設置成對應的HTTP狀態(tài)碼,如用戶名不存在,可以理解為HTTP 狀態(tài)碼里的404資源不存在,這樣我們就設置成USERNAME_NOT_EXIST(HttpStatus.NOT_FOUND,10002, "用戶名不存在")這樣做的好處是在監(jiān)控HTTP狀態(tài)碼異常時也可以監(jiān)控到業(yè)務出問題了。

public enum UserCodeEnum implements BaseEnum {
    USERNAME_EXIST(HttpStatus.OK,10001, "用戶名已存在"),
    USERNAME_NOT_EXIST(HttpStatus.NOT_FOUND,10002, "用戶名不存在"),
    USERNAME_DISABLE(HttpStatus.OK,10003, "用戶被禁用"),
    ;
    @Getter
    private HttpStatus httpStatus;
    //用戶模塊錯誤碼10xxx
    private int code;
    private String name;
}

OrderCodeEnum

public enum OrderCodeEnum implements BaseEnum {
    ORDER_CANCELLED(HttpStatus.OK,20001, "訂閱已取消"),
    ORDER_TIMEOUT(HttpStatus.OK,20002, "訂閱已超時"),

    ;
    //訂單模塊錯誤碼20xxx
    private int code;
    @Getter
    private HttpStatus httpStatus;
    private String name;
}

三、統一接口返回

為了達到統一的接口數據返回格式,我們需要定義統一的接口返回類ApiResult,其它定義的code業(yè)務狀態(tài)碼,message提示消息和業(yè)務數據data參數。

統一接口返回包裝

@NoArgsConstructor
@Data
public class ApiResult {
    private String code;
    private String message;
    private Object data;
    public ApiResult(BaseEnum apiCode, Map<String, Object> data) {
        this.code = apiCode.getEnumName();
        this.message = apiCode.getName();
        this.data = data;
    }
    public ApiResult(HttpStatus httpStatus, Object data) {
        this.code = httpStatus.name();
        this.message = httpStatus.getReasonPhrase();
        this.data = data;
    }
    public ApiResult(HttpStatus httpStatus,String message, Object data) {
        this.code = httpStatus.name();
        this.message = message;
        this.data = data;
    }
    public ApiResult(BaseEnum apiCode, String explanation, Map<String, Object> data) {
        this.code = apiCode.getEnumName();
        this.message = apiCode.getName() + (explanation != null ? "【" + explanation + "】" : "");
        this.data = data;
    }
}

公共Controller

為了方便Controller返回統一的數據格式,我可以定義BaseController,重載多種返回數據格式,業(yè)務Controller只需繼承BaseController就可以直接調用 return renderOk(data)返回統一的接口數據格式。

public abstract class BaseController {
    @Resource
    protected HttpServletRequest httpRequest;

    protected ResponseEntity<ApiResult> renderOk() {
        return renderOk(null);
    }

    protected ResponseEntity<ApiResult> renderOk(Map<String, Object> data) {
        ApiResult apiResult = new ApiResult(HttpStatus.OK, data);
        return new ResponseEntity<>(apiResult, HttpStatus.OK);
    }

    protected ResponseEntity<ApiResult> renderOk(Object data) {
        ApiResult apiResult = new ApiResult(HttpStatus.OK, data);
        return new ResponseEntity<>(apiResult, HttpStatus.OK);
    }

    protected ResponseEntity<ApiResult> renderError(HttpStatus apiCode) {
        ApiResult apiResult = new ApiResult(apiCode, null);
        return new ResponseEntity<>(apiResult, HttpStatus.OK);
    }

    protected ResponseEntity<ApiResult> renderError(BaseEnum apiCode) {
        ApiResult apiResult = new ApiResult(apiCode, null);
        return new ResponseEntity<>(apiResult, HttpStatus.OK);
    }

    protected ResponseEntity<Map<String, Object>> renderError(HttpException httpException) {
        Map<String, Object> map = ImmutableMap.of("code", httpException.getCode(), "message", httpException.getMessage());
        return new ResponseEntity<>(map, httpException.getHttpStatus());
    }

    protected ResponseEntity<ApiResult> renderError(HttpException httpException, Object data) {
        ApiResult apiResult = new ApiResult(httpException.getHttpStatus(), data);
        return new ResponseEntity<>(apiResult, httpException.getHttpStatus());
    }

    protected ResponseEntity<Map<String, Object>> render(Map<String, Object> map) {
        return new ResponseEntity<>(map, HttpStatus.OK);
    }
}

四、統一異常攔截

針對代碼中的非正常行業(yè),可以統一使用拋自定義異常的方式,這樣只需配置一個統一的異常攔截器,統一返回狀態(tài)碼。

@Slf4j
@ControllerAdvice
public class ErrorHandler extends BaseController {
    @ExceptionHandler(value = {HttpException.class})
    public ResponseEntity<Map<String, Object>>  httpException(HttpException ex) {
        log.error("{}", ex);
        return renderError(ex);
    }
}

五、測試

這樣我們使用狀態(tài)碼就比較簡單了,主要分為三種:

  • 公共異常:throw new CommException(CommCodeEnum.INVALID_ARGUMENT);
  • http狀態(tài)碼類異常: throw new HttpException(HttpStatus.GATEWAY_TIMEOUT);
  • 業(yè)務類異常:如用戶throw new UserException(UserCodeEnum.USERNAME_NOT_EXIST),訂單throw new OrderException(OrderCodeEnum.ORDER_TIMEOUT, "請求訂單超時")等。
@RestController
public class UserController extends BaseController {
    @Resource
    private UserService userService;
    @GetMapping("/test")
    public ResponseEntity<ApiResult> getById(@RequestParam Long id) {
        //1.公共異常
        if (id == null) {
            throw new CommException(CommCodeEnum.INVALID_ARGUMENT);
        }
        //2.http協議異常
        User user = null;
        try {
            user = userService.selectById(id);
            int b = 1 / 0;
        } catch (Exception exception) {
            throw new HttpException(HttpStatus.GATEWAY_TIMEOUT);
        }
        //3.用戶模塊異常
        if (user == null) {
          // throw new UserException(UserCodeEnum.USERNAME_NOT_EXIST);
        }
        //4.訂單模塊異常
        try {
            //調用訂單

        } catch (Exception e) {
            //throw new OrderException(OrderCodeEnum.ORDER_TIMEOUT, "請求訂單超時");
        }
        return renderOk(user);
    }
}

正常返回狀態(tài)碼

接口正常返回統一使用code:OK,http狀態(tài)碼為200,

公共異??梢栽O置非200HTTP狀態(tài)碼

公共異常狀態(tài)碼

HTTP異常 HTTP狀態(tài)碼都是非200

http異常狀態(tài)碼

用戶異常HTTP狀態(tài)碼可以是200也可以非200

用戶異常狀態(tài)碼

訂單異常HTTP狀態(tài)碼可以是200也可以非200

訂單異常狀態(tài)碼

六、總結

本文介紹了HTTP狀態(tài)碼及業(yè)務狀態(tài)碼的區(qū)別和作用,提出并實現一種統一維護業(yè)務狀態(tài)碼和HTTP狀態(tài)碼的思路,該思路融合了HTTP狀態(tài)碼,規(guī)范了接口返回格式,統一的業(yè)務狀態(tài)碼,大大方便了在系統中使用異常和定義狀態(tài)碼。

到此這篇關于淺析Java如何優(yōu)雅的設計接口狀態(tài)碼和異常的文章就介紹到這了,更多相關Java設計接口狀態(tài)碼內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • Java實現從PLC讀取數據的常見主流且可行方案

    Java實現從PLC讀取數據的常見主流且可行方案

    要從PLC讀取數據,Java本身并不直接支持PLC的通信協議,所以你需要借助一些中間件或庫來實現,以下是幾種主流且可行的方案,大家可以根據自己的需要進行選擇
    2026-03-03
  • Java使用MyBatis框架分頁的5種方式

    Java使用MyBatis框架分頁的5種方式

    這篇文章主要為大家詳細介紹了Java使用MyBatis框架分頁的5種方式,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-08-08
  • 一篇文章帶你入門Springboot整合微信登錄與微信支付(附源碼)

    一篇文章帶你入門Springboot整合微信登錄與微信支付(附源碼)

    微信支付是騰訊公司的支付業(yè)務品牌,微信支付商戶平臺支持線下場所、公眾號、小程序、PC網站、APP、企業(yè)微信等經營場景快速接入微信支付。這里一篇文章帶你入門!
    2021-06-06
  • IDEA打開項目不顯示或者缺失項目文件目錄的解決方案

    IDEA打開項目不顯示或者缺失項目文件目錄的解決方案

    這篇文章主要介紹了IDEA打開項目不顯示或者缺失項目文件目錄的解決方案,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2025-05-05
  • mybatis?mapper.xml?注釋帶參數的坑及解決

    mybatis?mapper.xml?注釋帶參數的坑及解決

    這篇文章主要介紹了mybatis?mapper.xml?注釋帶參數的坑及解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-01-01
  • maven配置多個鏡像的實現方法

    maven配置多個鏡像的實現方法

    這篇文章主要介紹了maven配置多個鏡像的實現方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-06-06
  • Java基于裝飾者模式實現的染色饅頭案例詳解

    Java基于裝飾者模式實現的染色饅頭案例詳解

    這篇文章主要介紹了Java基于裝飾者模式實現的染色饅頭案例,簡單描述了裝飾者模式的概念、原理及Java使用裝飾者模式的相關實現步驟、操作技巧與注意事項,需要的朋友可以參考下
    2018-05-05
  • Java字符串原理分析之String是否可變

    Java字符串原理分析之String是否可變

    當我們在求職時,面試官很喜歡問我們關于String的一些原理性知識,比如String的不可變性、字符串的內存分配等,為了讓大家更好地應對面試,并理解String的底層設計,接下來會給大家聊聊String的一些原理,比如String為什么具有不可變性,需要的朋友可以參考下
    2023-05-05
  • 淺談java項目與javaweb項目導入jar包的區(qū)別

    淺談java項目與javaweb項目導入jar包的區(qū)別

    下面小編就為大家分享一篇淺談java項目與javaweb項目導入jar包的區(qū)別,具有很好的參考價值。希望對大家有所幫助。一起跟隨小編過來看看吧
    2017-11-11
  • zookeeper集群搭建超詳細過程

    zookeeper集群搭建超詳細過程

    這篇文章主要介紹了zookeeper集群搭建超詳細過程,本文對zookeeper集群測試通過圖文并茂的形式給大家介紹的非常詳細,需要的朋友可以參考下
    2022-06-06

最新評論

芷江| 高邮市| 乌海市| 甘孜县| 陇西县| 永吉县| 嘉祥县| 钟祥市| 邵武市| 苏尼特右旗| 凉山| 丹凤县| 土默特右旗| 田东县| 邛崃市| 陆丰市| 海盐县| 石泉县| 黔南| 化隆| 磐安县| 剑川县| 鸡泽县| 邳州市| 潼南县| 宁海县| 阳东县| 宿松县| 武强县| 瓦房店市| 玉林市| 大渡口区| 毕节市| 荆州市| 肥城市| 西安市| 双桥区| 花莲市| 屯昌县| 佳木斯市| 股票|