PropertyEditor is not called on AJAX (JSON) request - java

I have problem with Ajax request on form submit. The form contains these stringify JSON data:
{"articleContent":"<p>aaa</p>","title":"Po vyplnění titulku aktuality budete","header":"aa","enabled":false,"timestamp":"1358610697521","publishedSince":"03.01.2013 00:00","publishedUntil":"","id":"10"}
When json contains "03.01.2013 00:00" value, server respons is 400 Bad Request
Problem is that, custom DateTimePropertyEditor (which is registrated with #InitBinder) is not called, and DateTime in String format is not conveted. Have you any idea How to solve this problem?
Controllers mapped method, which is processing request
#RequestMapping( value = "/admin/article/edit/{articleId}", method = RequestMethod.POST, headers = {"content-type=application/json"})
public #ResponseBody JsonResponse processAjaxUpdate(#RequestBody Article article, #PathVariable Long articleId){
JsonResponse response = new JsonResponse();
Article persistedArticle = articleService.getArticleById(articleId);
if(persistedArticle == null){
return response;
}
List<String> errors = articleValidator.validate(article, persistedArticle);
if(errors.size() == 0){
updateArticle(article, persistedArticle);
response.setStatus(JsonStatus.SUCCESS);
response.setResult(persistedArticle.getChanged().getMillis());
}else{
response.setResult(errors);
}
return response;
}
InitBinder
#InitBinder
public void initBinder(WebDataBinder binder) {
binder.registerCustomEditor(DateTime.class, this.dateTimeEditor);
}

I solved this problem with using #JsonDeserialize
#JsonDeserialize(using=DateTimeDeserializer.class)
public DateTime getPublishedUntil() {
return publishedUntil;
}
I have to implemetd custom Deserializer.
public class DateTimeDeserializer extends StdDeserializer<DateTime> {
private DateTimeFormatter formatter = DateTimeFormat.forPattern(Constants.DATE_TIME_FORMAT);
public DateTimeDeserializer(){
super(DateTime.class);
}
#Override
public DateTime deserialize(JsonParser json, DeserializationContext context) throws IOException, JsonProcessingException {
try {
if(StringUtils.isBlank(json.getText())){
return null;
}
return formatter.parseDateTime(json.getText());
} catch (ParseException e) {
return null;
}
}
}

This is not handled by a Property Editor - which acts on form fields and not on json bodies. To handle a non-standard date format in a json, you will have to customize the underlying ObjectMapper. Assuming you are using jackson 2.0+, these are what you can do:
a. Tag the publishedSince field with an annotation that tells Object mapper the format for date - based on instructions here:
public class Article{
...
#JsonFormat(shape=JsonFormat.Shape.STRING, pattern="MM.dd.yyyy HH:mm")
private Date publishedSince;
}
b. Or second option is to modify the ObjectMapper itself, this could be global though, so may not work for you:
public class CustomObjectMapper extends ObjectMapper {
public CustomObjectMapper(){
super.setDateFormat(new SimpleDateFormat("MM.dd.yyyy hh:mm"));
}
}
and configure this with Spring MVC:
<mvc:annotation-driven>
<mvc:message-converters register-defaults="true">
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
<property name="objectMapper">
<bean class="..CustomObjectMapper"/>
</property>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>

With Spring MVC 4.2.1.RELEASE, you need to use the new Jackson2 dependencies as below for the Deserializer to work.
Dont use this
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
<version>1.9.12</version>
</dependency>
Use this instead.
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.2.2</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.2.2</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.2.2</version>
</dependency>
Also use com.fasterxml.jackson.databind.JsonDeserializer and com.fasterxml.jackson.databind.annotation.JsonDeserialize for the deserialization and not the classes from org.codehaus.jackson

Related

Jackson doesn't unmarshall xml correctly in Spring

