【问题标题】:How to change the data fomat of the JSON node while serializing and deserializing in jacksonjackson中序列化和反序列化时如何改变JSON节点的数据格式
【发布时间】:2016-11-11 14:15:12
【问题描述】:

我有以下传入的 json,我将其反序列化为 Model.java,然后将该 java 对象复制到 ModelView.java。我不想将日期从 String 转换为毫秒并将 Outgoing json 作为响应发送。 我该怎么做?

我有特定的理由使用对象映射器将值从 Model.java 复制到 ModelView.java。所以请不要建议修改那部分。我希望通过注释来做到这一点。我很确定可以做到,但不知道怎么做。

这里提供的 json 是一个简单的。在实际场景中我有一个很大的 json。

传入的json

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

传出的 Json

{
 "date":236484625196
}

我的控制器类

@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);
    }
}

模型.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 应该保持不变。

【问题讨论】:

    标签: json serialization jackson deserialization jackson-modules


    【解决方案1】:

    Jackson 有一些内置的日期格式,例如,您可以在对象映射器上设置 DateFormatter,但我相信这只有在序列化和反序列化格式相同时才有效。

    一个更简单的日期序列化和反序列化方法,如果你希望序列化和反序列化是不同的格式,是直接在你的 Model.class 上使用 @JsonSerialize 和 @JsonDeserialize 注释(如果你的唯一目的,这可能会淘汰对 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
    }
    

    【讨论】:

    • 嗨@Andrew 我采纳了你的建议来实现自定义序列化程序,但做起来有点不同。我将 ModelView.java 的数据类型从 Long 更改为 String 并在该字段上实现了一个序列化程序。在序列化程序中,我没有使用 jsonGenerator.writeString ,而是使用了 jsonGenerator.number 并且它起作用了。
    猜你喜欢
    • 2015-03-19
    • 2023-03-04
    • 2016-12-11
    • 1970-01-01
    • 2014-01-06
    • 2011-08-14
    • 2015-02-28
    • 2011-07-09
    • 2013-04-09
    相关资源
    最近更新 更多