使用包含数组和自定义字段的杰克逊创建有效的JSON

时间:2016-04-11 01:33:42

标签: java json jackson

下面的代码使用Jackson生成JSON,就数据而言是好的,但它不是JSON

生成的JSON没有通过JSONLint,因为它在方括号和引号周围引用了引号。它也是我用它攻击的反斜杠 - 但我很确定我在下面做的事情有问题

以下是我要做的事情:

JSON应该看起来如下(我在这里添加的skip字段除外,突出显示在序列化时它将从Object中省略):

{
    "users": [{
        "foo": "abc1",
        "bar": "def1",
        "skip": "this field is skipped"
    }, {
        "foo": "abc2",
        "bar": "def2",
        "skip": "this field is skipped"
    }],
    "uri": "/users"
}

用户密钥是一组用户 - 上面显示了2个元素。跳过字段不应该是最终json的一部分,而是每个用户的一部分'对象

添加了URI字段

我的代码如下。它成功地跳过了跳过'跳过'字段,它成功构建一个几乎是JSON的字符串,如果消除了奇怪的格式。但我承认这段代码很可怕而且可能会更好(虽然我不知道自从我是新手以来)

你问的奇怪格式是什么?

  1. 反斜杠(你可以看到我已经使用hackey regex消除了)
  2. 引用[和]
  3. 引用,(逗号)
  4. 代码:

    get("/users", (request, response) -> {
        //this is the array of objects
        Object[] allUsers = listenUp.get_all_users();
    
        //Ignore this field per ListenUpUser object
        String[] ignorableFieldNames = { "skip" };
    
        ObjectMapper mapper = new ObjectMapper();
        mapper.enable(SerializationFeature.INDENT_OUTPUT);
    
        mapper.addMixIn(Object.class, PropertyFilterMixIn.class);
        FilterProvider filters = new SimpleFilterProvider()
                .addFilter("filter properties by name",
                        SimpleBeanPropertyFilter.serializeAllExcept(
                                ignorableFieldNames));
        ObjectWriter writer = mapper.writer(filters);
    
        ArrayNode array = mapper.createArrayNode();
    
        for(int i = 0; i < allUsers.length; i++) {
            array.add(writer.writeValueAsString(allUsers[i]));
        }
    
        JsonNodeFactory nodeFactory = JsonNodeFactory.instance;
        ObjectNode child = mapper.createObjectNode();
        child.put("users", array.toString());
        child.put("uri", "/users");
        response.status(200);
        response.type("application/json");
        String a = child.toString().replaceAll("\\\\", "");
        return a;
    });
    

    这已在文件顶部定义(对于跳过字段逻辑)

    @JsonFilter("filter properties by name")
    class PropertyFilterMixIn {}
    

1 个答案:

答案 0 :(得分:1)

我认为您可以使用Hashmap<String, Object>。杰克逊将了解如何将过滤器应用于数组中的Object,并将跳过它找到的任何其他对象(字符串/数组)。这是演示,对我有用:

import com.fasterxml.jackson.annotation.JsonFilter;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.ser.FilterProvider;
import com.fasterxml.jackson.databind.ser.impl.SimpleBeanPropertyFilter;
import com.fasterxml.jackson.databind.ser.impl.SimpleFilterProvider;
import org.json.JSONException;

import java.io.IOException;
import java.util.HashMap;

public class test12 {
    public static void main(String[] args) throws IOException, JSONException {
        Object[] allUsers = get_all_users();

        String[] ignorableFieldNames = {"skip"};

        ObjectMapper mapper = new ObjectMapper();
        mapper.enable(SerializationFeature.INDENT_OUTPUT);

        mapper.addMixIn(Object.class, PropertyFilterMixIn.class);
        FilterProvider filters = new SimpleFilterProvider()
                .addFilter("filter properties by name",
                        SimpleBeanPropertyFilter.serializeAllExcept(
                                ignorableFieldNames));
        mapper.setFilterProvider(filters);

        HashMap<String, Object> map = new HashMap<String, Object>();
        map.put("users", allUsers);
        map.put("uri", "/users");
        String result = mapper.writeValueAsString(map);

        System.out.println(result);
    }

    @JsonFilter("filter properties by name")
    public static class PropertyFilterMixIn {
    }

    private static Object[] get_all_users() {
        User user1 = new User();
        user1.foo = "abc1";
        user1.bar = "def1";
        user1.skip = "this field is skipped";
        User user2 = new User();
        user2.foo = "abc2";
        user2.bar = "def2";
        user2.skip = "this field is skipped";
        return new Object[]{user1, user2};
    }

    public static class User {
        public String foo;
        public String bar;
        public String skip;
    }
}

<强>结果:

{
  "users" : [ {
    "foo" : "abc1",
    "bar" : "def1"
  }, {
    "foo" : "abc2",
    "bar" : "def2"
  } ],
  "uri" : "/users"
}