I'd like to write a rest service that accepts and produces XML or JSON based on the information from headers. To do so, I followed one of tutorials. The problem is that when I try to read fields of dto in Spring controller, they are all set to null.
For test purposes, I send in body a DTO and in controller I return it concatenating string Changed to two of its fields.
In body I send:
<?xml version="1.0" encoding="UTF-8"?>
<name>name</name>
<description>description</description>
However, I receive:
<Dto name="null Changed" description="null Changed"/>
I send request by Postman:
Here's my configuration:
Controller
#RestController
public class Controller {
#RequestMapping(value = "/endpoint", method = RequestMethod.POST,
consumes = {APPLICATION_JSON_VALUE, APPLICATION_XML_VALUE},
produces = {APPLICATION_JSON_VALUE, APPLICATION_XML_VALUE})
public Dto getAndReturnEntity(#RequestBody Dto dto) {
dto.setName(dto.getName() + " Changed");
dto.setDescription(dto.getDescription() + " Changed");
return dto;
}
}
DTO
#JacksonXmlRootElement
public class Dto {
#JacksonXmlProperty(isAttribute = true) // I also tried without it
private String name;
#JacksonXmlProperty(isAttribute = true)
private String description;
// getters and setters ommited for brevity
}
Configuration for Spring
#Configuration
#EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter {
#Override
public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
configurer.favorPathExtension(true).
favorParameter(false).
parameterName("mediaType").
ignoreAcceptHeader(false).
useJaf(false).
defaultContentType(MediaType.APPLICATION_JSON).
mediaType("xml", MediaType.APPLICATION_XML).
mediaType("json", MediaType.APPLICATION_JSON);
}
}
Relevant part of pom.xml
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
The input XML should be like this:
<Dto>
<name>abcd</name>
<description>desc</description>
</Dto>
In case you want the tag names be different than you can use either custom object mapper or add #JsonProperty.

jsonb: nested serializing not called by Jsonb

New Tag request: java-ee-8
It's got a new feature, called jsonb. With jsonb, I cannot get nested serialization working. See bold printed below.
So, I wrote a jaxrs-application. This application's got a messagebodywriter using jsonb:
final JsonbConfig defaultConfig = new JsonbConfig()
.withFormatting(Boolean.TRUE)
.withNullValues(Boolean.TRUE)
.withSerializers(
new QueryParamEntrySerializer(),
new ApiResponseDtoSerializer())
.withAdapters(new ResponseStatusJsonbAdapter());
final Jsonb jsonb = JsonbBuilder.create(defaultConfig);
ApiResponseDto is like following:
#Value.Immutable
#JsonbTypeSerializer(ApiResponseDtoSerializer.class)
public interface ApiResponseDto {
ResponseStatus status();
String message();
Optional<? extends Object> data();
}
ResponseStatus is an enumm and gets serialized via the above TypeAdapter just fine.
For this class I wrote the ApiResponseDtoSerializer.
#Provider
public class ApiResponseDtoSerializer implements JsonbSerializer<ImmutableApiResponseDto> {
#Override
public void serialize(
final ImmutableApiResponseDto obj,
final JsonGenerator generator,
final SerializationContext ctx) {
generator.writeStartObject();
ctx.serialize("status", obj.status(), generator);
ctx.serialize("data", obj.data(), generator);
ctx.serialize("message", obj.message(), generator);
generator.writeEnd();
}
}
Now the Optional data() shall contain an ImmutableSet of QueryParamEntry like this:
#Value.Immutable
#JsonbTypeSerializer(ImmutableQueryParamEntrySerializer.class)
public interface QueryParamEntry {
#Value.Parameter
String key();
#Value.Parameter
Optional<String> value();
}
The type adapter is this one:
#Provider
public class ImmutableQueryParamEntrySerializer implements JsonbSerializer<ImmutableQueryParamEntry> {
private static final Logger LOG = LoggerFactory.getLogger(ImmutableQueryParamEntrySerializer.class);
#Override
public void serialize(
final ImmutableQueryParamEntry obj,
final JsonGenerator generator,
final SerializationContext ctx) {
generator.writeStartObject();
LOG.debug("Writing: key = [{}].", obj.key());
ctx.serialize("key", obj.key(), generator);
ctx.serialize("value", obj.value(), generator);
generator.writeEnd();
}
}
The final output is:
{
"status": "success",
"data": [
{
"key": null,
"value": null
}
],
"message": "Returning query param values."
}
As you can see, the nested serialization did not work. Jsonb seems to find the correct type (because otherwise it wouldn't serialize an object at all). But even the log statement from my SerializerClass is never called.
Btw: You need Guava 22 and immutables.github.io to compile this code, and slf4j obviously:
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>jaxrs-api</artifactId>
<version>3.0.2.Final</version>
<scope>provided</scope>
</dependency>
<!-- JSON-P API -->
<dependency>
<groupId>javax.json</groupId>
<artifactId>javax.json-api</artifactId>
<version>1.1</version>
<scope>provided</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/javax.json.bind/javax.json.bind-api -->
<dependency>
<groupId>javax.json.bind</groupId>
<artifactId>javax.json.bind-api</artifactId>
<version>1.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.immutables</groupId>
<artifactId>value</artifactId>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
</dependency>
So here is what it takes to make it work.
I got rid of the custom Serializers. As mentioned in my comment, they are broken before the unreleased version 1.0.3 anyway.
Instead, rename your methods to getStatus(), getMessage() and getData() (notice the get-Prefix).
For getData();, return just an Optional<Object>, not Optional<? extends Object>. Otherwise, immutables will refuse the special treatment of Optional.
After that, all just worked nicely.

Jackson (de)serialization of Java8 date/time by a JAX-RS client

I'm making a serivce client for a REST endpoint, using a JAX-RS client for the HTTP requests and Jackson to (de)serialize JSON entities. In order to handle JSR-310 (Java8) date/time objects I added the com.fasterxml.jackson.datatype:jackson-datatype-jsr310 module as a dependency to the service client, but I didn't get it to work.
How to configure JAX-RS and/or Jackson to use the jsr310 module?
I use the following dependencies:
<dependency>
<groupId>javax.ws.rs</groupId>
<artifactId>javax.ws.rs-api</artifactId>
<version>${jax-rs.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
<version>${jackson.version}</version>
</dependency>
I don't want to make the service client (which is released as a library) dependent on any specific implementation – like Jersey, so I only depend on the JAX-RS API. To run my integration tests I added:
<dependency>
<groupId>org.glassfish.jersey.core</groupId>
<artifactId>jersey-client</artifactId>
<version>${jersey.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.inject</groupId>
<artifactId>jersey-hk2</artifactId>
<version>${jersey.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-jackson</artifactId>
<version>${jersey.version}</version>
<scope>test</scope>
</dependency>
Instantiation of the JAX-RS client is done in a factory object, as follows:
import javax.ws.rs.Produces;
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
#Produces
public Client produceClient() {
return ClientBuilder.newClient();
}
A typical DTO looks like this:
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
import java.time.Instant;
import static java.util.Objects.requireNonNull;
#JsonPropertyOrder({"n", "t"})
public final class Message {
private final String name;
private final Instant timestamp;
#JsonCreator
public Message(#JsonProperty("n") final String name,
#JsonProperty("t") final Instant timestamp) {
this.name = requireNonNull(name);
this.timestamp = requireNonNull(timestamp);
}
#JsonProperty("n")
public String getName() {
return this.name;
}
#JsonProperty("t")
public Instant getTimestamp() {
return this.timestamp;
}
// equals(Object), hashCode() and toString()
}
Requests are done like this:
import javax.ws.rs.client.Entity;
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.core.MediaType;
public final class Gateway {
private final WebTarget endpoint;
public Message postSomething(final Something something) {
return this.endpoint
.request(MediaType.APPLICATION_JSON_TYPE)
.post(Entity.json(something), Message.class);
}
// where Message is the class defined above and Something is a similar DTO
}
JSON serialization and deserialization works fine for Strings, ints, BigIntegers, Lists, etc. However, when I do something like System.out.println(gateway.postSomthing(new Something("x", "y")); in my tests I get the following exception:
com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of `java.time.Instant` (no Creators, like default construct, exist): no String-argument constructor/factory method to deserialize from String value ('Fri, 22 Sep 2017 10:26:52 GMT')
at [Source: (org.glassfish.jersey.message.internal.ReaderInterceptorExecutor$UnCloseableInputStream); line: 1, column: 562] (through reference chain: Message["t"])
at org.example.com.ServiceClientTest.test(ServiceClientTest.java:52)
Caused by: com.fasterxml.jackson.databind.exc.InvalidDefinitionException:
Cannot construct instance of `java.time.Instant` (no Creators, like default construct, exist): no String-argument constructor/factory method to deserialize from String value ('Fri, 22 Sep 2017 10:26:52 GMT')
at [Source: (org.glassfish.jersey.message.internal.ReaderInterceptorExecutor$UnCloseableInputStream); line: 1, column: 562] (through reference chain: Message["t"])
at org.example.com.ServiceClientTest.test(ServiceClientTest.java:52)
From which I conclude that Jackson doesn't know how to deserialize Strings into Instants. I found blogs and SO questions about this topic, but I found no clear explanation on how to make it work.
Note that I'd like the service client to handle date strings like "Fri, 22 Sep 2017 10:26:52 GMT" as well as "2017-09-22T10:26:52.123Z", but I want it to always serialize to ISO 8601 date strings.
Who can explain how to make deserialization into an Instant work?
In the example code you're currently depending on jersey-media-json-jackson. You're probably better of by depending on Jackson's JAX-RS JSON as you are able to configure the Jackson mapper using the standard JAX-RS API (and of cource the Jackson API).
<dependency>
<groupId>com.fasterxml.jackson.jaxrs</groupId>
<artifactId>jackson-jaxrs-json-provider</artifactId>
<version>${jackson.version}</version>
</dependency>
After removing the jersey-media-json-jackson and adding the jackson-jaxrs-json-provider dependency you can configure the JacksonJaxbJsonProvider and register it in the class that produces the Client:
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.fasterxml.jackson.jaxrs.json.JacksonJaxbJsonProvider;
import com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider;
import javax.ws.rs.Produces;
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import static com.fasterxml.jackson.jaxrs.json.JacksonJaxbJsonProvider.DEFAULT_ANNOTATIONS;
public class ClientProducer {
private JacksonJsonProvider jsonProvider;
public ClientProducer() {
// Create an ObjectMapper to be used for (de)serializing to/from JSON.
ObjectMapper objectMapper = new ObjectMapper();
// Register the JavaTimeModule for JSR-310 DateTime (de)serialization
objectMapper.registerModule(new JavaTimeModule());
// Configure the object mapper te serialize to timestamp strings.
objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
// Create a Jackson Provider
this.jsonProvider = new JacksonJaxbJsonProvider(objectMapper, DEFAULT_ANNOTATIONS);
}
#Produces
public Client produceClient() {
return ClientBuilder.newClient()
// Register the jsonProvider
.register(this.jsonProvider);
}
}
Hope this helps.
You can configure the Jackson ObjectMapper in a ContextResolver. The Jackson JAX-RS provider will lookup this resolver and get the ObjectMapper from it.
#Provider
public class ObjectMapperResolver implements ContextResolver<ObjectMapper> {
private final ObjectMapper mapper;
public ObjectMapperResolver() {
mapper = new ObjectMapper();
// configure mapper
}
#Override
public ObjectMapper getContext(Class<?> cls) {
return mapper;
}
}
Then just register the resolver like you would any other provider or resource in your JAX-RS application.

jackson - jackson not creating json for nested objects

I have a user list class and an API that returns user list and total records.
The class is as follows :
#JsonInclude(JsonInclude.Include.NON_NULL)
public class FMSResponseInfo {
#JsonProperty("status")
private String status;
#JsonProperty("message")
private String message;
#JsonProperty("data")
private Object data;
#JsonProperty("status")
public String getStatus() {
return status;
}
#JsonProperty("status")
public void setStatus(String status) {
this.status = status;
}
#JsonProperty("message")
public String getMessage() {
return message;
}
#JsonProperty("message")
public void setMessage(String message) {
this.message = message;
}
#JsonProperty("data")
public Object getData() {
return data;
}
#JsonProperty("data")
public void setData(Object data) {
this.data = data;
}
}
#JsonInclude(JsonInclude.Include.NON_NULL)
public class UserListResDTO {
#JsonProperty("users")
private List<UserDTO> users;
#JsonProperty("totalRecords")
private long totalRecords;
public List<UserDTO> getUsers() {
return users;
}
public void setUsers(List<UserDTO> users) {
this.users = users;
}
public long getTotalRecords() {
return totalRecords;
}
public void setTotalRecords(long totalRecords) {
this.totalRecords = totalRecords;
}
}
I am setting an object of type UserListResDTO in FMSResponseInfo as shown below.
I have been successful in creating web services and returning response as json, so far. But the problem I am facing is that the API returns the response as follows :
{"data":"org.package.UserListResDTO#70783307","message":"Success","status":"200"}
And this is how I have written the web service :
#Path("/getUsers")
#GET
#Produces(MediaType.APPLICATION_JSON)
public FMSResponseInfo getUsers(#QueryParam("page") #DefaultValue("0") int page) {
System.out.println("In getUsers()");
FMSResponseInfo fmsResponseInfo = new FMSResponseInfo();
try {
UserListResDTO userList = fmsUserManager.getAllUsers(page);
fmsResponseInfo.setData(userList);
fmsResponseInfo.setStatus(FMSErrorMessageEnum.SUCCESS_CODE.getValue());
fmsResponseInfo.setMessage(FMSErrorMessageEnum.SUCCESS_MESSAGE.getValue());
} catch (Exception e) {
return FMSUtil.getErrorResponseInfo(FMSErrorMessageEnum.INTERNAL_SERVER_ERROR_CODE.getValue(),
e.getMessage());
}
System.out.println("Out getUsers()");
return fmsResponseInfo;
}
I guess there is some problem with the dependencies or something that I am unable to resolve. Major dependencies in my pom are :
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-servlet</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.7.2</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.7.2</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-moxy</artifactId>
</dependency>
and I am creating Web services by extending Application class as follow :
#ApplicationPath("rest")
public class FMSApplication extends Application {
public Set<Class<?>> getClasses(){
Set<Class<?>> set = new HashSet<Class<?>>();
set.add(FMSUserManagerWebService.class);
set.add(FMSDocumentManagerWebService.class);
set.add(FMSInboxManagerWebService.class);
set.add(FMSLocationManagerWebService.class);
return set;
}
}
Any help will be really appreciated as I am new to this REST web services and have been stuck for quite long.
This link will explain the answer
https://jersey.java.net/documentation/latest/media.html#d0e7963
9.1.1.1. POJO support
POJO support represents the easiest way to convert your Java Objects
to JSON and back.
Media modules that support this approach are MOXy and Jackson
The link to Jackson includes
9.1.4.1. Dependency
To use Jackson 2.x as your JSON provider you need to add
jersey-media-json-jackson module to your pom.xml file
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-jackson</artifactId>
<version>2.22.2</version>
</dependency>
I don't know much about moxy but you had jackson on your CLASSPATH and were using Jackson annonations. Jersey however was configured to use moxy.
From link
JSON binding support via MOXy is a default and preferred way of
supporting JSON binding in your Jersey applications since Jersey 2.0.
When JSON MOXy module is on the class-path, Jersey will automatically
discover the module and seamlessly enable JSON binding support via
MOXy in your applications.
MOXy seemed to have handled FMSResponseInfo. Why it didn't handle the other object I do not know. But since you wanted to use Jackson you should have been using the Jackson module.
As suggested by Shire Resident in the comments using the following dependency I was able to resolve the problem :
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-jackson</artifactId>
<version>2.22.2</version>
</dependency>

java.util.Date in Spring Data Rest

I'm using a java.util.Date in spring(3.1) data REST. How can I get the date to print in a human readable form? (e.g. MM/DD/YYYY)?
#Entity
public class MyEntity{
...
#Column(name="A_DATE_COLUMN")
#DateTimeFormat(iso=ISO.DATE)
private Date aDate;
..getters and setters
}
However when i print my entity(after overriding toString), I'm always getting the date as a long. It seems like #DateTimeFormat does not change the behaviour. I also tried different iso formats and that didnt help either.
"aDate" : 1320130800000
Here is my POM file entry for the spring data rest
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-rest-webmvc</artifactId>
<version>1.0.0.RELEASE</version>
<exclusions>
<exclusion>
<groupId></groupId>
<artifactId>slf4j-log4j12</artifactId>
</exclusion>
<exclusion>
<artifactId>commons-logging</artifactId>
<groupId>commons-logging</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
<version>2.1</version>
</dependency>
Any help is much appeciated.
PS. Here is the toString Implementation
#Override
public String toString() {
return getClass().getName() + "{"+
"\n\taDate: " + aDate
+ "\n}";
}
looks like you will need to write a custom serializer to make Jackson (the JSON library spring uses under the hood) properly serialize the date out to text.
your getter will then look like this (where JsonDateSerializer is the custom class)
#JsonSerialize(using=JsonDateSerializer.class)
public Date getDate() {
return date;
}
check out this blog post that includes code for the serializer. The serializer code is replicated here, but the explanation in the blog post may help.
/**
* Used to serialize Java.util.Date, which is not a common JSON
* type, so we have to create a custom serialize method;.
*/
#Component
public class JsonDateSerializer extends JsonSerializer<Date>{
private static final SimpleDateFormat dateFormat = new SimpleDateFormat("MM-dd-yyyy");
#Override
public void serialize(Date date, JsonGenerator gen, SerializerProvider provider)
throws IOException, JsonProcessingException {
String formattedDate = dateFormat.format(date);
gen.writeString(formattedDate);
}
}

Categories