[BAEL-2547] jackson deserialization class-casting exception
This commit is contained in:
parent
3f29e25765
commit
1a2bd73487
|
@ -0,0 +1,70 @@
|
|||
package com.baeldung.jackson.tocollection;
|
||||
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
public class Book {
|
||||
private Integer bookId;
|
||||
private String title;
|
||||
private String author;
|
||||
|
||||
public Book() {}
|
||||
|
||||
public Book(Integer bookId, String title, String author) {
|
||||
this.bookId = bookId;
|
||||
this.title = title;
|
||||
this.author = author;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (!(o instanceof Book)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Book book = (Book) o;
|
||||
|
||||
if (!Objects.equals(bookId, book.bookId)) {
|
||||
return false;
|
||||
}
|
||||
if (!Objects.equals(title, book.title)) {
|
||||
return false;
|
||||
}
|
||||
return Objects.equals(author, book.author);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = bookId != null ? bookId.hashCode() : 0;
|
||||
result = 31 * result + (title != null ? title.hashCode() : 0);
|
||||
result = 31 * result + (author != null ? author.hashCode() : 0);
|
||||
return result;
|
||||
}
|
||||
|
||||
public Integer getBookId() {
|
||||
return bookId;
|
||||
}
|
||||
|
||||
public void setBookId(Integer bookId) {
|
||||
this.bookId = bookId;
|
||||
}
|
||||
|
||||
public String getTitle() {
|
||||
return title;
|
||||
}
|
||||
|
||||
public void setTitle(String title) {
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
public String getAuthor() {
|
||||
return author;
|
||||
}
|
||||
|
||||
public void setAuthor(String author) {
|
||||
this.author = author;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
package com.baeldung.jackson.tocollection;
|
||||
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.type.CollectionType;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class JsonToCollectionUtil {
|
||||
|
||||
private JsonToCollectionUtil(){}
|
||||
|
||||
public static <T> List<T> jsonArrayToList(String json, Class<T> elementClass) throws IOException {
|
||||
ObjectMapper objectMapper = new ObjectMapper();
|
||||
CollectionType listType = objectMapper.getTypeFactory().constructCollectionType(ArrayList.class, elementClass);
|
||||
return objectMapper.readValue(json, listType);
|
||||
}
|
||||
|
||||
public static <T> List<T> jsonArrayToList2(String json, Class<T> elementClass) throws IOException {
|
||||
return new ObjectMapper().readValue(json, new TypeReference<List<T>>() {});
|
||||
}
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
[ {
|
||||
"bookId" : 1,
|
||||
"title" : "A Song of Ice and Fire",
|
||||
"author" : "George R. R. Martin"
|
||||
}, {
|
||||
"bookId" : 2,
|
||||
"title" : "The Hitchhiker's Guide to the Galaxy",
|
||||
"author" : "Douglas Adams"
|
||||
}, {
|
||||
"bookId" : 3,
|
||||
"title" : "Hackers And Painters",
|
||||
"author" : "Paul Graham"
|
||||
} ]
|
|
@ -0,0 +1,17 @@
|
|||
<ArrayList>
|
||||
<item>
|
||||
<bookId>1</bookId>
|
||||
<title>A Song of Ice and Fire</title>
|
||||
<author>George R. R. Martin</author>
|
||||
</item>
|
||||
<item>
|
||||
<bookId>2</bookId>
|
||||
<title>The Hitchhiker's Guide to the Galaxy</title>
|
||||
<author>Douglas Adams</author>
|
||||
</item>
|
||||
<item>
|
||||
<bookId>3</bookId>
|
||||
<title>Hackers And Painters</title>
|
||||
<author>Paul Graham</author>
|
||||
</item>
|
||||
</ArrayList>
|
|
@ -0,0 +1,130 @@
|
|||
package com.baeldung.jackson.tocollection;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.type.CollectionType;
|
||||
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
|
||||
import org.assertj.core.util.Lists;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Scanner;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||
|
||||
public class DeserializeToJavaCollectionUnitTest {
|
||||
private ObjectMapper objectMapper;
|
||||
private XmlMapper xmlMapper;
|
||||
private List<Book> expectedBookList;
|
||||
|
||||
|
||||
@BeforeEach
|
||||
void setup() {
|
||||
objectMapper = new ObjectMapper();
|
||||
xmlMapper = new XmlMapper();
|
||||
expectedBookList = Lists.newArrayList(
|
||||
new Book(1, "A Song of Ice and Fire", "George R. R. Martin"),
|
||||
new Book(2, "The Hitchhiker's Guide to the Galaxy", "Douglas Adams"),
|
||||
new Book(3, "Hackers And Painters", "Paul Graham"));
|
||||
}
|
||||
|
||||
private String readFile(String path) {
|
||||
try (Scanner scanner = new Scanner(getClass().getResourceAsStream(path), "UTF-8")) {
|
||||
return scanner.useDelimiter("\\A").next();
|
||||
}
|
||||
}
|
||||
|
||||
/*====================
|
||||
* JSON tests
|
||||
*====================
|
||||
*/
|
||||
@Test
|
||||
void givenJsonString_whenDeserializingToList_thenThrowingClassCastException() throws JsonProcessingException {
|
||||
String jsonString = readFile("/to-java-collection/books.json");
|
||||
List<Book> bookList = objectMapper.readValue(jsonString, ArrayList.class);
|
||||
assertThat(bookList).size().isEqualTo(3);
|
||||
assertThatExceptionOfType(ClassCastException.class)
|
||||
.isThrownBy(() -> bookList.get(0).getBookId())
|
||||
.withMessageMatching(".*java.util.LinkedHashMap cannot be cast to .*com.baeldung.jackson.tocollection.Book.*");
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenJsonString_whenDeserializingWithTypeReference_thenGetExpectedList() throws JsonProcessingException {
|
||||
String jsonString = readFile("/to-java-collection/books.json");
|
||||
List<Book> bookList = objectMapper.readValue(jsonString, new TypeReference<List<Book>>() {});
|
||||
assertThat(bookList.get(0)).isInstanceOf(Book.class);
|
||||
assertThat(bookList).isEqualTo(expectedBookList);
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenJsonString_whenDeserializingWithJavaType_thenGetExpectedList() throws JsonProcessingException {
|
||||
String jsonString = readFile("/to-java-collection/books.json");
|
||||
CollectionType listType = objectMapper.getTypeFactory().constructCollectionType(ArrayList.class, Book.class);
|
||||
List<Book> bookList = objectMapper.readValue(jsonString, listType);
|
||||
assertThat(bookList.get(0)).isInstanceOf(Book.class);
|
||||
assertThat(bookList).isEqualTo(expectedBookList);
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenJsonString_whenDeserializingWithConvertValueAndTypeReference_thenGetExpectedList() throws JsonProcessingException {
|
||||
String jsonString = readFile("/to-java-collection/books.json");
|
||||
JsonNode jsonNode = objectMapper.readTree(jsonString);
|
||||
List<Book> bookList = objectMapper.convertValue(jsonNode, new TypeReference<List<Book>>() {});
|
||||
assertThat(bookList.get(0)).isInstanceOf(Book.class);
|
||||
assertThat(bookList).isEqualTo(expectedBookList);
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenJsonString_whenDeserializingWithConvertValueAndJavaType_thenGetExpectedList() throws JsonProcessingException {
|
||||
String jsonString = readFile("/to-java-collection/books.json");
|
||||
JsonNode jsonNode = objectMapper.readTree(jsonString);
|
||||
List<Book> bookList = objectMapper.convertValue(jsonNode, objectMapper.getTypeFactory().constructCollectionType(ArrayList.class, Book.class));
|
||||
assertThat(bookList.get(0)).isInstanceOf(Book.class);
|
||||
assertThat(bookList).isEqualTo(expectedBookList);
|
||||
}
|
||||
|
||||
/*====================
|
||||
* XML tests
|
||||
*====================
|
||||
*/
|
||||
@Test
|
||||
void givenXml_whenDeserializingToList_thenThrowingClassCastException() throws JsonProcessingException {
|
||||
String xml = readFile("/to-java-collection/books.xml");
|
||||
List<Book> bookList = xmlMapper.readValue(xml, ArrayList.class);
|
||||
assertThat(bookList).size().isEqualTo(3);
|
||||
assertThatExceptionOfType(ClassCastException.class)
|
||||
.isThrownBy(() -> bookList.get(0).getBookId())
|
||||
.withMessageMatching(".*java.util.LinkedHashMap cannot be cast to .*com.baeldung.jackson.tocollection.Book.*");
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenXml_whenDeserializingWithTypeReference_thenGetExpectedList() throws JsonProcessingException {
|
||||
String xml = readFile("/to-java-collection/books.xml");
|
||||
List<Book> bookList = xmlMapper.readValue(xml, new TypeReference<List<Book>>() {});
|
||||
assertThat(bookList.get(0)).isInstanceOf(Book.class);
|
||||
assertThat(bookList).isEqualTo(expectedBookList);
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenXml_whenDeserializingWithConvertValueAndTypeReference_thenGetExpectedList() throws JsonProcessingException {
|
||||
String xml = readFile("/to-java-collection/books.xml");
|
||||
List node = xmlMapper.readValue(xml, List.class);
|
||||
List<Book> bookList = xmlMapper.convertValue(node, new TypeReference<List<Book>>() {});
|
||||
assertThat(bookList.get(0)).isInstanceOf(Book.class);
|
||||
assertThat(bookList).isEqualTo(expectedBookList);
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenXml_whenDeserializingWithConvertValueAndJavaType_thenGetExpectedList() throws JsonProcessingException {
|
||||
String xml = readFile("/to-java-collection/books.xml");
|
||||
List node = xmlMapper.readValue(xml, List.class);
|
||||
List<Book> bookList = xmlMapper.convertValue(node, objectMapper.getTypeFactory().constructCollectionType(ArrayList.class, Book.class));
|
||||
assertThat(bookList.get(0)).isInstanceOf(Book.class);
|
||||
assertThat(bookList).isEqualTo(expectedBookList);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
package com.baeldung.jackson.tocollection;
|
||||
|
||||
import org.assertj.core.util.Lists;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.Scanner;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||
|
||||
class JsonToCollectionUtilUnitTest {
|
||||
|
||||
private List<Book> expectedBookList;
|
||||
|
||||
|
||||
@BeforeEach
|
||||
void setup() {
|
||||
expectedBookList = Lists.newArrayList(
|
||||
new Book(1, "A Song of Ice and Fire", "George R. R. Martin"),
|
||||
new Book(2, "The Hitchhiker's Guide to the Galaxy", "Douglas Adams"),
|
||||
new Book(3, "Hackers And Painters", "Paul Graham"));
|
||||
}
|
||||
|
||||
private String readFile(String path) {
|
||||
try (Scanner scanner = new Scanner(getClass().getResourceAsStream(path), "UTF-8")) {
|
||||
return scanner.useDelimiter("\\A").next();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenJsonString_whenCalljsonArrayToList_thenGetExpectedList() throws IOException {
|
||||
String jsonString = readFile("/to-java-collection/books.json");
|
||||
List<Book> bookList = JsonToCollectionUtil.jsonArrayToList(jsonString, Book.class);
|
||||
assertThat(bookList.get(0)).isInstanceOf(Book.class);
|
||||
assertThat(bookList).isEqualTo(expectedBookList);
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenJsonString_whenCalljsonArrayToList2_thenGetException() throws IOException {
|
||||
String jsonString = readFile("/to-java-collection/books.json");
|
||||
List<Book> bookList = JsonToCollectionUtil.jsonArrayToList2(jsonString, Book.class);
|
||||
assertThat(bookList).size().isEqualTo(3);
|
||||
assertThatExceptionOfType(ClassCastException.class)
|
||||
.isThrownBy(() -> bookList.get(0).getBookId())
|
||||
.withMessageMatching(".*java.util.LinkedHashMap cannot be cast to .*com.baeldung.jackson.tocollection.Book.*");
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue