View | Details | Raw Unified | Return to bug 59609
Collapse All | Expand All

(-)a/src/components/org/apache/jmeter/extractor/json/jsonpath/JSONManager.java (-2 / +23 lines)
Lines 19-28 Link Here
19
package org.apache.jmeter.extractor.json.jsonpath;
19
package org.apache.jmeter.extractor.json.jsonpath;
20
20
21
import java.text.ParseException;
21
import java.text.ParseException;
22
import java.util.ArrayList;
22
import java.util.HashMap;
23
import java.util.HashMap;
23
import java.util.List;
24
import java.util.List;
24
import java.util.Map;
25
import java.util.Map;
25
26
27
import net.minidev.json.JSONArray;
28
import net.minidev.json.JSONObject;
29
26
import com.jayway.jsonpath.Configuration;
30
import com.jayway.jsonpath.Configuration;
27
import com.jayway.jsonpath.JsonPath;
31
import com.jayway.jsonpath.JsonPath;
28
import com.jayway.jsonpath.Option;
32
import com.jayway.jsonpath.Option;
Lines 60-72 public class JSONManager { Link Here
60
     * 
64
     * 
61
     * @param jsonString JSON String from which data is extracted
65
     * @param jsonString JSON String from which data is extracted
62
     * @param jsonPath JSON-PATH expression
66
     * @param jsonPath JSON-PATH expression
63
     * @return List of String extracted data
67
     * @return List of JSON Strings of the extracted data
64
     * @throws ParseException
68
     * @throws ParseException
65
     */
69
     */
66
    public List<Object> extractWithJsonPath(String jsonString, String jsonPath)
70
    public List<Object> extractWithJsonPath(String jsonString, String jsonPath)
67
            throws ParseException {
71
            throws ParseException {
68
        JsonPath jsonPathParser = getJsonPath(jsonPath);
72
        JsonPath jsonPathParser = getJsonPath(jsonPath);
69
        return jsonPathParser.read(jsonString, 
73
        List<Object> extractedObjects = jsonPathParser.read(jsonString,
70
                DEFAULT_CONFIGURATION);
74
                DEFAULT_CONFIGURATION);
75
        List<Object> results = new ArrayList<>(extractedObjects.size());
76
        for (Object obj: extractedObjects) {
77
            results.add(stringifyJSONObject(obj));
78
        }
79
        return results;
71
    }
80
    }
81
82
    @SuppressWarnings("unchecked")
83
    private String stringifyJSONObject(Object obj) {
84
        if (obj instanceof Map) {
85
            return new JSONObject((Map<String, ?>) obj).toJSONString();
86
        }
87
        if (obj instanceof JSONArray) {
88
            return ((JSONArray)obj).toJSONString();
89
        }
90
        return obj == null ? "" : obj.toString(); //$NON-NLS-1$
91
    }
92
72
}
93
}
(-)a/src/components/org/apache/jmeter/extractor/json/jsonpath/JSONPostProcessor.java (-16 / +21 lines)
Lines 125-135 public class JSONPostProcessor extends AbstractScopedTestElement implements Seri Link Here
125
                                        new StringBuilder(getComputeConcatenation()
125
                                        new StringBuilder(getComputeConcatenation()
126
                                                ? extractedValues.size() * 20
126
                                                ? extractedValues.size() * 20
127
                                                : 1);
127
                                                : 1);
