Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Ole Hermann Bakka
todo-list-example
Commits
06855370
Commit
06855370
authored
Nov 23, 2021
by
Hallvard Trætteberg
Browse files
Make config of todomodel serialization more flexible.
parent
68e89d60
Changes
9
Hide whitespace changes
Inline
Side-by-side
todolist/core/src/main/java/todolist/json/TodoPersistence.java
View file @
06855370
...
...
@@ -10,6 +10,9 @@ import java.io.Writer;
import
java.nio.charset.StandardCharsets
;
import
java.nio.file.Path
;
import
java.nio.file.Paths
;
import
java.util.EnumSet
;
import
java.util.Set
;
import
todolist.core.TodoModel
;
import
todolist.json.internal.TodoModule
;
...
...
@@ -19,19 +22,27 @@ import todolist.json.internal.TodoModule;
*/
public
class
TodoPersistence
{
public
enum
TodoModelParts
{
SETTINGS
,
LISTS
,
LIST_CONTENTS
}
private
ObjectMapper
mapper
;
public
TodoPersistence
()
{
mapper
=
createObjectMapper
();
}
public
static
SimpleModule
createJacksonModule
(
boolean
deep
)
{
return
new
TodoModule
(
deep
);
public
static
SimpleModule
createJacksonModule
(
Set
<
TodoModelParts
>
parts
)
{
return
new
TodoModule
(
parts
);
}
public
static
ObjectMapper
createObjectMapper
()
{
public
static
ObjectMapper
createObjectMapper
(
Set
<
TodoModelParts
>
parts
)
{
return
new
ObjectMapper
()
.
registerModule
(
createJacksonModule
(
true
));
.
registerModule
(
createJacksonModule
(
parts
));
}
public
static
ObjectMapper
createObjectMapper
()
{
return
createObjectMapper
(
EnumSet
.
allOf
(
TodoModelParts
.
class
));
}
public
TodoModel
readTodoModel
(
Reader
reader
)
throws
IOException
{
...
...
todolist/core/src/main/java/todolist/json/internal/TodoModelSerializer.java
View file @
06855370
...
...
@@ -4,19 +4,19 @@ import com.fasterxml.jackson.core.JsonGenerator;
import
com.fasterxml.jackson.databind.JsonSerializer
;
import
com.fasterxml.jackson.databind.SerializerProvider
;
import
java.io.IOException
;
import
java.util.EnumSet
;
import
java.util.Set
;
import
todolist.core.AbstractTodoList
;
import
todolist.core.TodoModel
;
import
todolist.json.TodoPersistence.TodoModelParts
;
class
TodoModelSerializer
extends
JsonSerializer
<
TodoModel
>
{
private
final
boolean
deep
;
public
TodoModelSerializer
(
boolean
deep
)
{
this
.
deep
=
deep
;
}
private
final
Set
<
TodoModelParts
>
parts
;
public
TodoModelSerializer
()
{
this
(
true
)
;
public
TodoModelSerializer
(
Set
<
TodoModelParts
>
parts
)
{
this
.
parts
=
parts
;
}
/*
...
...
@@ -27,23 +27,27 @@ class TodoModelSerializer extends JsonSerializer<TodoModel> {
public
void
serialize
(
TodoModel
model
,
JsonGenerator
jsonGen
,
SerializerProvider
serializerProvider
)
throws
IOException
{
jsonGen
.
writeStartObject
();
jsonGen
.
writeArrayFieldStart
(
"lists"
);
for
(
AbstractTodoList
list
:
model
)
{
if
(
deep
)
{
jsonGen
.
writeObject
(
list
);
}
else
{
jsonGen
.
writeStartObject
();
jsonGen
.
writeStringField
(
"name"
,
list
.
getName
());
if
(
list
.
getDeadline
()
!=
null
)
{
jsonGen
.
writeStringField
(
"deadline"
,
list
.
getDeadline
().
toString
());
if
(
parts
.
contains
(
TodoModelParts
.
LIST_CONTENTS
)
||
parts
.
contains
(
TodoModelParts
.
LISTS
))
{
jsonGen
.
writeArrayFieldStart
(
"lists"
);
for
(
AbstractTodoList
list
:
model
)
{
if
(
parts
.
contains
(
TodoModelParts
.
LIST_CONTENTS
))
{
jsonGen
.
writeObject
(
list
);
}
else
if
(
parts
.
contains
(
TodoModelParts
.
LISTS
))
{
jsonGen
.
writeStartObject
();
jsonGen
.
writeStringField
(
"name"
,
list
.
getName
());
if
(
list
.
getDeadline
()
!=
null
)
{
jsonGen
.
writeStringField
(
"deadline"
,
list
.
getDeadline
().
toString
());
}
// no items!
jsonGen
.
writeEndObject
();
}
// no items!
jsonGen
.
writeEndObject
();
}
jsonGen
.
writeEndArray
();
}
if
(
parts
.
contains
(
TodoModelParts
.
SETTINGS
))
{
jsonGen
.
writeFieldName
(
"settings"
);
jsonGen
.
writeObject
(
model
.
getSettings
());
}
jsonGen
.
writeEndArray
();
jsonGen
.
writeFieldName
(
"settings"
);
jsonGen
.
writeObject
(
model
.
getSettings
());
jsonGen
.
writeEndObject
();
}
}
\ No newline at end of file
todolist/core/src/main/java/todolist/json/internal/TodoModule.java
View file @
06855370
package
todolist.json.internal
;
import
java.util.EnumSet
;
import
java.util.Set
;
import
com.fasterxml.jackson.core.Version
;
import
com.fasterxml.jackson.databind.module.SimpleModule
;
import
todolist.core.AbstractTodoList
;
import
todolist.core.TodoItem
;
import
todolist.core.TodoModel
;
import
todolist.core.TodoSettings
;
import
todolist.json.TodoPersistence.TodoModelParts
;
/**
* A Jackson module for configuring JSON serialization of TodoModel instances.
...
...
@@ -18,7 +22,7 @@ public class TodoModule extends SimpleModule {
/**
* Initializes this TodoModule with appropriate serializers and deserializers.
*/
public
TodoModule
(
boolean
deepTodoModelSerializer
)
{
public
TodoModule
(
Set
<
TodoModelParts
>
parts
)
{
super
(
NAME
,
Version
.
unknownVersion
());
addSerializer
(
TodoItem
.
class
,
new
TodoItemSerializer
());
addDeserializer
(
TodoItem
.
class
,
new
TodoItemDeserializer
());
...
...
@@ -26,7 +30,7 @@ public class TodoModule extends SimpleModule {
addSerializer
(
AbstractTodoList
.
class
,
new
TodoListSerializer
());
addDeserializer
(
AbstractTodoList
.
class
,
new
TodoListDeserializer
());
addSerializer
(
TodoModel
.
class
,
new
TodoModelSerializer
(
deepTodoModelSerializer
));
addSerializer
(
TodoModel
.
class
,
new
TodoModelSerializer
(
parts
));
addDeserializer
(
TodoModel
.
class
,
new
TodoModelDeserializer
());
addSerializer
(
TodoSettings
.
class
,
new
TodoSettingsSerializer
());
...
...
@@ -34,6 +38,6 @@ public class TodoModule extends SimpleModule {
}
public
TodoModule
()
{
this
(
true
);
this
(
EnumSet
.
allOf
(
TodoModelParts
.
class
)
);
}
}
todolist/rest/src/main/java/todolist/restapi/TodoListResource.java
View file @
06855370
...
...
@@ -3,6 +3,7 @@ package todolist.restapi;
import
jakarta.ws.rs.Consumes
;
import
jakarta.ws.rs.DELETE
;
import
jakarta.ws.rs.GET
;
import
jakarta.ws.rs.NotFoundException
;
import
jakarta.ws.rs.POST
;
import
jakarta.ws.rs.PUT
;
import
jakarta.ws.rs.Path
;
...
...
@@ -51,9 +52,11 @@ public class TodoListResource {
this
.
todoList
=
todoList
;
}
// throw an exception in case of missing todolist
// hopefully this will give an appropriate http response code
private
void
checkTodoList
()
{
if
(
this
.
todoList
==
null
)
{
throw
new
IllegalArgument
Exception
(
"No TodoList named \""
+
name
+
"\""
);
throw
new
NotFound
Exception
(
"No TodoList named \""
+
name
+
"\""
);
}
}
...
...
@@ -74,7 +77,7 @@ public class TodoListResource {
try
{
todoPersistence
.
saveTodoModel
(
todoModel
);
}
catch
(
IllegalStateException
|
IOException
e
)
{
System
.
err
.
println
(
"Couldn't auto-save TodoModel: "
+
e
);
LOG
.
error
(
"Couldn't auto-save TodoModel: "
,
e
);
}
}
}
...
...
todolist/rest/src/main/java/todolist/restserver/TodoConfig.java
View file @
06855370
...
...
@@ -8,6 +8,8 @@ import java.nio.charset.StandardCharsets;
import
org.glassfish.hk2.utilities.binding.AbstractBinder
;
import
org.glassfish.jersey.jackson.JacksonFeature
;
import
org.glassfish.jersey.server.ResourceConfig
;
import
todolist.core.TodoItem
;
import
todolist.core.TodoList
;
import
todolist.core.TodoModel
;
import
todolist.json.TodoPersistence
;
...
...
@@ -71,7 +73,9 @@ public class TodoConfig extends ResourceConfig {
}
}
TodoModel
todoModel
=
new
TodoModel
();
todoModel
.
addTodoList
(
new
TodoList
(
"todo1"
));
TodoList
todoList1
=
new
TodoList
(
"todo1"
);
todoList1
.
addTodoItem
(
new
TodoItem
());
todoModel
.
addTodoList
(
todoList1
);
todoModel
.
addTodoList
(
new
TodoList
(
"todo2"
));
return
todoModel
;
}
...
...
todolist/rest/src/main/java/todolist/restserver/TodoModuleObjectMapperProvider.java
View file @
06855370
package
todolist.restserver
;
import
java.util.EnumSet
;
import
com.fasterxml.jackson.databind.ObjectMapper
;
import
jakarta.ws.rs.Consumes
;
import
jakarta.ws.rs.Produces
;
...
...
@@ -7,6 +9,7 @@ import jakarta.ws.rs.core.MediaType;
import
jakarta.ws.rs.ext.ContextResolver
;
import
jakarta.ws.rs.ext.Provider
;
import
todolist.json.TodoPersistence
;
import
todolist.json.TodoPersistence.TodoModelParts
;
/**
* Provides the Jackson module used for JSON serialization.
...
...
@@ -19,7 +22,10 @@ public class TodoModuleObjectMapperProvider implements ContextResolver<ObjectMap
private
final
ObjectMapper
objectMapper
;
public
TodoModuleObjectMapperProvider
()
{
objectMapper
=
TodoPersistence
.
createObjectMapper
();
// Uuse variant which only serializes list properties as part of TodoModel objects, and
// not the contents, nor settings
// The contents or settings are serialized as part of TodoList and TodoSettings objects
objectMapper
=
TodoPersistence
.
createObjectMapper
(
EnumSet
.
of
(
TodoModelParts
.
LISTS
));
}
@Override
...
...
todolist/rest/src/test/java/todolist/restserver/TodoServiceTest.java
View file @
06855370
...
...
@@ -17,6 +17,7 @@ import org.junit.jupiter.api.AfterEach;
import
org.junit.jupiter.api.BeforeEach
;
import
org.junit.jupiter.api.Test
;
import
todolist.core.AbstractTodoList
;
import
todolist.core.TodoList
;
import
todolist.core.TodoModel
;
import
todolist.restapi.TodoModelService
;
...
...
@@ -84,6 +85,8 @@ public class TodoServiceTest extends JerseyTest {
try
{
AbstractTodoList
todoList
=
objectMapper
.
readValue
(
getResponse
.
readEntity
(
String
.
class
),
AbstractTodoList
.
class
);
assertEquals
(
"todo1"
,
todoList
.
getName
());
assertTrue
(
todoList
instanceof
TodoList
);
assertTrue
(((
TodoList
)
todoList
).
iterator
().
hasNext
());
}
catch
(
JsonProcessingException
e
)
{
fail
(
e
.
getMessage
());
}
...
...
todolist/springboot/restserver/src/main/java/todolist/springboot/restserver/TodoModelApplication.java
View file @
06855370
package
todolist.springboot.restserver
;
import
java.util.EnumSet
;
import
com.fasterxml.jackson.databind.Module
;
import
org.springframework.boot.SpringApplication
;
import
org.springframework.boot.autoconfigure.SpringBootApplication
;
import
org.springframework.context.annotation.Bean
;
import
todolist.json.TodoPersistence
;
import
todolist.json.TodoPersistence.TodoModelParts
;
/**
* The Spring application.
...
...
@@ -14,7 +17,7 @@ public class TodoModelApplication {
@Bean
public
Module
objectMapperModule
()
{
return
TodoPersistence
.
createJacksonModule
(
false
);
return
TodoPersistence
.
createJacksonModule
(
EnumSet
.
of
(
TodoModelParts
.
LISTS
)
);
}
public
static
void
main
(
String
[]
args
)
{
...
...
todolist/springboot/restserver/src/main/java/todolist/springboot/restserver/TodoModelService.java
View file @
06855370
...
...
@@ -6,6 +6,8 @@ import java.io.Reader;
import
java.net.URL
;
import
java.nio.charset.StandardCharsets
;
import
org.springframework.stereotype.Service
;
import
todolist.core.TodoItem
;
import
todolist.core.TodoList
;
import
todolist.core.TodoModel
;
import
todolist.json.TodoPersistence
;
...
...
@@ -56,7 +58,9 @@ public class TodoModelService {
}
}
TodoModel
todoModel
=
new
TodoModel
();
todoModel
.
addTodoList
(
new
TodoList
(
"todo1"
));
TodoList
todoList1
=
new
TodoList
(
"todo1"
);
todoList1
.
addTodoItem
(
new
TodoItem
());
todoModel
.
addTodoList
(
todoList1
);
todoModel
.
addTodoList
(
new
TodoList
(
"todo2"
));
return
todoModel
;
}
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment