Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 序列化列表<;项目>;使用自定义字段创建JSON_Java_Json_Spring Mvc_Gson - Fatal编程技术网

Java 序列化列表<;项目>;使用自定义字段创建JSON

Java 序列化列表<;项目>;使用自定义字段创建JSON,java,json,spring-mvc,gson,Java,Json,Spring Mvc,Gson,我试图用SpringMVC创建一个简单的RESTAPI,它以JSON格式返回数据 我正在研究一个返回作者列表的方法,可以从example.com/api/authors?find=somename访问该方法 我有一个名为Authors的JPA实体。我有一个@服务,它获取一个列表集合。Author实体具有属性,如id、firstName、lastName、birthDate 我试图实现的是,我的JSON结果类似于: { "data": [ { "id

我试图用SpringMVC创建一个简单的RESTAPI,它以JSON格式返回数据

我正在研究一个返回作者列表的方法,可以从example.com/api/authors?find=somename访问该方法

我有一个名为Authors的JPA实体。我有一个
@服务
,它获取一个
列表
集合。
Author
实体具有属性,如
id、firstName、lastName、birthDate

我试图实现的是,我的JSON结果类似于:

{
    "data": [
        {
            "id": 1,
            "name": "Leo Tolstoi",
            "age": 49
        },
        {
            "id": 2,
            "name": "Billy Shakespeare",
            "age": 32
        }
    ]
}
如您所见,结果有两个字段,它们不是直接来自实体,而是应该从
Author
实体的值生成。
name
字段是
author.getFirstName()+“”+author.getLastName()
age
someUtilityClass.calage(author.getBirthDate())

我正试图找出如何使用GSON获得这种输出

我可以做的是从服务类中获取数据并对其进行迭代,将每个迭代行保存到一个映射(或者,可能只是将每一行保存到类似于
列表
实体的东西,该实体具有类似
id、name、age等字段)。但这种方法似乎不是很干净


你们能提出一些解决方案吗?

你们应该为作者使用自定义序列化程序

因为您只需要一个序列化程序,所以下面是一个可以执行的示例。请注意,年龄在大多数情况下都会减少一岁

public static void main(String[] args) {
    GsonBuilder gBuild = new GsonBuilder();
    gBuild.registerTypeAdapter(Author.class, new AuthorSerializer());

    Author author = new Author();
    Calendar cal = Calendar.getInstance();
    cal.set(Calendar.YEAR, 1988);
    cal.set(Calendar.MONTH, 1);
    cal.set(Calendar.DAY_OF_MONTH, 1);
    author.setBirthDate(cal);
    author.setFirstName("John");
    author.setLastName("Smith");

    Gson gson = gBuild.setPrettyPrinting().create();
    System.out.println(gson.toJson(author));
}

private static class AuthorSerializer implements JsonSerializer<Author> {
    @Override
    public JsonElement serialize(Author src, Type typeOfSrc, JsonSerializationContext context) {
        Calendar today = Calendar.getInstance();
        int age = today.get(Calendar.YEAR) - src.getBirthDate().get(Calendar.YEAR);
        String fullName = src.getFirstName() + " " + src.getLastName();
        JsonObject obj = new JsonObject();
        obj.addProperty("fullName", fullName);
        obj.addProperty("age", age);
        return obj;
    }
}
publicstaticvoidmain(字符串[]args){
GsonBuilder gBuild=新的GsonBuilder();
gBuild.registerTypeAdapter(Author.class,new AuthorSerializer());
作者=新作者();
Calendar cal=Calendar.getInstance();
校准集(日历年,1988年);
校准设置(日历月,1);
校准设置(日历日/月/日,1);
作者:setBirthDate(加州);
作者:setFirstName(“约翰”);
作者:setLastName(“史密斯”);
Gson Gson=gBuild.setPrettyPrinting().create();
System.out.println(gson.toJson(author));
}
私有静态类AuthorSerializer实现JsonSerializer{
@凌驾
公共JsonElement序列化(作者src,类型typeOfSrc,JsonSerializationContext){
Calendar today=Calendar.getInstance();
int age=today.get(Calendar.YEAR)-src.getBirthDate().get(Calendar.YEAR);
字符串fullName=src.getFirstName()+“”+src.getLastName();
JsonObject obj=新的JsonObject();
对象addProperty(“全名”,全名);
对象添加属性(“年龄”,年龄);
返回obj;
}
}

DTO方法是合适的。否则,请使用
TypeAdapter
,但在这种情况下,您将业务逻辑放在序列化程序中,这是没有意义的,依我看。那么,什么是好方法呢?将数据库结果1:1转换为JSON是一个非常糟糕的想法。它可能会破坏客户端的应用程序,因为字段名可能会波动。而且数据库可能包含不适合公开披露的值。例如,密码散列、个人信息等。编写一个DTO转换器并序列化生成的DTO。那么使用我最初的方法吗?我查了一下DTO的意思,似乎我提议的AuthorJson实体就是这个意思。它包含为给定结果返回所需的属性。我会这样做。但我不需要对自己的JSON输出进行反序列化,它是为消费而设计的。那么您只需制作一个序列化器就可以了。通常,您同时创建序列化器和反序列化器。在内部,GSON可能需要一个反序列化器或实例创建者。