128
                                for (Object stringExtracted : extractedValues) {
128
                                for (Object extractedObject : extractedValues) {
129
                                    vars.put(currentRefName + "_" + index, 
129
                                    String extractedString = stringify(extractedObject);
130
                                            stringExtracted != null ? stringExtracted.toString() : ""); //$NON-NLS-1$
130
                                    vars.put(currentRefName + "_" + index,
131
                                            extractedString); //$NON-NLS-1$
131
                                    if (getComputeConcatenation()) {
132
                                    if (getComputeConcatenation()) {
132
                                        concat.append(stringExtracted)
133
                                        concat.append(extractedString)
133
                                                .append(JSONPostProcessor.JSON_CONCATENATION_SEPARATOR);
134
                                                .append(JSONPostProcessor.JSON_CONCATENATION_SEPARATOR);
134
                                    }
135
                                    }
135
                                    index++;
136
                                    index++;
Lines 141-149 public class JSONPostProcessor extends AbstractScopedTestElement implements Seri Link Here
141
                            } else if (matchNumber == 0) {
142
                            } else if (matchNumber == 0) {
142
                                // Random extraction
143
                                // Random extraction
143
                                int matchSize = extractedValues.size();
144
                                int matchSize = extractedValues.size();
144
                                Object obj = extractedValues.get(JMeterUtils.getRandomInt(matchSize));
145
                                int matchNr = JMeterUtils.getRandomInt(matchSize);
145
                                vars.put(currentRefName, 
146
                                placeObjectIntoVars(vars, currentRefName,
146
                                        obj != null ? obj.toString() : ""); //$NON-NLS-1$
147
                                        extractedValues, matchNr);
147
                            } else {
148
                            } else {
148
                                // extract at position
149
                                // extract at position
149
                                if (matchNumber > extractedValues.size()) {
150
                                if (matchNumber > extractedValues.size()) {
Lines 155-174 public class JSONPostProcessor extends AbstractScopedTestElement implements Seri Link Here
155
                                    }
156
                                    }
156
                                    vars.put(currentRefName, defaultValues[i]);
157
                                    vars.put(currentRefName, defaultValues[i]);
157
                                } else {
158
                                } else {
158
                                    Object obj = extractedValues.get(matchNumber - 1);
159
                                    placeObjectIntoVars(vars, currentRefName, extractedValues, matchNumber - 1);
159
                                    vars.put(currentRefName, 
160
                                            obj != null ? obj.toString() : ""); //$NON-NLS-1$
161
                                }
160
                                }
162
                            }
161
                            }
163
                        } else {
162
                        } else {
164
                            // else just one value extracted
163
                            // else just one value extracted
165
                            Object obj = extractedValues.get(0);
164
                            placeObjectIntoVars(vars, currentRefName, extractedValues, 0);
166
                            String objAsString = 
167
                                    obj != null ? obj.toString() : ""; //$NON-NLS-1$
168
                            vars.put(currentRefName, 
169
                                    objAsString); 
170
                            if (matchNumber < 0 && getComputeConcatenation()) {
165
                            if (matchNumber < 0 && getComputeConcatenation()) {
171
                                vars.put(currentRefName + ALL_SUFFIX, objAsString);
166
                                vars.put(currentRefName + ALL_SUFFIX, vars.get(currentRefName));
172
                            }
167
                            }
173
                        }
168
                        }
174
                        vars.put(currentRefName + REF_MATCH_NR, Integer.toString(extractedValues.size()));
169
                        vars.put(currentRefName + REF_MATCH_NR, Integer.toString(extractedValues.size()));
Lines 187-192 public class JSONPostProcessor extends AbstractScopedTestElement implements Seri Link Here
187
        }
182
        }
188
    }
183
    }
189
184
185
    private void placeObjectIntoVars(JMeterVariables vars, String currentRefName,
186
            List<Object> extractedValues, int matchNr) {
187
        vars.put(currentRefName,
188
                stringify(extractedValues.get(matchNr)));
189
    }
190
191
    private String stringify(Object obj) {
192
        return obj == null ? "" : obj.toString(); //$NON-NLS-1$
193
    }
194
190
    public String getJsonPathExpressions() {
195
    public String getJsonPathExpressions() {
191
        return getPropertyAsString(JSON_PATH_EXPRESSIONS);
196
        return getPropertyAsString(JSON_PATH_EXPRESSIONS);
192
    }
197
    }
(-)a/test/src/org/apache/jmeter/extractor/TestJSONPostProcessor.java (+123 lines)
Line 0 Link Here
1
/*
2
 * Licensed to the Apache Software Foundation (ASF) under one or more
3
 * contributor license agreements.  See the NOTICE file distributed with
4
 * this work for additional information regarding copyright ownership.
5
 * The ASF licenses this file to You under the Apache License, Version 2.0
6
 * (the "License"); you may not use this file except in compliance with
7
 * the License.  You may obtain a copy of the License at
8
 *
9
 *   http://www.apache.org/licenses/LICENSE-2.0
10
 *
11
 * Unless required by applicable law or agreed to in writing, software
12
 * distributed under the License is distributed on an "AS IS" BASIS,
13
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
 * See the License for the specific language governing permissions and
15
 * limitations under the License.
16
 * 
17
 */
