0

У меня есть следующий Incoming json, который я deserialize для Model.java, а затем скопируйте этот Java-объект в ModelView.java. Я не буду конвертировать дату из String в миллисекунды и отправить ответ исходящего json в качестве ответа. Как мне это сделать?Как изменить fomat данных узла JSON при сериализации и десериализации в jackson

У меня есть определенная причина, чтобы скопировать значение из Model.java в ModelView.java с помощью объекта mapper. Поэтому, пожалуйста, не предлагайте изменить эту часть. Я хочу сделать это через аннотацию. Я уверен, что это можно сделать, но не знаю, как это сделать.

Предлагаемый здесь json является упрощенным. У меня есть большой json в реальном сценарии.

Входящие JSON

{ 
"date":"2016-03-31" 
} 

Исходящий Json

{ 
"date":236484625196 
} 

My Controller Класс

@Controller 
public class SomeController extends BaseController { 

    @Autowired 
    private SomeService someService; 


    @RequestMapping(method = RequestMethod.GET, produces = "application/json") 
    public @ResponseBody 
    ResponseEntity<RestResponse> getDetails(HttpServletRequest request, HttpServletResponse response) { 

     Model model = someService.getData(); 

     ModelView modelView = ModelView.valueOf(model); 

     return getSuccessResponse(modelView); 
    } 
} 

Model.java

@JsonInclude(Include.NON_NULL) 
@JsonIgnoreProperties(ignoreUnknown = true) 
public class Model implements Serializable { 

    private String date; 

    //normal getters and setters 
} 

ModelView.java

@JsonInclude(Include.NON_NULL) 
@JsonIgnoreProperties(ignoreUnknown = true) 
public class ModelView implements Serializable { 

    private Long date; 
    //normal getters and setters 


    public static ModelView valueOf(Model model){ 
     SimpleDateFormat sdf = new SimpleDateFormat("yyyy-mm-dd"); 

     ObjectMapper mapper = new ObjectMapper(); 
     ModelView modelView = mapper.convertValue(model, ModelView.class); 
     try { 

      modelView.setDate(sdf.parse(model.getDate()).getTime()); 
     } catch (ParseException e) { 
      IntLogger.error("logging error here"); 
     } 
     return modelView; 
    } 
} 

Я открыт для изменения имени переменной от «дата» на что-то еще в ModelView.java, но исходящее JSON должен оставаться таким же.

ответ

1

У Jackson есть форматирование с форматированием даты, например, вы можете установить DateFormatter на объекте mapper, но я считаю, что это работает только в том случае, если формат сериализации и десериализации один и тот же.

Простейший подход к сериализации сериализации и десериализации, если вы хотите, чтобы сериализация и десериализация были в другом формате, должны использовать аннотации @JsonSerialize и @JsonDeserialize непосредственно на вашем Model.class (это может привести к устареванию необходимости в ModelView, если ваш единственный целью было преобразование даты).

Вы можете создать два класса для сериализации и десериализации:

public class JsonDateDeserializer extends JsonDeserializer<Date> { 

    @Override 
    public Date deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException { 
     final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); 
     String dateString = jsonParser.getText(); 
     try { 
      return dateFormat.parse(dateString); 
     } 
     catch (ParseException e) { 
      throw new RuntimeException(e); 
     } 
    } 
} 

Тогда для сериализации к исходящему JSON:

public class JsonDateSerializer extends JsonSerializer<Date> { 

    @Override 
    public void serialize(Date date, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException, JsonProcessingException { 
     jsonGenerator.writeString(Long.toString(date.getTime())); 

    } 
} 

Теперь для Вас просто аннотировать Model.java:

@JsonInclude(Include.NON_NULL) 
@JsonIgnoreProperties(ignoreUnknown = true) 
public class Model implements Serializable { 

    @JsonSerialize(using = JsonDateSerializer.class) 
    @JsonDeserialize(using = JsonDateDeserializer.class) 
    private String date; 

    //normal getters and setters 
} 
+0

Hi @Andrew Я принял ваш совет по внедрению пользовательского сериализатора, но сделал это немного по-другому. Я изменил тип данных моего ModelView.java с 'Long' на' String' и реализовал только сериализатор в этом поле. А в сериализаторе вместо 'jsonGenerator.writeString' я использовал' jsonGenerator.number', и он сработал. – advaita

+0

Отлично! Рад, что это сработало! –