国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

Java開源工具庫使用之httpclient

這篇具有很好參考價值的文章主要介紹了Java開源工具庫使用之httpclient。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

前言

HttpClient 成立于2001年,是 Apache Jakarta Commons 項目下的子項目,2004 年離開 Commons,提升成為一個單獨的 Jakarta 項目。2005 年,Jakarta 創(chuàng)建了 HttpComponents 項目,目標是開發(fā) HttpClient 3.x 的繼任者。2007 年,Commons 項目,也就是 HttpClient 項目的發(fā)源地,離開了 Jakarta, 成為了1個新的頂級項目。不久之后,HttpComponents 也離開了 Jakarta, 成為一個獨立的頂級項目,負責維護 HttpClient 的工作。

  • HttpClient 提供了高效、最新、功能豐富的支持 HTTP 協(xié)議的客戶端編程工具包,支持最新版本的 HTTP 協(xié)議。

  • HttpComponents 項目,包含 HttpClientHttpCore, AsyncClient 三大模塊,提供了更好的性能和更大的靈活性。

  • HttpClient 是依賴于 HttpCore 的,最新的 HttpClient 版本為 5.2

  • HttpClient 是以 3.1 版本為分隔,大版本之間用法有很多不同

  • 最新文檔地址:https://hc.apache.org/httpcomponents-client-5.2.x/index.html

  • 舊版文檔地址:https://hc.apache.org/httpclient-legacy/userguide.html

  • github 地址:https://github.com/apache/httpcomponents-client

  • pom 依賴

    <!-- 最新版本5 -->
    <dependency>
        <groupId>org.apache.httpcomponents.client5</groupId>
        <artifactId>httpclient5</artifactId>
        <version>5.2.1</version>
    </dependency>
    
    <!-- 版本4 -->
    <dependency>
        <groupId>org.apache.httpcomponents</groupId>
        <artifactId>httpclient</artifactId>
        <version>4.5.13</version>
    </dependency>
    
    <!-- 舊版本3,07年后沒更新 -->
    <dependency>
        <groupId>commons-httpclient</groupId>
        <artifactId>commons-httpclient</artifactId>
        <version>3.1</version>
    </dependency>
    

一、簡單使用

1.1 get 請求

String url = "http://httpbin.org/get";
try (final CloseableHttpClient httpclient = HttpClients.createDefault()) {
    final HttpGet httpget = new HttpGet(url);

    // Create a custom response handler
    final HttpClientResponseHandler<String> responseHandler = response -> {
        final int status = response.getCode();
        if (status >= HttpStatus.SC_SUCCESS && status < HttpStatus.SC_REDIRECTION) {
            final HttpEntity entity = response.getEntity();
            try {
                return entity != null ? EntityUtils.toString(entity) : null;
            } catch (final ParseException ex) {
                throw new ClientProtocolException(ex);
            }
        } else {
            throw new ClientProtocolException("Unexpected response status: " + status);
        }
    };
    final String responseBody = httpclient.execute(httpget, responseHandler);
    System.out.println(responseBody);
}

1.2 post 簡單表單請求

String url = "http://httpbin.org/post";
String username = "root";
String loginPw = "";
try (final CloseableHttpClient httpclient = HttpClients.createDefault()) {
    final HttpPost httppost = new HttpPost(url);
    final List<NameValuePair> params = new ArrayList<>();
    params.add(new BasicNameValuePair("username", username));
    params.add(new BasicNameValuePair("password", loginPw));
    httppost.setEntity(new UrlEncodedFormEntity(params));

    // Create a custom response handler
    final HttpClientResponseHandler<String> responseHandler = response -> {
        final int status = response.getCode();
        if (status >= HttpStatus.SC_SUCCESS && status < HttpStatus.SC_REDIRECTION) {
            final HttpEntity entity = response.getEntity();
            try {
                return entity != null ? EntityUtils.toString(entity) : null;
            } catch (final ParseException ex) {
                throw new ClientProtocolException(ex);
            }
        } else {
            throw new ClientProtocolException("Unexpected response status: " + status);
        }
    };
    final String responseBody = httpclient.execute(httppost, responseHandler);
    System.out.println(responseBody);
}

1.3 表單上傳文件

final HttpPost httppost = new HttpPost(url);
            
final MultipartEntityBuilder builder = MultipartEntityBuilder.create();
builder.addTextBody("username", username);
builder.addTextBody("password", password);
builder.addBinaryBody("file", new File("src/test/resources/test.txt"), ContentType.APPLICATION_OCTET_STREAM, "test.txt");

final HttpEntity multipart = builder.build();

httppost.setEntity(multipart);

1.4 上傳 json 數(shù)據(jù)

final HttpPost httppost = new HttpPost(url);

httppost.setHeader("Accept", "application/json");
httppost.setHeader("Content-type", "application/json");

final String json = "{\"id\":1,\"name\":\"John\"}";
final StringEntity stringEntity = new StringEntity(json);
httppost.setEntity(stringEntity);

二、高級用法

2.1 超時和重試

超時控制可以通過 RequestConfig 這個類控制

String url = "http://httpbin.org/get";

RequestConfig requestConfig = RequestConfig.custom()
    .setConnectionRequestTimeout(Timeout.ofSeconds(100L))//連接請求超時, 0為無限。默認值:3分鐘。
    .setResponseTimeout(Timeout.ofSeconds(600L)) // 響應超時時間,0為無限。帶有消息復用的HTTP傳輸可能不支持響應超時
    .build();

try (final CloseableHttpClient httpclient = HttpClients.createDefault()) {
    final HttpGet httpGet = new HttpGet(url);
    httpGet.setConfig(requestConfig);
    final HttpClientResponseHandler<String> responseHandler = response -> {
        final int status = response.getCode();

        if (status >= HttpStatus.SC_SUCCESS && status < HttpStatus.SC_REDIRECTION) {
            final HttpEntity entity = response.getEntity();
            try {
                return entity != null ? EntityUtils.toString(entity) : null;
            } catch (final ParseException ex) {
                throw new ClientProtocolException(ex);
            }
        } else {
            throw new ClientProtocolException("Unexpected response status: " + status);
        }
    };
    httpclient.execute(httpGet, responseHandler);
}

重試,默認重試策略為最大次數(shù)1次,重試間隔為1秒。

String url = "http://httpbin.org/get";

try (final CloseableHttpClient httpclient = HttpClients.custom()
     .setRetryStrategy(new DefaultHttpRequestRetryStrategy(3, TimeValue.ofSeconds(20L)))
     .build()) {
    final HttpGet httpGet = new HttpGet(url);

    final HttpClientResponseHandler<String> responseHandler = response -> {
        final int status = response.getCode();

        if (status >= HttpStatus.SC_SUCCESS && status < HttpStatus.SC_REDIRECTION) {
            final HttpEntity entity = response.getEntity();
            try {
                return entity != null ? EntityUtils.toString(entity) : null;
            } catch (final ParseException ex) {
                throw new ClientProtocolException(ex);
            }
        } else {
            throw new ClientProtocolException("Unexpected response status: " + status);
        }
    };
    httpclient.execute(httpGet, responseHandler);
}

2.2 Cookie

HttpClients.createDefault 已經內置默認 Cookie 管理器可以用來攜帶 Cookie 訪問

String url = "http://httpbin.org/cookies/set/foo/bar";
String url2 = "http://httpbin.org/cookies";

try (final CloseableHttpClient httpclient = HttpClients.createDefault()) {
    final HttpGet httpGet = new HttpGet(url);

    final HttpClientResponseHandler<String> responseHandler = response -> {
        final int status = response.getCode();

        if (status >= HttpStatus.SC_SUCCESS && status < HttpStatus.SC_REDIRECTION) {
            final HttpEntity entity = response.getEntity();
            try {
                return entity != null ? EntityUtils.toString(entity) : null;
            } catch (final ParseException ex) {
                throw new ClientProtocolException(ex);
            }
        } else {
            throw new ClientProtocolException("Unexpected response status: " + status);
        }
    };
    final HttpGet httpGet2 = new HttpGet(url2);

    String responseBody2 = httpclient.execute(httpGet2, responseHandler);
    System.out.println(responseBody2);

    final String responseBody = httpclient.execute(httpGet, responseHandler);
    System.out.println(responseBody);

    responseBody2 = httpclient.execute(httpGet2, responseHandler);
    System.out.println(responseBody2);
}

還可以訪問通過本地上下文綁定 cookie,從而獲取cookie 信息

