Serialization for Java Calendar - java

How do I create a custom serialization for java Calendar to json by extending json serializer<Calendar>?
I tried the same for java.until.Date and it's working. In the serialization method, I converted Date as String and write it in json format.
The sample code done for java.util.Date is similar to code given below
public class CDJsonDateSerializer extends JsonSerializer<Date>{
#Override
public void serialize(Date date, JsonGenerator jsonGenerator,SerializerProvider provider)
throws IOException {
SimpleDateFormat dateFormat = new SimpleDateFormat("MM/dd/yyyy");
String dateString = dateFormat.format(date);
jsonGenerator.writeString(dateString);
}
}
And it is used like so:
#JsonSerialize(using = CDJsonDateSerializer.class)
private Date startDate;
What can I do for Serialize Calendar in java to json without losing data in Calendar object ?

From JSON to Calendar
Create a JsonSerializer:
public class CalendarSerializer extends JsonSerializer<Calendar> {
private SimpleDateFormat formatter = new SimpleDateFormat("MM/dd/yyyy");
#Override
public void serialize(Calendar calendar, JsonGenerator jsonGenerator,
SerializerProvider serializerProvider) throws IOException {
String dateAsString = formatter.format(calendar.getTime());
jsonGenerator.writeString(dateAsString);
}
}
And then use it:
#JsonSerialize(using = CalendarSerializer.class)
private Calendar calendar;
From Calendar to JSON
Create a JsonDeserializer:
public class CalendarDeserializer extends JsonDeserializer<Calendar> {
private SimpleDateFormat formatter = new SimpleDateFormat("MM/dd/yyyy");
#Override
public Calendar deserialize(JsonParser jsonParser,
DeserializationContext deserializationContext)
throws IOException {
String dateAsString = jsonParser.getText();
try {
Date date = formatter.parse(dateAsString);
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
return calendar;
} catch (Exception e) {
throw new IOException(e);
}
}
And then use it:
#JsonDeserialize(using = CalendarDeserializer.class)
private Calendar calendar;

If the only data you need as json is a date, you can using Gson:
JsonObject albums = new JsonObject();
albums.addProperty("date", new Date());
if your json instead has more than that, you can sonsider to define your own class and serialze it by adding this method to the defined class:
public String toJson() {
Gson gson = new Gson();
return gson.toJson(this);
}

Related

Unmarshalling dates using JAXB but getting nullpointer exception

I am trying to convert XML to java object. In my xml, there is field which looks like:
<pickDisplayTs>2021-09-24T18:03:06.603 +0000</pickDisplayTs>
My Java object looks like the following:
#XmlElement(name = "pickDisplayTs" )
#XmlJavaTypeAdapter(DateAdapter.class)
public Date pickDisplayTs;
My DataAdapter class is the following:
import javax.xml.bind.annotation.adapters.XmlAdapter;
import java.text.SimpleDateFormat;
import java.util.Date;
public class DateAdapter extends XmlAdapter<String, Date> {
private static final String CUSTOM_FORMAT_STRING = "yyyy-MM-
dd'T'HH:mm:ss.SSS'Z'";
#Override
public Date unmarshal(String v) throws Exception {
return new SimpleDateFormat(CUSTOM_FORMAT_STRING).parse(v);
}
#Override
public String marshal(Date v) throws Exception {
return new SimpleDateFormat(CUSTOM_FORMAT_STRING).format(v);
}
}
Code reference: https://github.com/eugenp/tutorials/blob/950bbadc353bdca114befc98cf4a18476352220e/jaxb/src/main/java/com/baeldung/jaxb/dateunmarshalling/DateAdapter.java
This is the method for unmarshalling the xml file:
String filepath = "xml/PickComplete.xml";
String xmlPickComplete = readFromResources(filepath);
PickComp pickCompleteMq = Xml.xmlToObject(xmlPickComplete, PickingSubSystemOrderCompleteMessage.class);
The entire pickCompleteMq is coming to be null but if I am declaring the pickDisplayTs as string, its all good, not sure where I am going wrong. But I need the field to be in Date.
Any help will be appreciated. Thank you.
The problem is with the input. XML extract you have provided doesn't follow the DateAdapter you are using. If you marshal a pojo that contain Date the expected xml tag should be
<pickDisplayTs>2022-02-16T14:02:13.010Z</pickDisplayTs>
Trying to parse the given input gives ParseException.
Code snippet:
Date parse = new SimpleDateFormat(CUSTOM_FORMAT_STRING).parse("2021-09-24T18:03:06.603 +0000");
System.out.println(parse);
Output
java.text.ParseException: Unparseable date: "2021-09-24T18:03:06.603 +0000"
at java.text.DateFormat.parse(DateFormat.java:366)
Solution proposal:
private static final String CUSTOM_FORMAT_STRING = "yyyy-MM-dd'T'HH:mm:ss.SSS Z";
public static void main(String[] args) throws ParseException {
String dateStr = "2021-09-24T18:03:06.603 +0000";
Date marshaledDate = new SimpleDateFormat(CUSTOM_FORMAT_STRING).parse(dateStr);
SimpleDateFormat format = new SimpleDateFormat(CUSTOM_FORMAT_STRING);
format.setTimeZone(TimeZone.getTimeZone("UTC"));
String unmarshalledDate = format.format(marshaledDate);
System.out.println(unmarshalledDate);
}
You can use the above logic in your DataAdapter class as follows:
public class DateAdapter extends XmlAdapter<String, Date> {
private static final String CUSTOM_FORMAT_STRING = "yyyy-MM-dd'T'HH:mm:ss.SSS Z";
#Override
public Date unmarshal(String v) throws Exception {
return new SimpleDateFormat(CUSTOM_FORMAT_STRING).parse(v);
}
#Override
public String marshal(Date v) throws Exception {
SimpleDateFormat sdf = new SimpleDateFormat(CUSTOM_FORMAT_STRING);
sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
return sdf.format(v);
}
}

Java ModelMapper map an object in an object

I have the following DTO and VO:
VO
public class ProjectVO {
private Date fechaInicio;
private Date fechaFin;
}
DTO
public class ProjectDTO {
private String fechaInicio;
private String fechaFin;
}
And the following converter to convert the strings to dates:
Converter<String, Date> dateConverter = new Converter<String, Date>()
{
public Date convert(MappingContext<String, Date> context)
{
Date date;
try {
date = new SimpleDateFormat("dd/MM/yyyy").parse(context.getSource());
} catch (ParseException e) {
throw new DateFormatException();
}
return date;
}
};
modelMapper.addConverter(dateConverter);
If I convert a single String to a date using modelmapper it'll work perfectly with this converter.
But now I need to convert my ProjectDTO object to a ProjectVO one and I am getting an error saying that it cannot convert a String to a Date. I suspect this is because the Date is inside the Project object. Am I right? How can I solve this?
Thanks.
Okay it works like a charm and automatically detects it if I use this:
modelMapper.createTypeMap(String.class, Date.class);
and then add the custom converter I created :)

Is there anyway I can pass a parameter to GSON JsonSerializer?

I've got a json file which has got a Date field. I'm transforming this to a required Date format(dd/MM/yyyy) using JsonDeserializer and registering the class as a TypeAdapter in GsonBuilder. Now, I want to transform this field to different date formats(say ISO8601) for different use cases. Instead of creating new JsonDeserializer's for different date formats, Is there anyway I can pass date format as one of the parameters to JsonSerializer class to make it extensible.
Deserializer class:
public class DateDeserializer implements JsonDeserializer<Date> {
private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("dd/MM/yyyy");
#Override
public Date deserialize(JsonElement jsonElement, Type type, JsonDeserializationContext jsonDeserializationContext) {
String dateString = jsonElement.getAsString();
if (!StringUtils.isEmpty(dateString)) {
try {
return DATE_FORMAT.parse(dateString);
} catch (ParseException e) {
}
}
}
GsonBuilder:
public static final Gson GSON = new GsonBuilder()
.registerTypeAdapter(Date.class, new DateDeserializer())
.serializeNulls()
.create();

How to convert date to the Brazilian standard using JAXB

I'm having problem to convert the xml object using JAXB. The date is in the format Sun Jan 30 16:08:23 BRT 18, but need to convert to the Brazilian format 12-08-2009 16:08:23.
The input is coming in format 2009-08-12 16:08:23 and want output 12-08-2009 16:08:23.
Conversion class JAXB:
public class DateAdapter extends XmlAdapter<String, Date> {
Locale brasil = new Locale("pt", "BR");
private final SimpleDateFormat dateFormat = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss", brasil);
#Override
public String marshal(Date v) throws Exception {
return dateFormat.format(v);
}
#Override
public Date unmarshal(String v) throws Exception, ParseException {
return dateFormat.parse(v);
}
}
Where i call the Adapter.
#XmlJavaTypeAdapter(DateAdapter.class)
private Date ultima_atualizacaoProduto;
You can't use the same DateFormat both both parsing as well as formatting. Assuming 30 is the Year in your question, here is how you can do it:
public class DateAdapter extends XmlAdapter<String, Date> {
private Locale brasil = new Locale("pt", "BR");
private final SimpleDateFormat SD1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
private final SimpleDateFormat SD2 = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss");
#Override
public String marshal(Date v) throws Exception {
return SD2.format(v);
}
#Override
public Date unmarshal(String v) throws Exception, ParseException {
return SD1.parse(v);
}
}
Input:
2009-08-12 16:08:23
Output:
12-08-2009 16:08:23
in general only use UTC time for DB and transfer and convert it with java8 java.time.*.
If JDK<8, you can use joda time api.

Jackson De/Serializing Date-to-String-to-Date in generic Maps

There are many examples of Jackson to/from java.util.Date code but they all seem to leverage POJO annotation. I have generic Maps of scalars that I wish to de/serialize to JSON. This is the current deserializer setup; very simple:
public class JSONUtils {
static {
DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS");
mapper = new ObjectMapper();
mapper.configure(DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS, true);
mapper.setDateFormat(df); // this works for outbounds but has no effect on inbounds
mapper.getDeserializationConfig().with(df); // Gave this a shot but still does not sniff strings for a format that we declare should be treated as java.util.Date
}
public static Map<String,Object> parseJSON(InputStream is) {
Map<String,Object> data = null;
try {
data = mapper.readValue(is, Map.class);
} catch(Exception e) {
// ...
}
return data;
}
I grok that a dateserializer can turn java.util.Date into a ISO 8601-ish string. It's going the other way that puzzles me. Clearly, in a JSON doc with no context, a string is a string so I cannot know if it was once a date. So I am prepared to duck type this and examine all strings being deserialized and if they smell like YYYY-MM-DDTHH:MM:SS.sss datetimes, then I will make a java.util.Date instead of just passing back a String. So given:
{ "name": "buzz",
"theDate": "2013-09-10T12:00:00.000"
}
will yield
Map<String,Object> m = mapper.readValue(is, Map.class);
Object o1 = m.get("name"); // o1 is instanceof String
Object o2 = m.get("theDate"); // o2 is instanceof Date
But this means that the deserializer has to return two different types and I have not been able to figure out how to do this in Jackson. Does anyone know of a good, compact example that will sniff for date-like strings and turn them into Dates, leaving others as Strings?
I've been looking for the answer on a related subject recently and come up with the following solution, thanks to Justin Musgrove and his article Custom jackson date deserializer.
Basically, the idea is to replace standard deserializer for Object.class that will convert any string in the specified format to the Date object or fallback to the standard behaviour otherwise. Obviously, this operation comes at cost of extra processing, so you'd want to keep a dedicated instance of ObjectMapper configured for this and only use it when absolutely necessary or if prepared doing second pass anyway.
Note that the Date string format in your example has no timezone component, which may cause some issues, but I leave the format as requested. You can use a parser of your choice in place of the FastDateFormat from Apache Commons Lang. I actually use Instant in my case.
CustomObjectDeserializer.java
import java.io.IOException;
import org.apache.commons.lang3.time.FastDateFormat;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.JsonTokenId;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.deser.std.UntypedObjectDeserializer;
public class CustomObjectDeserializer extends UntypedObjectDeserializer {
private static final long serialVersionUID = 1L;
private static final FastDateFormat format = FastDateFormat.getInstance("yyyy-MM-dd'T'HH:mm:ss.SSS");
public CustomObjectDeserializer() {
super(null, null);
}
#Override
public Object deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException {
if (p.getCurrentTokenId() == JsonTokenId.ID_STRING) {
try {
String value = p.getText();
// put your own parser here
return format.parse(value);
} catch (Exception e) {
return super.deserialize(p, ctxt);
}
} else {
return super.deserialize(p, ctxt);
}
}
}
JSONUtils.java
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.Map;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
public class JSONUtils {
private static final ObjectMapper mapper = new ObjectMapper();
static {
mapper.configure(DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS, true);
SimpleModule module = new SimpleModule("DateConverter");
// register a new deserializer extending and replacing UntypedObjectDeserializer
module.addDeserializer(Object.class, new CustomObjectDeserializer());
mapper.registerModule(module);
}
public static Map<String, Object> parseJSON(InputStream is) {
Map<String, Object> data = null;
try {
data = mapper.readValue(is, Map.class);
} catch (Exception e) {
// ...
e.printStackTrace();
}
return data;
}
public static void main(String[] args) throws Exception {
String input = "{\"name\": \"buzz\", \"theDate\": \"2013-09-10T12:00:00.000\"}";
InputStream is = new ByteArrayInputStream(input.getBytes(StandardCharsets.UTF_8));
Map<String, Object> m = mapper.readValue(is, Map.class);
Object o1 = m.get("name"); // o1 is instanceof String
Object o2 = m.get("theDate"); // o2 is instanceof Date
System.out.println(o1.getClass().getName() + " : " + o1);
System.out.println(o2.getClass().getName() + " : " + o2);
}
}
If you have a POJO, you can easy use annotation on get and set method with serializer and deserializer.
following an example that serialize and deserialize objects in different ways: List<POJO> to String, String to Map and Map to List<POJO> again. Obviously, in the map the Date values are as String.
This solution is thread safe because uses org.joda.time.format.DateTimeFormat and org.joda.time.format.DateTimeFormatter, you can find more info herein this post How to deserialize JS date using Jackson? and this link http://fahdshariff.blogspot.co.uk/2010/08/dateformat-with-multiple-threads.html
My POJO:
#JsonAutoDetect
public class QueueTask implements Serializable {
private static final long serialVersionUID = -4411796657106403937L;
public enum ActivitiQueueStatus {
IN_PROGRESS(AsyncProcessingWorkflowContentModel.InProgressTask.TYPE.getLocalName()), //
IN_QUEUE(AsyncProcessingWorkflowContentModel.InQueueTask.TYPE.getLocalName());
private String value;
private ActivitiQueueStatus(final String value) {
this.value = value;
}
public static ActivitiQueueStatus enumOf(final String value) {
for (ActivitiQueueStatus enum_i : values()) {
if (enum_i.value.equals(value))
return enum_i;
}
throw new IllegalArgumentException("value '" + value + "' is not a valid enum");
}
}
private String user;
private Date creationDate;
private int noRowsSelected;
private ActivitiQueueStatus status;
public String getUser() {
return user;
}
public void setUser(String user) {
this.user = user;
}
#JsonSerialize(using = JsonDateSerializer.class)
public Date getCreationDate() {
return creationDate;
}
#JsonDeserialize(using = JsonDateDeSerializer.class)
public void setCreationDate(Date creationDate) {
this.creationDate = creationDate;
}
public int getNoRowsSelected() {
return noRowsSelected;
}
public void setNoRowsSelected(int noRowsSelected) {
this.noRowsSelected = noRowsSelected;
}
public ActivitiQueueStatus getStatus() {
return status;
}
public void setStatus(ActivitiQueueStatus status) {
this.status = status;
}
}
My Serializer:
#Component
public class JsonDateDeSerializer extends JsonDeserializer<Date> {
// use joda library for thread safe issue
private static final DateTimeFormatter dateFormat = DateTimeFormat.forPattern("dd/MM/yyyy hh:mm:ss");
#Override
public Date deserialize(final JsonParser jp, final DeserializationContext ctxt) throws IOException, JsonProcessingException {
if (jp.getCurrentToken().equals(JsonToken.VALUE_STRING))
return dateFormat.parseDateTime(jp.getText().toString()).toDate();
return null;
}
}
and Deserializer:
#Component
public class JsonDateSerializer extends JsonSerializer<Date> {
// use joda library for thread safe issue
private static final DateTimeFormatter dateFormat = DateTimeFormat.forPattern("dd/MM/yyyy hh:mm:ss");
#Override
public void serialize(final Date date, final JsonGenerator gen, final SerializerProvider provider) throws IOException, JsonProcessingException {
final String formattedDate = dateFormat.print(date.getTime());
gen.writeString(formattedDate);
}
}
My Service:
public class ServiceMock {
// mock this parameter for usage.
public List<QueueTask> getActiveActivities(QName taskStatus) {
final List<QueueTask> listToReturn = new LinkedList<QueueTask>();
final SimpleDateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy hh:mm:ss");
Date d1 = null, d2 = null, d3 = null, d4 = null, d5 = null;
try {
d1 = dateFormat.parse("01/02/2013 12:44:44");
d2 = dateFormat.parse("21/12/2013 16:44:44");
d3 = dateFormat.parse("21/12/2013 16:45:44");
d4 = dateFormat.parse("21/12/2013 16:44:46");
d5 = dateFormat.parse("11/09/2013 16:44:44");
} catch (ParseException e) {
}
QueueTask dataSet = new QueueTask();
dataSet = new QueueTask();
dataSet.setUser("user_b");
dataSet.setStatus(ActivitiQueueStatus.enumOf("placeInQueue"));
dataSet.setNoRowsSelected(500);
dataSet.setCreationDate(d1);
listToReturn.add(dataSet);
dataSet = new QueueTask();
dataSet.setUser("user_d");
dataSet.setStatus(ActivitiQueueStatus.enumOf("placeInQueue"));
dataSet.setNoRowsSelected(300);
dataSet.setCreationDate(d2);
listToReturn.add(dataSet);
dataSet = new QueueTask();
dataSet.setUser("user_a");
dataSet.setStatus(ActivitiQueueStatus.enumOf("inProgress"));
dataSet.setNoRowsSelected(700);
dataSet.setCreationDate(d3);
listToReturn.add(dataSet);
dataSet = new QueueTask();
dataSet.setUser("user_k");
dataSet.setStatus(ActivitiQueueStatus.enumOf("inProgress"));
dataSet.setNoRowsSelected(700);
dataSet.setCreationDate(d4);
listToReturn.add(dataSet);
dataSet = new QueueTask();
dataSet.setUser("user_l");
dataSet.setStatus(ActivitiQueueStatus.enumOf("inProgress"));
dataSet.setNoRowsSelected(700);
dataSet.setCreationDate(d5);
listToReturn.add(dataSet);
return listToReturn;
}
}
MAIN usage:
public class SerializationServiceTest {
private static final Logger LOGGER = LoggerFactory.getLogger(OUPQueueStatusServiceIT.class);
public void testGetActiveActivitiesSerialization() throws Exception {
LOGGER.info("testGetActiveActivitiesSerialization - start");
ServiceMock mockedService = new ServiceMock();
// AsyncProcessingWorkflowContentModel.InProgressTask.TYPE is an QName, mock this calling
List<QueueTask> tasks = mockedService.getActiveActivities(AsyncProcessingWorkflowContentModel.InProgressTask.TYPE);
assertNotNull(tasks);
assertTrue(tasks.size() == 5);
assertNotNull(tasks.get(0).getUser());
assertNotNull(tasks.get(0).getCreationDate());
assertNotNull(tasks.get(0).getStatus());
assertNotNull(tasks.get(0).getNoRowsSelected());
final ObjectMapper mapper = new ObjectMapper();
final String jsonString = mapper.writeValueAsString(tasks);
assertNotNull(jsonString);
assertTrue(jsonString.contains("creationDate"));
// test serialization from string to Map
final List<Map<String, Object>> listOfMap = mapper.readValue(jsonString, new TypeReference<List<Map<String, Object>>>() {
});
assertNotNull(listOfMap);
final DateFormat formatter = new SimpleDateFormat("dd/MM/yyyy hh:mm:ss");
for (Map<String, Object> map_i : listOfMap) {
// check date value
assertTrue(map_i.containsKey("creationDate"));
final Date date = formatter.parse("" + map_i.get("creationDate"));
assertNotNull(date);
assertNotNull(map_i.get("user"));
assertNotNull(map_i.get("status"));
assertNotNull(ActivitiQueueStatus.valueOf("" + map_i.get("status")));
assertNotNull(map_i.get("noRowsSelected"));
}
// test de-serialization
List<QueueTask> deserializedTaskList = mapper.convertValue(listOfMap, new TypeReference<List<QueueTask>>() {
});
assertNotNull(deserializedTaskList);
assertTrue(deserializedTaskList.size() == 5);
for (QueueTask t : deserializedTaskList) {
assertNotNull(t.getUser());
assertNotNull(t.getCreationDate());
assertNotNull(t.getDownloadType());
assertNotNull(t.getStatus());
}
LOGGER.info("testGetActiveActivitiesSerialization - end");
}
public static void main(String[] args) throws Exception {
new SerializationServiceTest().SerializationServiceTest();
}
}
After some weeks poking around on this (and no other comments or answers), I now believe what I seek is NOT possible in Jackson. Deserialization of JSON into a Map with ducktyping for dates must occur after-the-fact. There is no way to interpose the parse stream, sniff the string for YYYY-MM-DDTHH:MM:SS.SSS and upon match substitute a Date object instead of String. You must let Jackson build the Map, then outside of Jackson go back to the top and walk the Map, sniffing for dates.
I will add that since I have a very specific duck I am looking for, the fastest implementation to turn the String into a Date is a hand-rolled thing about 120 lines long that validates and sets up the proper integer m-d-y-h-m-s-ms for Calendar then calls getTime(). 10,000,000 conversions takes 4240 millis, or about 2.3m/sec.
Before the joda-time lobby pipes up, yes, I tried that first:
// This is set up ONCE, outside the timing loop:
DateTimeFormatter format = ISODateTimeFormat.dateHourMinuteSecondMillis();
// These are in the timing loop:
while(loop) {
DateTime time = format.parseDateTime("2013-09-09T14:45:00.123");
Date d = time.toDate();
}
takes about 9630 millis to run, about 1.04m/sec; half the speed. But that's still WAY faster than the "out of the box use javax" option:
java.util.Calendar c2 = javax.xml.bind.DatatypeConverter.parseDateTime(s);
Date d = c2.getTime();
This takes 30428 mills to run, about .33m/sec -- almost 7x slower than the handroll.
SimpleDateFormat is not thread-safe so therefore was not considered in for use in converter utility where I cannot make any assumptions about the callers.
Here is a basic example on how to use Jackson to serialize deserialize a date from an object
public class JacksonSetup {
private static class JacksonSerializer {
private static JacksonSerializer instance;
private JacksonSerializer() {
}
public static JacksonSerializer getInstance() {
if (instance == null)
instance = new JacksonSerializer();
return instance;
}
public <E extends ModelObject> void writeTo(E object, Class<E> type, OutputStream out) throws IOException {
ObjectMapper mapper = getMapper();
mapper.writeValue(out, object);
}
public <E extends ModelObject> void writeTo(E object, Class<E> type, Writer out) throws IOException {
ObjectMapper mapper = getMapper();
mapper.writeValue(out, object);
}
public <E extends ModelObject> E read(String input, Class<E> type) throws IOException {
ObjectMapper mapper = getMapper();
E result = (E) mapper.readValue(input, type);
return result;
}
private ObjectMapper getMapper() {
ObjectMapper mapper = new ObjectMapper();
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
AnnotationIntrospector introspector = new JaxbAnnotationIntrospector(mapper.getTypeFactory());
mapper.setAnnotationIntrospector(introspector);
return mapper;
}
}
private static class JaxbDateSerializer extends XmlAdapter<String, Date> {
private SimpleDateFormat dateFormat = new SimpleDateFormat("MM-dd-yyyy");
#Override
public String marshal(Date date) throws Exception {
return dateFormat.format(date);
}
#Override
public Date unmarshal(String date) throws Exception {
return dateFormat.parse(date);
}
}
private static abstract class ModelObject {
}
private static class Person extends ModelObject {
private String name;
private Date bday;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
#XmlElement(name = "birth-day")
#XmlJavaTypeAdapter(JaxbDateSerializer.class)
public Date getBday() {
return bday;
}
public void setBday(Date bday) {
this.bday = bday;
}
}
public static void main(String[] args) {
try {
Person person = new Person();
person.setName("Jhon Doe");
person.setBday(new Date());
Writer writer = new StringWriter();
JacksonSerializer.getInstance().writeTo(person, Person.class, writer);
System.out.println(writer.toString());
} catch (Exception e) {
e.printStackTrace();
}
}
}

Categories