[FEAT] support native ISO8601 Time serialisation in the tool rest APi and the data

need to call the ContextGenericTools.addJsr310(rc); to register it
This commit is contained in:
Edouard DUPIN 2024-12-29 18:21:31 +01:00
parent b6464b7962
commit 01560cd285
7 changed files with 163 additions and 4 deletions

View File

@ -134,18 +134,18 @@
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.18.0-rc1</version>
<version>2.18.1</version>
</dependency>
<!-- encode output in CSV -->
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-csv</artifactId>
<version>2.18.0-rc1</version>
<version>2.18.1</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
<version>2.18.0-rc1</version>
<version>2.18.1</version>
</dependency>
<dependency>
<groupId>jakarta.servlet</groupId>

View File

@ -0,0 +1,30 @@
package org.kar.archidata.tools;
import org.glassfish.jersey.jackson.internal.jackson.jaxrs.json.JacksonJaxbJsonProvider;
import org.glassfish.jersey.server.ResourceConfig;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
public class ContextGenericTools {
/**
* Add support of Jackson jsr310 for data and time serialization and un-serialization.
* @param rc Resource exception model.
*/
public static void addJsr310(final ResourceConfig rc) {
// Configure Jackson for dates and times
final ObjectMapper objectMapper = new ObjectMapper();
objectMapper.registerModule(new JavaTimeModule()); // Module for Java 8+ Date and Time API
objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
// configure jackson provider for JSON mapper
final JacksonJaxbJsonProvider provider = new JacksonJaxbJsonProvider();
provider.setMapper(objectMapper);
// Record it on the Resource configuration
rc.register(provider);
}
}

View File

@ -17,7 +17,9 @@ import org.slf4j.LoggerFactory;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.exc.MismatchedInputException;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import jakarta.ws.rs.core.HttpHeaders;
@ -25,10 +27,15 @@ public class RESTApi {
final static Logger LOGGER = LoggerFactory.getLogger(RESTApi.class);
final String baseUrl;
private String token = null;
final ObjectMapper mapper = new ObjectMapper();
final ObjectMapper mapper;
public RESTApi(final String baseUrl) {
this.baseUrl = baseUrl;
this.mapper = new ObjectMapper();
// add by default support of LocalTime and LocalDate and LocalDateTime
this.mapper.registerModule(new JavaTimeModule()); // Module for Java 8+ Date and Time API
this.mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
}
public void setToken(final String token) {

View File

@ -0,0 +1,75 @@
package test.kar.archidata.apiExtern;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.MethodOrderer;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestMethodOrder;
import org.junit.jupiter.api.extension.ExtendWith;
import org.kar.archidata.tools.ConfigBaseVariable;
import org.kar.archidata.tools.RESTApi;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import test.kar.archidata.ConfigureDb;
import test.kar.archidata.StepwiseExtension;
import test.kar.archidata.apiExtern.model.DataForJSR310;
@ExtendWith(StepwiseExtension.class)
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
public class TestTime {
private final static Logger LOGGER = LoggerFactory.getLogger(TestTime.class);
public final static String ENDPOINT_NAME = "TimeResource";
static WebLauncherTest webInterface = null;
static RESTApi api = null;
private static Long idTest = 0L;
@BeforeAll
public static void configureWebServer() throws Exception {
ConfigureDb.configure();
LOGGER.info("configure server ...");
webInterface = new WebLauncherTest();
LOGGER.info("Clean previous table");
LOGGER.info("Start REST (BEGIN)");
webInterface.process();
LOGGER.info("Start REST (DONE)");
api = new RESTApi(ConfigBaseVariable.apiAdress);
api.setToken(Common.ADMIN_TOKEN);
}
@AfterAll
public static void stopWebServer() throws Exception {
LOGGER.info("Kill the web server");
webInterface.stop();
webInterface = null;
ConfigureDb.clear();
}
@Order(1)
@Test
public void insertValue() throws Exception {
final DataForJSR310 data = new DataForJSR310();
data.time = LocalTime.now();
data.date = LocalDate.now();
data.dateTime = LocalDateTime.now();
final DataForJSR310 inserted = api.post(DataForJSR310.class, TestTime.ENDPOINT_NAME, data);
Assertions.assertNotNull(inserted);
Assertions.assertNotNull(inserted.time);
Assertions.assertNotNull(inserted.date);
Assertions.assertNotNull(inserted.dateTime);
Assertions.assertEquals(inserted.time, data.time);
Assertions.assertEquals(inserted.date, data.date);
Assertions.assertEquals(inserted.dateTime, data.dateTime);
}
}

View File

@ -22,11 +22,13 @@ import org.kar.archidata.filter.CORSFilter;
import org.kar.archidata.filter.OptionFilter;
import org.kar.archidata.migration.MigrationEngine;
import org.kar.archidata.tools.ConfigBaseVariable;
import org.kar.archidata.tools.ContextGenericTools;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import jakarta.ws.rs.core.UriBuilder;
import test.kar.archidata.apiExtern.resource.TestResource;
import test.kar.archidata.apiExtern.resource.TimeResource;
public class WebLauncher {
final static Logger LOGGER = LoggerFactory.getLogger(WebLauncher.class);
@ -109,9 +111,12 @@ public class WebLauncher {
GenericCatcher.addAll(rc);
// add default resource:
rc.register(TestResource.class);
rc.register(TimeResource.class);
rc.register(DataResource.class);
rc.register(ProxyResource.class);
ContextGenericTools.addJsr310(rc);
// add jackson to be discover when we are ins standalone server
rc.register(JacksonFeature.class);
// enable this to show low level request

View File

@ -0,0 +1,17 @@
package test.kar.archidata.apiExtern.model;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
public class DataForJSR310 {
public LocalTime time;
public LocalDate date;
public LocalDateTime dateTime;
@Override
public String toString() {
return "DataForJSR310 [time=" + this.time + ", date=" + this.date + ", dateTime=" + this.dateTime + "]";
}
}

View File

@ -0,0 +1,25 @@
package test.kar.archidata.apiExtern.resource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import jakarta.annotation.security.PermitAll;
import jakarta.ws.rs.POST;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.MediaType;
import test.kar.archidata.apiExtern.model.DataForJSR310;
@Path("/TimeResource")
@Produces({ MediaType.APPLICATION_JSON })
public class TimeResource {
private static final Logger LOGGER = LoggerFactory.getLogger(TimeResource.class);
@POST
@PermitAll
public DataForJSR310 post(final DataForJSR310 data) throws Exception {
LOGGER.warn("receive Data: {}", data);
return data;
}
}