String url = "http://httpbin.org/cookies/set/foo/bar";

try (final CloseableHttpClient httpclient = HttpClients.createDefault()) {
    // 創(chuàng)建一個本地的 Cookie 存儲
    final CookieStore cookieStore = new BasicCookieStore();

    final HttpClientContext localContext = HttpClientContext.create();
    // 綁定 cookieStore 到 localContext
    localContext.setCookieStore(cookieStore);

    final HttpGet httpget = new HttpGet(url);

    final HttpClientResponseHandler<String> responseHandler = response -> {
        final int status = response.getCode();

        if (status >= HttpStatus.SC_SUCCESS && status < HttpStatus.SC_REDIRECTION) {
            final HttpEntity entity = response.getEntity();
            try {
                final List<Cookie> cookies = cookieStore.getCookies();
                for (Cookie cookie : cookies) {
                    System.out.println("Local cookie: " + cookie);
                }
                return entity != null ? EntityUtils.toString(entity) : null;
            } catch (final ParseException ex) {
                throw new ClientProtocolException(ex);
            }
        } else {
            throw new ClientProtocolException("Unexpected response status: " + status);
        }
    };

    String response = httpclient.execute(httpget, localContext, responseHandler);
    System.out.println(response);
}

2.3 攔截器

httpclient 支持通過攔截器對請求進行一定的處理,有如下幾個方法添加攔截器

  • addRequestInterceptorFirst
  • addRequestInterceptorLast
  • addResponseInterceptorFirst
  • addResponseInterceptorLast
  • addExecInterceptorFirst
  • addExecInterceptorLast
  • addExecInterceptorBefore
  • addExecInterceptorAfter

添加的攔截器可分為3種類型: request, response和 exec,對應請求,響應和執(zhí)行。其中Exec執(zhí)行的名字在枚舉ChainElement 中,在 HttpClientBuilder 類源碼中,可以發(fā)現(xiàn)除了 CACHING 其它都可以通過配置使用,并且枚舉中的順序也是Exec執(zhí)行的順序,其中 MAIN_TRANSPORT 執(zhí)行包含 request 和 response 攔截器執(zhí)行

ChainElement 定義了一組可用于構建HTTP請求處理管道的元素,每個元素都可以實現(xiàn)特定的功能,如添加自定義HTTP頭、添加身份驗證信息等。

public enum ChainElement {
    REDIRECT, COMPRESS, BACK_OFF, RETRY, CACHING, PROTOCOL, CONNECT, MAIN_TRANSPORT
}

下面是一個對官方攔截器例子修改的代碼

AtomicLong count = new AtomicLong();

