Merge branch 'master' into master
This commit is contained in:
@@ -90,6 +90,12 @@
|
||||
</exclusions>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.mock-server</groupId>
|
||||
<artifactId>mockserver-netty</artifactId>
|
||||
<version>${mockserver.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.github.tomakehurst</groupId>
|
||||
<artifactId>wiremock</artifactId>
|
||||
@@ -112,6 +118,7 @@
|
||||
<!-- util -->
|
||||
<httpasyncclient.version>4.1.4</httpasyncclient.version>
|
||||
<!-- testing -->
|
||||
<mockserver.version>5.6.1</mockserver.version>
|
||||
<wiremock.version>2.5.1</wiremock.version>
|
||||
<httpclient.version>4.5.8</httpclient.version> <!-- 4.3.6 --> <!-- 4.4-beta1 -->
|
||||
<!-- http client & core 5 -->
|
||||
|
||||
@@ -0,0 +1,80 @@
|
||||
package com.baeldung.httpclient;
|
||||
|
||||
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;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.ServerSocket;
|
||||
import java.net.URISyntaxException;
|
||||
|
||||
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;
|
||||
|
||||
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();
|
||||
serverPort = 8080;
|
||||
System.out.println("Free port "+serverPort);
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+1
-1
@@ -38,7 +38,7 @@ import org.apache.hc.core5.ssl.SSLContexts;
|
||||
import org.apache.hc.core5.ssl.TrustStrategy;
|
||||
|
||||
|
||||
class HttpAsyncClientLiveTest {
|
||||
class HttpAsyncClientLiveTest extends GetRequestMockServer {
|
||||
|
||||
private static final String HOST = "http://www.google.com";
|
||||
private static final String HOST_WITH_SSL = "https://mms.nw.ru/";
|
||||
|
||||
@@ -9,3 +9,5 @@ You can build the project from the command line using: *mvn clean install*, or i
|
||||
- [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)
|
||||
- [Get Last N Messages in Apache Kafka Topic](https://www.baeldung.com/java-apache-kafka-get-last-n-messages)
|
||||
- [Is a Key Required as Part of Sending Messages to Kafka?](https://www.baeldung.com/java-kafka-message-key)
|
||||
- [Read Data From the Beginning Using Kafka Consumer API](https://www.baeldung.com/java-kafka-consumer-api-read)
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
package com.baeldung.kafka.consumer;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.Arrays;
|
||||
import java.util.Properties;
|
||||
import java.util.UUID;
|
||||
|
||||
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.serialization.StringDeserializer;
|
||||
import org.apache.kafka.common.serialization.StringSerializer;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class ConsumeFromBeginning {
|
||||
|
||||
private static Logger logger = LoggerFactory.getLogger(ConsumeFromBeginning.class);
|
||||
|
||||
private static String TOPIC = "baeldung";
|
||||
private static int messagesInTopic = 10;
|
||||
|
||||
private static KafkaProducer<String, String> producer;
|
||||
private static KafkaConsumer<String, String> consumer;
|
||||
|
||||
public static void main(String[] args) {
|
||||
setup();
|
||||
|
||||
publishMessages();
|
||||
|
||||
consumeFromBeginning();
|
||||
}
|
||||
|
||||
private static void consumeFromBeginning() {
|
||||
consumer.subscribe(Arrays.asList(TOPIC));
|
||||
|
||||
ConsumerRecords<String, String> records = consumer.poll(Duration.ofSeconds(10));
|
||||
|
||||
for (ConsumerRecord<String, String> record : records) {
|
||||
logger.info(record.value());
|
||||
}
|
||||
|
||||
consumer.seekToBeginning(consumer.assignment());
|
||||
|
||||
records = consumer.poll(Duration.ofSeconds(10));
|
||||
|
||||
for (ConsumerRecord<String, String> record : records) {
|
||||
logger.info(record.value());
|
||||
}
|
||||
}
|
||||
|
||||
private static void publishMessages() {
|
||||
for (int i = 1; i <= messagesInTopic; i++) {
|
||||
ProducerRecord<String, String> record = new ProducerRecord<>(TOPIC, String.valueOf(i));
|
||||
producer.send(record);
|
||||
}
|
||||
}
|
||||
|
||||
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.AUTO_OFFSET_RESET_CONFIG, "earliest");
|
||||
consumerProperties.put(ConsumerConfig.GROUP_ID_CONFIG, UUID.randomUUID()
|
||||
.toString());
|
||||
|
||||
producer = new KafkaProducer<>(producerProperties);
|
||||
consumer = new KafkaConsumer<>(consumerProperties);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
package com.baeldung.kafka.message;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Properties;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.Future;
|
||||
|
||||
import org.apache.kafka.clients.admin.Admin;
|
||||
import org.apache.kafka.clients.admin.AdminClientConfig;
|
||||
import org.apache.kafka.clients.admin.NewTopic;
|
||||
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.serialization.StringDeserializer;
|
||||
import org.apache.kafka.common.serialization.StringSerializer;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class MessageWithKey {
|
||||
|
||||
private static Logger logger = LoggerFactory.getLogger(MessageWithKey.class);
|
||||
|
||||
private static String TOPIC = "baeldung";
|
||||
private static int PARTITIONS = 5;
|
||||
private static short REPLICATION_FACTOR = 1;
|
||||
|
||||
private static String MESSAGE_KEY = "message-key";
|
||||
|
||||
private static Admin admin;
|
||||
private static KafkaProducer<String, String> producer;
|
||||
private static KafkaConsumer<String, String> consumer;
|
||||
|
||||
public static void main(String[] args) throws ExecutionException, InterruptedException {
|
||||
setup();
|
||||
|
||||
publishMessagesWithoutKey();
|
||||
|
||||
consumeMessages();
|
||||
|
||||
publishMessagesWithKey();
|
||||
|
||||
consumeMessages();
|
||||
}
|
||||
|
||||
private static void consumeMessages() {
|
||||
consumer.subscribe(Arrays.asList(TOPIC));
|
||||
|
||||
ConsumerRecords<String, String> records = consumer.poll(Duration.ofSeconds(5));
|
||||
for (ConsumerRecord<String, String> record : records) {
|
||||
logger.info("Key : {}, Value : {}", record.key(), record.value());
|
||||
}
|
||||
}
|
||||
|
||||
private static void publishMessagesWithKey() throws ExecutionException, InterruptedException {
|
||||
for (int i = 1; i <= 10; i++) {
|
||||
ProducerRecord<String, String> record = new ProducerRecord<>(TOPIC, MESSAGE_KEY, String.valueOf(i));
|
||||
Future<RecordMetadata> future = producer.send(record);
|
||||
RecordMetadata metadata = future.get();
|
||||
|
||||
logger.info(String.valueOf(metadata.partition()));
|
||||
}
|
||||
}
|
||||
|
||||
private static void publishMessagesWithoutKey() throws ExecutionException, InterruptedException {
|
||||
for (int i = 1; i <= 10; i++) {
|
||||
ProducerRecord<String, String> record = new ProducerRecord<>(TOPIC, String.valueOf(i));
|
||||
Future<RecordMetadata> future = producer.send(record);
|
||||
RecordMetadata metadata = future.get();
|
||||
|
||||
logger.info(String.valueOf(metadata.partition()));
|
||||
}
|
||||
}
|
||||
|
||||
private static void setup() {
|
||||
Properties adminProperties = new Properties();
|
||||
adminProperties.put(AdminClientConfig.BOOTSTRAP_SERVERS_CONFIG, "localhost:9092");
|
||||
|
||||
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.AUTO_OFFSET_RESET_CONFIG, "earliest");
|
||||
consumerProperties.put(ConsumerConfig.GROUP_ID_CONFIG, UUID.randomUUID()
|
||||
.toString());
|
||||
|
||||
admin = Admin.create(adminProperties);
|
||||
producer = new KafkaProducer<>(producerProperties);
|
||||
consumer = new KafkaConsumer<>(consumerProperties);
|
||||
|
||||
admin.createTopics(Collections.singleton(new NewTopic(TOPIC, PARTITIONS, REPLICATION_FACTOR)));
|
||||
}
|
||||
|
||||
}
|
||||
+109
@@ -0,0 +1,109 @@
|
||||
package com.baeldung.kafka.consumer;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.Arrays;
|
||||
import java.util.Properties;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
|
||||
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.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.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
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 ConsumeFromBeginningLiveTest {
|
||||
|
||||
private static Logger logger = LoggerFactory.getLogger(ConsumeFromBeginningLiveTest.class);
|
||||
|
||||
private static String TOPIC = "baeldung";
|
||||
private static int messagesInTopic = 10;
|
||||
|
||||
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.AUTO_OFFSET_RESET_CONFIG, "earliest");
|
||||
consumerProperties.put(ConsumerConfig.GROUP_ID_CONFIG, UUID.randomUUID()
|
||||
.toString());
|
||||
|
||||
producer = new KafkaProducer<>(producerProperties);
|
||||
consumer = new KafkaConsumer<>(consumerProperties);
|
||||
}
|
||||
|
||||
private static void publishMessages() throws ExecutionException, InterruptedException {
|
||||
for (int i = 1; i <= messagesInTopic; i++) {
|
||||
ProducerRecord<String, String> record = new ProducerRecord<>(TOPIC, String.valueOf(i));
|
||||
producer.send(record)
|
||||
.get();
|
||||
}
|
||||
}
|
||||
|
||||
@AfterAll
|
||||
static void destroy() {
|
||||
KAFKA_CONTAINER.stop();
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenMessages_whenConsumedFromBeginning_thenCheckIfConsumedFromBeginning() throws ExecutionException, InterruptedException {
|
||||
|
||||
publishMessages();
|
||||
|
||||
consumer.subscribe(Arrays.asList(TOPIC));
|
||||
|
||||
ConsumerRecords<String, String> records = consumer.poll(Duration.ofSeconds(10));
|
||||
|
||||
int messageCount = 0;
|
||||
for (ConsumerRecord<String, String> record : records) {
|
||||
logger.info(record.value());
|
||||
messageCount++;
|
||||
}
|
||||
|
||||
assertEquals(messagesInTopic, messageCount);
|
||||
|
||||
consumer.seekToBeginning(consumer.assignment());
|
||||
|
||||
records = consumer.poll(Duration.ofSeconds(10));
|
||||
|
||||
messageCount = 0;
|
||||
for (ConsumerRecord<String, String> record : records) {
|
||||
logger.info(record.value());
|
||||
messageCount++;
|
||||
}
|
||||
|
||||
assertEquals(messagesInTopic, messageCount);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,130 @@
|
||||
package com.baeldung.kafka.message;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Properties;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.Future;
|
||||
|
||||
import org.apache.kafka.clients.admin.Admin;
|
||||
import org.apache.kafka.clients.admin.AdminClientConfig;
|
||||
import org.apache.kafka.clients.admin.NewTopic;
|
||||
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.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 MessageWithKeyLiveTest {
|
||||
|
||||
private static String TOPIC = "baeldung";
|
||||
private static int PARTITIONS = 5;
|
||||
private static short REPLICATION_FACTOR = 1;
|
||||
|
||||
private static String MESSAGE_KEY = "message-key";
|
||||
private static String MESSAGE_VALUE = "Hello World";
|
||||
|
||||
private static Admin admin;
|
||||
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 adminProperties = new Properties();
|
||||
adminProperties.put(AdminClientConfig.BOOTSTRAP_SERVERS_CONFIG, KAFKA_CONTAINER.getBootstrapServers());
|
||||
|
||||
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.AUTO_OFFSET_RESET_CONFIG, "earliest");
|
||||
consumerProperties.put(ConsumerConfig.GROUP_ID_CONFIG, UUID.randomUUID()
|
||||
.toString());
|
||||
|
||||
admin = Admin.create(adminProperties);
|
||||
producer = new KafkaProducer<>(producerProperties);
|
||||
consumer = new KafkaConsumer<>(consumerProperties);
|
||||
|
||||
admin.createTopics(Collections.singleton(new NewTopic(TOPIC, PARTITIONS, REPLICATION_FACTOR)));
|
||||
}
|
||||
|
||||
@AfterAll
|
||||
static void destroy() {
|
||||
KAFKA_CONTAINER.stop();
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenAMessageWithKey_whenPublishedToKafkaAndConsumed_thenCheckForKey() throws ExecutionException, InterruptedException {
|
||||
|
||||
ProducerRecord<String, String> producerRecord = new ProducerRecord<>(TOPIC, MESSAGE_KEY, MESSAGE_VALUE);
|
||||
Future<RecordMetadata> future = producer.send(producerRecord);
|
||||
|
||||
RecordMetadata metadata = future.get();
|
||||
|
||||
assertNotNull(metadata);
|
||||
|
||||
consumer.subscribe(Arrays.asList(TOPIC));
|
||||
|
||||
ConsumerRecords<String, String> records = consumer.poll(Duration.ofSeconds(5));
|
||||
for (ConsumerRecord<String, String> consumerRecord : records) {
|
||||
assertEquals(MESSAGE_KEY, consumerRecord.key());
|
||||
assertEquals(MESSAGE_VALUE, consumerRecord.value());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenAListOfMessageWithKeys_whenPublishedToKafka_thenCheckedIfPublishedToSamePartition() throws ExecutionException, InterruptedException {
|
||||
|
||||
boolean isSamePartition = true;
|
||||
int partition = 0;
|
||||
|
||||
for (int i = 1; i <= 10; i++) {
|
||||
ProducerRecord<String, String> producerRecord = new ProducerRecord<>(TOPIC, MESSAGE_KEY, MESSAGE_VALUE);
|
||||
Future<RecordMetadata> future = producer.send(producerRecord);
|
||||
|
||||
RecordMetadata metadata = future.get();
|
||||
|
||||
assertNotNull(metadata);
|
||||
if (i == 1) {
|
||||
partition = metadata.partition();
|
||||
} else {
|
||||
if (partition != metadata.partition()) {
|
||||
isSamePartition = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
assertTrue(isSamePartition);
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
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>
|
||||
<artifactId>apache-poi-2</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
@@ -19,10 +19,15 @@
|
||||
<artifactId>poi-ooxml</artifactId>
|
||||
<version>${poi.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.poi</groupId>
|
||||
<artifactId>poi-scratchpad</artifactId>
|
||||
<version>${poi.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<properties>
|
||||
<poi.version>5.2.0</poi.version>
|
||||
<poi.version>5.2.3</poi.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,38 @@
|
||||
package com.baeldung.poi.replacevariables;
|
||||
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
import org.apache.poi.hwpf.HWPFDocument;
|
||||
import org.apache.poi.hwpf.usermodel.Range;
|
||||
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
|
||||
|
||||
public class DocTextReplacer {
|
||||
|
||||
public void replaceText() throws IOException {
|
||||
String filePath = getClass().getClassLoader()
|
||||
.getResource("baeldung.doc")
|
||||
.getPath();
|
||||
try (InputStream inputStream = new FileInputStream(filePath); POIFSFileSystem fileSystem = new POIFSFileSystem(inputStream)) {
|
||||
HWPFDocument doc = new HWPFDocument(fileSystem);
|
||||
doc = replaceText(doc, "Baeldung", "Hello");
|
||||
saveFile(filePath, doc);
|
||||
doc.close();
|
||||
}
|
||||
}
|
||||
|
||||
private HWPFDocument replaceText(HWPFDocument doc, String originalText, String updatedText) {
|
||||
Range range = doc.getRange();
|
||||
range.replaceText(originalText, updatedText);
|
||||
return doc;
|
||||
}
|
||||
|
||||
private void saveFile(String filePath, HWPFDocument doc) throws IOException {
|
||||
try (FileOutputStream out = new FileOutputStream(filePath)) {
|
||||
doc.write(out);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+63
@@ -0,0 +1,63 @@
|
||||
package com.baeldung.poi.replacevariables;
|
||||
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.poi.xwpf.usermodel.XWPFDocument;
|
||||
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
|
||||
import org.apache.poi.xwpf.usermodel.XWPFRun;
|
||||
import org.apache.poi.xwpf.usermodel.XWPFTable;
|
||||
import org.apache.poi.xwpf.usermodel.XWPFTableCell;
|
||||
import org.apache.poi.xwpf.usermodel.XWPFTableRow;
|
||||
|
||||
public class DocxNaiveTextReplacer {
|
||||
|
||||
public void replaceText() throws IOException {
|
||||
String filePath = getClass().getClassLoader()
|
||||
.getResource("baeldung-copy.docx")
|
||||
.getPath();
|
||||
try (InputStream inputStream = new FileInputStream(filePath)) {
|
||||
XWPFDocument doc = new XWPFDocument(inputStream);
|
||||
doc = replaceText(doc, "Baeldung", "Hello");
|
||||
saveFile(filePath, doc);
|
||||
doc.close();
|
||||
}
|
||||
}
|
||||
|
||||
private XWPFDocument replaceText(XWPFDocument doc, String originalText, String updatedText) {
|
||||
replaceTextInParagraphs(doc.getParagraphs(), originalText, updatedText);
|
||||
for (XWPFTable tbl : doc.getTables()) {
|
||||
for (XWPFTableRow row : tbl.getRows()) {
|
||||
for (XWPFTableCell cell : row.getTableCells()) {
|
||||
replaceTextInParagraphs(cell.getParagraphs(), originalText, updatedText);
|
||||
}
|
||||
}
|
||||
}
|
||||
return doc;
|
||||
}
|
||||
|
||||
private void replaceTextInParagraphs(List<XWPFParagraph> paragraphs, String originalText, String updatedText) {
|
||||
paragraphs.forEach(paragraph -> replaceTextInParagraph(paragraph, originalText, updatedText));
|
||||
}
|
||||
|
||||
private void replaceTextInParagraph(XWPFParagraph paragraph, String originalText, String updatedText) {
|
||||
List<XWPFRun> runs = paragraph.getRuns();
|
||||
for (XWPFRun run : runs) {
|
||||
String text = run.getText(0);
|
||||
if (text != null && text.contains(originalText)) {
|
||||
String updatedRunText = text.replace(originalText, updatedText);
|
||||
run.setText(updatedRunText, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void saveFile(String filePath, XWPFDocument doc) throws IOException {
|
||||
try (FileOutputStream out = new FileOutputStream(filePath)) {
|
||||
doc.write(out);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
package com.baeldung.poi.replacevariables;
|
||||
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
import org.apache.poi.xwpf.usermodel.XWPFDocument;
|
||||
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
|
||||
import org.apache.poi.xwpf.usermodel.XWPFRun;
|
||||
import org.apache.poi.xwpf.usermodel.XWPFTable;
|
||||
import org.apache.poi.xwpf.usermodel.XWPFTableCell;
|
||||
import org.apache.poi.xwpf.usermodel.XWPFTableRow;
|
||||
|
||||
public class DocxTextReplacer {
|
||||
|
||||
public void replaceText() throws IOException {
|
||||
String filePath = getClass().getClassLoader()
|
||||
.getResource("baeldung.docx")
|
||||
.getPath();
|
||||
try (InputStream inputStream = new FileInputStream(filePath)) {
|
||||
XWPFDocument doc = new XWPFDocument(inputStream);
|
||||
doc = replaceText(doc, "Baeldung", "Hello");
|
||||
saveFile(filePath, doc);
|
||||
doc.close();
|
||||
}
|
||||
}
|
||||
|
||||
private XWPFDocument replaceText(XWPFDocument doc, String originalText, String updatedText) {
|
||||
replaceTextInParagraphs(doc.getParagraphs(), originalText, updatedText);
|
||||
for (XWPFTable tbl : doc.getTables()) {
|
||||
for (XWPFTableRow row : tbl.getRows()) {
|
||||
for (XWPFTableCell cell : row.getTableCells()) {
|
||||
replaceTextInParagraphs(cell.getParagraphs(), originalText, updatedText);
|
||||
}
|
||||
}
|
||||
}
|
||||
return doc;
|
||||
}
|
||||
|
||||
private void replaceTextInParagraphs(List<XWPFParagraph> paragraphs, String originalText, String updatedText) {
|
||||
paragraphs.forEach(paragraph -> replaceTextInParagraph(paragraph, originalText, updatedText));
|
||||
}
|
||||
|
||||
private void replaceTextInParagraph(XWPFParagraph paragraph, String originalText, String updatedText) {
|
||||
String paragraphText = paragraph.getParagraphText();
|
||||
if (paragraphText.contains(originalText)) {
|
||||
String updatedParagraphText = paragraphText.replace(originalText, updatedText);
|
||||
while (paragraph.getRuns().size() > 0) {
|
||||
paragraph.removeRun(0);
|
||||
}
|
||||
XWPFRun newRun = paragraph.createRun();
|
||||
newRun.setText(updatedParagraphText);
|
||||
}
|
||||
}
|
||||
|
||||
private void saveFile(String filePath, XWPFDocument doc) throws IOException {
|
||||
try (FileOutputStream out = new FileOutputStream(filePath)) {
|
||||
doc.write(out);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
+31
@@ -0,0 +1,31 @@
|
||||
package com.baeldung.poi.replacevariables;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.apache.poi.hwpf.HWPFDocument;
|
||||
import org.apache.poi.hwpf.extractor.WordExtractor;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
class DocTextReplacerUnitTest {
|
||||
|
||||
@Test
|
||||
void whenReplaceText_ThenTextReplaced() throws IOException {
|
||||
new DocTextReplacer().replaceText();
|
||||
|
||||
String filePath = getClass().getClassLoader()
|
||||
.getResource("baeldung.doc")
|
||||
.getPath();
|
||||
try (FileInputStream fis = new FileInputStream(filePath); HWPFDocument document = new HWPFDocument(fis); WordExtractor extractor = new WordExtractor(document)) {
|
||||
long occurrencesOfHello = Arrays.stream(extractor.getText()
|
||||
.split("\\s+"))
|
||||
.filter(s -> s.contains("Hello"))
|
||||
.count();
|
||||
assertEquals(5, occurrencesOfHello);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
package com.baeldung.poi.replacevariables;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.apache.poi.xwpf.extractor.XWPFWordExtractor;
|
||||
import org.apache.poi.xwpf.usermodel.XWPFDocument;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
class DocxNaiveTextReplacerUnitTest {
|
||||
|
||||
@Test
|
||||
void whenReplaceText_ThenTextReplaced() throws IOException {
|
||||
new DocxNaiveTextReplacer().replaceText();
|
||||
|
||||
String filePath = getClass().getClassLoader()
|
||||
.getResource("baeldung-copy.docx")
|
||||
.getPath();
|
||||
try (FileInputStream fis = new FileInputStream(filePath); XWPFDocument document = new XWPFDocument(fis); XWPFWordExtractor extractor = new XWPFWordExtractor(document)) {
|
||||
long occurrencesOfHello = Arrays.stream(extractor.getText()
|
||||
.split("\\s+"))
|
||||
.filter(s -> s.contains("Hello"))
|
||||
.count();
|
||||
assertTrue(occurrencesOfHello < 5);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
package com.baeldung.poi.replacevariables;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.apache.poi.xwpf.extractor.XWPFWordExtractor;
|
||||
import org.apache.poi.xwpf.usermodel.XWPFDocument;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
class DocxTestReplacerUnitTest {
|
||||
|
||||
@Test
|
||||
void whenReplaceText_ThenTextReplaced() throws IOException {
|
||||
new DocxTextReplacer().replaceText();
|
||||
|
||||
String filePath = getClass().getClassLoader()
|
||||
.getResource("baeldung.docx")
|
||||
.getPath();
|
||||
try (FileInputStream fis = new FileInputStream(filePath); XWPFDocument document = new XWPFDocument(fis); XWPFWordExtractor extractor = new XWPFWordExtractor(document)) {
|
||||
long occurrencesOfHello = Arrays.stream(extractor.getText()
|
||||
.split("\\s+"))
|
||||
.filter(s -> s.contains("Hello"))
|
||||
.count();
|
||||
assertEquals(5, occurrencesOfHello);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -7,3 +7,5 @@ This module contains articles about the Java List collection
|
||||
- [Finding All Duplicates in a List in Java](https://www.baeldung.com/java-list-find-duplicates)
|
||||
- [Moving Items Around in an Arraylist](https://www.baeldung.com/java-arraylist-move-items)
|
||||
- [Check if a List Contains an Element From Another List in Java](https://www.baeldung.com/java-check-elements-between-lists)
|
||||
- [Array vs. List Performance in Java](https://www.baeldung.com/java-array-vs-list-performance)
|
||||
- [Set Default Value for Elements in List](https://www.baeldung.com/java-list-set-default-values)
|
||||
|
||||
@@ -1,2 +1,3 @@
|
||||
## Relevant Articles
|
||||
- [Copying All Keys and Values From One Hashmap Onto Another Without Replacing Existing Keys and Values](https://www.baeldung.com/java-copy-hashmap-no-changes)
|
||||
- [Convert Hashmap to JSON Object in Java](https://www.baeldung.com/java-convert-hashmap-to-json-object)
|
||||
|
||||
+76
@@ -0,0 +1,76 @@
|
||||
package java.com.baeldung.objecttomap;
|
||||
import com.google.gson.Gson;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import wiremock.com.fasterxml.jackson.core.type.TypeReference;
|
||||
import wiremock.com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import wiremock.com.google.common.reflect.TypeToken;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class ObjectToMapUnitTest {
|
||||
Employee employee = new Employee("John", 3000.0);
|
||||
|
||||
@Test
|
||||
public void givenJavaObject_whenUsingReflection_thenConvertToMap() throws IllegalAccessException {
|
||||
Map<String, Object> map = convertUsingReflection(employee);
|
||||
Assert.assertEquals(employee.getName(), map.get("name"));
|
||||
Assert.assertEquals(employee.getSalary(), map.get("salary"));
|
||||
}
|
||||
|
||||
private Map<String, Object> convertUsingReflection(Object object) throws IllegalAccessException {
|
||||
Map<String, Object> map = new HashMap<>();
|
||||
Field[] fields = object.getClass().getDeclaredFields();
|
||||
|
||||
for (Field field : fields) {
|
||||
field.setAccessible(true);
|
||||
map.put(field.getName(), field.get(object));
|
||||
}
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenJavaObject_whenUsingJackson_thenConvertToMap() {
|
||||
ObjectMapper objectMapper = new ObjectMapper();
|
||||
Map<String, Object> map = objectMapper.convertValue(employee, new TypeReference<Map<String, Object>>() {});
|
||||
Assert.assertEquals(employee.getName(), map.get("name"));
|
||||
Assert.assertEquals(employee.getSalary(), map.get("salary"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenJavaObject_whenUsingGson_thenConvertToMap() {
|
||||
Gson gson = new Gson();
|
||||
String json = gson.toJson(employee);
|
||||
Map<String, Object> map = gson.fromJson(json, new TypeToken<Map<String, Object>>() {}.getType());
|
||||
Assert.assertEquals(employee.getName(), map.get("name"));
|
||||
Assert.assertEquals(employee.getSalary(), map.get("salary"));
|
||||
}
|
||||
|
||||
private static class Employee {
|
||||
private String name;
|
||||
private Double salary;
|
||||
|
||||
public Employee(String name, Double salary) {
|
||||
this.name = name;
|
||||
this.salary = salary;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public Double getSalary() {
|
||||
return salary;
|
||||
}
|
||||
|
||||
public void setSalary(Double age) {
|
||||
this.salary = salary;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -12,3 +12,5 @@ This module contains articles about core Java input/output(IO) APIs.
|
||||
- [Storing Java Scanner Input in an Array](https://www.baeldung.com/java-store-scanner-input-in-array)
|
||||
- [How to Take Input as String With Spaces in Java Using Scanner?](https://www.baeldung.com/java-scanner-input-with-spaces)
|
||||
- [Write Console Output to Text File in Java](https://www.baeldung.com/java-write-console-output-file)
|
||||
- [What’s the difference between Scanner next() and nextLine() methods?](https://www.baeldung.com/java-scanner-next-vs-nextline)
|
||||
- [Handle NoSuchElementException When Reading a File Through Scanner](https://www.baeldung.com/java-scanner-nosuchelementexception-reading-file)
|
||||
|
||||
+55
-7
@@ -3,33 +3,81 @@ package com.baeldung.regex.z_regexp;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.regex.Pattern;
|
||||
public class ZRegularExpressionUnitTest {
|
||||
@Test
|
||||
public void givenCreditCardNumber_thenReturnIfMatched() {
|
||||
String creditCardNumber = "1234567890123456";
|
||||
String creditCardNumber2 = "1234567890123456\n";
|
||||
String pattern = "\\d{16}\\z";
|
||||
Assertions.assertTrue(creditCardNumber.matches(pattern));
|
||||
Assertions.assertTrue(Pattern.compile(pattern).matcher(creditCardNumber).find());
|
||||
Assertions.assertFalse(Pattern.compile(pattern).matcher(creditCardNumber2).find());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenCreditCardNumber_thenReturnIfNotMatched() {
|
||||
String creditCardNumber = "1234567890123456\n";
|
||||
String pattern = "\\d{16}\\z";
|
||||
Assertions.assertFalse(Pattern.compile(pattern).matcher(creditCardNumber).find());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenLogOutput_thenReturnIfMatched() {
|
||||
String logLine = "2022-05-01 14:30:00,123 INFO Some log message";
|
||||
String pattern = ".*message\\z";
|
||||
Assertions.assertTrue(logLine.matches(pattern));
|
||||
Assertions.assertTrue(Pattern.compile(pattern).matcher(logLine).find());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenLogOutput_thenReturnIfNotMatched() {
|
||||
String logLine = "2022-05-01 14:30:00,123 INFO Some log message\n";
|
||||
String pattern = ".*message\\z";
|
||||
Assertions.assertFalse(Pattern.compile(pattern).matcher(logLine).find());
|
||||
}
|
||||
@Test
|
||||
public void givenEmailMessage_thenReturnIfMatched() {
|
||||
String myMessage = "Hello HR, I hope i can write to Baeldung\n";
|
||||
String pattern = ".*Baeldung\\s*\\Z";
|
||||
Assertions.assertTrue(myMessage.matches(pattern));
|
||||
String myMessage2 = "Hello HR, I hope\n i can write to Baeldung";
|
||||
String pattern = ".*Baeldung\\Z";
|
||||
String pattern2 = ".*hope\\Z";
|
||||
Assertions.assertTrue(Pattern.compile(pattern).matcher(myMessage).find());
|
||||
Assertions.assertFalse(Pattern.compile(pattern2).matcher(myMessage2).find());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenEmailMessage_thenReturnIfNotMatched() {
|
||||
String myMessage = "Hello HR, I hope\n i can write to Baeldung";
|
||||
String pattern = ".*hope\\Z";
|
||||
Assertions.assertFalse(Pattern.compile(pattern).matcher(myMessage).find());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenFileExtension_thenReturnIfMatched() {
|
||||
String fileName = "image.jpeg";
|
||||
String fileName = "image.jpeg\n";
|
||||
String fileName2 = "image2.jpeg\n.png";
|
||||
String pattern = ".*\\.jpeg\\Z";
|
||||
Assertions.assertTrue(fileName.matches(pattern));
|
||||
Assertions.assertTrue(Pattern.compile(pattern).matcher(fileName).find());
|
||||
Assertions.assertFalse(Pattern.compile(pattern).matcher(fileName2).find());
|
||||
}
|
||||
|
||||
}
|
||||
@Test
|
||||
public void givenFileExtension_thenReturnIfNotMatched() {
|
||||
String fileName = "image2.jpeg\n.png";
|
||||
String pattern = ".*\\.jpeg\\Z";
|
||||
Assertions.assertFalse(Pattern.compile(pattern).matcher(fileName).find());
|
||||
}
|
||||
@Test
|
||||
public void givenURL_thenReturnIfMatched() {
|
||||
String url = "https://www.example.com/api/endpoint\n";
|
||||
String pattern = ".*/endpoint$";
|
||||
Assertions.assertTrue(Pattern.compile(pattern).matcher(url).find());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenSentence_thenReturnIfMatched() {
|
||||
String sentence = "Hello, how are you?";
|
||||
String pattern = ".*[.?!]$";
|
||||
Assertions.assertTrue(Pattern.compile(pattern).matcher(sentence).find());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -7,3 +7,4 @@
|
||||
- [Deserialization Vulnerabilities in Java](https://www.baeldung.com/java-deserialization-vulnerabilities)
|
||||
- [Serialization Validation in Java](https://www.baeldung.com/java-validate-serializable)
|
||||
- [What Is the serialVersionUID?](https://www.baeldung.com/java-serial-version-uid)
|
||||
- [Java Serialization: readObject() vs. readResolve()](https://www.baeldung.com/java-serialization-readobject-vs-readresolve)
|
||||
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
package com.baeldung.readresolvevsreadobject;
|
||||
|
||||
import java.io.ObjectStreamException;
|
||||
import java.io.Serializable;
|
||||
|
||||
public class Singleton implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
private static Singleton INSTANCE = new Singleton();
|
||||
|
||||
private Singleton() {
|
||||
}
|
||||
|
||||
public static Singleton getInstance() {
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
private Object readResolve() throws ObjectStreamException {
|
||||
return INSTANCE;
|
||||
}
|
||||
}
|
||||
+59
@@ -0,0 +1,59 @@
|
||||
package com.baeldung.readresolvevsreadobject;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.io.Serializable;
|
||||
|
||||
public class User implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 3659932210257138726L;
|
||||
private String userName;
|
||||
private String password;
|
||||
|
||||
public String getUserName() {
|
||||
return userName;
|
||||
}
|
||||
|
||||
public void setUserName(String userName) {
|
||||
this.userName = userName;
|
||||
}
|
||||
|
||||
public String getPassword() {
|
||||
return password;
|
||||
}
|
||||
|
||||
public void setPassword(String password) {
|
||||
this.password = password;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "User [userName=" + userName + ", password=" + password + "]";
|
||||
}
|
||||
|
||||
public User() {
|
||||
}
|
||||
|
||||
public User(String userName, String password) {
|
||||
super();
|
||||
this.userName = userName;
|
||||
this.password = password;
|
||||
}
|
||||
|
||||
private void writeObject(ObjectOutputStream oos) throws IOException {
|
||||
this.password = "xyz" + password;
|
||||
oos.defaultWriteObject();
|
||||
}
|
||||
|
||||
private void readObject(ObjectInputStream aInputStream)
|
||||
throws ClassNotFoundException, IOException {
|
||||
aInputStream.defaultReadObject();
|
||||
this.password = password.substring(3);
|
||||
}
|
||||
|
||||
private Object readResolve() {
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
package com.baeldung.readresolvevsreadobject;
|
||||
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
import org.junit.Test;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotEquals;
|
||||
|
||||
public class SingletonUnitTest {
|
||||
|
||||
@Test
|
||||
public void testSingletonObj_withNoReadResolve() throws ClassNotFoundException, IOException {
|
||||
// Serialization
|
||||
FileOutputStream fos = new FileOutputStream("singleton.ser");
|
||||
ObjectOutputStream oos = new ObjectOutputStream(fos);
|
||||
Singleton actualSingletonObject = Singleton.getInstance();
|
||||
oos.writeObject(actualSingletonObject);
|
||||
|
||||
// Deserialization
|
||||
Singleton deserializedSingletonObject = null;
|
||||
FileInputStream fis = new FileInputStream("singleton.ser");
|
||||
ObjectInputStream ois = new ObjectInputStream(fis);
|
||||
deserializedSingletonObject = (Singleton) ois.readObject();
|
||||
// remove readResolve() from Singleton class and uncomment this to test.
|
||||
//assertNotEquals(actualSingletonObject.hashCode(), deserializedSingletonObject.hashCode());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSingletonObj_withCustomReadResolve()
|
||||
throws ClassNotFoundException, IOException {
|
||||
// Serialization
|
||||
FileOutputStream fos = new FileOutputStream("singleton.ser");
|
||||
ObjectOutputStream oos = new ObjectOutputStream(fos);
|
||||
Singleton actualSingletonObject = Singleton.getInstance();
|
||||
oos.writeObject(actualSingletonObject);
|
||||
|
||||
// Deserialization
|
||||
Singleton deserializedSingletonObject = null;
|
||||
FileInputStream fis = new FileInputStream("singleton.ser");
|
||||
ObjectInputStream ois = new ObjectInputStream(fis);
|
||||
deserializedSingletonObject = (Singleton) ois.readObject();
|
||||
assertEquals(actualSingletonObject.hashCode(), deserializedSingletonObject.hashCode());
|
||||
}
|
||||
}
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
package com.baeldung.readresolvevsreadobject;
|
||||
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
import org.junit.Test;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotEquals;
|
||||
|
||||
public class UserUnitTest {
|
||||
|
||||
@Test
|
||||
public void testDeserializeObj_withOverriddenReadObject()
|
||||
throws ClassNotFoundException, IOException {
|
||||
// Serialization
|
||||
FileOutputStream fos = new FileOutputStream("user.ser");
|
||||
ObjectOutputStream oos = new ObjectOutputStream(fos);
|
||||
User acutalObject = new User("Sachin", "Kumar");
|
||||
oos.writeObject(acutalObject);
|
||||
|
||||
// Deserialization
|
||||
User deserializedUser = null;
|
||||
FileInputStream fis = new FileInputStream("user.ser");
|
||||
ObjectInputStream ois = new ObjectInputStream(fis);
|
||||
deserializedUser = (User) ois.readObject();
|
||||
assertNotEquals(deserializedUser.hashCode(), acutalObject.hashCode());
|
||||
assertEquals(deserializedUser.getUserName(), "Sachin");
|
||||
assertEquals(deserializedUser.getPassword(), "Kumar");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeserializeObj_withDefaultReadObject()
|
||||
throws ClassNotFoundException, IOException {
|
||||
// Serialization
|
||||
FileOutputStream fos = new FileOutputStream("user.ser");
|
||||
ObjectOutputStream oos = new ObjectOutputStream(fos);
|
||||
User acutalObject = new User("Sachin", "Kumar");
|
||||
oos.writeObject(acutalObject);
|
||||
|
||||
// Deserialization
|
||||
User deserializedUser = null;
|
||||
FileInputStream fis = new FileInputStream("user.ser");
|
||||
ObjectInputStream ois = new ObjectInputStream(fis);
|
||||
deserializedUser = (User) ois.readObject();
|
||||
assertNotEquals(deserializedUser.hashCode(), acutalObject.hashCode());
|
||||
assertEquals(deserializedUser.getUserName(), "Sachin");
|
||||
// remove readObject() from User class and uncomment this to test.
|
||||
//assertEquals(deserializedUser.getPassword(), "xyzKumar");
|
||||
}
|
||||
}
|
||||
@@ -3,5 +3,5 @@
|
||||
This module contains articles about Gson
|
||||
|
||||
### Relevant Articles:
|
||||
|
||||
- [Solving Gson Parsing Errors](https://www.baeldung.com/gson-parsing-errors)
|
||||
|
||||
|
||||
@@ -129,13 +129,6 @@
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>jitpack.io</id>
|
||||
<url>https://jitpack.io</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
<build>
|
||||
<finalName>libraries-3</finalName>
|
||||
<plugins>
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user