Java 序列化逻辑应该在实体或其他类中吗

Java 序列化逻辑应该在实体或其他类中吗,java,json,design-patterns,serialization,pojo,Java,Json,Design Patterns,Serialization,Pojo,对象序列化逻辑(字段到XML或JSON名称和值的映射)应该放在哪里?在每个实体对象内部,还是只与序列化有关的一组不同的类中?是否有其他与此问题相关的最佳实践 例如: class Person { String name; } 有些人是这样做的: class Person { String name; public String toJson () { // build JSON, use 'name' field } } 但是,如果我们还需要toX

对象序列化逻辑(字段到XML或JSON名称和值的映射)应该放在哪里?在每个实体对象内部,还是只与序列化有关的一组不同的类中?是否有其他与此问题相关的最佳实践

例如:

class Person {
    String name;
}
有些人是这样做的:

class Person {
    String name;
    public String toJson () {
      // build JSON, use 'name' field
    }
}
但是,如果我们还需要toXML()、toCSV()、toXYZ(),那么保持这个方向将产生严重污染的代码,并打破单一责任原则,即使使用单一的toJson方法IMHO,该原则也已经被打破

另一种选择,这是我通常做的:

interface Serializer {  public String toJson (); }

class PersonJsonSerializer implements Serializer {
    private Person p;
    public PersonJsonSerializer (Person p) { this.person = p; }
    public String toJson () {
      // build JSON, use p.name
    }
}
然后,工厂根据实体类型分发序列化程序:

class JsonSerializerFactory {
    public Serializer getSerializer (Object o) {
        if (o instanceof Person) {
            return new PersonJsonSerializer ((Person)o);
        }
        else if (o instanceof Account) {
            return new AccountJsonSerializer ((Account)o);
        }
        // ... etc
    }
}
还有XMLSerializerFactory、CSVSerializerFactory等等

然而,大多数情况下,人们希望完全控制序列化,不愿意接受它,而是希望在每个类中都有toJson方法。他们会声称,这种方法更简单,更不容易出错


首选的方法是什么?是否有更好的替代方案来实现此问题的解决方案?

我认为序列化逻辑不应该是POCO/数据类的一部分,原因有很多:

  • 单一责任原则(数据类应仅定义数据模型,注意序列化逻辑)
  • 您可能需要不同类型的序列化程序(json/xml等,如您所述)
  • 大多数情况下,序列化实现是通用解决方案或外部包。即使您想要为某些对象定制实现,仍然可以有一个通用的解决方案,您可以为特定的类扩展它,所以不需要为每个类都使用它
  • 您可以使用属性来修饰POCO类,以针对特殊情况指导序列化程序(例如控制属性序列、属性名称,甚至控制复杂类型属性的客户序列化程序)

  • 还有其他原因,但有一些强有力的理由说明为什么不应该将序列化逻辑放入POCO/数据模型中。

    使用序列化的自定义JSON对象非常简单

    我在我的项目中写了一个claas,我给你一个如何在项目中实现这个的线索

    应用程序(POJO类)

    现在,LoanApplicationSerializer类包含自定义 使用序列化逻辑

    包org.webservice.business.serializer;
    导入java.io.IOException;
    导入org.webservice.business.dto.Application;
    导入com.fasterxml.jackson.core.JsonGenerator;
    导入com.fasterxml.jackson.core.JsonProcessingException;
    导入com.fasterxml.jackson.databind.JsonSerializer;
    导入com.fasterxml.jackson.databind.SerializerProvider;
    公共类应用程序序列化程序扩展了JsonSerializer{
    @凌驾
    public void serialize(应用程序prm_objObjectToSerialize、JsonGenerator prm_objJsonGenerator、SerializerProvider prm_objSerializerProvider)引发IOException、JsonProcessingException{
    if(null==prm_对象作业对象序列化){
    }否则{
    试一试{
    prm_objjsonggenerator.writeStartObject();
    prm_objjsonggenerator.writeNumberField(“amount”,prm_objObjectToSerialize.getAmount());
    prm_objjsonggenerator.writeNumberField(“duration”,prm_objObjectToSerialize.getDuration());
    prm_objjsonggenerator.writeStringField(“businesstype”,prm_objObjectToSerialize.getBusinessType());
    prm_objjsonggenerator.writeStringField(“currency”,prm_objObjectToSerialize.getCurrency());
    }捕获(异常v_异常){
    v_exception.printStackTrace()
    }最后{
    prm_objjsonggenerator.writeEndObject();
    }
    }
    }
    
    当存在JAXB、Jackson等标准库时,为什么要使用自己的序列化逻辑?我同意你的看法。问题是,有时你对可用选项不够熟悉,或者时间有限,而且期限很紧,或者仅仅因为找到了“正确的”库从一个永无止境的选项海洋中取出的库会导致分析瘫痪,而您决定只要开始编码就更好了。但我同意,没有必要重新发明轮子。
     import java.io.Serializable;
     import java.util.List;
     import org.webservice.business.serializer.ApplicationSerializer;
     import com.fasterxml.jackson.databind.annotation.JsonSerialize; 
    
    @JsonSerialize(using=ApplicationSerializer.class)
      public class Application  implements Serializable {
    
    private static final long serialVersionUID = 1L;
    private double amount;
    private String businessType;
    private String currency;
    private int duration;
    }
    
     package org.webservice.business.serializer;
    
      import java.io.IOException;
      import org.webservice.business.dto.Application;
      import com.fasterxml.jackson.core.JsonGenerator;
      import com.fasterxml.jackson.core.JsonProcessingException;
      import com.fasterxml.jackson.databind.JsonSerializer;
      import com.fasterxml.jackson.databind.SerializerProvider;
    
     public class ApplicationSerializer extends JsonSerializer<Application> {
    
    @Override
    public void serialize(Application prm_objObjectToSerialize, JsonGenerator prm_objJsonGenerator, SerializerProvider prm_objSerializerProvider) throws IOException, JsonProcessingException {
        if (null == prm_objObjectToSerialize) {
        } else {
            try {
                prm_objJsonGenerator.writeStartObject();
    
                prm_objJsonGenerator.writeNumberField("amount", prm_objObjectToSerialize.getAmount());               
                prm_objJsonGenerator.writeNumberField("duration", prm_objObjectToSerialize.getDuration());
                prm_objJsonGenerator.writeStringField("businesstype", prm_objObjectToSerialize.getBusinessType());
                prm_objJsonGenerator.writeStringField("currency", prm_objObjectToSerialize.getCurrency());
    
    
            } catch (Exception v_exException) {
                v_exException.printStackTrace()
            } finally {
                prm_objJsonGenerator.writeEndObject();
            }
        }
      }