try (final CloseableHttpClient httpclient = HttpClients.custom()
     .addExecInterceptorAfter(ChainElement.PROTOCOL.name(), "custom", (request, scope, chain) -> {
         request.setHeader("request-id", Long.toString(count.incrementAndGet()));
         return chain.proceed(request, scope);
     })
     .addExecInterceptorAfter("custom", "quit3rd", ((request, scope, chain) -> {
         final Header idHeader = request.getFirstHeader("request-id");
         if (idHeader != null && "3".equalsIgnoreCase(idHeader.getValue())) {
             final ClassicHttpResponse response = new BasicClassicHttpResponse(HttpStatus.SC_NOT_FOUND, "Oppsie");
             response.setEntity(new StringEntity("bad luck", ContentType.TEXT_PLAIN));
             return response;
         } else {
             return chain.proceed(request, scope);
         }
     }))

     .addExecInterceptorBefore(ChainElement.CONNECT.name(), "AAA", (request, scope, chain) -> {
         System.out.println("AAA");
         return chain.proceed(request, scope);
     })
     .addExecInterceptorBefore("AAA", "BBB", (request, scope, chain) -> {
         System.out.println("BBB");
         return chain.proceed(request, scope);
     })
     .addExecInterceptorAfter("AAA", "CCC", (request, scope, chain) -> {
         System.out.println("CCC");
         return chain.proceed(request, scope);
     })

     .addRequestInterceptorFirst((request, entity, context) -> {
         System.out.println("第一個request first現(xiàn)在獲取:" + context.getAttribute("foo"));
     })
     .addRequestInterceptorFirst((request, entity, context) -> {
         System.out.println("第二個request first, 現(xiàn)在設置name");
         context.setAttribute("foo", "bar");
     })
     .addRequestInterceptorLast((request, entity, context) -> {
         System.out.println("第一個request last現(xiàn)在獲?。? + context.getAttribute("foo"));
     })

     .build()) {


    for (int i = 0; i < 5; i++) {
        final HttpGet httpget = new HttpGet("http://httpbin.org/get");

        System.out.println("Executing request " + httpget.getMethod() + " " + httpget.getUri());

        httpclient.execute(httpget, response -> {
            System.out.println("----------------------------------------");
            System.out.println(httpget + "->" + new StatusLine(response));
            EntityUtils.consume(response.getEntity());
            return null;
        });
    }
}

下面動圖顯示的是調試過程中 execChain 執(zhí)行鏈的順序

java httpclient,java,github,software,java,開源,apache,httpclient,http

下面是 調試過程中的request和response 攔截器,從名字就可以看出除了Main類是自定義的攔截器,其余都是自帶的,其中cookie處理也是通過攔截器實現(xiàn)的。

java httpclient,java,github,software,java,開源,apache,httpclient,http

2.4 fluent API

HttpClienet 4.5 版本以上支持fluent API, 優(yōu)點是代碼更簡潔,同時為線程安全的。文章來源地址http://www.zghlxwxcb.cn/news/detail-736082.html

<dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>fluent-hc</artifactId>
    <version>4.5.13</version>
</dependency>
String urlGet = "http://httpbin.org/get";
String urlPost = "http://httpbin.org/post";

String response = Request.Get(urlGet)
    .addHeader("Authorization", "Bear:dw")
    .execute()
    .handleResponse(httpResponse -> {
        int code = httpResponse.getStatusLine().getStatusCode();
        if (code == HttpStatus.SC_SUCCESS) {
            return org.apache.http.util.EntityUtils.toString(httpResponse.getEntity());
        }
        return null;
    });

System.out.println(response);

String result = Request.Post(urlPost)
    .bodyForm(Form.form().add("foo", "bar").build())
    .execute()
    .returnContent()
    .asString();

System.out.println(result);

三、3.1舊版本使用

3.1 Get 請求

String url = "http://httpbin.com";
HttpClient client = new HttpClient();
GetMethod method = new GetMethod(url);
method.getParams().setParameter(HttpMethodParams.RETRY_HANDLER,
                                new DefaultHttpMethodRetryHandler(3, false));
try {
    // Execute the method.
    int statusCode = client.executeMethod(method);

    if (statusCode != HttpStatus.SC_OK) {
        System.err.println("Method failed: " + method.getStatusLine());
    }

    // Read the response body.
    byte[] responseBody = method.getResponseBody();

    // Deal with the response.
    // Use caution: ensure correct character encoding and is not binary data
    System.out.println(new String(responseBody));

} catch (HttpException e) {
    System.err.println("Fatal protocol violation: " + e.getMessage());
    e.printStackTrace();
} catch (IOException e) {
    System.err.println("Fatal transport error: " + e.getMessage());
    e.printStackTrace();
} finally {
    // Release the connection.
    method.releaseConnection();
}

3.2 Post 請求

String url = "http://httpbin.org/post";
HttpClient client = new HttpClient();
PostMethod method = new PostMethod(url);
NameValuePair[] data = {
    new NameValuePair("user", "joe"),
    new NameValuePair("password", "bloggs")
};
method.setRequestBody(data);

try {
    int statusCode = client.executeMethod(method);
    if (statusCode != HttpStatus.SC_OK) {
        System.err.println("Method failed: " + method.getStatusLine());
    }
    byte[] responseBody = method.getResponseBody();
    System.out.println(new String(responseBody));
} catch (HttpException e) {
    System.err.println("Fatal protocol violation: " + e.getMessage());
    e.printStackTrace();
} catch (IOException e) {
    System.err.println("Fatal transport error: " + e.getMessage());
    e.printStackTrace();
} finally {
    method.releaseConnection();
}

四、異步版本使用

4.1 基本請求

final IOReactorConfig ioReactorConfig = IOReactorConfig.custom()
                .setSoTimeout(Timeout.ofSeconds(5))
                .build();

final CloseableHttpAsyncClient client = HttpAsyncClients.custom()
    .setIOReactorConfig(ioReactorConfig)
    .build();

client.start();

final HttpHost target = new HttpHost("httpbin.org");
final String[] requestUris = new String[] {"/", "/ip", "/user-agent", "/headers"};

for (final String requestUri: requestUris) {
    final SimpleHttpRequest request = SimpleRequestBuilder.get()
        .setHttpHost(target)
        .setPath(requestUri)
        .build();

    System.out.println("請求url:" + requestUri);
    final Future<SimpleHttpResponse> future = client.execute(
        SimpleRequestProducer.create(request),
        SimpleResponseConsumer.create(),
        new FutureCallback<SimpleHttpResponse>() {

            @Override
            public void completed(final SimpleHttpResponse response) {
                System.out.println(requestUri + " 返回狀態(tài)碼:" + response.getCode() + ",返回內容:" + response.getBodyText());
            }

            @Override
            public void failed(final Exception ex) {
                System.out.println(request + "->" + ex);
            }

            @Override
            public void cancelled() {
                System.out.println(request + " cancelled");
            }

        });
    future.get();
}

System.out.println("Shutting down");
client.close(CloseMode.GRACEFUL);

4.2 請求流水線執(zhí)行

final MinimalHttpAsyncClient client = HttpAsyncClients.createMinimal(
    H2Config.DEFAULT,
    Http1Config.DEFAULT,
    IOReactorConfig.DEFAULT,
    PoolingAsyncClientConnectionManagerBuilder.create()
    .setDefaultTlsConfig(TlsConfig.custom()
                         .setVersionPolicy(HttpVersionPolicy.FORCE_HTTP_1)
                         .build())
    .build());

client.start();

final HttpHost target = new HttpHost("httpbin.org");
final Future<AsyncClientEndpoint> leaseFuture = client.lease(target, null);
final AsyncClientEndpoint endpoint = leaseFuture.get(30, TimeUnit.SECONDS);
try {
    final String[] requestUris = new String[] {"/", "/ip", "/user-agent", "/headers"};

    final CountDownLatch latch = new CountDownLatch(requestUris.length);
    for (final String requestUri: requestUris) {
        final SimpleHttpRequest request = SimpleRequestBuilder.get()
            .setHttpHost(target)
            .setPath(requestUri)
            .build();

        System.out.println("Executing request " + request);
        endpoint.execute(
            SimpleRequestProducer.create(request),
            SimpleResponseConsumer.create(),
            new FutureCallback<SimpleHttpResponse>() {

                @Override
                public void completed(final SimpleHttpResponse response) {
                    latch.countDown();
                    System.out.println(request + "->" + new StatusLine(response));
                    System.out.println(response.getBody());
                }

                @Override
                public void failed(final Exception ex) {
                    latch.countDown();
                    System.out.println(request + "->" + ex);
                }

                @Override
                public void cancelled() {
                    latch.countDown();
                    System.out.println(request + " cancelled");
                }

            });
    }
    latch.await();
} finally {
    endpoint.releaseAndReuse();
}

System.out.println("Shutting down");
client.close(CloseMode.GRACEFUL);

參考

  1. https://hc.apache.org/httpclient-legacy/index.html

到了這里,關于Java開源工具庫使用之httpclient的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網!

本文來自互聯(lián)網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。如若轉載,請注明出處: 如若內容造成侵權/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經查實,立即刪除!

領支付寶紅包贊助服務器費用

相關文章

  • GitHub上熱門的Java開源項目

    GitHub上熱門的Java開源項目

    1 JavaGuide https://github.com/Snailclimb/JavaGuide?Star 26396 ?一份Java學習指南,涵蓋大部分Java程序員所需要掌握的核心知識 2 DoraemonKit https://github.com/didi/DoraemonKit?Star 4826 簡稱 \\\"DoKit\\\",中文名哆啦A夢,意味著能夠像哆啦A夢一樣提供給他的主人各種各樣的工具,一款功能齊全的客戶端(

    2023年04月19日
    瀏覽(38)
  • Github上最熱門的十大Java開源項目,springboot面試

    Github上最熱門的十大Java開源項目,springboot面試

    https://github.com/zhangdaiscott/jeecg-boot Star 7861 一款基于代碼生成器的Java快速開發(fā)平臺,開源界“小普元”超越傳統(tǒng)商業(yè)企業(yè)級開發(fā)平臺!采用前后端分離架構:SpringBoot 2.x,Ant DesignVue,Mybatis-plus,Shiro,JWT。強大的代碼生成器讓前后端代碼一鍵生成,無需寫任何代碼!號稱可以幫

    2024年04月17日
    瀏覽(27)
  • 逛了五年GitHub,終于整理出七大java開源技術項目文檔,趕緊收藏

    逛了五年GitHub,終于整理出七大java開源技術項目文檔,趕緊收藏

    前言 大家都知道 Github 是一個程序員福地,這里有各種厲害的開源框架、軟件或者教程。這些東西對于我們學習和進步有著莫大的進步,所以將 Github 上非常棒的七大Java開源項目技術文檔整理下來供大家學習! 深入理解Spring Cloud與微服務構建 由淺入深,全面講解Spring Cloud基

    2024年03月08日
    瀏覽(20)
  • 從GitHub火到頭條!這份萬眾期待的阿里內部JAVA面試手冊,開源了

    從GitHub火到頭條!這份萬眾期待的阿里內部JAVA面試手冊,開源了

    現(xiàn)在的互聯(lián)網開發(fā)崗招聘,程序員面試背八股文已經成為了不可逆轉的形式,其中一個Java崗幾百人在投簡歷也已經成為了常態(tài)!更何況一份面試題動輒七八百道, 你吃透了,技術只要不是很差,面試怎么可能有大問題? 但是也有尷尬的情況發(fā)生:面試八股文背的特別好(

    2024年02月07日
    瀏覽(21)
  • Java HttpClient爬蟲請求

    添加依賴 pom文件 GET 無參形式 GET帶參請求 POST無參請求 POST帶參請求

    2024年02月16日
    瀏覽(23)
  • java httpclient 請求

    要使用Java的HttpClient庫發(fā)送HTTP請求,您需要導入相應的庫并編寫Java代碼。HttpClient是Apache HttpComponents項目的一部分,可以使用它來執(zhí)行HTTP請求。以下是一個簡單的示例,演示如何使用HttpClient發(fā)送GET請求: import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpGet; im

    2024年02月07日
    瀏覽(13)
  • java開源xml工具類介紹

    ????????在Java中處理XML的常用開源工具有很多,以下是一些流行的庫以及簡單的示例代碼: ????????DOM4J ????????DOM4J 是一個非常流行的Java庫,用于處理XML,DOM4J 易于使用,并且提供了很好的性能。 ????????Maven 依賴? ? ?? ????????讀取 XML 文件的簡單示例

    2024年02月21日
    瀏覽(12)
  • Netty是一個由JBOSS提供的開源Java框架,目前已經成為Github上的獨立項目

    Netty是一個由JBOSS提供的開源Java框架,目前已經成為Github上的獨立項目

    Netty是一個由JBOSS提供的開源Java框架,目前已經成為Github上的獨立項目。它提供了一個異步、事件驅動的網絡應用程序框架和工具,用于快速開發(fā)高性能、高可靠性的網絡服務器和客戶端程序。 Netty是一個基于NIO的客戶、服務器端的編程框架,使用Netty可以確保快速和簡單地開

    2024年01月16日
    瀏覽(24)
  • 阿里開源的java而分析工具(arthas)

    阿里開源的java而分析工具(arthas)

    1、官網地址:https://alibaba.github.io/arthas/quick-start.html 2、安裝 wget https://alibaba.github.io/arthas/arthas-boot.jar java -jar arthas-boot.jar 發(fā)生這個問題的原因有兩個: 一個是目前機器中沒有安裝Oracle的jdk; 一個是沒有java程序運行 解決方案: 1.卸載openJDK ?安裝Oracle的jdk? 參加地址:https://

    2024年02月04日
    瀏覽(19)
  • 開源|用 Java 實現(xiàn)一個生成 Markdown 文本的工具

    公司的 IM 每天有許多機器人推送的消息,我也在使用,這個功能是好的,但是當我們想去發(fā)送一些格式優(yōu)美的消息時,卻要費許多功夫,主要來源于字符串拼接,如果要拼接出 Markdown 格式的那就更費力了,另外由拼接帶來的是混亂的代碼,為了解決這個痛點,我寫了一個

    2023年04月15日
    瀏覽(22)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領取紅包,優(yōu)惠每天領

二維碼1

領取紅包

二維碼2

領紅包