18
19
package org.apache.jmeter.extractor;
20
21
import java.nio.charset.StandardCharsets;
22
23
import net.minidev.json.parser.JSONParser;
24
import net.minidev.json.parser.ParseException;
25
26
import org.apache.jmeter.extractor.json.jsonpath.JSONPostProcessor;
27
import org.apache.jmeter.samplers.SampleResult;
28
import org.apache.jmeter.threads.JMeterContext;
29
import org.apache.jmeter.threads.JMeterContextService;
30
import org.apache.jmeter.threads.JMeterVariables;
31
import org.junit.Assert;
32
import org.junit.Test;
33
34
public class TestJSONPostProcessor {
35
36
    private static final String VAR_NAME = "varName";
37
38
    @Test
39
    public void testBug59609() throws ParseException {
40
        JMeterContext context = JMeterContextService.getContext();
41
        JSONPostProcessor processor = setupProcessor(context, "0", false);
42
43
        String innerValue = "{\"a\":\"one\",\"b\":\"two\"}";
44
        String data = "{\"context\":" + innerValue + "}";
45
        SampleResult result = new SampleResult();
46
        result.setResponseData(data.getBytes(StandardCharsets.UTF_8));
47
48
        JMeterVariables vars = new JMeterVariables();
49
        context.setVariables(vars);
50
        context.setPreviousResult(result);
51
52
        processor.setJsonPathExpressions("$.context");
53
        processor.process();
54
55
        JSONParser parser = new JSONParser(0);
56
        Object expectedValue = parser.parse(innerValue);
57
        Assert.assertEquals(expectedValue, parser.parse(vars.get(VAR_NAME)));
58
        Assert.assertEquals("1", vars.get(VAR_NAME + "_matchNr"));
59
    }
60
61
    @Test
62
    public void testExtractSimpleArrayElements() {
63
        JMeterContext context = JMeterContextService.getContext();
64
        JSONPostProcessor processor = setupProcessor(context, "-1");
65
        String data = "[1,2,3]";
66
        SampleResult result = new SampleResult();
67
        result.setResponseData(data.getBytes(StandardCharsets.UTF_8));
68
        JMeterVariables vars = new JMeterVariables();
69
        context.setVariables(vars);
70
        context.setPreviousResult(result);
71
72
        processor.setJsonPathExpressions("$[*]");
73
        processor.process();
74
75
        Assert.assertEquals("1,2,3", vars.get(VAR_NAME+ "_ALL"));
76
        for (int i = 1; i <= 3; i++) {
77
            String v = Integer.toString(i);
78
            Assert.assertEquals(v, vars.get(VAR_NAME + "_" + v));
79
        }
80
81
        Assert.assertEquals("3", vars.get(VAR_NAME + "_matchNr"));
82
    }
83
84
    @Test
85
    public void testExtractComplexElements() {
86
        JMeterContext context = JMeterContextService.getContext();
87
        JSONPostProcessor processor = setupProcessor(context, "-1");
88
        String data = "[{\"a\":[1,{\"d\":2},3]},[\"b\",{\"h\":23}],3]";
89
        SampleResult result = new SampleResult();
90
        result.setResponseData(data.getBytes(StandardCharsets.UTF_8));
91
        JMeterVariables vars = new JMeterVariables();
92
        context.setVariables(vars);
93
        context.setPreviousResult(result);
94
95
        processor.setJsonPathExpressions("$[*]");
96
        processor.process();
97
98
        String jsonWithoutOuterParens = data.substring(1, data.length() - 1);
99
        Assert.assertEquals(jsonWithoutOuterParens, vars.get(VAR_NAME + "_ALL"));
100
101
        Assert.assertEquals("{\"a\":[1,{\"d\":2},3]}", vars.get(VAR_NAME + "_1"));
102
        Assert.assertEquals("[\"b\",{\"h\":23}]", vars.get(VAR_NAME + "_2"));
103
        Assert.assertEquals("3", vars.get(VAR_NAME + "_3"));
104
105
        Assert.assertEquals("3", vars.get(VAR_NAME + "_matchNr"));
106
    }
107
108
    private JSONPostProcessor setupProcessor(JMeterContext context,
109
    String matchNumbers) {
110
        return setupProcessor(context, matchNumbers, true);
111
    }
112
113
    private JSONPostProcessor setupProcessor(JMeterContext context,
114
            String matchNumbers, boolean computeConcatenation) {
115
        JSONPostProcessor processor = new JSONPostProcessor();
116
        processor.setThreadContext(context);
117
        processor.setRefNames(VAR_NAME);
118
        processor.setMatchNumbers(matchNumbers);
119
        processor.setComputeConcatenation(computeConcatenation);
120
        return processor;
121
    }
122
123
}

Return to bug 59609