How to Set Json Request Body using ObjectMapper, JsonNode and ObjectNode

背景

在写API automation cases时,经常会遇到Json格式的request和response。在设计cases时,对json request body会有不同的设置,为了方便,我们可以写个方法满足不同层级的key,value设置。

技术

ObjectMapper 是Jackson 库的一个主要类,它将JSON映射到Java对象(反序列化),或将Java对象映射到JSON(序列化),为了使用Jackson读写json,需要创建Jackson ObjectMapper 实例。

Maven安装,POM中导入:

 <dependency>
     <groupId>com.fasterxml.jackson.core</groupId>
     <artifactId>jackson-databind</artifactId>
     <version>2.9.0</version>
 </dependency>

JsonNode vs. ObjectNode
JsonNode就是Json格式中的每个字段对象。它是所有JSON节点的基类,它是一个抽象类,绝大多数的get方法均放在了此抽象类里,目的是在不进行类型强制转换的情况下遍历结构。(下图来源网路,源出处不祥,愿owner见谅)
JsonNode
大多数的修改方法都必须通过特定的子类类型去调用,因为在构建/修改某个Node节点时,类型类型信息一般是明确的,而在读取Node节点时大多数时候并不 太关心节点类型。

Jackson JsonNode对象不可变,只可读取,这意味着不能直接构建JsonNode实例的对象图,但你可以创建JsonNode 的子类ObjectNode实例的对象图。

实现

有了上面的基础,我们就可以来实践一把:

创建ObjectMapper实例,读json文件。ResourceReader类

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
/**
 * Reads the JSON resource file.
 *
 * @param path String path to file
 * @return Document
 * @throws IOException    e
 */
public static ObjectNode readJsonFile(String path) throws IOException {
    
    
    ObjectMapper mapper = new ObjectMapper();
    ObjectNode obj = mapper.readValue(getFile(path), ObjectNode.class);
    return obj;
}

遍历json文件,设置需要改变的字段值。读取node类型为JsonNode,需要重新设置其值时,应该转换成ObjectNode。针对不同类型(Aarry,string, int)的node做了不同处理。

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.xxxx.infra.services.fw.ResourceReader;
import io.restassured.specification.RequestSpecification;

/**
 * sets the json request body from the specified file with the provided
 * json value from the feature file
 *
 * @param request The request
 * @param service The service
 * @param name    The file name
 * @param tagValues customerized values for keys
 * @return the request body with provided json value
 * @throws IOException if there is an issue with an IO operation
 */
public static void setRequestBodyFromJsonFileWithKeysValues(RequestSpecification request, String service, String name, Map<String, String> tagValues)
        throws IOException {
    
    
    String path = "request/body/" + service + "/" + name + ".json";
    ObjectNode jsonNodes = ResourceReader.readJsonFile(path);
    for (String key : tagValues.keySet()) {
    
    
        String[] node_list = key.split("\\.");
        int nodeCount = node_list.length;
        ObjectNode parentNode = jsonNodes;
        JsonNode lastNode;
        if(nodeCount == 1){
    
    
            lastNode = parentNode.get(node_list[0]);
        }
        else {
    
    
            // travel json node to find the nearest parent node for the provided node
            for (int i = 0; i < nodeCount - 1; i++) {
    
    
                lastNode = parentNode.get(node_list[i]);
                parentNode = (ObjectNode)lastNode;
            }
            lastNode = parentNode.get(node_list[nodeCount - 1]);
        }
        if (lastNode.isArray()) {
    
    
            ArrayNode jsonArr = parentNode.withArray(node_list[nodeCount - 1]);
            jsonArr.removeAll();
            String[] keyValueList = tagValues.get(key).split(",");
            for (String value : keyValueList) {
    
    
                jsonArr.add(value);
            }
        } else if (lastNode.isTextual() || lastNode.isInt()) {
    
    
            parentNode.remove(key);
            parentNode.put(key, tagValues.get(key));
        }
        request.body(jsonNodes);
    }
}

原json文件

{
    
    
  "query": "please input",
  "startIndex": 0,
  "sortType": "relevance",
  "filters": {
    
    
    "areaOfExpertise": ["Consultant Paediatrician"]
  },
  "sortOrder": "desc",
  "itemsPerPage": 50
}

cucumber feature file中step

And the body content is in the "webservices" "uk-context-search-with-filters" JSON file with the following keys and value:
      | filters.areaOfExpertise | Consultant Paediatric Neurosurgeon,Consultant Paediatrician |
      | query                   | PETER                                                       |
      | itemsPerPage            | 10                                                          |

Request Body中下列字段值已经变化了。
filters.areaOfExpertise
query
itemsPerPage

{
    
    
    "startIndex": 0,
    "sortType": "relevance",
    "filters": {
    
    
        "areaOfExpertise": [
            "Consultant Paediatric Neurosurgeon",
            "Consultant Paediatrician"
        ]
    },
    "sortOrder": "desc",
    "query": "PETER",
    "itemsPerPage": "10"
}

猜你喜欢

转载自blog.csdn.net/wumingxiaoyao/article/details/112742294