【Java】Apache HttpClientの使い方メモ

# Mavenプロジェクトの作成
下記の記事を参考にして、Mavenプロジェクトを作成。

https://qiita.com/hide/items/6593f3f02c3f28e57f2d

```console
mvn archetype:generate \
  -DarchetypeArtifactId=maven-archetype-quickstart \
  -DinteractiveMode=false \
  -DgroupId=com.sample \
  -DartifactId=http-client-sample
```

# pom.xmlの編集
`pom.xml`を編集して、Apache HttpClientを導入します。
また、以下の記事を参考にして、`mvn`コマンドでの実行と実行可能JARファイル生成のための設定を追加します。

https://qiita.com/tarosa0001/items/e019ec4daaaf54684c53

https://qiita.com/hide/items/0c8795054219d04e5e98

```xml:pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.sample</groupId>
  <artifactId>http-client-sample</artifactId>
  <packaging>jar</packaging>
  <version>1.0-SNAPSHOT</version>
  <name>http-client-sample</name>
  <url>http://maven.apache.org</url>
  <properties>
    <java.version>1.8</java.version>
    <maven.compiler.target>${java.version}</maven.compiler.target>
    <maven.compiler.source>${java.version}</maven.compiler.source>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>
  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>org.apache.httpcomponents</groupId>
      <artifactId>httpclient</artifactId>
      <version>4.5.13</version>
    </dependency>
    <!--
    <dependency>
      <groupId>org.apache.logging.log4j</groupId>
      <artifactId>log4j-api</artifactId>
      <version>2.14.1</version>
    </dependency>
    <dependency>
      <groupId>org.apache.logging.log4j</groupId>
      <artifactId>log4j-core</artifactId>
      <version>2.14.1</version>
    </dependency>
    -->
  </dependencies>
  <build>
    <plugins>
      <plugin>
        <groupId>org.codehaus.mojo</groupId>
        <artifactId>exec-maven-plugin</artifactId>
        <version>3.0.0</version>
        <configuration>
          <mainClass>com.sample.App</mainClass>
        </configuration>
      </plugin>
      <!-- 実行可能jarファイル用のプラグイン -->
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-assembly-plugin</artifactId>
        <version>3.3.0</version>
        <configuration>
          <finalName>sample</finalName>
          <descriptorRefs>
            <!-- 依存するリソースをすべてjarに同梱する -->
            <descriptorRef>jar-with-dependencies</descriptorRef>
          </descriptorRefs>
          <archive>
            <manifest>
              <mainClass>com.sample.App</mainClass>
            </manifest>
          </archive>
        </configuration>
        <executions>
          <execution>
            <!-- idタグは任意の文字列であれば何でもよい -->
            <id>make-assembly</id>
            <phase>package</phase>
            <goals>
              <goal>single</goal>
            </goals>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>
</project>
```


# Javaコード
以下の記事を参考にさせていただき、GETリクエストとPOSTリクエストを行うプログラムを作成します。

https://weblabo.oscasierra.net/java-apache-httpclient45-start/

```java:App.java
package com.sample;

public class App
{
    public static void main( String[] args ) {
        Client clinet = new Client("testId");
        clinet.exec();
    }
}
```

```java:Client.java
package com.sample;

import org.apache.http.HttpStatus;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.BasicCookieStore;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.util.EntityUtils;

public class Client {
    // private static final Logger logger = LogManager.getLogger(MethodHandles.lookup().lookupClass());
	private String id;
	
	public Client(String id) {
		this.id = id;
	}

	public void exec() {
        // Cookieを扱うための準備
		BasicCookieStore cookieStore = new BasicCookieStore();

        try ( CloseableHttpClient httpClient = HttpClientBuilder.create().setDefaultCookieStore(cookieStore).build(); ) {
            RequestConfig config = RequestConfig.custom()
                .setSocketTimeout(3000)
                .setConnectTimeout(3000)
                .build();
            
            // Cookieを設定
            HttpGet httpGet = new HttpGet("https://httpbin.org/cookies/set?key=" + this.id);
            httpGet.setConfig(config);
            
            // GETリクエストの実行
            try ( CloseableHttpResponse httpResponse = httpClient.execute(httpGet); ) {
                if ( httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK ) {
                	System.out.println("Cookie設定");
                    System.out.println(EntityUtils.toString(httpResponse.getEntity()));
                } else {
                    System.out.println("エラー: " + httpResponse.getStatusLine().getStatusCode());
                    return;
                }
            } catch (Exception e) {
                throw e;
            }
            
            // JSONをPost
            HttpPost httpPost = new HttpPost("https://httpbin.org/anything");
	        
	        // 文字コードを指定
	        httpPost.setHeader("Content-type", "application/json; charset=UTF-8");
	        // PostするJSON文字列のセット
	        String json = "{\"name\":\"foo\", \"mail\":\"bar\"}";
	        StringEntity entity = new StringEntity(json, "UTF-8");
	        httpPost.setEntity(entity);
	        
	        // POSTリクエストの実行
            try ( CloseableHttpResponse httpResponse = httpClient.execute(httpPost); ) {
                if( httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK ) {
                	System.out.println("Post実行");
                    System.out.println(EntityUtils.toString(httpResponse.getEntity()));
                } else {
                    System.out.println("エラー: " + httpResponse.getStatusLine().getStatusCode());
                    return;
                }
            } catch (Exception e) {
                throw e;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
	}
}
```

APIのエンドポイントとして、[httpbin](https://httpbin.org/)というWebサービスを利用させていただきました。

https://qiita.com/sameyasu/items/adacceb8a1bee893599b

# 実行
`pom.xml`のある場所で、以下のコマンドで実行します。

```console
mvn compile
mvn exec:java
```

実行可能JARファイルの作成と実行は、以下のコマンドで行います。

```console
mvn install
cd target/
java -jar sample-jar-with-dependencies.jar
```

# 参考
https://weblabo.oscasierra.net/java-apache-httpclient45-start/

https://milk0824.hatenadiary.jp/entry/2017/08/07/221443

https://www.baeldung.com/httpclient-4-cookies

https://www.baeldung.com/java-apache-httpclient-cookies