Merge branch 'eugenp:master' into master
This commit is contained in:
commit
42897274b9
|
@ -69,6 +69,7 @@ jmeter/src/main/resources/*-Basic*.csv
|
||||||
jmeter/src/main/resources/*-JMeter*.csv
|
jmeter/src/main/resources/*-JMeter*.csv
|
||||||
jmeter/src/main/resources/*ReportsDashboard*.csv
|
jmeter/src/main/resources/*ReportsDashboard*.csv
|
||||||
jmeter/src/main/resources/dashboard/*ReportsDashboard*.csv
|
jmeter/src/main/resources/dashboard/*ReportsDashboard*.csv
|
||||||
|
jmeter/src/main/resources/*FileExtractionExample.csv
|
||||||
|
|
||||||
ninja/devDb.mv.db
|
ninja/devDb.mv.db
|
||||||
|
|
||||||
|
@ -88,6 +89,7 @@ spring-soap/src/main/java/com/baeldung/springsoap/gen/
|
||||||
/report-*.json
|
/report-*.json
|
||||||
transaction.log
|
transaction.log
|
||||||
*-shell.log
|
*-shell.log
|
||||||
|
customers.xml
|
||||||
|
|
||||||
apache-cxf/cxf-aegis/baeldung.xml
|
apache-cxf/cxf-aegis/baeldung.xml
|
||||||
testing-modules/report-*.json
|
testing-modules/report-*.json
|
||||||
|
@ -102,6 +104,7 @@ spring-boot-modules/spring-boot-react/frontend/build
|
||||||
spring-boot-modules/spring-boot-react/frontend/node
|
spring-boot-modules/spring-boot-react/frontend/node
|
||||||
spring-boot-modules/spring-boot-react/frontend/yarn.lock
|
spring-boot-modules/spring-boot-react/frontend/yarn.lock
|
||||||
spring-boot-modules/spring-boot-properties-3/*.log
|
spring-boot-modules/spring-boot-properties-3/*.log
|
||||||
|
spring-boot-modules/spring-boot-properties-3/*.gz
|
||||||
|
|
||||||
# SDKMan
|
# SDKMan
|
||||||
.sdkmanrc
|
.sdkmanrc
|
||||||
|
@ -109,5 +112,12 @@ spring-boot-modules/spring-boot-properties-3/*.log
|
||||||
# Localstack
|
# Localstack
|
||||||
**/.localstack
|
**/.localstack
|
||||||
|
|
||||||
|
#libraries-2
|
||||||
|
libraries-2/employee*
|
||||||
|
libraries-2/src/test/resources/crawler4j/**
|
||||||
|
|
||||||
#web-modules/ninja
|
#web-modules/ninja
|
||||||
devDb*.db
|
devDb*.db
|
||||||
|
|
||||||
|
#jaxb
|
||||||
|
*.xjb
|
|
@ -74,6 +74,10 @@ Building a single module
|
||||||
====================
|
====================
|
||||||
To build a specific module, run the command: `mvn clean install` in the module directory.
|
To build a specific module, run the command: `mvn clean install` in the module directory.
|
||||||
|
|
||||||
|
It can happen that your module is part of a parent module e.g. `parent-boot-1`,`parent-spring-5` etc, then you will need to build the parent module first so that you can build your module.
|
||||||
|
We have created a `parents` profile that you can use to build just the parent modules, just run the profile as:
|
||||||
|
`mvn clean install -Pparents`
|
||||||
|
|
||||||
|
|
||||||
Building modules from the root of the repository
|
Building modules from the root of the repository
|
||||||
====================
|
====================
|
||||||
|
|
|
@ -36,7 +36,6 @@
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<akka.http.version>10.0.11</akka.http.version>
|
<akka.http.version>10.0.11</akka.http.version>
|
||||||
<akka.stream.version>2.5.11</akka.stream.version>
|
<akka.stream.version>2.5.11</akka.stream.version>
|
||||||
|
|
|
@ -43,7 +43,7 @@
|
||||||
</dependencyManagement>
|
</dependencyManagement>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<spring.version>4.3.4.RELEASE</spring.version>
|
<spring.version>5.3.25</spring.version>
|
||||||
<akka.version>2.4.14</akka.version>
|
<akka.version>2.4.14</akka.version>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,58 @@
|
||||||
|
package com.baeldung.algorithms.checktargetsum;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
public class CheckTargetSum {
|
||||||
|
public boolean isTargetSumExistNaive(int[] nums, int target) {
|
||||||
|
for (int i = 0; i < nums.length; i++) {
|
||||||
|
for (int j = i + 1; j < nums.length; j++) {
|
||||||
|
if (nums[i] + nums[j] == target) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isTargetSumExistSorted(int[] nums, int target) {
|
||||||
|
Arrays.sort(nums);
|
||||||
|
|
||||||
|
int start = 0;
|
||||||
|
int end = nums.length - 1;
|
||||||
|
|
||||||
|
while (start < end) {
|
||||||
|
int sum = nums[start] + nums[end];
|
||||||
|
|
||||||
|
if (sum == target) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sum < target) {
|
||||||
|
start++;
|
||||||
|
} else {
|
||||||
|
end--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isTargetSumExistHashSet(int[] nums, int target) {
|
||||||
|
Set<Integer> hashSet = new HashSet<>();
|
||||||
|
|
||||||
|
for (int num : nums) {
|
||||||
|
int diff = target - num;
|
||||||
|
|
||||||
|
if (hashSet.contains(diff)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
hashSet.add(num);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,46 @@
|
||||||
|
package com.baeldung.algorithms.checktargetsum;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertFalse;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
|
public class CheckTargetSumUnitTest {
|
||||||
|
private CheckTargetSum checkTargetSum = new CheckTargetSum();
|
||||||
|
|
||||||
|
private int[] nums = new int[] { 10, 5, 15, 7, 14, 1, 9 };
|
||||||
|
|
||||||
|
private int existingTarget = 6;
|
||||||
|
|
||||||
|
private int nonExistingTarget = 27;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenArrayOfIntegers_whenTargetSumNaive_thenPairExists() {
|
||||||
|
assertTrue(checkTargetSum.isTargetSumExistNaive(nums, existingTarget));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenArrayOfIntegers_whenTargetSumNaive_thenPairDoesNotExists() {
|
||||||
|
assertFalse(checkTargetSum.isTargetSumExistNaive(nums, nonExistingTarget));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenArrayOfIntegers_whenTargetSumSorted_thenPairExists() {
|
||||||
|
assertTrue(checkTargetSum.isTargetSumExistNaive(nums, existingTarget));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenArrayOfIntegers_whenTargetSumSorted_thenPairDoesNotExists() {
|
||||||
|
assertFalse(checkTargetSum.isTargetSumExistNaive(nums, nonExistingTarget));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenArrayOfIntegers_whenTargetSumHashSet_thenPairExists() {
|
||||||
|
assertTrue(checkTargetSum.isTargetSumExistNaive(nums, existingTarget));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenArrayOfIntegers_whenTargetSumHashSet_thenPairDoesNotExists() {
|
||||||
|
assertFalse(checkTargetSum.isTargetSumExistNaive(nums, nonExistingTarget));
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,4 +1,6 @@
|
||||||
### Relevant Articles:
|
### Relevant Articles:
|
||||||
|
|
||||||
- [Algorithm to Identify and Validate a Credit Card Number](https://www.baeldung.com/java-validate-cc-number)
|
- [Algorithm to Identify and Validate a Credit Card Number](https://www.baeldung.com/java-validate-cc-number)
|
||||||
|
- [Find the N Most Frequent Elements in a Java Array](https://www.baeldung.com/java-n-most-frequent-elements-array)
|
||||||
|
- [Getting Pixel Array From Image in Java](https://www.baeldung.com/java-getting-pixel-array-from-image)
|
||||||
- More articles: [[<-- prev]](/algorithms-miscellaneous-6)
|
- More articles: [[<-- prev]](/algorithms-miscellaneous-6)
|
||||||
|
|
|
@ -0,0 +1,93 @@
|
||||||
|
package com.baeldung.algorithms.frequentelements;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
public class MostFrequentElementsFinder {
|
||||||
|
|
||||||
|
public static List<Integer> findByHashMapAndPriorityQueue(Integer[] array, int n) {
|
||||||
|
Map<Integer, Integer> countMap = new HashMap<>();
|
||||||
|
|
||||||
|
// For each element i in the array, add it to the countMap and increment its count.
|
||||||
|
for (Integer i : array) {
|
||||||
|
countMap.put(i, countMap.getOrDefault(i, 0) + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a max heap (priority queue) that will prioritize elements with higher counts.
|
||||||
|
PriorityQueue<Integer> heap = new PriorityQueue<>(
|
||||||
|
(a, b) -> countMap.get(b) - countMap.get(a));
|
||||||
|
|
||||||
|
// Add all the unique elements in the array to the heap.
|
||||||
|
heap.addAll(countMap.keySet());
|
||||||
|
|
||||||
|
List<Integer> result = new ArrayList<>();
|
||||||
|
for (int i = 0; i < n && !heap.isEmpty(); i++) {
|
||||||
|
// Poll the highest-count element from the heap and add it to the result list.
|
||||||
|
result.add(heap.poll());
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<Integer> findByStream(Integer[] arr, int n) {
|
||||||
|
return Arrays.stream(arr).collect(Collectors.groupingBy(i -> i, Collectors.counting()))
|
||||||
|
.entrySet().stream()
|
||||||
|
.sorted(Collections.reverseOrder(Map.Entry.comparingByValue()))
|
||||||
|
.map(Map.Entry::getKey)
|
||||||
|
.limit(n)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<Integer> findByTreeMap(Integer[] arr, int n) {
|
||||||
|
// Create a TreeMap and use a reverse order comparator to sort the entries by frequency in descending order
|
||||||
|
Map<Integer, Integer> countMap = new TreeMap<>(Collections.reverseOrder());
|
||||||
|
|
||||||
|
for (int i : arr) {
|
||||||
|
countMap.put(i, countMap.getOrDefault(i, 0) + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a list of the map entries and sort them by value (i.e. by frequency) in descending order
|
||||||
|
List<Map.Entry<Integer, Integer>> sortedEntries = new ArrayList<>(countMap.entrySet());
|
||||||
|
sortedEntries.sort((e1, e2) -> e2.getValue().compareTo(e1.getValue()));
|
||||||
|
|
||||||
|
// Extract the n most frequent elements from the sorted list of entries
|
||||||
|
List<Integer> result = new ArrayList<>();
|
||||||
|
for (int i = 0; i < n && i < sortedEntries.size(); i++) {
|
||||||
|
result.add(sortedEntries.get(i).getKey());
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<Integer> findByBucketSort(Integer[] arr, int n) {
|
||||||
|
List<Integer> result = new ArrayList<>();
|
||||||
|
Map<Integer, Integer> freqMap = new HashMap<>();
|
||||||
|
List<Integer>[] bucket = new List[arr.length + 1];
|
||||||
|
|
||||||
|
// Loop through the input array and update the frequency count of each element in the HashMap
|
||||||
|
for (int num : arr) {
|
||||||
|
freqMap.put(num, freqMap.getOrDefault(num, 0) + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Loop through the HashMap and add each element to its corresponding bucket based on its frequency count
|
||||||
|
for (int num : freqMap.keySet()) {
|
||||||
|
int freq = freqMap.get(num);
|
||||||
|
if (bucket[freq] == null) {
|
||||||
|
bucket[freq] = new ArrayList<>();
|
||||||
|
}
|
||||||
|
bucket[freq].add(num);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Loop through the bucket array in reverse order and add the elements to the result list
|
||||||
|
// until we have found the n most frequent elements
|
||||||
|
for (int i = bucket.length - 1; i >= 0 && result.size() < n; i--) {
|
||||||
|
if (bucket[i] != null) {
|
||||||
|
result.addAll(bucket[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return a sublist of the result list containing only the first n elements
|
||||||
|
return result.subList(0, n);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,65 @@
|
||||||
|
package com.baeldung.algorithms.pixelarray;
|
||||||
|
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
import java.awt.image.DataBufferByte;
|
||||||
|
public class GetPixelArray {
|
||||||
|
|
||||||
|
public static int[][] get2DPixelArraySlow(BufferedImage sampleImage) {
|
||||||
|
int width = sampleImage.getWidth();
|
||||||
|
int height = sampleImage.getHeight();
|
||||||
|
int[][] result = new int[height][width];
|
||||||
|
|
||||||
|
for (int row = 0; row < height; row++) {
|
||||||
|
for (int col = 0; col < width; col++) {
|
||||||
|
result[row][col] = sampleImage.getRGB(col, row);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int[][] get2DPixelArrayFast(BufferedImage image) {
|
||||||
|
final byte[] pixelData = ((DataBufferByte) image.getRaster().getDataBuffer()).getData();
|
||||||
|
final int width = image.getWidth();
|
||||||
|
final int height = image.getHeight();
|
||||||
|
final boolean hasAlphaChannel = image.getAlphaRaster() != null;
|
||||||
|
|
||||||
|
int[][] result = new int[height][width];
|
||||||
|
if (hasAlphaChannel) {
|
||||||
|
final int numberOfValues = 4;
|
||||||
|
for (int valueIndex = 0, row = 0, col = 0; valueIndex + numberOfValues - 1 < pixelData.length; valueIndex += numberOfValues) {
|
||||||
|
// Getting the values for each pixel from the pixelData array.
|
||||||
|
int argb = 0;
|
||||||
|
argb += (((int) pixelData[valueIndex] & 0xff) << 24); // alpha value
|
||||||
|
argb += ((int) pixelData[valueIndex + 1] & 0xff); // blue value
|
||||||
|
argb += (((int) pixelData[valueIndex + 2] & 0xff) << 8); // green value
|
||||||
|
argb += (((int) pixelData[valueIndex + 3] & 0xff) << 16); // red value
|
||||||
|
result[row][col] = argb;
|
||||||
|
|
||||||
|
col++;
|
||||||
|
if (col == width) {
|
||||||
|
col = 0;
|
||||||
|
row++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
final int numberOfValues = 3;
|
||||||
|
for (int valueIndex = 0, row = 0, col = 0; valueIndex + numberOfValues - 1 < pixelData.length; valueIndex += numberOfValues) {
|
||||||
|
int argb = 0;
|
||||||
|
argb += -16777216; // 255 alpha value (fully opaque)
|
||||||
|
argb += ((int) pixelData[valueIndex] & 0xff); // blue value
|
||||||
|
argb += (((int) pixelData[valueIndex + 1] & 0xff) << 8); // green value
|
||||||
|
argb += (((int) pixelData[valueIndex + 2] & 0xff) << 16); // red value
|
||||||
|
result[row][col] = argb;
|
||||||
|
|
||||||
|
col++;
|
||||||
|
if (col == width) {
|
||||||
|
col = 0;
|
||||||
|
row++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,33 @@
|
||||||
|
package com.baeldung.algorithms.frequentelements;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Java6Assertions.assertThat;
|
||||||
|
|
||||||
|
public class MostFrequentElementsUnitTest {
|
||||||
|
|
||||||
|
private final Integer[] inputArray = {1, 2, 3, 4, 5, 5, 5, 6, 6, 7, 7, 7, 7, 8, 9, 9, 9, 9, 9};
|
||||||
|
private final int n = 3;
|
||||||
|
private final Integer[] outputArray = {9, 7, 5};
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void givenIntegersArray_UseFindByHashMapAndPriorityQueueMethod_thenReturnMostFrequentElements() {
|
||||||
|
assertThat(MostFrequentElementsFinder.findByHashMapAndPriorityQueue(inputArray, n)).containsExactly(outputArray);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void givenIntegersArray_UseFindByBucketSortMethod_thenReturnMostFrequentElements() {
|
||||||
|
assertThat(MostFrequentElementsFinder.findByBucketSort(inputArray, n)).containsExactly(outputArray);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void givenIntegersArray_UseFindByStreamMethod_thenReturnMostFrequentElements() {
|
||||||
|
assertThat(MostFrequentElementsFinder.findByStream(inputArray, n)).containsExactly(outputArray);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void givenIntegersArray_UseFindByTreeMapMethod_thenReturnMostFrequentElements() {
|
||||||
|
assertThat(MostFrequentElementsFinder.findByTreeMap(inputArray, n)).containsExactly(outputArray);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,30 @@
|
||||||
|
package com.baeldung.algorithms.pixelarray;
|
||||||
|
|
||||||
|
import static com.baeldung.algorithms.pixelarray.GetPixelArray.get2DPixelArrayFast;
|
||||||
|
import static com.baeldung.algorithms.pixelarray.GetPixelArray.get2DPixelArraySlow;
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import javax.imageio.ImageIO;
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
public class GetPixelArrayUnitTest {
|
||||||
|
@Test
|
||||||
|
public void givenImage_whenGetPixelArray_thenBothMethodsReturnEqualValues() {
|
||||||
|
BufferedImage sampleImage = null;
|
||||||
|
try {
|
||||||
|
sampleImage = ImageIO.read(new File("src/main/resources/images/sampleImage.jpg"));
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
int[][] firstResult = get2DPixelArraySlow(sampleImage);
|
||||||
|
int[][] secondResult = get2DPixelArrayFast(sampleImage);
|
||||||
|
|
||||||
|
assertTrue(Arrays.deepEquals(firstResult, secondResult));
|
||||||
|
}
|
||||||
|
}
|
|
@ -21,7 +21,6 @@
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<auto-service.version>1.0-rc2</auto-service.version>
|
<auto-service.version>1.0-rc2</auto-service.version>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
|
@ -20,4 +20,8 @@
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<cxf.version>4.0.0</cxf.version>
|
||||||
|
</properties>
|
||||||
|
|
||||||
</project>
|
</project>
|
|
@ -23,6 +23,16 @@
|
||||||
<artifactId>cxf-rt-transports-http-jetty</artifactId>
|
<artifactId>cxf-rt-transports-http-jetty</artifactId>
|
||||||
<version>${cxf.version}</version>
|
<version>${cxf.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>jakarta.xml.ws</groupId>
|
||||||
|
<artifactId>jakarta.xml.ws-api</artifactId>
|
||||||
|
<version>${jakarta-xml.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>jakarta.jws</groupId>
|
||||||
|
<artifactId>jakarta.jws-api</artifactId>
|
||||||
|
<version>${jakarta.jws.version}</version>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
|
@ -37,4 +47,10 @@
|
||||||
</plugins>
|
</plugins>
|
||||||
</build>
|
</build>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<cxf.version>4.0.0</cxf.version>
|
||||||
|
<jakarta-xml.version>4.0.0</jakarta-xml.version>
|
||||||
|
<jakarta.jws.version>3.0.0</jakarta.jws.version>
|
||||||
|
</properties>
|
||||||
|
|
||||||
</project>
|
</project>
|
|
@ -2,8 +2,8 @@ package com.baeldung.cxf.introduction;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import javax.jws.WebService;
|
import jakarta.jws.WebService;
|
||||||
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
|
import jakarta.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
|
||||||
|
|
||||||
@WebService
|
@WebService
|
||||||
public interface Baeldung {
|
public interface Baeldung {
|
||||||
|
|
|
@ -3,7 +3,7 @@ package com.baeldung.cxf.introduction;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import javax.jws.WebService;
|
import jakarta.jws.WebService;
|
||||||
|
|
||||||
@WebService(endpointInterface = "com.baeldung.cxf.introduction.Baeldung")
|
@WebService(endpointInterface = "com.baeldung.cxf.introduction.Baeldung")
|
||||||
public class BaeldungImpl implements Baeldung {
|
public class BaeldungImpl implements Baeldung {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package com.baeldung.cxf.introduction;
|
package com.baeldung.cxf.introduction;
|
||||||
|
|
||||||
import javax.xml.ws.Endpoint;
|
import jakarta.xml.ws.Endpoint;
|
||||||
|
|
||||||
public class Server {
|
public class Server {
|
||||||
public static void main(String args[]) throws InterruptedException {
|
public static void main(String args[]) throws InterruptedException {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package com.baeldung.cxf.introduction;
|
package com.baeldung.cxf.introduction;
|
||||||
|
|
||||||
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
|
import jakarta.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
|
||||||
|
|
||||||
@XmlJavaTypeAdapter(StudentAdapter.class)
|
@XmlJavaTypeAdapter(StudentAdapter.class)
|
||||||
public interface Student {
|
public interface Student {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package com.baeldung.cxf.introduction;
|
package com.baeldung.cxf.introduction;
|
||||||
|
|
||||||
import javax.xml.bind.annotation.adapters.XmlAdapter;
|
import jakarta.xml.bind.annotation.adapters.XmlAdapter;
|
||||||
|
|
||||||
public class StudentAdapter extends XmlAdapter<StudentImpl, Student> {
|
public class StudentAdapter extends XmlAdapter<StudentImpl, Student> {
|
||||||
public StudentImpl marshal(Student student) throws Exception {
|
public StudentImpl marshal(Student student) throws Exception {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package com.baeldung.cxf.introduction;
|
package com.baeldung.cxf.introduction;
|
||||||
|
|
||||||
import javax.xml.bind.annotation.XmlType;
|
import jakarta.xml.bind.annotation.XmlType;
|
||||||
|
|
||||||
@XmlType(name = "Student")
|
@XmlType(name = "Student")
|
||||||
public class StudentImpl implements Student {
|
public class StudentImpl implements Student {
|
||||||
|
|
|
@ -3,8 +3,8 @@ package com.baeldung.cxf.introduction;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import javax.xml.bind.annotation.XmlElement;
|
import jakarta.xml.bind.annotation.XmlElement;
|
||||||
import javax.xml.bind.annotation.XmlType;
|
import jakarta.xml.bind.annotation.XmlType;
|
||||||
|
|
||||||
@XmlType(name = "StudentMap")
|
@XmlType(name = "StudentMap")
|
||||||
public class StudentMap {
|
public class StudentMap {
|
||||||
|
|
|
@ -3,7 +3,7 @@ package com.baeldung.cxf.introduction;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import javax.xml.bind.annotation.adapters.XmlAdapter;
|
import jakarta.xml.bind.annotation.adapters.XmlAdapter;
|
||||||
|
|
||||||
public class StudentMapAdapter extends XmlAdapter<StudentMap, Map<Integer, Student>> {
|
public class StudentMapAdapter extends XmlAdapter<StudentMap, Map<Integer, Student>> {
|
||||||
public StudentMap marshal(Map<Integer, Student> boundMap) throws Exception {
|
public StudentMap marshal(Map<Integer, Student> boundMap) throws Exception {
|
||||||
|
|
|
@ -5,8 +5,8 @@ import static org.junit.Assert.assertEquals;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import javax.xml.namespace.QName;
|
import javax.xml.namespace.QName;
|
||||||
import javax.xml.ws.Service;
|
import jakarta.xml.ws.Service;
|
||||||
import javax.xml.ws.soap.SOAPBinding;
|
import jakarta.xml.ws.soap.SOAPBinding;
|
||||||
|
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
|
@ -16,12 +16,28 @@
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.cxf</groupId>
|
<groupId>org.apache.cxf</groupId>
|
||||||
<artifactId>cxf-rt-frontend-jaxrs</artifactId>
|
<artifactId>cxf-rt-frontend-jaxrs</artifactId>
|
||||||
<version>${cxf.version}</version>
|
<version>4.0.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.cxf</groupId>
|
<groupId>org.apache.cxf</groupId>
|
||||||
<artifactId>cxf-rt-transports-http-jetty</artifactId>
|
<artifactId>cxf-rt-transports-http-jetty</artifactId>
|
||||||
<version>${cxf.version}</version>
|
<version>4.0.0</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>jakarta.xml.ws</groupId>
|
||||||
|
<artifactId>jakarta.xml.ws-api</artifactId>
|
||||||
|
<version>${jakarta-xml.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>jakarta.jws</groupId>
|
||||||
|
<artifactId>jakarta.jws-api</artifactId>
|
||||||
|
<version>${jakarta-jws.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>jakarta.platform</groupId>
|
||||||
|
<artifactId>jakarta.jakartaee-web-api</artifactId>
|
||||||
|
<version>${jakarta-platform.version}</version>
|
||||||
|
<scope>compile</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.httpcomponents</groupId>
|
<groupId>org.apache.httpcomponents</groupId>
|
||||||
|
@ -50,6 +66,9 @@
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<httpclient.version>4.5.2</httpclient.version>
|
<httpclient.version>4.5.2</httpclient.version>
|
||||||
|
<jakarta-xml.version>4.0.0</jakarta-xml.version>
|
||||||
|
<jakarta-jws.version>3.0.0</jakarta-jws.version>
|
||||||
|
<jakarta-platform.version>9.0.0</jakarta-platform.version>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
</project>
|
</project>
|
|
@ -1,8 +1,8 @@
|
||||||
package com.baeldung.cxf.jaxrs.implementation;
|
package com.baeldung.cxf.jaxrs.implementation;
|
||||||
|
|
||||||
import javax.ws.rs.*;
|
import jakarta.ws.rs.*;
|
||||||
import javax.ws.rs.core.Response;
|
import jakarta.ws.rs.core.Response;
|
||||||
import javax.xml.bind.annotation.XmlRootElement;
|
import jakarta.xml.bind.annotation.XmlRootElement;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package com.baeldung.cxf.jaxrs.implementation;
|
package com.baeldung.cxf.jaxrs.implementation;
|
||||||
|
|
||||||
import javax.ws.rs.*;
|
import jakarta.ws.rs.*;
|
||||||
import javax.ws.rs.core.Response;
|
import jakarta.ws.rs.core.Response;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package com.baeldung.cxf.jaxrs.implementation;
|
package com.baeldung.cxf.jaxrs.implementation;
|
||||||
|
|
||||||
import javax.xml.bind.annotation.XmlRootElement;
|
import jakarta.xml.bind.annotation.XmlRootElement;
|
||||||
|
|
||||||
@XmlRootElement(name = "Student")
|
@XmlRootElement(name = "Student")
|
||||||
public class Student {
|
public class Student {
|
||||||
|
|
|
@ -7,7 +7,7 @@ import java.io.InputStream;
|
||||||
import java.io.InputStreamReader;
|
import java.io.InputStreamReader;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
|
|
||||||
import javax.xml.bind.JAXB;
|
import jakarta.xml.bind.JAXB;
|
||||||
|
|
||||||
import org.apache.http.HttpResponse;
|
import org.apache.http.HttpResponse;
|
||||||
import org.apache.http.client.methods.HttpDelete;
|
import org.apache.http.client.methods.HttpDelete;
|
||||||
|
|
|
@ -40,10 +40,22 @@
|
||||||
<artifactId>spring-webmvc</artifactId>
|
<artifactId>spring-webmvc</artifactId>
|
||||||
<version>${spring.version}</version>
|
<version>${spring.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.sun.xml.ws</groupId>
|
||||||
|
<artifactId>jaxws-ri</artifactId>
|
||||||
|
<version>2.3.3</version>
|
||||||
|
<type>pom</type>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>javax.servlet</groupId>
|
<groupId>javax.servlet</groupId>
|
||||||
<artifactId>javax.servlet-api</artifactId>
|
<artifactId>javax.servlet-api</artifactId>
|
||||||
<version>${javax.servlet-api.version}</version>
|
<version>4.0.1</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>javax.servlet</groupId>
|
||||||
|
<artifactId>jstl</artifactId>
|
||||||
|
<version>1.2</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
|
@ -103,8 +115,9 @@
|
||||||
</profiles>
|
</profiles>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<spring.version>4.3.4.RELEASE</spring.version>
|
<spring.version>5.3.25</spring.version>
|
||||||
<cargo-maven2-plugin.version>1.6.1</cargo-maven2-plugin.version>
|
<cargo-maven2-plugin.version>1.6.1</cargo-maven2-plugin.version>
|
||||||
|
<maven-war-plugin.version>3.3.2</maven-war-plugin.version>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
</project>
|
</project>
|
|
@ -23,6 +23,11 @@
|
||||||
<artifactId>cxf-rt-rs-sse</artifactId>
|
<artifactId>cxf-rt-rs-sse</artifactId>
|
||||||
<version>${cxf-version}</version>
|
<version>${cxf-version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>jakarta.ws.rs</groupId>
|
||||||
|
<artifactId>jakarta.ws.rs-api</artifactId>
|
||||||
|
<version>${jakarta-ws.version}</version>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
|
@ -55,7 +60,8 @@
|
||||||
</build>
|
</build>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<cxf-version>3.2.0</cxf-version>
|
<cxf-version>4.0.0</cxf-version>
|
||||||
|
<jakarta-ws.version>3.1.0</jakarta-ws.version>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
</project>
|
</project>
|
|
@ -1,10 +1,10 @@
|
||||||
package com.baeldung.sse.jaxrs.client;
|
package com.baeldung.sse.jaxrs.client;
|
||||||
|
|
||||||
import javax.ws.rs.client.Client;
|
import jakarta.ws.rs.client.Client;
|
||||||
import javax.ws.rs.client.ClientBuilder;
|
import jakarta.ws.rs.client.ClientBuilder;
|
||||||
import javax.ws.rs.client.WebTarget;
|
import jakarta.ws.rs.client.WebTarget;
|
||||||
import javax.ws.rs.sse.InboundSseEvent;
|
import jakarta.ws.rs.sse.InboundSseEvent;
|
||||||
import javax.ws.rs.sse.SseEventSource;
|
import jakarta.ws.rs.sse.SseEventSource;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
public class SseClientApp {
|
public class SseClientApp {
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
package com.baeldung.sse.jaxrs.client;
|
package com.baeldung.sse.jaxrs.client;
|
||||||
|
|
||||||
import javax.ws.rs.client.Client;
|
import jakarta.ws.rs.client.Client;
|
||||||
import javax.ws.rs.client.ClientBuilder;
|
import jakarta.ws.rs.client.ClientBuilder;
|
||||||
import javax.ws.rs.client.WebTarget;
|
import jakarta.ws.rs.client.WebTarget;
|
||||||
import javax.ws.rs.sse.InboundSseEvent;
|
import jakarta.ws.rs.sse.InboundSseEvent;
|
||||||
import javax.ws.rs.sse.SseEventSource;
|
import jakarta.ws.rs.sse.SseEventSource;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
|
|
|
@ -15,16 +15,14 @@
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>javax.ws.rs</groupId>
|
<groupId>jakarta.ws.rs</groupId>
|
||||||
<artifactId>javax.ws.rs-api</artifactId>
|
<artifactId>jakarta.ws.rs-api</artifactId>
|
||||||
<version>${rs-api.version}</version>
|
<version>${jakarta-ws.version}</version>
|
||||||
<scope>provided</scope>
|
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>javax.enterprise</groupId>
|
<groupId>jakarta.enterprise</groupId>
|
||||||
<artifactId>cdi-api</artifactId>
|
<artifactId>jakarta.enterprise.cdi-api</artifactId>
|
||||||
<version>${cdi-api.version}</version>
|
<version>${jakarta-cdi-api}</version>
|
||||||
<scope>provided</scope>
|
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>javax.json.bind</groupId>
|
<groupId>javax.json.bind</groupId>
|
||||||
|
@ -37,6 +35,11 @@
|
||||||
<build>
|
<build>
|
||||||
<finalName>${project.artifactId}</finalName>
|
<finalName>${project.artifactId}</finalName>
|
||||||
<plugins>
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-war-plugin</artifactId>
|
||||||
|
<version>${maven-war-plugin.version}</version>
|
||||||
|
</plugin>
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>net.wasdev.wlp.maven.plugins</groupId>
|
<groupId>net.wasdev.wlp.maven.plugins</groupId>
|
||||||
<artifactId>liberty-maven-plugin</artifactId>
|
<artifactId>liberty-maven-plugin</artifactId>
|
||||||
|
@ -78,9 +81,10 @@
|
||||||
<liberty-maven-plugin.version>2.4.2</liberty-maven-plugin.version>
|
<liberty-maven-plugin.version>2.4.2</liberty-maven-plugin.version>
|
||||||
<failOnMissingWebXml>false</failOnMissingWebXml>
|
<failOnMissingWebXml>false</failOnMissingWebXml>
|
||||||
<openliberty-version>18.0.0.2</openliberty-version>
|
<openliberty-version>18.0.0.2</openliberty-version>
|
||||||
<rs-api.version>2.1</rs-api.version>
|
<jakarta-ws.version>3.1.0</jakarta-ws.version>
|
||||||
<cdi-api.version>2.0</cdi-api.version>
|
<jakarta-cdi-api>4.0.1</jakarta-cdi-api>
|
||||||
<bind-api.version>1.0</bind-api.version>
|
<bind-api.version>1.0</bind-api.version>
|
||||||
|
<maven-war-plugin.version>3.3.2</maven-war-plugin.version>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
</project>
|
</project>
|
|
@ -1,7 +1,7 @@
|
||||||
package com.baeldung.sse.jaxrs;
|
package com.baeldung.sse.jaxrs;
|
||||||
|
|
||||||
import javax.ws.rs.ApplicationPath;
|
import jakarta.ws.rs.ApplicationPath;
|
||||||
import javax.ws.rs.core.Application;
|
import jakarta.ws.rs.core.Application;
|
||||||
|
|
||||||
@ApplicationPath("sse")
|
@ApplicationPath("sse")
|
||||||
public class AppConfig extends Application {
|
public class AppConfig extends Application {
|
||||||
|
|
|
@ -1,15 +1,15 @@
|
||||||
package com.baeldung.sse.jaxrs;
|
package com.baeldung.sse.jaxrs;
|
||||||
|
|
||||||
import javax.enterprise.context.ApplicationScoped;
|
import jakarta.enterprise.context.ApplicationScoped;
|
||||||
import javax.inject.Inject;
|
import jakarta.inject.Inject;
|
||||||
import javax.ws.rs.*;
|
import jakarta.ws.rs.*;
|
||||||
import javax.ws.rs.core.Context;
|
import jakarta.ws.rs.core.Context;
|
||||||
import javax.ws.rs.core.HttpHeaders;
|
import jakarta.ws.rs.core.HttpHeaders;
|
||||||
import javax.ws.rs.core.MediaType;
|
import jakarta.ws.rs.core.MediaType;
|
||||||
import javax.ws.rs.sse.OutboundSseEvent;
|
import jakarta.ws.rs.sse.OutboundSseEvent;
|
||||||
import javax.ws.rs.sse.Sse;
|
import jakarta.ws.rs.sse.Sse;
|
||||||
import javax.ws.rs.sse.SseBroadcaster;
|
import jakarta.ws.rs.sse.SseBroadcaster;
|
||||||
import javax.ws.rs.sse.SseEventSink;
|
import jakarta.ws.rs.sse.SseEventSink;
|
||||||
|
|
||||||
@ApplicationScoped
|
@ApplicationScoped
|
||||||
@Path("stock")
|
@Path("stock")
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
package com.baeldung.sse.jaxrs;
|
package com.baeldung.sse.jaxrs;
|
||||||
|
|
||||||
import javax.enterprise.context.ApplicationScoped;
|
import jakarta.enterprise.context.ApplicationScoped;
|
||||||
import javax.enterprise.context.Initialized;
|
import jakarta.enterprise.context.Initialized;
|
||||||
import javax.enterprise.event.Event;
|
import jakarta.enterprise.event.Event;
|
||||||
import javax.enterprise.event.Observes;
|
import jakarta.enterprise.event.Observes;
|
||||||
import javax.inject.Inject;
|
import jakarta.inject.Inject;
|
||||||
import javax.inject.Named;
|
import jakarta.inject.Named;
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.math.RoundingMode;
|
import java.math.RoundingMode;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
|
|
|
@ -12,6 +12,6 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring
|
||||||
- [Reading an HTTP Response Body as a String in Java](https://www.baeldung.com/java-http-response-body-as-string)
|
- [Reading an HTTP Response Body as a String in Java](https://www.baeldung.com/java-http-response-body-as-string)
|
||||||
- [How To Get Cookies From the Apache HttpClient Response](https://www.baeldung.com/java-apache-httpclient-cookies)
|
- [How To Get Cookies From the Apache HttpClient Response](https://www.baeldung.com/java-apache-httpclient-cookies)
|
||||||
- [Enabling Logging for Apache HttpClient](https://www.baeldung.com/apache-httpclient-enable-logging)
|
- [Enabling Logging for Apache HttpClient](https://www.baeldung.com/apache-httpclient-enable-logging)
|
||||||
- [Expand Shortened URLs with Apache HttpClient](https://www.baeldung.com/apache-httpclient-expand-url)
|
|
||||||
- [Apache HttpClient vs. CloseableHttpClient](https://www.baeldung.com/apache-httpclient-vs-closeablehttpclient)
|
- [Apache HttpClient vs. CloseableHttpClient](https://www.baeldung.com/apache-httpclient-vs-closeablehttpclient)
|
||||||
|
- [Expand Shortened URLs with Apache HttpClient](https://www.baeldung.com/apache-httpclient-expand-url)
|
||||||
- More articles: [[<-- prev]](../apache-httpclient)
|
- More articles: [[<-- prev]](../apache-httpclient)
|
||||||
|
|
|
@ -21,17 +21,6 @@
|
||||||
<version>${commons-lang3.version}</version>
|
<version>${commons-lang3.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<!-- http client -->
|
<!-- http client -->
|
||||||
<dependency>
|
|
||||||
<groupId>org.apache.httpcomponents</groupId>
|
|
||||||
<artifactId>httpclient</artifactId>
|
|
||||||
<version>${httpclient.version}</version>
|
|
||||||
<exclusions>
|
|
||||||
<exclusion>
|
|
||||||
<artifactId>commons-logging</artifactId>
|
|
||||||
<groupId>commons-logging</groupId>
|
|
||||||
</exclusion>
|
|
||||||
</exclusions>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.httpcomponents.client5</groupId>
|
<groupId>org.apache.httpcomponents.client5</groupId>
|
||||||
<artifactId>httpclient5</artifactId>
|
<artifactId>httpclient5</artifactId>
|
||||||
|
@ -97,8 +86,7 @@
|
||||||
<properties>
|
<properties>
|
||||||
<assertj.version>3.22.0</assertj.version>
|
<assertj.version>3.22.0</assertj.version>
|
||||||
<mockserver.version>5.11.2</mockserver.version>
|
<mockserver.version>5.11.2</mockserver.version>
|
||||||
<httpclient.version>4.5.8</httpclient.version>
|
<httpclient5.version>5.2.1</httpclient5.version>
|
||||||
<httpclient5.version>5.2</httpclient5.version>
|
|
||||||
<maven.compiler.source.version>11</maven.compiler.source.version>
|
<maven.compiler.source.version>11</maven.compiler.source.version>
|
||||||
<maven.compiler.target.version>11</maven.compiler.target.version>
|
<maven.compiler.target.version>11</maven.compiler.target.version>
|
||||||
<spring-boot.version>2.1.7.RELEASE</spring-boot.version>
|
<spring-boot.version>2.1.7.RELEASE</spring-boot.version>
|
||||||
|
|
|
@ -23,7 +23,7 @@ import java.io.IOException;
|
||||||
class HttpClientGettingCookieValueUnitTest {
|
class HttpClientGettingCookieValueUnitTest {
|
||||||
private static Logger log = LoggerFactory.getLogger(HttpClientGettingCookieValueUnitTest.class);
|
private static Logger log = LoggerFactory.getLogger(HttpClientGettingCookieValueUnitTest.class);
|
||||||
|
|
||||||
private static final String SAMPLE_URL = "http://www.baeldung.com/";
|
private static final String SAMPLE_URL = "http://www.github.com/";
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void whenSettingCustomCookieOnTheRequest_thenGettingTheSameCookieFromTheResponse() throws IOException {
|
void whenSettingCustomCookieOnTheRequest_thenGettingTheSameCookieFromTheResponse() throws IOException {
|
||||||
|
|
|
@ -0,0 +1,126 @@
|
||||||
|
package com.baeldung.httpclient.expandUrl;
|
||||||
|
|
||||||
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
|
import static org.hamcrest.Matchers.equalTo;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import com.google.common.base.Preconditions;
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.tuple.ImmutablePair;
|
||||||
|
import org.apache.commons.lang3.tuple.Pair;
|
||||||
|
|
||||||
|
import org.apache.hc.client5.http.classic.methods.HttpHead;
|
||||||
|
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
|
||||||
|
|
||||||
|
import org.apache.hc.client5.http.impl.classic.HttpClientBuilder;
|
||||||
|
import org.apache.hc.core5.http.Header;
|
||||||
|
import org.apache.hc.core5.http.HttpHeaders;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.AfterAll;
|
||||||
|
import org.junit.jupiter.api.BeforeAll;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
class HttpClientExpandUrlLiveTest {
|
||||||
|
|
||||||
|
private static CloseableHttpClient httpClient;
|
||||||
|
|
||||||
|
@BeforeAll
|
||||||
|
static void setup() {
|
||||||
|
httpClient = HttpClientBuilder.create()
|
||||||
|
.disableRedirectHandling()
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@AfterAll
|
||||||
|
static void tearDown() throws IOException {
|
||||||
|
if (httpClient != null) {
|
||||||
|
httpClient.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void givenShortenedOnce_whenUrlIsExpanded_thenCorrectResult() throws IOException {
|
||||||
|
final String expectedResult = "https://www.baeldung.com/rest-versioning";
|
||||||
|
final String actualResult = expandSingleLevel("http://bit.ly/3LScTri");
|
||||||
|
assertThat(actualResult, equalTo(expectedResult));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void givenShortenedMultiple_whenUrlIsExpanded_thenCorrectResult() throws IOException {
|
||||||
|
final String expectedResult = "https://www.baeldung.com/rest-versioning";
|
||||||
|
final String actualResult = expand("http://t.co/e4rDDbnzmk");
|
||||||
|
assertThat(actualResult, equalTo(expectedResult));
|
||||||
|
}
|
||||||
|
|
||||||
|
private String expand(final String urlArg) throws IOException {
|
||||||
|
String originalUrl = urlArg;
|
||||||
|
String newUrl = expandSingleLevel(originalUrl);
|
||||||
|
while (!originalUrl.equals(newUrl)) {
|
||||||
|
originalUrl = newUrl;
|
||||||
|
newUrl = expandSingleLevel(originalUrl);
|
||||||
|
}
|
||||||
|
|
||||||
|
return newUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
final String expandSafe(final String urlArg) throws IOException {
|
||||||
|
String originalUrl = urlArg;
|
||||||
|
String newUrl = expandSingleLevelSafe(originalUrl).getRight();
|
||||||
|
final List<String> alreadyVisited = Lists.newArrayList(originalUrl, newUrl);
|
||||||
|
while (!originalUrl.equals(newUrl)) {
|
||||||
|
originalUrl = newUrl;
|
||||||
|
final Pair<Integer, String> statusAndUrl = expandSingleLevelSafe(originalUrl);
|
||||||
|
newUrl = statusAndUrl.getRight();
|
||||||
|
final boolean isRedirect = statusAndUrl.getLeft() == 301 || statusAndUrl.getLeft() == 302;
|
||||||
|
if (isRedirect && alreadyVisited.contains(newUrl)) {
|
||||||
|
throw new IllegalStateException("Likely a redirect loop");
|
||||||
|
}
|
||||||
|
alreadyVisited.add(newUrl);
|
||||||
|
}
|
||||||
|
|
||||||
|
return newUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Pair<Integer, String> expandSingleLevelSafe(final String url) throws IOException {
|
||||||
|
try {
|
||||||
|
HttpHead request = new HttpHead(url);
|
||||||
|
Pair<Integer, String> resp = httpClient.execute(request, response -> {
|
||||||
|
final int statusCode = response.getCode();
|
||||||
|
if (statusCode != 301 && statusCode != 302) {
|
||||||
|
return new ImmutablePair<>(statusCode, url);
|
||||||
|
}
|
||||||
|
final Header[] headers = response.getHeaders(HttpHeaders.LOCATION);
|
||||||
|
Preconditions.checkState(headers.length == 1);
|
||||||
|
final String newUrl = headers[0].getValue();
|
||||||
|
|
||||||
|
return new ImmutablePair<>(statusCode, newUrl);
|
||||||
|
});
|
||||||
|
return resp;
|
||||||
|
} catch (final IllegalArgumentException uriEx) {
|
||||||
|
return new ImmutablePair<>(500, url);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String expandSingleLevel(final String url) throws IOException {
|
||||||
|
try {
|
||||||
|
HttpHead request = new HttpHead(url);
|
||||||
|
String expandedUrl = httpClient.execute(request, response -> {
|
||||||
|
final int statusCode = response.getCode();
|
||||||
|
if (statusCode != 301 && statusCode != 302) {
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
final Header[] headers = response.getHeaders(HttpHeaders.LOCATION);
|
||||||
|
Preconditions.checkState(headers.length == 1);
|
||||||
|
|
||||||
|
return headers[0].getValue();
|
||||||
|
});
|
||||||
|
return expandedUrl;
|
||||||
|
} catch (final IllegalArgumentException uriEx) {
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,37 +1,39 @@
|
||||||
package com.baeldung.httpclient.httpclient;
|
package com.baeldung.httpclient.httpclient;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
import org.apache.hc.client5.http.classic.HttpClient;
|
import org.apache.hc.client5.http.classic.HttpClient;
|
||||||
import org.apache.hc.client5.http.classic.methods.HttpGet;
|
import org.apache.hc.client5.http.classic.methods.HttpGet;
|
||||||
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
|
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
|
||||||
import org.apache.hc.client5.http.impl.classic.CloseableHttpResponse;
|
|
||||||
import org.apache.hc.client5.http.impl.classic.HttpClientBuilder;
|
import org.apache.hc.client5.http.impl.classic.HttpClientBuilder;
|
||||||
import org.apache.hc.client5.http.impl.classic.HttpClients;
|
import org.apache.hc.client5.http.impl.classic.HttpClients;
|
||||||
import org.apache.hc.core5.http.HttpEntity;
|
import org.apache.hc.core5.http.HttpEntity;
|
||||||
import org.apache.hc.core5.http.HttpResponse;
|
|
||||||
import org.apache.hc.core5.http.HttpStatus;
|
import org.apache.hc.core5.http.HttpStatus;
|
||||||
import org.apache.hc.core5.http.io.entity.EntityUtils;
|
import org.apache.hc.core5.http.io.entity.EntityUtils;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
|
||||||
|
|
||||||
class ApacheHttpClientUnitTest extends GetRequestMockServer {
|
class ApacheHttpClientUnitTest extends GetRequestMockServer {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void givenDeveloperUsedHttpClient_whenExecutingGetRequest_thenStatusIsOkButSonarReportsAnIssue() throws IOException {
|
void givenDeveloperUsedHttpClient_whenExecutingGetRequest_thenStatusIsOkButSonarReportsAnIssue() throws IOException {
|
||||||
HttpClient httpClient = HttpClients.createDefault();
|
HttpClient httpClient = HttpClients.createDefault();
|
||||||
HttpGet httpGet = new HttpGet(serviceOneUrl);
|
HttpGet httpGet = new HttpGet(serviceOneUrl);
|
||||||
HttpResponse response = httpClient.execute(httpGet);
|
httpClient.execute(httpGet, response -> {
|
||||||
assertThat(response.getCode()).isEqualTo(HttpStatus.SC_OK);
|
assertThat(response.getCode()).isEqualTo(HttpStatus.SC_OK);
|
||||||
|
return response;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void givenDeveloperUsedCloseableHttpClient_whenExecutingGetRequest_thenStatusIsOk() throws IOException {
|
void givenDeveloperUsedCloseableHttpClient_whenExecutingGetRequest_thenStatusIsOk() throws IOException {
|
||||||
try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
|
try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
|
||||||
HttpGet httpGet = new HttpGet(serviceOneUrl);
|
HttpGet httpGet = new HttpGet(serviceOneUrl);
|
||||||
HttpResponse response = httpClient.execute(httpGet);
|
httpClient.execute(httpGet, response -> {
|
||||||
assertThat(response.getCode()).isEqualTo(HttpStatus.SC_OK);
|
assertThat(response.getCode()).isEqualTo(HttpStatus.SC_OK);
|
||||||
|
return response;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,20 +41,10 @@ class ApacheHttpClientUnitTest extends GetRequestMockServer {
|
||||||
void givenDeveloperUsedHttpClientBuilder_whenExecutingGetRequest_thenStatusIsOk() throws IOException {
|
void givenDeveloperUsedHttpClientBuilder_whenExecutingGetRequest_thenStatusIsOk() throws IOException {
|
||||||
try (CloseableHttpClient httpClient = HttpClientBuilder.create().build()) {
|
try (CloseableHttpClient httpClient = HttpClientBuilder.create().build()) {
|
||||||
HttpGet httpGet = new HttpGet(serviceOneUrl);
|
HttpGet httpGet = new HttpGet(serviceOneUrl);
|
||||||
HttpResponse response = httpClient.execute(httpGet);
|
httpClient.execute(httpGet, response -> {
|
||||||
assertThat(response.getCode()).isEqualTo(HttpStatus.SC_OK);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void givenDeveloperUsedCloseableHttpResponse_whenExecutingGetRequest_thenStatusIsOk() throws IOException {
|
|
||||||
try (CloseableHttpClient httpClient = HttpClientBuilder.create().build()) {
|
|
||||||
HttpGet httpGet = new HttpGet(serviceOneUrl);
|
|
||||||
try (CloseableHttpResponse response = httpClient.execute(httpGet)) {
|
|
||||||
HttpEntity entity = response.getEntity();
|
|
||||||
EntityUtils.consume(entity);
|
|
||||||
assertThat(response.getCode()).isEqualTo(HttpStatus.SC_OK);
|
assertThat(response.getCode()).isEqualTo(HttpStatus.SC_OK);
|
||||||
}
|
return response;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,18 +52,20 @@ class ApacheHttpClientUnitTest extends GetRequestMockServer {
|
||||||
void givenDeveloperUsedSingleClient_whenExecutingTwoGetRequest_thenStatusIsOk() throws IOException {
|
void givenDeveloperUsedSingleClient_whenExecutingTwoGetRequest_thenStatusIsOk() throws IOException {
|
||||||
try (CloseableHttpClient httpClient = HttpClientBuilder.create().build()) {
|
try (CloseableHttpClient httpClient = HttpClientBuilder.create().build()) {
|
||||||
HttpGet httpGetOne = new HttpGet(serviceOneUrl);
|
HttpGet httpGetOne = new HttpGet(serviceOneUrl);
|
||||||
try (CloseableHttpResponse responseOne = httpClient.execute(httpGetOne)) {
|
httpClient.execute(httpGetOne, responseOne -> {
|
||||||
HttpEntity entityOne = responseOne.getEntity();
|
HttpEntity entityOne = responseOne.getEntity();
|
||||||
EntityUtils.consume(entityOne);
|
EntityUtils.consume(entityOne);
|
||||||
assertThat(responseOne.getCode()).isEqualTo(HttpStatus.SC_OK);
|
assertThat(responseOne.getCode()).isEqualTo(HttpStatus.SC_OK);
|
||||||
}
|
return responseOne;
|
||||||
|
});
|
||||||
|
|
||||||
HttpGet httpGetTwo = new HttpGet(serviceTwoUrl);
|
HttpGet httpGetTwo = new HttpGet(serviceTwoUrl);
|
||||||
try (CloseableHttpResponse responseTwo = httpClient.execute(httpGetTwo)) {
|
httpClient.execute(httpGetTwo, responseTwo -> {
|
||||||
HttpEntity entityTwo = responseTwo.getEntity();
|
HttpEntity entityTwo = httpGetTwo.getEntity();
|
||||||
EntityUtils.consume(entityTwo);
|
EntityUtils.consume(entityTwo);
|
||||||
assertThat(responseTwo.getCode()).isEqualTo(HttpStatus.SC_OK);
|
assertThat(responseTwo.getCode()).isEqualTo(HttpStatus.SC_OK);
|
||||||
}
|
return responseTwo;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,40 @@
|
||||||
|
package com.baeldung.httpclient;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import org.apache.hc.client5.http.classic.methods.HttpGet;
|
||||||
|
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
|
||||||
|
import org.apache.hc.client5.http.impl.classic.HttpClients;
|
||||||
|
import org.apache.hc.core5.http.HttpEntity;
|
||||||
|
import org.apache.hc.core5.http.HttpStatus;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
class HttpClientCancelRequestLiveTest {
|
||||||
|
|
||||||
|
private static final String SAMPLE_URL = "http://www.github.com";
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void whenRequestIsCanceled_thenCorrect() throws IOException {
|
||||||
|
HttpGet request = new HttpGet(SAMPLE_URL);
|
||||||
|
try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
|
||||||
|
httpClient.execute(request, response -> {
|
||||||
|
HttpEntity entity = response.getEntity();
|
||||||
|
|
||||||
|
System.out.println("----------------------------------------");
|
||||||
|
System.out.println(response.getCode());
|
||||||
|
if (entity != null) {
|
||||||
|
System.out.println("Response content length: " + entity.getContentLength());
|
||||||
|
}
|
||||||
|
System.out.println("----------------------------------------");
|
||||||
|
// Do not feel like reading the response body
|
||||||
|
// Call abort on the request object
|
||||||
|
request.abort();
|
||||||
|
|
||||||
|
assertThat(response.getCode()).isEqualTo(HttpStatus.SC_OK);
|
||||||
|
return response;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,8 +1,8 @@
|
||||||
package com.baeldung.httpclient.base;
|
package com.baeldung.httpclient.base;
|
||||||
|
|
||||||
import com.baeldung.httpclient.ResponseUtil;
|
import com.baeldung.httpclient.ResponseUtil;
|
||||||
|
|
||||||
import org.apache.http.Header;
|
import org.apache.http.Header;
|
||||||
import org.apache.http.HttpEntity;
|
|
||||||
import org.apache.http.HttpHeaders;
|
import org.apache.http.HttpHeaders;
|
||||||
import org.apache.http.client.config.RequestConfig;
|
import org.apache.http.client.config.RequestConfig;
|
||||||
import org.apache.http.client.methods.CloseableHttpResponse;
|
import org.apache.http.client.methods.CloseableHttpResponse;
|
||||||
|
@ -10,7 +10,6 @@ import org.apache.http.client.methods.HttpGet;
|
||||||
import org.apache.http.conn.ConnectTimeoutException;
|
import org.apache.http.conn.ConnectTimeoutException;
|
||||||
import org.apache.http.impl.client.CloseableHttpClient;
|
import org.apache.http.impl.client.CloseableHttpClient;
|
||||||
import org.apache.http.impl.client.HttpClientBuilder;
|
import org.apache.http.impl.client.HttpClientBuilder;
|
||||||
import org.apache.http.impl.client.HttpClients;
|
|
||||||
import org.apache.http.impl.conn.BasicHttpClientConnectionManager;
|
import org.apache.http.impl.conn.BasicHttpClientConnectionManager;
|
||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
|
@ -73,30 +72,4 @@ public class HttpClientLiveTest {
|
||||||
assertThat(headers, not(emptyArray()));
|
assertThat(headers, not(emptyArray()));
|
||||||
}
|
}
|
||||||
|
|
||||||
// tests - cancel request
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public final void whenRequestIsCanceled_thenCorrect() throws IOException {
|
|
||||||
instance = HttpClients.custom().build();
|
|
||||||
final HttpGet request = new HttpGet(SAMPLE_URL);
|
|
||||||
response = instance.execute(request);
|
|
||||||
|
|
||||||
try {
|
|
||||||
final HttpEntity entity = response.getEntity();
|
|
||||||
|
|
||||||
System.out.println("----------------------------------------");
|
|
||||||
System.out.println(response.getStatusLine());
|
|
||||||
if (entity != null) {
|
|
||||||
System.out.println("Response content length: " + entity.getContentLength());
|
|
||||||
}
|
|
||||||
System.out.println("----------------------------------------");
|
|
||||||
|
|
||||||
// Do not feel like reading the response body
|
|
||||||
// Call abort on the request object
|
|
||||||
request.abort();
|
|
||||||
} finally {
|
|
||||||
response.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,16 @@
|
||||||
## Apache HttpClient
|
## Apache HttpClient 4
|
||||||
|
|
||||||
This module contains articles about Apache HttpClient 4.5
|
This module contains articles about Apache HttpClient 4.5
|
||||||
|
|
||||||
### Relevant Articles
|
### Relevant Articles
|
||||||
|
|
||||||
|
- [Apache HttpClient – Cancel Request](https://www.baeldung.com/httpclient-cancel-request)
|
||||||
- [Apache HttpClient with SSL](https://www.baeldung.com/httpclient-ssl)
|
- [Apache HttpClient with SSL](https://www.baeldung.com/httpclient-ssl)
|
||||||
- [Apache HttpClient Timeout](https://www.baeldung.com/httpclient-timeout)
|
- [Apache HttpClient Timeout](https://www.baeldung.com/httpclient-timeout)
|
||||||
- [Custom HTTP Header with the Apache HttpClient](https://www.baeldung.com/httpclient-custom-http-header)
|
- [Custom HTTP Header with the Apache HttpClient](https://www.baeldung.com/httpclient-custom-http-header)
|
||||||
|
- [Apache HttpClient vs. CloseableHttpClient](https://www.baeldung.com/apache-httpclient-vs-closeablehttpclient)
|
||||||
|
- [Expand Shortened URLs with Apache HttpClient](https://www.baeldung.com/apache-httpclient-expand-url)
|
||||||
|
- [Retrying Requests using Apache HttpClient](https://www.baeldung.com/java-retrying-requests-using-apache-httpclient)
|
||||||
|
|
||||||
### Running the Tests
|
### Running the Tests
|
||||||
To run the live tests, use the command: mvn clean install -Plive
|
To run the live tests, use the command: mvn clean install -Plive
|
|
@ -1,11 +1,11 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<artifactId>httpclient4</artifactId>
|
<artifactId>apache-httpclient4</artifactId>
|
||||||
<version>0.1-SNAPSHOT</version>
|
<version>0.1-SNAPSHOT</version>
|
||||||
<name>httpclient4</name>
|
<name>apache-httpclient4</name>
|
||||||
<packaging>war</packaging>
|
<packaging>war</packaging>
|
||||||
|
|
||||||
<parent>
|
<parent>
|
||||||
|
@ -152,6 +152,11 @@
|
||||||
</exclusion>
|
</exclusion>
|
||||||
</exclusions>
|
</exclusions>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.mock-server</groupId>
|
||||||
|
<artifactId>mockserver-netty</artifactId>
|
||||||
|
<version>${mockserver.version}</version>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.github.tomakehurst</groupId>
|
<groupId>com.github.tomakehurst</groupId>
|
||||||
<artifactId>wiremock</artifactId>
|
<artifactId>wiremock</artifactId>
|
||||||
|
@ -284,8 +289,10 @@
|
||||||
<wiremock.version>2.5.1</wiremock.version>
|
<wiremock.version>2.5.1</wiremock.version>
|
||||||
<httpcore.version>4.4.16</httpcore.version>
|
<httpcore.version>4.4.16</httpcore.version>
|
||||||
<httpclient.version>4.5.14</httpclient.version>
|
<httpclient.version>4.5.14</httpclient.version>
|
||||||
|
<mockserver.version>5.11.2</mockserver.version>
|
||||||
<!-- maven plugins -->
|
<!-- maven plugins -->
|
||||||
<cargo-maven2-plugin.version>1.6.1</cargo-maven2-plugin.version>
|
<cargo-maven2-plugin.version>1.6.1</cargo-maven2-plugin.version>
|
||||||
|
<maven-war-plugin.version>3.3.2</maven-war-plugin.version>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
</project>
|
</project>
|
|
@ -0,0 +1,57 @@
|
||||||
|
package com.baeldung.httpclient;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import org.apache.http.HttpEntity;
|
||||||
|
import org.apache.http.client.methods.CloseableHttpResponse;
|
||||||
|
import org.apache.http.client.methods.HttpGet;
|
||||||
|
import org.apache.http.impl.client.CloseableHttpClient;
|
||||||
|
import org.apache.http.impl.client.HttpClientBuilder;
|
||||||
|
import org.apache.http.impl.client.HttpClients;
|
||||||
|
|
||||||
|
import org.junit.After;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
public class HttpClientCancelRequestV4LiveTest {
|
||||||
|
|
||||||
|
private static final String SAMPLE_URL = "http://www.github.com";
|
||||||
|
|
||||||
|
private CloseableHttpClient instance;
|
||||||
|
|
||||||
|
private CloseableHttpResponse response;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public final void before() {
|
||||||
|
instance = HttpClientBuilder.create().build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@After
|
||||||
|
public final void after() throws IllegalStateException, IOException {
|
||||||
|
ResponseUtil.closeResponse(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public final void whenRequestIsCanceled_thenCorrect() throws IOException {
|
||||||
|
instance = HttpClients.custom().build();
|
||||||
|
final HttpGet request = new HttpGet(SAMPLE_URL);
|
||||||
|
response = instance.execute(request);
|
||||||
|
|
||||||
|
try {
|
||||||
|
final HttpEntity entity = response.getEntity();
|
||||||
|
|
||||||
|
System.out.println("----------------------------------------");
|
||||||
|
System.out.println(response.getStatusLine());
|
||||||
|
if (entity != null) {
|
||||||
|
System.out.println("Response content length: " + entity.getContentLength());
|
||||||
|
}
|
||||||
|
System.out.println("----------------------------------------");
|
||||||
|
|
||||||
|
// Do not feel like reading the response body
|
||||||
|
// Call abort on the request object
|
||||||
|
request.abort();
|
||||||
|
} finally {
|
||||||
|
response.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,31 @@
|
||||||
|
package com.baeldung.httpclient.httpclient;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import org.apache.http.HttpEntity;
|
||||||
|
import org.apache.http.HttpStatus;
|
||||||
|
import org.apache.http.client.methods.CloseableHttpResponse;
|
||||||
|
import org.apache.http.client.methods.HttpGet;
|
||||||
|
import org.apache.http.impl.client.CloseableHttpClient;
|
||||||
|
import org.apache.http.impl.client.HttpClientBuilder;
|
||||||
|
import org.apache.http.util.EntityUtils;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
class ApacheHttpClientUnitTest extends GetRequestMockServer {
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void givenDeveloperUsedCloseableHttpResponse_whenExecutingGetRequest_thenStatusIsOk() throws IOException {
|
||||||
|
try (CloseableHttpClient httpClient = HttpClientBuilder.create().build()) {
|
||||||
|
HttpGet httpGet = new HttpGet(serviceOneUrl);
|
||||||
|
try (CloseableHttpResponse response = httpClient.execute(httpGet)) {
|
||||||
|
HttpEntity entity = response.getEntity();
|
||||||
|
EntityUtils.consume(entity);
|
||||||
|
assertThat(response.getStatusLine().getStatusCode()).isEqualTo(HttpStatus.SC_OK);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,78 @@
|
||||||
|
package com.baeldung.httpclient.httpclient;
|
||||||
|
|
||||||
|
import org.apache.http.HttpStatus;
|
||||||
|
import org.junit.jupiter.api.AfterAll;
|
||||||
|
import org.junit.jupiter.api.BeforeAll;
|
||||||
|
import org.mockserver.client.MockServerClient;
|
||||||
|
import org.mockserver.integration.ClientAndServer;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.ServerSocket;
|
||||||
|
import java.net.URISyntaxException;
|
||||||
|
|
||||||
|
import static org.mockserver.integration.ClientAndServer.startClientAndServer;
|
||||||
|
import static org.mockserver.matchers.Times.exactly;
|
||||||
|
import static org.mockserver.model.HttpRequest.request;
|
||||||
|
import static org.mockserver.model.HttpResponse.response;
|
||||||
|
|
||||||
|
public class GetRequestMockServer {
|
||||||
|
|
||||||
|
public static ClientAndServer mockServer;
|
||||||
|
public static String serviceOneUrl;
|
||||||
|
public static String serviceTwoUrl;
|
||||||
|
|
||||||
|
private static int serverPort;
|
||||||
|
|
||||||
|
public static final String SERVER_ADDRESS = "127.0.0.1";
|
||||||
|
public static final String PATH_ONE = "/test1";
|
||||||
|
public static final String PATH_TWO = "/test2";
|
||||||
|
public static final String METHOD = "GET";
|
||||||
|
|
||||||
|
@BeforeAll
|
||||||
|
static void startServer() throws IOException, URISyntaxException {
|
||||||
|
serverPort = getFreePort();
|
||||||
|
serviceOneUrl = "http://" + SERVER_ADDRESS + ":" + serverPort + PATH_ONE;
|
||||||
|
serviceTwoUrl = "http://" + SERVER_ADDRESS + ":" + serverPort + PATH_TWO;
|
||||||
|
mockServer = startClientAndServer(serverPort);
|
||||||
|
mockGetRequest();
|
||||||
|
}
|
||||||
|
|
||||||
|
@AfterAll
|
||||||
|
static void stopServer() {
|
||||||
|
mockServer.stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void mockGetRequest() {
|
||||||
|
new MockServerClient(SERVER_ADDRESS, serverPort)
|
||||||
|
.when(
|
||||||
|
request()
|
||||||
|
.withPath(PATH_ONE)
|
||||||
|
.withMethod(METHOD),
|
||||||
|
exactly(5)
|
||||||
|
)
|
||||||
|
.respond(
|
||||||
|
response()
|
||||||
|
.withStatusCode(HttpStatus.SC_OK)
|
||||||
|
.withBody("{\"status\":\"ok\"}")
|
||||||
|
);
|
||||||
|
new MockServerClient(SERVER_ADDRESS, serverPort)
|
||||||
|
.when(
|
||||||
|
request()
|
||||||
|
.withPath(PATH_TWO)
|
||||||
|
.withMethod(METHOD),
|
||||||
|
exactly(1)
|
||||||
|
)
|
||||||
|
.respond(
|
||||||
|
response()
|
||||||
|
.withStatusCode(HttpStatus.SC_OK)
|
||||||
|
.withBody("{\"status\":\"ok\"}")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int getFreePort () throws IOException {
|
||||||
|
try (ServerSocket serverSocket = new ServerSocket(0)) {
|
||||||
|
return serverSocket.getLocalPort();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -25,4 +25,4 @@ public class ApacheHttpClientUnitTest {
|
||||||
logger.debug("Response -> {}", EntityUtils.toString(entity));
|
logger.debug("Response -> {}", EntityUtils.toString(entity));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,168 @@
|
||||||
|
package com.baeldung.httpclient.retry;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.URI;
|
||||||
|
import java.net.UnknownHostException;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
import org.apache.http.HttpRequestInterceptor;
|
||||||
|
import org.apache.http.HttpResponseInterceptor;
|
||||||
|
import org.apache.http.client.methods.CloseableHttpResponse;
|
||||||
|
import org.apache.http.client.methods.HttpGet;
|
||||||
|
import org.apache.http.client.methods.HttpPatch;
|
||||||
|
import org.apache.http.client.methods.HttpPost;
|
||||||
|
import org.apache.http.client.methods.HttpPut;
|
||||||
|
import org.apache.http.client.protocol.HttpClientContext;
|
||||||
|
import org.apache.http.impl.client.CloseableHttpClient;
|
||||||
|
import org.apache.http.impl.client.DefaultHttpRequestRetryHandler;
|
||||||
|
import org.apache.http.impl.client.HttpClientBuilder;
|
||||||
|
import org.junit.jupiter.api.AfterEach;
|
||||||
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
public class ApacheHttpClientRetryLiveTest {
|
||||||
|
|
||||||
|
private Integer requestCounter;
|
||||||
|
private CloseableHttpClient httpClient;
|
||||||
|
|
||||||
|
@BeforeEach
|
||||||
|
void setUp() {
|
||||||
|
requestCounter = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@AfterEach
|
||||||
|
void tearDown() throws IOException {
|
||||||
|
if (httpClient != null) {
|
||||||
|
httpClient.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void createDefaultApacheHttpClient() {
|
||||||
|
this.httpClient = HttpClientBuilder
|
||||||
|
.create()
|
||||||
|
.addInterceptorFirst((HttpRequestInterceptor) (httpRequest, httpContext) -> {
|
||||||
|
requestCounter++;
|
||||||
|
}).build();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void createFailingHttpClient() {
|
||||||
|
this.httpClient = HttpClientBuilder
|
||||||
|
.create()
|
||||||
|
.addInterceptorFirst((HttpRequestInterceptor) (httpRequest, httpContext) -> requestCounter++)
|
||||||
|
.addInterceptorLast((HttpResponseInterceptor) (httpResponse, httpContext) -> {
|
||||||
|
throw new IOException();
|
||||||
|
})
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void createHttpClientWithRetryHandler() {
|
||||||
|
this.httpClient = HttpClientBuilder
|
||||||
|
.create()
|
||||||
|
.addInterceptorFirst((HttpRequestInterceptor) (httpRequest, httpContext) -> requestCounter++)
|
||||||
|
.addInterceptorLast((HttpResponseInterceptor) (httpRequest, httpContext) -> { throw new IOException(); })
|
||||||
|
.setRetryHandler(new DefaultHttpRequestRetryHandler(6, true))
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void createHttpClientWithCustomRetryHandler() {
|
||||||
|
this.httpClient = HttpClientBuilder
|
||||||
|
.create()
|
||||||
|
.addInterceptorFirst((HttpRequestInterceptor) (httpRequest, httpContext) -> requestCounter++)
|
||||||
|
.addInterceptorLast((HttpResponseInterceptor) (httpRequest, httpContext) -> { throw new IOException(); })
|
||||||
|
.setRetryHandler((exception, executionCount, context) -> {
|
||||||
|
if (executionCount < 5 && Objects.equals("GET", ((HttpClientContext) context).getRequest().getRequestLine().getMethod())) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void createHttpClientWithRetriesDisabled() {
|
||||||
|
this.httpClient = HttpClientBuilder
|
||||||
|
.create()
|
||||||
|
.addInterceptorFirst((HttpRequestInterceptor) (httpRequest, httpContext) -> requestCounter++)
|
||||||
|
.addInterceptorLast((HttpResponseInterceptor) (httpRequest, httpContext) -> { throw new IOException(); })
|
||||||
|
.disableAutomaticRetries()
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenDefaultConfiguration_whenReceivedIOException_thenRetriesPerformed() {
|
||||||
|
createFailingHttpClient();
|
||||||
|
assertThrows(IOException.class, () -> httpClient.execute(new HttpGet("https://httpstat.us/200")));
|
||||||
|
assertThat(requestCounter).isEqualTo(4);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenDefaultConfiguration_whenDomainNameNotResolved_thenNoRetryApplied() {
|
||||||
|
createDefaultApacheHttpClient();
|
||||||
|
HttpGet request = new HttpGet(URI.create("http://domain.that.does.not.exist:80/api/v1"));
|
||||||
|
|
||||||
|
assertThrows(UnknownHostException.class, () -> httpClient.execute(request));
|
||||||
|
assertThat(requestCounter).isEqualTo(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenDefaultConfiguration_whenGotInternalServerError_thenNoRetryLogicApplied() throws IOException {
|
||||||
|
createDefaultApacheHttpClient();
|
||||||
|
HttpGet request = new HttpGet(URI.create("https://httpstat.us/500"));
|
||||||
|
|
||||||
|
CloseableHttpResponse response = assertDoesNotThrow(() -> httpClient.execute(request));
|
||||||
|
assertThat(response.getStatusLine().getStatusCode()).isEqualTo(500);
|
||||||
|
assertThat(requestCounter).isEqualTo(1);
|
||||||
|
response.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenDefaultConfiguration_whenHttpPatchRequest_thenRetryIsNotApplied() {
|
||||||
|
createFailingHttpClient();
|
||||||
|
HttpPatch request = new HttpPatch(URI.create("https://httpstat.us/500"));
|
||||||
|
|
||||||
|
assertThrows(IOException.class, () -> httpClient.execute(request));
|
||||||
|
assertThat(requestCounter).isEqualTo(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenDefaultConfiguration_whenHttpPutRequest_thenRetryIsNotApplied() {
|
||||||
|
createFailingHttpClient();
|
||||||
|
HttpPut request = new HttpPut(URI.create("https://httpstat.us/500"));
|
||||||
|
|
||||||
|
assertThrows(IOException.class, () -> httpClient.execute(request));
|
||||||
|
assertThat(requestCounter).isEqualTo(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenConfiguredRetryHandler_whenHttpPostRequest_thenRetriesPerformed() {
|
||||||
|
createHttpClientWithRetryHandler();
|
||||||
|
|
||||||
|
HttpPost request = new HttpPost(URI.create("https://httpstat.us/200"));
|
||||||
|
|
||||||
|
assertThrows(IOException.class, () -> httpClient.execute(request));
|
||||||
|
assertThat(requestCounter).isEqualTo(7);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenCustomRetryHandler_whenUnknownHostException_thenRetryAnyway() {
|
||||||
|
createHttpClientWithCustomRetryHandler();
|
||||||
|
|
||||||
|
HttpGet request = new HttpGet(URI.create("https://domain.that.does.not.exist/200"));
|
||||||
|
|
||||||
|
assertThrows(IOException.class, () -> httpClient.execute(request));
|
||||||
|
assertThat(requestCounter).isEqualTo(5);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenDisabledRetries_whenExecutedHttpRequestEndUpWithIOException_thenRetryIsNotApplied() {
|
||||||
|
createHttpClientWithRetriesDisabled();
|
||||||
|
HttpGet request = new HttpGet(URI.create("https://httpstat.us/200"));
|
||||||
|
|
||||||
|
assertThrows(IOException.class, () -> httpClient.execute(request));
|
||||||
|
assertThat(requestCounter).isEqualTo(1);
|
||||||
|
}
|
||||||
|
}
|
|
@ -7,3 +7,4 @@ You can build the project from the command line using: *mvn clean install*, or i
|
||||||
|
|
||||||
### Relevant Articles:
|
### Relevant Articles:
|
||||||
- [Guide to Check if Apache Kafka Server Is Running](https://www.baeldung.com/apache-kafka-check-server-is-running)
|
- [Guide to Check if Apache Kafka Server Is Running](https://www.baeldung.com/apache-kafka-check-server-is-running)
|
||||||
|
- [Add Custom Headers to a Kafka Message](https://www.baeldung.com/java-kafka-custom-headers)
|
||||||
|
|
|
@ -0,0 +1,88 @@
|
||||||
|
package com.baeldung.kafka.headers;
|
||||||
|
|
||||||
|
import java.time.Duration;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
|
import org.apache.kafka.clients.consumer.ConsumerConfig;
|
||||||
|
import org.apache.kafka.clients.consumer.ConsumerRecord;
|
||||||
|
import org.apache.kafka.clients.consumer.ConsumerRecords;
|
||||||
|
import org.apache.kafka.clients.consumer.KafkaConsumer;
|
||||||
|
import org.apache.kafka.clients.producer.KafkaProducer;
|
||||||
|
import org.apache.kafka.clients.producer.ProducerConfig;
|
||||||
|
import org.apache.kafka.clients.producer.ProducerRecord;
|
||||||
|
import org.apache.kafka.common.header.Header;
|
||||||
|
import org.apache.kafka.common.header.Headers;
|
||||||
|
import org.apache.kafka.common.header.internals.RecordHeader;
|
||||||
|
import org.apache.kafka.common.serialization.StringDeserializer;
|
||||||
|
import org.apache.kafka.common.serialization.StringSerializer;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
public class KafkaMessageHeaders {
|
||||||
|
|
||||||
|
private static Logger logger = LoggerFactory.getLogger(KafkaMessageHeaders.class);
|
||||||
|
|
||||||
|
private static String TOPIC = "baeldung";
|
||||||
|
private static String MESSAGE_KEY = "message";
|
||||||
|
private static String MESSAGE_VALUE = "Hello World";
|
||||||
|
private static String HEADER_KEY = "website";
|
||||||
|
private static String HEADER_VALUE = "baeldung.com";
|
||||||
|
|
||||||
|
private static KafkaProducer<String, String> producer;
|
||||||
|
private static KafkaConsumer<String, String> consumer;
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
setup();
|
||||||
|
|
||||||
|
publishMessageWithCustomHeaders();
|
||||||
|
|
||||||
|
consumeMessageWithCustomHeaders();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void consumeMessageWithCustomHeaders() {
|
||||||
|
consumer.subscribe(Arrays.asList(TOPIC));
|
||||||
|
|
||||||
|
ConsumerRecords<String, String> records = consumer.poll(Duration.ofMinutes(1));
|
||||||
|
for (ConsumerRecord<String, String> record : records) {
|
||||||
|
logger.info(record.key());
|
||||||
|
logger.info(record.value());
|
||||||
|
|
||||||
|
Headers headers = record.headers();
|
||||||
|
for (Header header : headers) {
|
||||||
|
logger.info(header.key());
|
||||||
|
logger.info(new String(header.value()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void publishMessageWithCustomHeaders() {
|
||||||
|
List<Header> headers = new ArrayList<>();
|
||||||
|
headers.add(new RecordHeader(HEADER_KEY, HEADER_VALUE.getBytes()));
|
||||||
|
|
||||||
|
ProducerRecord<String, String> record1 = new ProducerRecord<>(TOPIC, null, MESSAGE_KEY, MESSAGE_VALUE, headers);
|
||||||
|
producer.send(record1);
|
||||||
|
|
||||||
|
ProducerRecord<String, String> record2 = new ProducerRecord<>(TOPIC, null, System.currentTimeMillis(), MESSAGE_KEY, MESSAGE_VALUE, headers);
|
||||||
|
producer.send(record2);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void setup() {
|
||||||
|
Properties producerProperties = new Properties();
|
||||||
|
producerProperties.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, "localhost:9092");
|
||||||
|
producerProperties.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class.getName());
|
||||||
|
producerProperties.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, StringSerializer.class.getName());
|
||||||
|
|
||||||
|
Properties consumerProperties = new Properties();
|
||||||
|
consumerProperties.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, "localhost:9092");
|
||||||
|
consumerProperties.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class.getName());
|
||||||
|
consumerProperties.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class.getName());
|
||||||
|
consumerProperties.put(ConsumerConfig.GROUP_ID_CONFIG, "ConsumerGroup1");
|
||||||
|
|
||||||
|
producer = new KafkaProducer<>(producerProperties);
|
||||||
|
consumer = new KafkaConsumer<>(consumerProperties);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,104 @@
|
||||||
|
package com.baeldung.kafka.headers;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||||
|
|
||||||
|
import java.time.Duration;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Properties;
|
||||||
|
import java.util.concurrent.ExecutionException;
|
||||||
|
import java.util.concurrent.Future;
|
||||||
|
|
||||||
|
import org.apache.kafka.clients.consumer.ConsumerConfig;
|
||||||
|
import org.apache.kafka.clients.consumer.ConsumerRecord;
|
||||||
|
import org.apache.kafka.clients.consumer.ConsumerRecords;
|
||||||
|
import org.apache.kafka.clients.consumer.KafkaConsumer;
|
||||||
|
import org.apache.kafka.clients.producer.KafkaProducer;
|
||||||
|
import org.apache.kafka.clients.producer.ProducerConfig;
|
||||||
|
import org.apache.kafka.clients.producer.ProducerRecord;
|
||||||
|
import org.apache.kafka.clients.producer.RecordMetadata;
|
||||||
|
import org.apache.kafka.common.header.Header;
|
||||||
|
import org.apache.kafka.common.header.Headers;
|
||||||
|
import org.apache.kafka.common.header.internals.RecordHeader;
|
||||||
|
import org.apache.kafka.common.serialization.StringDeserializer;
|
||||||
|
import org.apache.kafka.common.serialization.StringSerializer;
|
||||||
|
import org.junit.jupiter.api.AfterAll;
|
||||||
|
import org.junit.jupiter.api.BeforeAll;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.testcontainers.containers.KafkaContainer;
|
||||||
|
import org.testcontainers.junit.jupiter.Container;
|
||||||
|
import org.testcontainers.junit.jupiter.Testcontainers;
|
||||||
|
import org.testcontainers.utility.DockerImageName;
|
||||||
|
|
||||||
|
// This live test needs a Docker Daemon running so that a kafka container can be created
|
||||||
|
|
||||||
|
@Testcontainers
|
||||||
|
public class KafkaMessageHeadersLiveTest {
|
||||||
|
|
||||||
|
private static String TOPIC = "baeldung";
|
||||||
|
private static String MESSAGE_KEY = "message";
|
||||||
|
private static String MESSAGE_VALUE = "Hello World";
|
||||||
|
private static String HEADER_KEY = "website";
|
||||||
|
private static String HEADER_VALUE = "baeldung.com";
|
||||||
|
|
||||||
|
private static KafkaProducer<String, String> producer;
|
||||||
|
private static KafkaConsumer<String, String> consumer;
|
||||||
|
|
||||||
|
@Container
|
||||||
|
private static final KafkaContainer KAFKA_CONTAINER = new KafkaContainer(DockerImageName.parse("confluentinc/cp-kafka:latest"));
|
||||||
|
|
||||||
|
@BeforeAll
|
||||||
|
static void setup() {
|
||||||
|
KAFKA_CONTAINER.addExposedPort(9092);
|
||||||
|
|
||||||
|
Properties producerProperties = new Properties();
|
||||||
|
producerProperties.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, KAFKA_CONTAINER.getBootstrapServers());
|
||||||
|
producerProperties.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class.getName());
|
||||||
|
producerProperties.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, StringSerializer.class.getName());
|
||||||
|
|
||||||
|
Properties consumerProperties = new Properties();
|
||||||
|
consumerProperties.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, KAFKA_CONTAINER.getBootstrapServers());
|
||||||
|
consumerProperties.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class.getName());
|
||||||
|
consumerProperties.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class.getName());
|
||||||
|
consumerProperties.put(ConsumerConfig.GROUP_ID_CONFIG, "ConsumerGroup1");
|
||||||
|
|
||||||
|
producer = new KafkaProducer<>(producerProperties);
|
||||||
|
consumer = new KafkaConsumer<>(consumerProperties);
|
||||||
|
}
|
||||||
|
|
||||||
|
@AfterAll
|
||||||
|
static void destroy() {
|
||||||
|
KAFKA_CONTAINER.stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void givenAMessageWithCustomHeaders_whenPublishedToKafkaAndConsumed_thenCheckForCustomHeaders() throws ExecutionException, InterruptedException {
|
||||||
|
List<Header> headers = new ArrayList<>();
|
||||||
|
headers.add(new RecordHeader(HEADER_KEY, HEADER_VALUE.getBytes()));
|
||||||
|
|
||||||
|
ProducerRecord<String, String> record1 = new ProducerRecord<>(TOPIC, null, MESSAGE_KEY, MESSAGE_VALUE, headers);
|
||||||
|
Future<RecordMetadata> future = producer.send(record1);
|
||||||
|
|
||||||
|
RecordMetadata metadata = future.get();
|
||||||
|
|
||||||
|
assertNotNull(metadata);
|
||||||
|
|
||||||
|
consumer.subscribe(Arrays.asList(TOPIC));
|
||||||
|
|
||||||
|
ConsumerRecords<String, String> records = consumer.poll(Duration.ofMinutes(1));
|
||||||
|
for (ConsumerRecord<String, String> record : records) {
|
||||||
|
assertEquals(MESSAGE_KEY, record.key());
|
||||||
|
assertEquals(MESSAGE_VALUE, record.value());
|
||||||
|
|
||||||
|
Headers consumedHeaders = record.headers();
|
||||||
|
assertNotNull(consumedHeaders);
|
||||||
|
|
||||||
|
for (Header header : consumedHeaders) {
|
||||||
|
assertEquals(HEADER_KEY, header.key());
|
||||||
|
assertEquals(HEADER_VALUE, new String(header.value()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -35,12 +35,12 @@
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.flink</groupId>
|
<groupId>org.apache.flink</groupId>
|
||||||
<artifactId>flink-connector-kafka-0.11_2.11</artifactId>
|
<artifactId>flink-connector-kafka</artifactId>
|
||||||
<version>${flink.version}</version>
|
<version>${flink.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.flink</groupId>
|
<groupId>org.apache.flink</groupId>
|
||||||
<artifactId>flink-streaming-java_2.11</artifactId>
|
<artifactId>flink-streaming-java</artifactId>
|
||||||
<version>${flink.version}</version>
|
<version>${flink.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
|
@ -67,7 +67,7 @@
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.flink</groupId>
|
<groupId>org.apache.flink</groupId>
|
||||||
<artifactId>flink-test-utils_2.11</artifactId>
|
<artifactId>flink-test-utils</artifactId>
|
||||||
<version>${flink.version}</version>
|
<version>${flink.version}</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
@ -163,11 +163,28 @@
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-surefire-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<argLine>
|
||||||
|
--add-opens java.base/java.time=ALL-UNNAMED
|
||||||
|
--add-opens
|
||||||
|
java.base/java.nio=ALL-UNNAMED
|
||||||
|
--add-opens java.base/java.util=ALL-UNNAMED
|
||||||
|
</argLine>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<kafka.version>2.8.0</kafka.version>
|
<kafka.version>3.4.0</kafka.version>
|
||||||
<testcontainers-kafka.version>1.15.3</testcontainers-kafka.version>
|
<testcontainers-kafka.version>1.15.3</testcontainers-kafka.version>
|
||||||
<testcontainers-jupiter.version>1.15.3</testcontainers-jupiter.version>
|
<testcontainers-jupiter.version>1.15.3</testcontainers-jupiter.version>
|
||||||
<flink.version>1.5.0</flink.version>
|
<flink.version>1.16.1</flink.version>
|
||||||
<awaitility.version>3.0.0</awaitility.version>
|
<awaitility.version>3.0.0</awaitility.version>
|
||||||
<org.apache.spark.spark-core.version>2.4.8</org.apache.spark.spark-core.version>
|
<org.apache.spark.spark-core.version>2.4.8</org.apache.spark.spark-core.version>
|
||||||
<graphframes.version>0.8.1-spark3.0-s_2.12</graphframes.version>
|
<graphframes.version>0.8.1-spark3.0-s_2.12</graphframes.version>
|
||||||
|
|
|
@ -9,8 +9,8 @@ import org.apache.flink.streaming.api.TimeCharacteristic;
|
||||||
import org.apache.flink.streaming.api.datastream.DataStream;
|
import org.apache.flink.streaming.api.datastream.DataStream;
|
||||||
import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;
|
import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;
|
||||||
import org.apache.flink.streaming.api.windowing.time.Time;
|
import org.apache.flink.streaming.api.windowing.time.Time;
|
||||||
import org.apache.flink.streaming.connectors.kafka.FlinkKafkaConsumer011;
|
import org.apache.flink.streaming.connectors.kafka.FlinkKafkaConsumer;
|
||||||
import org.apache.flink.streaming.connectors.kafka.FlinkKafkaProducer011;
|
import org.apache.flink.streaming.connectors.kafka.FlinkKafkaProducer;
|
||||||
|
|
||||||
import static com.baeldung.flink.connector.Consumers.*;
|
import static com.baeldung.flink.connector.Consumers.*;
|
||||||
import static com.baeldung.flink.connector.Producers.*;
|
import static com.baeldung.flink.connector.Producers.*;
|
||||||
|
@ -25,12 +25,12 @@ public class FlinkDataPipeline {
|
||||||
|
|
||||||
StreamExecutionEnvironment environment = StreamExecutionEnvironment.getExecutionEnvironment();
|
StreamExecutionEnvironment environment = StreamExecutionEnvironment.getExecutionEnvironment();
|
||||||
|
|
||||||
FlinkKafkaConsumer011<String> flinkKafkaConsumer = createStringConsumerForTopic(inputTopic, address, consumerGroup);
|
FlinkKafkaConsumer<String> flinkKafkaConsumer = createStringConsumerForTopic(inputTopic, address, consumerGroup);
|
||||||
flinkKafkaConsumer.setStartFromEarliest();
|
flinkKafkaConsumer.setStartFromEarliest();
|
||||||
|
|
||||||
DataStream<String> stringInputStream = environment.addSource(flinkKafkaConsumer);
|
DataStream<String> stringInputStream = environment.addSource(flinkKafkaConsumer);
|
||||||
|
|
||||||
FlinkKafkaProducer011<String> flinkKafkaProducer = createStringProducer(outputTopic, address);
|
FlinkKafkaProducer<String> flinkKafkaProducer = createStringProducer(outputTopic, address);
|
||||||
|
|
||||||
stringInputStream.map(new WordsCapitalizer())
|
stringInputStream.map(new WordsCapitalizer())
|
||||||
.addSink(flinkKafkaProducer);
|
.addSink(flinkKafkaProducer);
|
||||||
|
@ -48,11 +48,11 @@ public class FlinkDataPipeline {
|
||||||
|
|
||||||
environment.setStreamTimeCharacteristic(TimeCharacteristic.EventTime);
|
environment.setStreamTimeCharacteristic(TimeCharacteristic.EventTime);
|
||||||
|
|
||||||
FlinkKafkaConsumer011<InputMessage> flinkKafkaConsumer = createInputMessageConsumer(inputTopic, kafkaAddress, consumerGroup);
|
FlinkKafkaConsumer<InputMessage> flinkKafkaConsumer = createInputMessageConsumer(inputTopic, kafkaAddress, consumerGroup);
|
||||||
flinkKafkaConsumer.setStartFromEarliest();
|
flinkKafkaConsumer.setStartFromEarliest();
|
||||||
|
|
||||||
flinkKafkaConsumer.assignTimestampsAndWatermarks(new InputMessageTimestampAssigner());
|
flinkKafkaConsumer.assignTimestampsAndWatermarks(new InputMessageTimestampAssigner());
|
||||||
FlinkKafkaProducer011<Backup> flinkKafkaProducer = createBackupProducer(outputTopic, kafkaAddress);
|
FlinkKafkaProducer<Backup> flinkKafkaProducer = createBackupProducer(outputTopic, kafkaAddress);
|
||||||
|
|
||||||
DataStream<InputMessage> inputMessagesStream = environment.addSource(flinkKafkaConsumer);
|
DataStream<InputMessage> inputMessagesStream = environment.addSource(flinkKafkaConsumer);
|
||||||
|
|
||||||
|
|
|
@ -3,26 +3,26 @@ package com.baeldung.flink.connector;
|
||||||
import com.baeldung.flink.model.InputMessage;
|
import com.baeldung.flink.model.InputMessage;
|
||||||
import com.baeldung.flink.schema.InputMessageDeserializationSchema;
|
import com.baeldung.flink.schema.InputMessageDeserializationSchema;
|
||||||
import org.apache.flink.api.common.serialization.SimpleStringSchema;
|
import org.apache.flink.api.common.serialization.SimpleStringSchema;
|
||||||
import org.apache.flink.streaming.connectors.kafka.FlinkKafkaConsumer011;
|
import org.apache.flink.streaming.connectors.kafka.FlinkKafkaConsumer;
|
||||||
|
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
|
|
||||||
public class Consumers {
|
public class Consumers {
|
||||||
|
|
||||||
public static FlinkKafkaConsumer011<String> createStringConsumerForTopic(String topic, String kafkaAddress, String kafkaGroup) {
|
public static FlinkKafkaConsumer<String> createStringConsumerForTopic(String topic, String kafkaAddress, String kafkaGroup) {
|
||||||
Properties props = new Properties();
|
Properties props = new Properties();
|
||||||
props.setProperty("bootstrap.servers", kafkaAddress);
|
props.setProperty("bootstrap.servers", kafkaAddress);
|
||||||
props.setProperty("group.id", kafkaGroup);
|
props.setProperty("group.id", kafkaGroup);
|
||||||
FlinkKafkaConsumer011<String> consumer = new FlinkKafkaConsumer011<>(topic, new SimpleStringSchema(), props);
|
FlinkKafkaConsumer<String> consumer = new FlinkKafkaConsumer<>(topic, new SimpleStringSchema(), props);
|
||||||
|
|
||||||
return consumer;
|
return consumer;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static FlinkKafkaConsumer011<InputMessage> createInputMessageConsumer(String topic, String kafkaAddress, String kafkaGroup) {
|
public static FlinkKafkaConsumer<InputMessage> createInputMessageConsumer(String topic, String kafkaAddress, String kafkaGroup) {
|
||||||
Properties properties = new Properties();
|
Properties properties = new Properties();
|
||||||
properties.setProperty("bootstrap.servers", kafkaAddress);
|
properties.setProperty("bootstrap.servers", kafkaAddress);
|
||||||
properties.setProperty("group.id", kafkaGroup);
|
properties.setProperty("group.id", kafkaGroup);
|
||||||
FlinkKafkaConsumer011<InputMessage> consumer = new FlinkKafkaConsumer011<InputMessage>(topic, new InputMessageDeserializationSchema(), properties);
|
FlinkKafkaConsumer<InputMessage> consumer = new FlinkKafkaConsumer<InputMessage>(topic, new InputMessageDeserializationSchema(), properties);
|
||||||
|
|
||||||
return consumer;
|
return consumer;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,15 +3,15 @@ package com.baeldung.flink.connector;
|
||||||
import com.baeldung.flink.model.Backup;
|
import com.baeldung.flink.model.Backup;
|
||||||
import com.baeldung.flink.schema.BackupSerializationSchema;
|
import com.baeldung.flink.schema.BackupSerializationSchema;
|
||||||
import org.apache.flink.api.common.serialization.SimpleStringSchema;
|
import org.apache.flink.api.common.serialization.SimpleStringSchema;
|
||||||
import org.apache.flink.streaming.connectors.kafka.FlinkKafkaProducer011;
|
import org.apache.flink.streaming.connectors.kafka.FlinkKafkaProducer;
|
||||||
|
|
||||||
public class Producers {
|
public class Producers {
|
||||||
|
|
||||||
public static FlinkKafkaProducer011<String> createStringProducer(String topic, String kafkaAddress) {
|
public static FlinkKafkaProducer<String> createStringProducer(String topic, String kafkaAddress) {
|
||||||
return new FlinkKafkaProducer011<>(kafkaAddress, topic, new SimpleStringSchema());
|
return new FlinkKafkaProducer<>(kafkaAddress, topic, new SimpleStringSchema());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static FlinkKafkaProducer011<Backup> createBackupProducer(String topic, String kafkaAddress) {
|
public static FlinkKafkaProducer<Backup> createBackupProducer(String topic, String kafkaAddress) {
|
||||||
return new FlinkKafkaProducer011<Backup>(kafkaAddress, topic, new BackupSerializationSchema());
|
return new FlinkKafkaProducer<Backup>(kafkaAddress, topic, new BackupSerializationSchema());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -188,13 +188,13 @@
|
||||||
<properties>
|
<properties>
|
||||||
<avro.version>1.8.2</avro.version>
|
<avro.version>1.8.2</avro.version>
|
||||||
<beam.version>2.45.0</beam.version>
|
<beam.version>2.45.0</beam.version>
|
||||||
<bval.version>1.1.2</bval.version>
|
<bval.version>2.0.6</bval.version>
|
||||||
<javax.validation.validation-api.version>1.1.0.Final</javax.validation.validation-api.version>
|
<javax.validation.validation-api.version>2.0.1.Final</javax.validation.validation-api.version>
|
||||||
<meecrowave-junit.version>1.2.0</meecrowave-junit.version>
|
<meecrowave-junit.version>1.2.15</meecrowave-junit.version>
|
||||||
<okhttp.version>3.10.0</okhttp.version>
|
<okhttp.version>3.10.0</okhttp.version>
|
||||||
<meecrowave-jpa.version>1.2.1</meecrowave-jpa.version>
|
<meecrowave-jpa.version>1.2.15</meecrowave-jpa.version>
|
||||||
<meecrowave-core.version>1.2.1</meecrowave-core.version>
|
<meecrowave-core.version>1.2.15</meecrowave-core.version>
|
||||||
<meecrowave-maven-plugin.version>1.2.1</meecrowave-maven-plugin.version>
|
<meecrowave-maven-plugin.version>1.2.15</meecrowave-maven-plugin.version>
|
||||||
<opennlp.opennlp-tools.version>1.8.4</opennlp.opennlp-tools.version>
|
<opennlp.opennlp-tools.version>1.8.4</opennlp.opennlp-tools.version>
|
||||||
<pulsar-client.version>2.1.1-incubating</pulsar-client.version>
|
<pulsar-client.version>2.1.1-incubating</pulsar-client.version>
|
||||||
<zookeeper.version>3.4.11</zookeeper.version>
|
<zookeeper.version>3.4.11</zookeeper.version>
|
||||||
|
|
|
@ -7,7 +7,7 @@ import org.junit.Test;
|
||||||
|
|
||||||
import com.baeldung.apache.beam.intro.WordCount;
|
import com.baeldung.apache.beam.intro.WordCount;
|
||||||
|
|
||||||
public class WordCountUnitTest {
|
public class WordCountIntegrationTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void givenInputFile_whenWordCountRuns_thenJobFinishWithoutError() {
|
public void givenInputFile_whenWordCountRuns_thenJobFinishWithoutError() {
|
|
@ -30,6 +30,16 @@
|
||||||
</exclusion>
|
</exclusion>
|
||||||
</exclusions>
|
</exclusions>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.dhatim</groupId>
|
||||||
|
<artifactId>fastexcel</artifactId>
|
||||||
|
<version>${fastexcel.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.dhatim</groupId>
|
||||||
|
<artifactId>fastexcel-reader</artifactId>
|
||||||
|
<version>${fastexcel.version}</version>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
|
@ -52,6 +62,7 @@
|
||||||
<properties>
|
<properties>
|
||||||
<poi.version>5.2.0</poi.version>
|
<poi.version>5.2.0</poi.version>
|
||||||
<jexcel.version>1.0.6</jexcel.version>
|
<jexcel.version>1.0.6</jexcel.version>
|
||||||
|
<fastexcel.version>0.15.3</fastexcel.version>
|
||||||
<maven.resources.plugin.version>3.2.0</maven.resources.plugin.version>
|
<maven.resources.plugin.version>3.2.0</maven.resources.plugin.version>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,63 @@
|
||||||
|
package com.baeldung.fastexcel;
|
||||||
|
|
||||||
|
import org.dhatim.fastexcel.Workbook;
|
||||||
|
import org.dhatim.fastexcel.Worksheet;
|
||||||
|
import org.dhatim.fastexcel.reader.Cell;
|
||||||
|
import org.dhatim.fastexcel.reader.ReadableWorkbook;
|
||||||
|
import org.dhatim.fastexcel.reader.Row;
|
||||||
|
import org.dhatim.fastexcel.reader.Sheet;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
public class FastexcelHelper {
|
||||||
|
|
||||||
|
public Map<Integer, List<String>> readExcel(String fileLocation) throws IOException {
|
||||||
|
Map<Integer, List<String>> data = new HashMap<>();
|
||||||
|
|
||||||
|
try (FileInputStream file = new FileInputStream(fileLocation); ReadableWorkbook wb = new ReadableWorkbook(file)) {
|
||||||
|
Sheet sheet = wb.getFirstSheet();
|
||||||
|
try (Stream<Row> rows = sheet.openStream()) {
|
||||||
|
rows.forEach(r -> {
|
||||||
|
data.put(r.getRowNum(), new ArrayList<>());
|
||||||
|
|
||||||
|
for (Cell cell : r) {
|
||||||
|
data.get(r.getRowNum()).add(cell.getRawValue());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void writeExcel() throws IOException {
|
||||||
|
File currDir = new File(".");
|
||||||
|
String path = currDir.getAbsolutePath();
|
||||||
|
String fileLocation = path.substring(0, path.length() - 1) + "fastexcel.xlsx";
|
||||||
|
|
||||||
|
try (OutputStream os = Files.newOutputStream(Paths.get(fileLocation)); Workbook wb = new Workbook(os, "MyApplication", "1.0")) {
|
||||||
|
Worksheet ws = wb.newWorksheet("Sheet 1");
|
||||||
|
|
||||||
|
ws.width(0, 25);
|
||||||
|
ws.width(1, 15);
|
||||||
|
|
||||||
|
ws.range(0, 0, 0, 1).style().fontName("Arial").fontSize(16).bold().fillColor("3366FF").set();
|
||||||
|
ws.value(0, 0, "Name");
|
||||||
|
ws.value(0, 1, "Age");
|
||||||
|
|
||||||
|
ws.range(2, 0, 2, 1).style().wrapText(true).set();
|
||||||
|
ws.value(2, 0, "John Smith");
|
||||||
|
ws.value(2, 1, 20L);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,49 @@
|
||||||
|
package com.baeldung.fastexcel;
|
||||||
|
|
||||||
|
import org.junit.After;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
|
public class FastexcelIntegrationTest {
|
||||||
|
|
||||||
|
private FastexcelHelper fastexcelHelper;
|
||||||
|
private static String FILE_NAME = "fastexcel.xlsx";
|
||||||
|
private String fileLocation;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void generateExcelFile() throws IOException {
|
||||||
|
|
||||||
|
File currDir = new File(".");
|
||||||
|
String path = currDir.getAbsolutePath();
|
||||||
|
fileLocation = path.substring(0, path.length() - 1) + FILE_NAME;
|
||||||
|
|
||||||
|
fastexcelHelper = new FastexcelHelper();
|
||||||
|
fastexcelHelper.writeExcel();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenParsingExcelFile_thenCorrect() throws IOException {
|
||||||
|
Map<Integer, List<String>> data = fastexcelHelper.readExcel(fileLocation);
|
||||||
|
|
||||||
|
assertEquals("Name", data.get(1).get(0));
|
||||||
|
assertEquals("Age", data.get(1).get(1));
|
||||||
|
|
||||||
|
assertEquals("John Smith", data.get(3).get(0));
|
||||||
|
assertEquals("20", data.get(3).get(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
@After
|
||||||
|
public void cleanup() {
|
||||||
|
File testFile = new File(fileLocation);
|
||||||
|
if (testFile.exists()) {
|
||||||
|
testFile.delete();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -7,7 +7,6 @@
|
||||||
<version>1.0-SNAPSHOT</version>
|
<version>1.0-SNAPSHOT</version>
|
||||||
<name>apache-spark</name>
|
<name>apache-spark</name>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
<url>http://maven.apache.org</url>
|
|
||||||
|
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>com.baeldung</groupId>
|
<groupId>com.baeldung</groupId>
|
||||||
|
|
|
@ -3,14 +3,14 @@
|
||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<artifactId>lambda</artifactId>
|
<artifactId>lambda-function</artifactId>
|
||||||
<version>0.1.0-SNAPSHOT</version>
|
<version>0.1.0-SNAPSHOT</version>
|
||||||
<name>lambda</name>
|
<name>lambda-function</name>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>com.baeldung</groupId>
|
<groupId>com.baeldung</groupId>
|
||||||
<artifactId>aws-lambda</artifactId>
|
<artifactId>aws-lambda-modules</artifactId>
|
||||||
<version>1.0.0-SNAPSHOT</version>
|
<version>1.0.0-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue